在 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,取得最新版本。

在 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 會將對應的標籤和 taint 新增至 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 會將對應的標籤和 taint 新增至 GKE 自動佈建的節點,以執行這些 Pod。

  3. 部署工作負載:

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

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

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

節點 taint 中存在 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 一律會在不同節點上執行。

使用 taint 和容許條件區隔工作負載的限制

您無法使用下列鍵前置字元來分隔工作負載:

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

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

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

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

建立具有節點汙染的叢集

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

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

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

  • 沒有任何 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:下列其中一種效果:PreferNoScheduleNoScheduleNoExecute
  • KEY=VALUE:與 EFFECT 相關聯的鍵/值組合。

控制台

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

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 按一下「 Create」(建立)

  3. 視需求設定叢集。

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

  5. 在「節點 Taint」區段中,按一下 「新增 Taint」

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

  7. 在「Key」(鍵) 和「Value」(值) 欄位中輸入所需鍵/值組合。

  8. 點選「建立」

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:節點集區的叢集名稱。

後續步驟