Docker から containerd ノードイメージに移行する


このページでは、Google Kubernetes Engine(GKE)の Standard クラスタとノードプールを、Docker から containerd コンテナ ランタイムを使用するノードイメージに移行する方法について説明します。

概要

Kubernetes ノードでは、コンテナ ランタイムを使用して、Pod で実行されるコンテナの起動、管理、停止を行います。containerd ランタイムは、GKE でサポートされている業界標準のコンテナ ランタイムです。

containerd ランタイムには、gVisorイメージ ストリーミングなどの豊富な機能を実装して GKE の機能を拡張できるようにするレイヤ抽象化の機能が用意されています。containerd ランタイムは、Docker ランタイムよりも効率的で安全なリソースとみなされます。

コンテナ ランタイムを移行するには:

  • Docker ランタイムを使用するノードを特定する
  • 移行の影響を検証する
  • ノードイメージを変更する

始める前に

作業を始める前に、次のことを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。

Docker ランタイムを使用するノードを特定する

Docker ベースのノードイメージを使用しているノードは、次の方法で確認できます。

  • スクリプトを使用して、Google Cloud プロジェクト全体のすべての GKE クラスタのすべてのノードで処理を繰り返します。
  • Google Cloud CLI、kubectl、Google Cloud コンソールのいずれかを使用して、ノードイメージを特定します。
  • サポート終了に関する分析情報と推奨事項を使用して、Google Cloud プロジェクトの特定のゾーンまたはリージョンのクラスタとノードを特定します。

移行が必要なすべてのノードを簡単に特定するために、スクリプトを使用することをおすすめします。

スクリプトを使用して Docker ノードを特定する

次のスクリプトは、使用可能なプロジェクトのすべてのクラスタ内のすべてのノードで繰り返し処理を行うと、次のような実行可能な推奨事項が提供されます。

このスクリプトは、デフォルトで containerd ノードイメージを含む Container-Optimized OS で稼働する GKE Autopilot クラスタを無視します。

次のスクリプトを実行します。

for project in $(gcloud projects list --format="value(projectId)")
do
  echo "ProjectId: $project"
  for clusters in $( \
    gcloud container clusters list \
      --project $project \
      --format="csv[no-heading](name,location,autopilot.enabled,currentMasterVersion,autoscaling.enableNodeAutoprovisioning,autoscaling.autoprovisioningNodePoolDefaults.imageType)")
  do
    IFS=',' read -r -a clustersArray <<< "$clusters"
    cluster_name="${clustersArray[0]}"
    cluster_zone="${clustersArray[1]}"
    cluster_isAutopilot="${clustersArray[2]}"
    cluster_version="${clustersArray[3]}"
    cluster_minorVersion=${cluster_version:0:4}
    cluster_autoprovisioning="${clustersArray[4]}"
    cluster_autoprovisioningImageType="${clustersArray[5]}"

    if [ "$cluster_isAutopilot" = "True" ]; then
      echo "  Cluster: $cluster_name (autopilot) (zone: $cluster_zone)"
      echo "    Autopilot clusters are running Containerd."
    else
      echo "  Cluster: $cluster_name (zone: $cluster_zone)"

      if [ "$cluster_autoprovisioning" = "True" ]; then
        if [ "$cluster_minorVersion"  \< "1.20" ]; then
          echo "    Node autoprovisioning is enabled, and new node pools will have image type 'COS'."
          echo "    This settings is not configurable on the current version of a cluster."
          echo "    Please upgrade you cluster and configure the default node autoprovisioning image type."
          echo "    "
        else
          if [ "$cluster_autoprovisioningImageType" = "COS" ]; then
            echo "    Node autoprovisioning is configured to create new node pools of type 'COS'."
            echo "    Run the following command to update:"
            echo "    gcloud container clusters update '$cluster_name' --project '$project' --zone '$cluster_zone' --enable-autoprovisioning --autoprovisioning-image-type='COS_CONTAINERD'"
            echo "    "
          fi

          if [ "$cluster_autoprovisioningImageType" = "UBUNTU" ]; then
            echo "    Node autoprovisioning is configured to create new node pools of type 'UBUNTU'."
            echo "    Run the following command to update:"
            echo "    gcloud container clusters update '$cluster_name' --project '$project' --zone '$cluster_zone' --enable-autoprovisioning --autoprovisioning-image-type='UBUNTU_CONTAINERD'"
            echo "    "
          fi
        fi
      fi

      for nodepools in $( \
        gcloud container node-pools list \
          --project $project \
          --cluster $cluster_name \
          --zone $cluster_zone \
          --format="csv[no-heading](name,version,config.imageType)")
      do
        IFS=',' read -r -a nodepoolsArray <<< "$nodepools"
        nodepool_name="${nodepoolsArray[0]}"
        nodepool_version="${nodepoolsArray[1]}"
        nodepool_imageType="${nodepoolsArray[2]}"

        nodepool_minorVersion=${nodepool_version:0:4}

        echo "    Nodepool: $nodepool_name, version: $nodepool_version ($nodepool_minorVersion), image: $nodepool_imageType"

        minorVersionWithRev="${nodepool_version/-gke./.}"
        linuxGkeMinVersion="1.14"
        windowsGkeMinVersion="1.21.1.2200"

        suggestedImageType="COS_CONTAINERD"

        if [ "$nodepool_imageType" = "UBUNTU" ]; then
          suggestedImageType="UBUNTU_CONTAINERD"
        elif [ "$nodepool_imageType" = "WINDOWS_LTSC" ]; then
          suggestedImageType="WINDOWS_LTSC_CONTAINERD"
        elif [ "$nodepool_imageType" = "WINDOWS_SAC" ]; then
          suggestedImageType="WINDOWS_SAC_CONTAINERD"
        fi

        tab=$'\n      ';
        nodepool_message="$tab Please update the nodepool to use Containerd."
        nodepool_message+="$tab Make sure to consult with the list of known issues https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd#known_issues."
        nodepool_message+="$tab Run the following command to upgrade:"
        nodepool_message+="$tab "
        nodepool_message+="$tab gcloud container clusters upgrade '$cluster_name' --project '$project' --zone '$cluster_zone' --image-type '$suggestedImageType' --node-pool '$nodepool_name'"
        nodepool_message+="$tab "

        # see https://cloud.google.com/kubernetes-engine/docs/concepts/node-images
        if [ "$nodepool_imageType" = "COS_CONTAINERD" ] || [ "$nodepool_imageType" = "UBUNTU_CONTAINERD" ] ||
           [ "$nodepool_imageType" = "WINDOWS_LTSC_CONTAINERD" ] || [ "$nodepool_imageType" = "WINDOWS_SAC_CONTAINERD" ]; then
          nodepool_message="$tab Nodepool is using Containerd already"
        elif ( [ "$nodepool_imageType" = "WINDOWS_LTSC" ] || [ "$nodepool_imageType" = "WINDOWS_SAC" ] ) &&
               [ "$(printf '%s\n' "$windowsGkeMinVersion" "$minorVersionWithRev" | sort -V | head -n1)" != "$windowsGkeMinVersion" ]; then
          nodepool_message="$tab Upgrade nodepool to the version that supports Containerd for Windows"
        elif [ "$(printf '%s\n' "$linuxGkeMinVersion" "$minorVersionWithRev" | sort -V | head -n1)" != "$linuxGkeMinVersion" ]; then
          nodepool_message="$tab Upgrade nodepool to the version that supports Containerd"
        fi
        echo "$nodepool_message"
      done
    fi # not autopilot
  done
done

# Sample output:
#
# ProjectId:  my-project-id
#  Cluster: autopilot-cluster-1 (autopilot) (zone: us-central1)
#    Autopilot clusters are running Containerd.
#  Cluster: cluster-1 (zone: us-central1-c)
#    Nodepool: default-pool, version: 1.18.12-gke.1210 (1.18), image: COS
#
#       Please update the nodepool to use Containerd.
#       Make sure to consult with the list of known issues https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd#known_issues.
#       Run the following command to upgrade:
#
#       gcloud container clusters upgrade 'cluster-1' --project 'my-project-id' --zone 'us-central1-c' --image-type 'COS_CONTAINERD' --node-pool 'default-pool'
#
#    Nodepool: pool-1, version: 1.18.12-gke.1210 (1.18), image: COS
#
#       Please update the nodepool to use Containerd.
#       Make sure to consult with the list of known issues https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd#known_issues.
#       Run the following command to upgrade:
#
#       gcloud container clusters upgrade 'cluster-1' --project 'my-project-id' --zone 'us-central1-c' --image-type 'COS_CONTAINERD' --node-pool 'pool-1'
#
#    Nodepool: winpool, version: 1.18.12-gke.1210 (1.18), image: WINDOWS_SAC
#
#       Upgrade nodepool to the version that supports Containerd for Windows
#
#  Cluster: another-test-cluster (zone: us-central1-c)
#    Nodepool: default-pool, version: 1.20.4-gke.400 (1.20), image: COS_CONTAINERD
#
#      Nodepool is using Containerd already
#

Google Cloud を使用してノードイメージを特定する

既存のノードのノードイメージは、Google Cloud CLI、kubectl、Google Cloud コンソールのいずれかを使用して確認できます。

gcloud

次のコマンドを実行します。

gcloud container node-pools list \
    --cluster=CLUSTER_NAME \
    --format="table(name,version,config.imageType)"

CLUSTER_NAME は、使用するクラスタの名前に置き換えます。

出力は次のようになります。

NAME          NODE_VERSION    IMAGE_TYPE
default-pool  1.19.6-gke.600  UBUNTU

Console

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

    Google Kubernetes Engine に移動

  2. クラスタのリストで、確認するクラスタの名前をクリックします。

  3. [ノード] タブを選択します。

  4. [ノードプール] セクションで、[イメージの種類] 列の値を確認します。

kubectl

次のコマンドを実行します。

kubectl get nodes -o wide

出力は次のようになります。

# For Docker runtime
NAME         STATUS   VERSION             OS-IMAGE                             CONTAINER-RUNTIME
gke-node-1   Ready    v1.16.15-gke.6000   Container-Optimized OS from Google   docker://19.3.1
gke-node-2   Ready    v1.16.15-gke.6000   Container-Optimized OS from Google   docker://19.3.1
gke-node-3   Ready    v1.16.15-gke.6000   Container-Optimized OS from Google   docker://19.3.1

CONTAINER-RUNTIME 列の値は、ランタイムとバージョンを示します。

非推奨に関する分析情報と推奨事項を使用してクラスタを特定する

GKE は、Docker ベースのノードイメージなど、非推奨になった機能と API の使用を検出します。詳細については、GKE のサポートの終了をご覧ください。

非推奨の使用状況を検出する一環として、GKE は分析情報と推奨事項を生成します。これにより、DEPRECATION_K8S_1_24_DOCKERSHIM 分析情報のサブタイプで Docker ベースのノードイメージの使用状況を識別できます。

分析情報と推奨事項のペアの 1 つは、Docker ベースのノードイメージを使用しているノードを持つクラスタを識別します。各分析情報と推奨事項は、Docker ベースのノードイメージを使用しており、containerd ノードイメージに移行する必要のあるクラスタ内の特定のノードプールのリストを提供します。

開始するには、非推奨の分析情報と推奨事項の表示の手順に沿ってください。 gcloud CLI コマンドでは、次のフラグを使用してこの非推奨に関する分析情報のみを表示します。

--filter="insightSubtype:DEPRECATION_K8S_1_24_DOCKERSHIM"

Docker ベースのノードイメージを使用しているクラスタのノードプールを特定したら、手順に沿ってノードイメージを containerd ノードイメージに変更します。

移行の影響を確認する

本番環境のクラスタとノードプールを containerd を使用するノードイメージに移行する前に、ステージング環境で移行の影響をテストし、問題のリスクを最小限に抑えることを強くおすすめします。

ノードの移行は、新しい構成でワークロード機能を確認する際に変数を分離できるように、ノードのアップグレードとは独立して行うことをおすすめします。また、同時にノードプールをバージョン 1.24 にアップグレードする場合、変更はロールバックできません。1.24 は、Docker ノードをサポートしておらず、マイナー バージョンをダウングレードできないためです。

ノードイメージを containerd イメージに変更する

スクリプトを使用して Docker ノードを識別した場合は、スクリプトから返された推奨コマンドを使用して、ノードの自動プロビジョニング設定とノードイメージを同等の containerd に変更できます。

ノードプールを更新して、gcloud CLI または Google Cloud コンソールで別のイメージを設定することで、Docker イメージタイプから containerd イメージタイプにノードを移行することもできます。

GKE は、選択したノードのアップグレード戦略と構成を使用して、ノードのイメージを移行します。この移行には Blue Green アップグレード戦略の使用をおすすめします。この戦略では、アップグレード中に新しいノードイメージでワークロードに問題が発生した場合に、元のノードイメージ構成を使用して前の環境にロールバックできます。

gcloud

次のコマンドを実行します。

gcloud container clusters upgrade CLUSTER_NAME \
    --image-type=NODE_IMAGE \
    --node-pool=POOL_NAME \
    --cluster-version=NODE_VERSION

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

  • NODE_IMAGE: ノードで使用するノードイメージ。
  • POOL_NAME: 移行するノードプールの名前。
  • NODE_VERSION: ノードプールの既存のバージョン。このフラグを設定することをおすすめします。そうしないと、GKE はノードプールのバージョンをコントロール プレーンのバージョンにアップグレードし、同じオペレーションでノードイメージを更新します。コントロール プレーンが 1.24 を実行している場合、コマンドは失敗します。コントロール プレーンが 1.23 を実行している場合、コマンドは成功し、2 つの変更(バージョン アップグレードとイメージ更新)を単独でテストできません。

出力は次のようになります。

NAME          NODE_VERSION    IMAGE_TYPE
default-pool  1.23.6-gke.600  UBUNTU_CONTAINERD

Console

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

    Google Kubernetes Engine に移動

  2. クラスタのリストで、確認するクラスタの名前をクリックします。

  3. [ノード] タブをクリックします。

  4. [ノードプール] セクションで、変更するノードプールの名前をクリックします。

  5. [ノードプールの詳細] ページで、[ 編集] をクリックします。

  6. [ノード] セクションの [イメージの種類] で、[変更] をクリックします。

  7. containerd イメージタイプのいずれかを選択します。

  8. [変更] をクリックします。

Docker ノードイメージにロールバックする

ノードが containerd ノードに自動または手動で移行され、ワークロードに問題がある場合は、次の手順で Docker ノードイメージに戻します。

  1. オペレーションの状況に応じて、次のいずれかの手順を選択します。
  2. GKE が移行を再試行しないように、メンテナンスの除外を構成します。
  3. Docker から移行できるように問題の根本原因を調べて、サポートされているバージョンの GKE がクラスタで実行されていることを確認します。
  4. もう一度ノードイメージを containerd イメージに変更します。メンテナンスの除外を解除すると、GKE はオペレーションを再度トリガーします。

Infrastructure as Code(IaC)ツールの構成を更新する

IaC ツール(Terraform、Ansible、Pulumi など)で GKE クラスタを管理する場合は、containerd ノードイメージを使用するように構成を更新して、ツールが以前の望ましい状態と新しい実際の状態を一致させないようにしてください。たとえば、GKE Terraform プロバイダは構成可能なイメージタイプをサポートしています。

containerd ノードイメージに移行した後は、ノードイメージが Docker ベースのノードイメージに更新されないように構成を更新します。

ノードの自動プロビジョニングのデフォルト ノード イメージを変更する

クラスタでノードの自動プロビジョニングを使用する場合は、デフォルトのイメージタイプを containerd ノードイメージに変更します。デフォルトのイメージタイプの変更は、新しく自動プロビジョニングされたノードプールにのみ適用されます。自動プロビジョニングされた既存のノードプールのノードイメージは手動で変更する必要があります。

デフォルト ノードの自動プロビジョニングのイメージタイプを変更するには、gcloud CLI または構成ファイルを使用します。

gcloud

次のコマンドを実行します。

gcloud container clusters update CLUSTER_NAME \
    --enable-autoprovisioning \
    --autoprovisioning-image-type=IMAGE_TYPE

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

  • CLUSTER_NAME: 更新するクラスタの名前。
  • IMAGE_TYPE: ノードイメージ タイプ。次のいずれかになります。

    • cos_containerd
    • ubuntu_containerd

ファイル

YAML 構成ファイルを使用して、ノードの自動プロビジョニングのデフォルトのノードイメージ タイプを変更できます。ファイルを使用する場合は、CPU とメモリリソースの最大値も指定する必要があります。

  1. 次の YAML ファイルを保存します。

    resourceLimits:
      - resourceType: 'cpu'
          minimum: 4
          maximum: 10
      - resourceType: 'memory'
          maximum: 64
    autoprovisioningNodePoolDefaults:
      imageType: 'IMAGE_TYPE'
    

    IMAGE_TYPE は、containerd のイメージタイプに置き換えます。

  2. 構成を適用します。

    gcloud container clusters update CLUSTER_NAME \
        --enable-autoprovisioning \
        --autoprovisioning-config-file=FILE_NAME
    

    FILE_NAME を構成ファイルへのパスに置き換えます。

トラブルシューティング

トラブルシューティングと既知の問題の回避策については、コンテナ ランタイムのトラブルシューティングをご覧ください。

次のステップ