GKE でワークロードの分離を構成する


このページでは、Pod を一緒に、個別に、または特定のロケーションでスケジュールするように Google Kubernetes Engine(GKE)に指示する方法を説明します。

ワークロードの分離では、taint と toleration を使用して、Pod を別のノードに分離するよう GKE に指示し、特定の条件を満たすノードに Pod を配置することや、特定のワークロードをまとめてスケジュールできます。ワークロードの分離を構成するために必要なことは、GKE クラスタの構成によって異なります。この違いを次の表に示します。

ワークロードの分離の構成

特定の Key-Value ペアの toleration を Pod 仕様に追加し、nodeSelector を使用してその Key-Value ペアを選択します。 GKE がノードを作成し、対応するノード taint を適用し、ノードで Pod をスケジュールします。

手順については、このページの Autopilot クラスタの個々のワークロードをご覧ください。

標準(ノードの自動プロビジョニングなし)
  1. ノード taint とノードラベルを使用してノードプールを作成する
  2. その taint の toleration を Pod の仕様に追加する

手順については、ワークロードを専用ノードプールに分離するをご覧ください。

このガイドでは、2 つのワークロード(バッチジョブとウェブサーバー)があり、互いに分離する必要があるというサンプル シナリオを使用します。

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 クラスタの個別のワークロード

ワークロードを互いに分離するには、ワークロードを実行するノードを定義する各ワークロード仕様に toleration とノードセレクタを追加します。この方法は、ノードの自動プロビジョニングが有効になっている 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 は、group=servers:NoSchedule taint が設定されているノードに Pod を配置できます。GKE は、これらのノードでこの toleration のない Pod をスケジュールできません。
    • spec.nodeSelector: GKE は、group: servers ノードラベルを持つノードに Pod を配置する必要があります。

    GKE は、これらの Pod を実行するために GKE が自動的にプロビジョニングするノードに、対応するラベルと taint を追加します。

  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 は、group=jobs:NoSchedule taint が設定されているノードに Pod を配置できます。GKE は、これらのノードでこの toleration のない Pod をスケジュールできません。
    • spec.nodeSelector: GKE は、group: jobs ノードラベルを持つノードに Pod を配置する必要があります。

    GKE は、これらの Pod を実行するために GKE が自動的にプロビジョニングするノードに、対応するラベルと taint を追加します。

  3. ワークロードをデプロイします。

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

ワークロードをデプロイすると、GKE はワークロードごとに次の処理を行います。

  1. GKE は、マニフェストで指定された対応するノード taint とノードラベルを持つ既存のノードを検索します。ノードが存在し、使用可能なリソースがある場合、GKE はノードにワークロードをスケジューリングします。
  2. ワークロードをスケジュールする有効なノードが見つからない場合、GKE は新しいノードを作成し、マニフェストに基づいて対応するノード taint とノードラベルを適用します。GKE は Pod を新しいノードに配置します。

ノード taint に NoSchedule 効果があると、toleration のないワークロードがノードに配置されません。

ワークロードの分離を確認する

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 と toleration によるワークロードの分離の制限

ワークロードの分離に次のキー接頭辞は使用できません。

  • GKE と Kubernetes 固有のキー
  • *cloud.google.com/
  • *kubelet.kubernetes.io/
  • *node.kubernetes.io/

ワークロードの分離には、独自の一意のキーを使用する必要があります。

ノード自動プロビジョニングのない Standard クラスタでの個別のワークロード

ノードの自動プロビジョニングを行わずに Standard クラスタでワークロードを分離するには、ワークロードに対応する適切なノード taint とノードラベルを持つノードプールを手動で作成する必要があります。手順については、ワークロードを専用ノードプールに分離するをご覧ください。この方法は、ノードプールの手動管理が必要となる特定の要件がある場合にのみ使用してください。

Node Taints を含むクラスタを作成する

GKE でクラスタを作成するとき、Node Taints をクラスタに割り当てることができます。これにより、クラスタとともに作成されたすべてのノードに taint が割り当てられます。

ノードプールを作成する場合、ノードプールはクラスタから taint を継承しません。ノードプールに対する taint が必要な場合は、ノードプールの作成時に --node-taints フラグを使用する必要があります。

NoSchedule 影響または NoExecute 影響を持つノードを含む Standard クラスタを作成すると、GKE は、クラスタの作成時に GKE が作成するデフォルトのノードプールに kube-dnsmetrics-server のような GKE マネージド コンポーネントをスケジュールできません。これらのコンポーネントにはノード taint に対応する toleration がないため、GKE はこれらのコンポーネントをスケジュールできません。次のいずれかの条件を満たす新しいノードプールを追加する必要があります。

  • taint なし
  • PreferNoSchedule の効果を持つ taint
  • components.gke.io/gke-managed-components=true:NoSchedule taint

これらの条件のいずれかにより、GKE は新しいノードプールで GKE マネージド コンポーネントをスケジュールできます。

手順については、専用ノードでのワークロードの分離をご覧ください。

gcloud

Node Taints を含むクラスタを作成します。

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

次のように置き換えます。

  • CLUSTER_NAME: 新しいクラスタの名前。
  • EFFECT: PreferNoScheduleNoScheduleNoExecute のいずれかの効果。
  • KEY=VALUE: EFFECT に関連付けられた Key-Value ペア。

コンソール

Node Taints を含むクラスタを作成します。

  1. Google Cloud コンソールで Google Kubernetes Engine のページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. 必要に応じてクラスタを構成します。

  4. ナビゲーション パネルの [ノードプール] で、変更するノードプールを展開し、[メタデータ] をクリックします。

  5. [Node Taints] セクションで、[ 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'
        }
      ]
      ...
    }
    ...
  }
}

ノードプールからすべての taint を削除する

ノードプールからすべての taint を削除するには、次のコマンドを実行します。

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

次のように置き換えます。

  • POOL_NAME: 変更するノードプールの名前。
  • CLUSTER_NAME: ノードプールのクラスタの名前。

次のステップ