影響K8S Pod分配和調度策略的兩大關鍵特性

在Kubernetes中有一個最複雜的調度器能夠處理pod的分配策略。基於在pod規範中所說起的資源需求,Kubernetes調度器會自動選擇最合適的節點來運行pod。node

但在許多實際場景下,咱們必須干預調度過程才能在pod和一個節點或兩個特定pod之間進行匹配。所以,Kubernetes中有一種十分強大的機制來管理及控制pod的分配邏輯。web

那麼,本文將探索影響Kubernetes中默認調度決定的關鍵特性。redis

節點親和性/反親和性

Kubernetes一貫以來都是依賴label和selector來對資源進行分組。例如,某服務使用selector來過濾具備特定label的pod,這些label能夠選擇性地接收流量。Label和selector可使用簡單的基於等式的條件(=and!=)來評估規則。經過nodeSelector的特性(即強制將pod調度到特定節點上),能夠將這一技術擴展到節點中。緩存

此外,label和selector開始支持基於集合的query,它帶來了基於in、notin和exist運算符的高級過濾技術。與基於等式的需求相結合,基於集合的需求提供了複雜的技術來過濾Kubernetes中的資源。app

節點親和性/反親和性使用label和annotation的基於表達集的過濾技術來定義特定節點上的pod的分配邏輯。Annotation能夠提供不會暴露到selector的其餘元數據,這意味着用於annotation的鍵不會包含在query和過濾資源中。可是節點親和性能夠在表達式中使用annotation。反親和性能夠確保pod不會被強制調度到與規則匹配的節點上。dom

除了可以在query中使用複雜的邏輯以外,節點親和性/反親和性可以爲分配邏輯強制施加硬性和軟性規則。硬性規則將會執行嚴格的策略,可能會阻止將pod分配到不符合條件的節點上。而軟性規則則會首先確認節點是否與特定的條件相匹配,若是它們不匹配,它將使用默認的調度模式來分配Pod。表達式requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution將會分別執行硬性規則和軟性規則。性能

如下是在硬性和軟性規則下使用節點親和性/反親和性的示例:ui

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
          - key: "failure-domain.beta.kubernetes.io/zone"
            operator: In
            values: ["asia-south1-a"]

以上規則將指示Kubernetes調度器嘗試將Pod分配到在GKE集羣的asia-south1-a區域中運行的節點上。若是沒有可用的節點,則調度器將會直接應用標準的分配邏輯。code

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
          - key: "failure-domain.beta.kubernetes.io/zone"
            operator: NotIn
            values: ["asia-south1-a"]

以上規則經過使用NotIn運算符來強制執行反親和性。這是一個硬性規則,它可以確保沒有pod被分配到運行在asia-south1-a空間中的GKE節點。blog

Pod親和性/反親和性

儘管節點親和性/反親和性可以處理pod和節點之間的匹配,可是有些場景下咱們須要確保pod在一塊兒運行或在相同的節點上不運行2個pod。Pod親和性/反親和性將幫助咱們應用強制實施粒度分配邏輯。

與節點親和性/反親和性中的表達式相似,pod親和性/反親和性也可以經過requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution強制實施硬性以及軟性規則。還能夠將節點親和性與pod親和性進行混合和匹配,以定義複雜的分配邏輯。

爲了可以更好地理解概念,想象一下咱們有一個web和緩存deployment,其中三個副本在一個3節點的集羣中運行。爲了確保在web和緩存pod之間低延遲,咱們想要在用一個節點上運行它們。與此同時,咱們不想在相同的節點上運行超過1個緩存pod。基於此狀況,咱們須要實施如下策略:每一個節點僅運行1個且只有1個緩存Pod的web pod。

首先,咱們將使用反親和性規則來部署緩存,它將阻止超過1個pod運行在1個節點上:

affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - redis
            topologyKey: "kubernetes.io/hostname"

topoloyKey使用附加到節點的默認label動態過濾節點的名稱。請注意,咱們使用podAntiAffinity表達式和in運算符來應用規則的方式。

假設在集羣的某個節點上安排了3個pod緩存,那麼如今咱們想要在與緩存Pod相同的節點上部署web pod。咱們將使用podAffinity來實施這一邏輯:

podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - redis
            topologyKey: "kubernetes.io/hostname"

以上代碼代表Kubernetes調度器要尋找有緩存Pod的節點並部署web pod。

除了節點和pod的親和性/反親和性以外,咱們還能使用taints和tolerations來定義自定義分配邏輯。此外,咱們還能寫自定義調度程序,它能夠從默認的調度程序中接管調度邏輯。

相關文章
相關標籤/搜索