Azure Kubernetes Services (AKS) 中進階排程器功能的最佳做法 \(部分機器翻譯\)

您在管理 Azure Kubernetes Service (AKS) 中的叢集時,往往需要隔離小組和工作負載。 Kubernetes 排程器所提供的進階功能可讓您控制:

  • 哪些 Pod 可以在特定節點上排程。
  • 多 Pod 應用程式如何適當地跨叢集散發。

本最佳做法文章著重於叢集運算子的進階 Kubernetes 排程功能。 在本文中,您將學會如何:

  • 使用污點和容差來限制可以在節點上排程的 Pod。
  • 為使用節點選取器或節點親和性,在特定節點上執行的 Pod 提供喜好設定。
  • 使用 Pod 間親和性或反親和性分割 Pod 或將 Pod 群組在一起。
  • 限制只有在具有可排程 GPU 的節點上才需要 GPU 的工作負載排程。

使用污點和容差提供專用節點

最佳做法指引:

限制耗用大量資源的應用程式 (如輸入控制器) 對特定節點的存取。 保持節點資源可提供需要它們的工作負載使用,並且不允許在節點上排程其他工作負載。

建立 AKS 叢集時,可以部署具有 GPU 支援的節點或大量功能強大的 CPU。 如需詳細資訊,請參閱在 AKS 上使用 GPU。 您可以將這些節點用於大型資料處理工作負載,例如機器學習 (ML) 或人工智慧 (AI)。

由於此節點資源硬體的部署成本通常昂貴,因此請限制可在這些節點上排程的工作負載。 相反地,請在叢集中使某些節點專門用來執行輸入服務,並防止其他工作負載。

使用多個節點集區,為不同節點提供此支援。 AKS 叢集支援一或多個節點集區。

Kubernetes 排程器會使用污點和容差來限制可以在節點上執行的工作負載。

  • 污點套用至節點,以指出只能在其上排程特定的 Pod。
  • 然後,將容差套用至 Pod,讓其可以「容許」節點的污點。

將 Pod 部署至 AKS 叢集時,Kubernetes 只會在污點與容差一致的節點上排程 Pod。 污點和容差會一起運作,以確保不會將 Pod 意外排程至節點上。 一或多個污點會套用至節點,將該節點標示為不接受任何無法容忍污點的 Pod。

例如,假設您已在 AKS 叢集中為具有 GPU 支援的節點新增節點集區。 您可以定義名稱,例如 gpu,然後定義排程的值。 將此值設定為 NoSchedule 會限制 Kubernetes 排程器不得在節點上排程未定義容差的 Pod。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name taintnp \
    --node-taints sku=gpu:NoSchedule \
    --no-wait

透過套用至節點集區中節點的污點,您會在 pod 規格中定義允許在節點上進行排程的容差。 下列範例定義 sku: gpueffect: NoSchedule 以容許上一個步驟中套用至節點的污點:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  tolerations:
  - key: "sku"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

使用 kubectl apply -f gpu-toleration.yaml 部署此 Pod 時,Kubernetes 可以在套用污點的節點上成功排程 Pod。 此邏輯隔離可讓您控制對叢集內資源的存取權。

套用污點時,請與應用程式開發人員和擁有者合作,以允許他們在部署中定義必要的容差。

如需如何在 AKS 中使用多個節點集區的詳細資訊,請參閱在 AKS 中建立叢集的多個節點集區 (部分機器翻譯)。

AKS 中污點和容差的行為

當您在 AKS 中升級節點集區時,污點和容差會遵循設定的模式,因為其會套用至新的節點:

使用 Azure 虛擬機擴展集的預設叢集

您可以從 AKS API 污染節點集區,讓新擴增的節點接收 API 指定的節點污點。

讓我們假設:

  1. 您從雙節點叢集開始:node1node2
  2. 您升級節點集區。
  3. 建立另外兩個節點:node3node4
  4. 污點會分別傳遞。
  5. 系統會刪除原始 node1node2

沒有虛擬機擴展集支援的叢集

讓我們再次假設:

  1. 您有雙節點叢集:node1node2
  2. 您升級節點集區。
  3. 建立額外的節點:node3
  4. 來自 node1 的污點會套用至 node3
  5. 系統會刪除 node1
  6. 系統會建立新的 node1,以取代原始 node1
  7. node2 污點會套用至新的 node1
  8. 系統會刪除 node2

基本上,node1 會變成 node3,而 node2 會變成新的 node1

當您在 AKS 中調整節點集區時,依設計污點和容差不會保留。

使用節點選取器和親和性來控制 pod 排程

最佳做法指導方針

使用節點選取器、節點親和性或 Pod 間親和性,來控制節點上的 Pod 排程。 這些設定可讓 Kubernetes 排程器以邏輯方式隔離工作負載,例如節點中的硬體。

污點和容差會以邏輯方式隔離具有硬式截斷的資源。 如果 Pod 無法容許節點的污點,則不會在節點上進行排程。

或者,您可以使用節點選取器。 例如,您將節點加上標籤,指出本機連接的 SSD 儲存體或大量的記憶體,然後在 Pod 規格中定義節點選取器。 Kubernetes 會在相符節點上排程這些 Pod。

與容差不同,仍然可以在加上標籤的節點上排程沒有相符節點選取器的 Pod。 此行為允許節點上未使用的資源取用,但優先使用定義相符節點選取器的 Pod。

讓我們看一下使用大量記憶體的節點範例。 這些節點可以優先使用要求大量記憶體的 Pod。 為了確定資源不會閒置,也允許其他 Pod 執行。 下列範例命令會將標籤為 hardware=highmem 的節點集區新增至 myResourceGroup 中的 myAKSCluster。 該節點集區中的所有節點都有此標籤。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name labelnp \
    --node-count 1 \
    --labels hardware=highmem \
    --no-wait

然後,pod 規格會新增 nodeSelector 屬性,以定義與節點上設定之標籤相符的節點選取器:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  nodeSelector:
      hardware: highmem

當您使用這些排程器選項時,請與應用程式開發人員和擁有者一起使用,以允許他們正確定義其 pod 規範。

如需使用節點選取器的詳細資訊,請參閱將 Pod 指派給節點

節點親和性

節點選取器是將 Pod 指派給指定節點的基本解決方案。 節點親和性提供更多的彈性,可讓您定義當 Pod 無法與節點相符時要發生的情況。 您可以:

  • 要求 Kubernetes 排程器與主機加上標籤的 Pod 相符。 或者,
  • 偏好相符項目,但如果沒有相符項目可用,則允許在不同的主機上排程 Pod。

下列範例將節點親和性設定為 requiredDuringSchedulingIgnoredDuringExecution。 此親和性要求Kubernetes計劃使用具有匹配標籤的節點。 如果沒有可用節點,則 pod 必須等候排程以繼續。 若要允許在其他節點上排程 pod,您可以將值設定為 preferredDuringSchedulingIgnoreDuringExecution

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: hardware
            operator: In
            values:
            - highmem

設定的 IgnoredDuringExecution 部分指出,如果節點標籤發生變更,則不應從節點中刪除該 Pod。 Kubernetes 排程器僅對正在排程的新 pod,而不是已在節點上排程的 pod 使用更新的節點標籤。

如需詳細資訊,請參閱親和性和反親和性

Inter-pod 親和性和反親和性

Kubernetes 排程器以邏輯方式隔離工作負載的最後一種方法,是使用 inter-pod 親和性或反親和性。 這些設定會定義「不應該」或「應該」在具有現有相符 Pod 的節點上進行排程。 根據預設,Kubernetes 排程器會嘗試跨節點在複本集中排程多個 pod。 您可以圍繞此行為定義更特定的規則。

例如,您有一個也會使用 Azure Cache for Redis 的 Web 應用程式。

  • 您會使用 Pod 反親和性規則,要求 Kubernetes 排程器跨節點散發複本。
  • 您會使用親和性規則來確保每個 Web 應用程式元件都在與對應快取相同的主機上排程。

跨節點的 pod 散發如下例所示:

節點 1 節點 2 節點 3
webapp-1 webapp-2 webapp-3
cache-1 cache-2 cache-3

Pod 間親和性和反親和性提供比節點選取器或節點親和性更複雜的部署。 透過部署,您會以邏輯方式隔離資源,並控制 Kubernetes 在節點上排程 Pod 的方式。

如需此 Web 應用程式使用 Azure Cache for Redis 範例的完整範例,請參閱在相同的節點上共置 Pod

下一步

這篇文章著重於 Kubernetes 排程器的進階功能。 如需 AKS 中叢集作業的相關詳細資訊,請參閱下列最佳作法: