異なるマシンタイプへのワークロードの移行

このチュートリアルでは、アプリケーションを停止せずに、GKE クラスタで実行されているワークロードを同じクラスタ内の新しいノードセットに移行する方法を示します。この移行方法は、異なるマシンタイプのノードにワークロードを移行する場合に有効です。

背景

ノードプールとは、マシンタイプ(CPU とメモリ)の認証スコープを含め、すべてが同じように構成されたマシンからなるサブセットです。ノードプールはクラスタ内のノードのサブセットで、1 つのコンテナ クラスタに 1 つ以上のノードプールが含まれます。

Compute Engine クラスタのマシン プロファイルを変更する必要がある場合、新しいノードプールを作成し、その新しいプールにワークロードを移行できます。

ダウンタイムを発生させずにワークロードを移行するには、次の操作を行います。

  • 既存のノードプールをスケジュール不可に設定します。
  • 既存のノードプールで実行されているワークロードをドレインします。
  • 既存のノードプールを削除します。

既存のノードプールをドレインすると、Kubernetes(GKE クラスタのオーケストレーション システム)は、強制排除された Pod を新しいノードプールに対して自動的に再スケジュールします。

始める前に

次の手順で Kubernetes Engine API を有効にします。
  1. Google Cloud Console で Kubernetes Engine ページにアクセスします。
  2. プロジェクトを作成または選択します。
  3. API と関連サービスが有効になるのを待ちます。 これには数分かかることがあります。
  4. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。 プロジェクトに対して課金が有効になっていることを確認する方法を学習する

このチュートリアルで使用されている以下のコマンドライン ツールをインストールします。

  • gcloud は、Kubernetes Engine クラスタの作成と削除に使用されます。gcloud は、Google Cloud SDK に含まれています。
  • kubectl は、Kubernetes Engine で使用されるクラスタ オーケストレーション システムである Kubernetes の管理に使用されます。gcloud を使用して kubectl をインストールできます。
    gcloud components install kubectl

gcloud コマンドライン ツールのデフォルトの設定

次のようにしてデフォルト値を設定しておくと、gcloud コマンドライン ツールでプロジェクト ID および Compute Engine ゾーン オプションを入力する時間が節約されます。
    gcloud config set project [PROJECT_ID]
    gcloud config set compute/zone [COMPUTE_ENGINE_ZONE]

ステップ 1: GKE クラスタを作成する

最初のステップは、アプリケーションのワークロードを実行するコンテナ クラスタを作成することです。次のコマンドを実行して、デフォルト マシンタイプ(n1-standard-1)に設定された 5 つのノードからなる新しいクラスタを作成します。

    gcloud container clusters create migration-tutorial --num-nodes=5
    

ステップ 2: レプリケートされたアプリケーションのデプロイを実行する

次のコマンドを実行して、サンプルウェブ アプリケーション コンテナ イメージの 6 つのレプリカのデプロイを作成します。

    kubectl run web --image=gcr.io/google-samples/hello-app:1.0 \
      --replicas=6 --limits='cpu=100m,memory=80Mi'
    

次のコマンドを実行すると、開始した Pod のリストが表示されます。

    kubectl get pods
    
出力:
    NAME                   READY     STATUS    RESTARTS   AGE
    web-2212180648-80q72   1/1       Running   0          10m
    web-2212180648-jwj0j   1/1       Running   0          10m
    web-2212180648-pf67q   1/1       Running   0          10m
    web-2212180648-pqz73   1/1       Running   0          10m
    web-2212180648-rrd3b   1/1       Running   0          10m
    web-2212180648-v3b18   1/1       Running   0          10m
    

ステップ 3: 大きいマシンタイプのノードプールを作成する

デフォルトでは、GKE によって、新しいクラスタごとに default-pool という名前のノードプールが作成されます。

    gcloud container node-pools list --cluster migration-tutorial
    
出力:
    NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
    default-pool  n1-standard-1  100           1.5.7
    

異なる [マシンタイプ] や認証スコープなど、構成の異なるインスタンスを導入するには、新しいノードプールを作成する必要があります。

次のコマンドは、n1-highmem-2 マシンタイプ(GKE のデフォルトである n1-standard-1 よりも大きいマシンタイプ)に設定された 5 つのハイメモリ インスタンスを含む新しいノードプールを larger-pool という名前で作成します。

    gcloud container node-pools create larger-pool \
      --cluster=migration-tutorial \
      --machine-type=n1-highmem-2 \
      --num-nodes=5
    

これでコンテナ クラスタに存在するノードプールが 2 つになりました。

    gcloud container node-pools list --cluster migration-tutorial
    
出力:
    NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
    default-pool  n1-standard-1  100           1.5.7
    larger-pool   n1-highmem-2   100           1.5.7
    

新しいノードプールのインスタンスが GKE クラスタに追加されています。

    kubectl get nodes
    
出力:
    NAME                                                STATUS    AGE       VERSION
    gke-migration-tutorial-default-pool-56e3af9a-059q   Ready     40m       v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready     40m       v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready     40m       v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready     40m       v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready     40m       v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready     4m        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready     4m        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready     4m        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready     4m        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready     4m        v1.5.7
    

ステップ 4: ワークロードを移行する

新しいノードプールを作成しても、ワークロードはまだ default-pool で実行されています。Pod が実行され、使用可能になっている間、Kubernetes は Pod の再スケジュールを行いません。

次のコマンドを実行して、Pod が実行されているノードを確認します(NODE 列に表示されます)。

    kubectl get pods -o=wide
    
出力:
    NAME                          READY     STATUS    IP         NODE
    web-2212180648-80q72          1/1       Running   10.8.3.4   gke-migration-tutorial-default-pool-56e3af9a-k6jm
    web-2212180648-jwj0j          1/1       Running   10.8.2.5   gke-migration-tutorial-default-pool-56e3af9a-0ng4
    web-2212180648-pf67q          1/1       Running   10.8.4.4   gke-migration-tutorial-default-pool-56e3af9a-lkrv
    web-2212180648-pqz73          1/1       Running   10.8.2.6   gke-migration-tutorial-default-pool-56e3af9a-0ng4
    web-2212180648-rrd3b          1/1       Running   10.8.4.3   gke-migration-tutorial-default-pool-56e3af9a-lkrv
    web-2212180648-v3b18          1/1       Running   10.8.1.4   gke-migration-tutorial-default-pool-56e3af9a-p9j4
    

これらの Pod を新しいノードプールに移行するには、次の操作を行います。

  1. 既存のノードプールを閉鎖する: これにより、既存のノードプール(default-pool)内のノードがスケジュール不可に設定されます。スケジュール不可に設定されると、Kubernetes はこれらのノードに新しい Pod をスケジュールしなくなります。

  2. 既存のノードプールをドレインする: これにより、既存のノードプール(default-pool)のノードで実行されているワークロードが正常に強制排除されます。

これらの操作を行うと、既存のノードプールで実行されている Pod が正常に終了し、Kubernetes が使用可能な他のノードに Pod を再スケジュールします。この場合、ステップ 3 で作成した larger-pool 内のノードだけ使用可能になります。

Kubernetes がアプリケーションを正常に終了するには、コンテナで SIGTERM 信号を処理する必要があります。この信号は、クライアントとのアクティブな接続を終了し、データベース トランザクションを適切に commit または中止するために使用されます。Pod 内のコンテナを終了するまでに Kubernetes が待機する時間を Pod マニフェストの spec.terminationGracePeriodSeconds フィールドに指定できます。デフォルトは 30 秒です。詳細については、Kubernetes のドキュメントで Pod の終了に関する説明をご覧ください。

まず、default-pool 内のノードを閉鎖します。次のコマンドを実行して、このノードプールに含まれているノードの一覧を表示します。

    kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool
    

kubectl cordon NODE コマンドを実行して、各ノードを閉鎖します。NODE は前のコマンドで確認した名前で置き換えます。各ノードに次のコマンドを実行して、ノードをスケジュール不可にします。

    for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
      kubectl cordon "$node";
    done
    
出力:
    node "gke-migration-tutorial-default-pool-56e3af9a-059q" cordoned
    node "gke-migration-tutorial-default-pool-56e3af9a-0ng4" cordoned
    node "gke-migration-tutorial-default-pool-56e3af9a-k6jm" cordoned
    node "gke-migration-tutorial-default-pool-56e3af9a-lkrv" cordoned
    node "gke-migration-tutorial-default-pool-56e3af9a-p9j4" cordoned
    

ノードのリストで、default-pool ノードのステータスが SchedulingDisabled になります。

    kubectl get nodes
    
出力:
    NAME                                                STATUS                     AGE       VERSION
    gke-migration-tutorial-default-pool-56e3af9a-059q   Ready,SchedulingDisabled   1h        v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready,SchedulingDisabled   1h        v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready,SchedulingDisabled   1h        v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready,SchedulingDisabled   1h        v1.5.7
    gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready,SchedulingDisabled   1h        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready                      1h        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready                      1h        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready                      1h        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready                      1h        v1.5.7
    gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready                      1h        v1.5.7
    

次に、各ノードの Pod を正常にドレインします。ドレインを実行するには、kubectl drain コマンドを実行して各ノードの Pod を強制排除します。

kubectl drain --force NODE コマンドも実行できます。NODE は、kubectl cordon コマンドに渡した名前のリストで置き換えます。

default-pool の各ノードに次のシェルコマンドを実行して、正常に終了するために割り当てられた期間である 10 秒間で Pod を強制排除することによって、ノードをドレインします。

    for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
      kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 "$node";
    done
    

このコマンドが完了すると、Pod が larger-pool ノードで実行されます。

    kubectl get pods -o=wide
    
出力:
    NAME                   READY     STATUS    IP         NODE
    web-2212180648-3n9hz   1/1       Running   10.8.9.4   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
    web-2212180648-88q1c   1/1       Running   10.8.7.4   gke-migration-tutorial-larger-pool-b8ec62a6-2rhk
    web-2212180648-dlmjc   1/1       Running   10.8.9.3   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
    web-2212180648-hcv46   1/1       Running   10.8.5.4   gke-migration-tutorial-larger-pool-b8ec62a6-hs6p
    web-2212180648-n0nht   1/1       Running   10.8.6.4   gke-migration-tutorial-larger-pool-b8ec62a6-7fl0
    web-2212180648-s51jb   1/1       Running   10.8.8.4   gke-migration-tutorial-larger-pool-b8ec62a6-4bb2
    

ステップ 5: 古いノードプールを削除する

web デプロイのすべての Pod が Kubernetes によって、larger-pool に再スケジュールされたら、不要になった default-pool を削除します。次のコマンドを実行して、default-pool を削除します。

    gcloud container node-pools delete default-pool --cluster migration-tutorial
    

このオペレーションが完了すると、コンテナ クラスタ内のノードプールは larger-pool だけになります。

    gcloud container node-pools list --cluster migration-tutorial
    
出力:
    NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
    larger-pool   n1-highmem-2   100           1.5.7
    

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

  • コンテナ クラスタを削除する: コンテナ クラスタを構成するリソース(Compute インスタンス、ディスク、ネットワーク リソースなど)を削除します。

    gcloud container clusters delete migration-tutorial

次のステップ