在 GKE 中設定工作負載區隔

本頁面說明如何指示 Google Kubernetes Engine (GKE) 一起、分開或在特定位置排程 Pod。

工作負載分離功能可讓您使用污點和容許度,指示 GKE 將 Pod 分離到不同節點、將 Pod 放置在符合特定條件的節點,或一起排程特定工作負載。設定工作負載分離功能時,您需要執行的操作取決於 GKE 叢集設定。下表說明兩者的差異:

工作負載分離設定

在 Pod 規格中新增特定鍵/值組合的容許條件,並使用 nodeSelector 選取該鍵/值組合。GKE 會建立節點、套用對應的節點汙染,並在節點上排定 Pod。

如需操作說明,請參閱本頁的「在 Autopilot 叢集中分離工作負載」。

標準 (不含節點自動佈建功能)
  1. 建立含有節點汙點和節點標籤的節點集區
  2. 在 Pod 規格中新增該 taint 的容許條件

如需操作說明,請參閱「在專屬節點集區中隔離工作負載」。

本指南會使用範例情境,說明如何將兩個工作負載 (批次工作和網路伺服器) 彼此分離。

何時在 GKE 中使用工作負載分離功能

如果工作負載執行不同的角色,且不應在相同的基礎機器上執行,工作負載分離功能就非常實用。以下是使用情境的一些例子:

  • 您有一個批次協調器工作負載,會建立您想分開處理的工作。
  • 您執行的遊戲伺服器具有要與工作階段 Pod 分開的媒合工作負載。
  • 您想將堆疊的各個部分彼此分開,例如將伺服器與資料庫分開。
  • 您想基於法規遵循或政策原因,將部分工作負載分開。

定價

在 Autopilot 叢集中,系統會針對 Pod 執行時要求的資源向您收費。詳情請參閱「Autopilot 定價」。使用工作負載分離的 Pod 強制執行的最低資源要求較高,高於一般 Pod。

在 Standard 叢集中,系統會根據每個節點的硬體設定和大小計費,無論節點上是否正在執行 Pod 都是如此。詳情請參閱「標準定價」。

事前準備

開始之前,請務必先完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。

在 Autopilot 叢集中區隔工作負載

如要區隔工作負載,請在每個工作負載規格中加入容許條件和節點選取器,定義工作負載應執行的節點。這個方法也適用於已啟用節點自動佈建功能的 Standard 叢集。

  1. 將下列資訊清單儲存為 web-server.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-server
    spec:
      replicas: 6
      selector:
        matchLabels:
          pod: nginx-pod
      template:
        metadata:
          labels:
            pod: nginx-pod
        spec:
          tolerations:
          - key: group
            operator: Equal
            value: "servers"
            effect: NoSchedule
          nodeSelector:
            group: "servers"
          containers:
          - name: web-server
            image: nginx
    

    這個資訊清單包含下列欄位:

    • spec.tolerations:GKE 可將 Pod 放置在具有 group=servers:NoSchedule 汙染的節點上。GKE 無法在這些節點上排程沒有這項容許條件的 Pod。
    • spec.nodeSelector:GKE 必須將 Pod 放置在具有 group: servers 節點標籤的節點上。

    GKE 會將對應的標籤和汙點新增至節點,並自動佈建這些節點來執行 Pod。

  2. 將下列資訊清單儲存為 batch-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: batch-job
    spec:
      completions: 5
      backoffLimit: 3
      ttlSecondsAfterFinished: 120
      template:
        metadata:
          labels:
            pod: pi-pod
        spec:
          restartPolicy: Never
          tolerations:
          - key: group
            operator: Equal
            value: "jobs"
            effect: NoSchedule
          nodeSelector:
            group: "jobs"
          containers:
          - name: pi
            image: perl
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
    

    這個資訊清單包含下列欄位:

    • spec.tolerations:GKE 可將 Pod 放置在具有 group=jobs:NoSchedule 汙染的節點上。GKE 無法在這些節點上排程沒有這項容許條件的 Pod。
    • spec.nodeSelector:GKE 必須將 Pod 放置在具有 group: jobs 節點標籤的節點上。

    GKE 會將對應的標籤和汙點新增至節點,並自動佈建這些節點來執行 Pod。

  3. 部署工作負載:

    kubectl apply -f batch-job.yaml web-server.yaml
    

部署工作負載時,GKE 會為每個工作負載執行下列操作:

  1. GKE 會尋找具有資訊清單中指定節點汙點和節點標籤的現有節點。如果節點存在且有可用資源,GKE 會將工作負載排程至節點。
  2. 如果 GKE 找不到可排定工作負載的現有節點,就會建立新節點,並根據資訊清單套用對應的節點汙點和節點標籤。GKE 會將 Pod 放置在新節點上。

節點汙染中存在 NoSchedule 效果,可確保沒有容許度的節點不會放置工作負載。

驗證工作負載分離

列出 Pod,找出節點名稱:

kubectl get pods --output=wide

輸出結果會與下列內容相似:

NAME                          READY   ...   NODE
batch-job-28j9h               0/1     ...   gk3-sandbox-autopilot-nap-1hzelof0-ed737889-2m59
batch-job-78rcn               0/1     ...   gk3-sandbox-autopilot-nap-1hzelof0-ed737889-2m59
batch-job-gg4x2               0/1     ...   gk3-sandbox-autopilot-nap-1hzelof0-ed737889-2m59
batch-job-qgsxh               0/1     ...   gk3-sandbox-autopilot-nap-1hzelof0-ed737889-2m59
batch-job-v4ksf               0/1     ...   gk3-sandbox-autopilot-nap-1hzelof0-ed737889-2m59
web-server-6bb8cd79b5-dw4ds   1/1     ...   gk3-sandbox-autopilot-nap-1eurxgsq-f2f3c272-n6xm
web-server-6bb8cd79b5-g5ld6   1/1     ...   gk3-sandbox-autopilot-nap-1eurxgsq-9f447e18-275z
web-server-6bb8cd79b5-jcdx5   1/1     ...   gk3-sandbox-autopilot-nap-1eurxgsq-9f447e18-275z
web-server-6bb8cd79b5-pxdzw   1/1     ...   gk3-sandbox-autopilot-nap-1eurxgsq-ccd22fd9-qtfq
web-server-6bb8cd79b5-s66rw   1/1     ...   gk3-sandbox-autopilot-nap-1eurxgsq-ccd22fd9-qtfq
web-server-6bb8cd79b5-zq8hh   1/1     ...   gk3-sandbox-autopilot-nap-1eurxgsq-f2f3c272-n6xm

這項輸出內容顯示 batch-job Pod 和 web-server Pod 一律會在不同節點上執行。

使用汙點和容許度的限制

您無法使用下列鍵前置字元進行工作負載分離:

  • GKE 和 Kubernetes 專屬金鑰
  • *cloud.google.com/
  • *kubelet.kubernetes.io/
  • *node.kubernetes.io/

您應使用自己的專屬金鑰,以區隔工作負載。

在沒有自動佈建節點功能的 Standard 叢集中,將工作負載分開

在沒有自動佈建節點功能的 Standard 叢集中區隔工作負載時,您必須手動建立節點集區,並使用適當的節點汙點和節點標籤來容納工作負載。如需操作說明,請參閱「在專屬節點集區中隔離工作負載」。只有在有特定需求,需要手動管理節點集區時,才建議使用這個方法。

建立具有節點汙染的叢集

在 GKE 中建立叢集時,您可以為叢集指派節點汙點。這會將汙點指派給叢集建立的所有節點。

如果您建立節點集區,節點集區不會從叢集繼承汙點。如要在節點集區上設定汙點,建立節點集區時必須使用 --node-taints 旗標。

如果您建立的標準叢集含有 NoSchedule 或 NoExecute 效果的節點汙染,GKE 就無法在您建立叢集時,排定部分 GKE 管理的元件 (例如 kube-dns 或 metrics-server) 在 GKE 建立的預設節點集區上執行。GKE 無法排程這些元件,因為這些元件沒有對應的節點容許條件。您必須新增符合下列任一條件的節點集區:

  • 沒有任何 taint
  • 具有 PreferNoSchedule 效果的汙點
  • components.gke.io/gke-managed-components=true:NoSchedule taint

只要符合任一條件,GKE 就能在新節點集區中排定 GKE 管理的元件。

如需操作說明,請參閱「在專屬節點上隔離工作負載」。

gcloud

建立具有節點汙染的叢集:

gcloud container clusters create CLUSTER_NAME \
    --node-taints KEY=VALUE:EFFECT

更改下列內容:

  • CLUSTER_NAME:新叢集的名稱。
  • EFFECT:下列其中一種效果:PreferNoSchedule、NoSchedule 或 NoExecute。
  • KEY=VALUE:與 EFFECT 相關聯的鍵/值組合。

控制台

建立具有節點汙染的叢集:

  1. 前往 Google Cloud 控制台的「Create a Kubernetes cluster」(建立 Kubernetes 叢集) 頁面。

    前往「建立 Kubernetes 叢集」

  2. 視需求設定叢集。

  3. 在導覽窗格的「Node Pools」(節點集區) 下方,展開要修改的節點集區,然後按一下「Metadata」(中繼資料)。

  4. 在「節點汙染」部分中,按一下 「新增汙染」。

  5. 在「效果」下拉式清單中,選取所需效果。

  6. 在「鍵」和「值」欄位中輸入所需鍵/值組合。

  7. 點選「建立」。

API

使用 API 建立叢集時,請在 `nodeConfig: 下方加入 nodeTaints 欄位:

POST https://container.googleapis.com/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/clusters

{
  'cluster': {
    'name': 'example-cluster',
    'nodeConfig': {
      'nodeTaints': [
        {
          'key': 'special',
          'Value': 'gpu',
          'effect': 'PreferNoSchedule'
        }
      ]
      ...
    }
    ...
  }
}

移除節點集區的所有汙點

如要從節點集區移除所有汙點,請執行下列指令:

gcloud beta container node-pools update POOL_NAME \
    --node-taints="" \
    --cluster=CLUSTER_NAME

更改下列內容:

  • POOL_NAME:要變更的節點集區名稱。
  • CLUSTER_NAME:節點集區的叢集名稱。

後續步驟