ノードを containerd 2 に移行する

Google Kubernetes Engine(GKE)クラスタは、バージョン 1.24 以降を実行するすべてのワーカーノードで containerd ノードイメージを使用します。ワーカーノードは、GKE バージョンに基づいて特定のバージョンの containerd を使用します。

  • containerd ノードイメージを使用して GKE 1.32 以前を実行するノードは、containerd 1.7 以前のバージョンを使用します。
  • GKE 1.33 を実行するノードは containerd 2.0 を使用します。

GKE ノードが 1.32 から 1.33 にアップグレードされると、ノードは containerd 1.7 から新しいメジャー バージョンの containerd 2.0 に移行します。GKE バージョンで使用する containerd バージョンを変更することはできません。

ワークロードが containerd 2 で想定どおりに実行されていることがわかっている場合、このページを読む必要はありません。

GKE での containerd 2 への移行

次のタイムラインを確認して、containerd 2 を使用するために GKE が既存のクラスタを移行する過程を確認してください。

  • マイナー バージョン 1.32 では、GKE は containerd 1.7 を使用します。containerd 1.7 では、Docker スキーマ 1 イメージと Container Runtime Interface(CRI)v1alpha2 API の両方が非推奨になりました。以前のバージョンで非推奨になったその他の機能については、非推奨の構成プロパティをご覧ください。
  • マイナー バージョン 1.33 では、GKE は containerd 2.0 を使用します。これにより、Docker スキーマ 1 イメージと CRI v1alpha2 API のサポートが終了します。
  • CRI プラグイン内の containerd 構成プロパティ、registry.authsregistry.configsregistry.mirrors は非推奨であり、containerd 2.2 で削除されます。GKE バージョンはまだ発表されていません。ただし、registry.configs.tls は、containerd 2.0 ですでに削除されています。

1.33 などの新しいマイナー バージョンへの自動アップグレードのおおよそのタイミングについては、リリース チャンネルのおおよそのスケジュールをご覧ください。

containerd 2 への移行の影響

containerd 2 へのこの移行の影響については、次のセクションをご覧ください。

自動アップグレードの一時停止

クラスタで非推奨の機能が使用されていることを検出すると、GKE は 1.33 への自動アップグレードを一時停止します。ただし、クラスタノードでこれらの機能を使用する場合は、メンテナンスの除外を作成して、ノードのアップグレードを防ぐことをおすすめします。メンテナンスの除外を使用すると、GKE で使用が検出されない場合、ノードがアップグレードされなくなります。

これらの機能の使用から移行した後、GKE は、次の条件が満たされている場合には、1.33 への自動マイナー アップグレードを再開します。

  • GKE が非推奨の機能の使用を 14 日間検出していない、または非推奨の CRI registry.configs プロパティを 3 日間検出していない。
  • 1.33 がクラスタノードの自動アップグレードのターゲットである。
  • その他のブロック要因がない。詳細については、自動アップグレードのタイミングをご覧ください。

Standard クラスタのノードプールの場合は、ノードプールを手動でアップグレードすることもできます。

サポート終了と移行の準備ができていない場合の影響

GKE は、標準サポートの終了まで自動アップグレードを一時停止します。クラスタが Extended チャンネルに登録されている場合、ノードは拡張サポートの終了まで同じバージョンを維持できます。サポート終了時のノードの自動アップグレードの詳細については、サポート終了時の自動アップグレードをご覧ください。

これらの機能から移行しない場合、1.32 がサポート終了になり、クラスタノードが 1.33 に自動的にアップグレードされると、クラスタで次の問題が発生する可能性があります。

  • Docker スキーマ 1 イメージを使用するワークロードが失敗します。
  • CRI v1alpha2 API を呼び出すアプリケーションで、API の呼び出しが失敗します。

影響を受けるクラスタを特定する

GKE はクラスタをモニタリングし、Recommender サービスを使用して分析情報と推奨事項という形式でガイダンスを提供します。これにより、非推奨の機能を使用するクラスタノードを特定できます。

バージョン要件

クラスタは、次のバージョン以降を実行している場合に、これらの分析情報と推奨事項を受け取ります。

  • 1.28.15-gke.1159000
  • 1.29.9-gke.1541000
  • 1.30.5-gke.1355000
  • 1.31.1-gke.1621000

分析情報と推奨事項を取得する

分析情報と推奨事項を表示するの説明に従ってください。分析情報は Google Cloud コンソールを使用して取得できます。Google Cloud CLI または Recommender API を使用して、次のサブタイプでフィルタすることもできます。

  • DEPRECATION_CONTAINERD_V1_SCHEMA_IMAGES: Docker スキーマ 1 イメージ
  • DEPRECATION_CONTAINERD_V1ALPHA2_CRI_API: CRI v1alpha2 API
  • DEPRECATION_CONTAINERD_V2_CONFIG_REGISTRY_CONFIGS: 非推奨の CRI registry.configs プロパティ(registry.configs.authregistry.configs.tls など)

非推奨の機能から移行する

containerd 2 で非推奨になった機能から移行する方法については、次の内容をご覧ください。

Docker スキーマ 1 イメージから移行する

移行が必要なイメージを使用しているワークロードを特定し、それらのワークロードを移行します。

この問題の影響を受ける Google 提供のイメージは gcr.io/google-containers/startup-script です。

  • gcr.io/google-containers/startup-script:v1: 非推奨の Schema 1 形式を使用しており、GKE 1.33 以降では pull できません。
  • gcr.io/google-containers/startup-script:v2: サポートされている Schema 2 形式を使用しており、正常に pull できます。

ワークロード(DaemonSet や Deployment など)で gcr.io/google-containers/startup-script:v1 を使用している場合は、イメージ参照を gcr.io/google-containers/startup-script:v2 に更新する必要があります。

移行するイメージを探す

移行が必要なイメージは、さまざまなツールを使用して見つけることができます。

分析情報と推奨事項、または Cloud Logging を使用する

影響を受けるクラスタを特定するで説明したように、クラスタが最小バージョン以降を実行している場合は、分析情報と推奨事項を使用して、Docker スキーマ 1 イメージを使用するクラスタを見つけることができます。また、Cloud Logging で次のクエリを使用して containerd ログを確認し、クラスタ内の Docker スキーマ 1 イメージを見つけることもできます。

jsonPayload.SYSLOG_IDENTIFIER="containerd"
"conversion from schema 1 images is deprecated"

イメージの取得から 30 日以上経過している場合、イメージのログが表示されないことがあります。

ノードで ctr コマンドを直接使用する

特定のノードに対してクエリを実行し、スキーマ 1 として pull され、削除されていないすべてのイメージを返すには、ノードで次のコマンドを実行します。

  ctr --namespace k8s.io images list 'labels."io.containerd.image/converted-docker-schema1"'

特定のノードのトラブルシューティングを行っていて、イメージの pull から 30 日以上経過しているため、Cloud Logging にログエントリが表示されない場合、このコマンドは便利です。

crane オープンソース ツールを使用する

crane などのオープンソース ツールを使用してイメージを確認することもできます。

次の crane コマンドを実行して、イメージのスキーマ バージョンを確認します。

crane manifest $tagged_image | jq .schemaVersion

ワークロードを準備する

Docker スキーマ 1 イメージを実行するワークロードを準備するには、それらのワークロードをスキーマ 2 の Docker イメージまたは Open Container Initiative(OCI)イメージに移行する必要があります。移行では、次のオプションを検討してください。

  • 交換用イメージを探す: 一般公開されているオープンソース イメージやベンダー提供のイメージを見つけることができます。
  • 既存のイメージを変換する: 交換用のイメージが見つからない場合は、次の手順で既存の Docker スキーマ 1 イメージを OCI イメージに変換できます。
    1. Docker イメージを containerd に pull します。これにより、イメージは自動的に OCI イメージに変換されます。
    2. 新しい OCI イメージをレジストリに push します。

CRI v1alpha2 API から移行する

CRI v1alpha2 API は Kubernetes 1.26 で削除されました。containerd ソケットにアクセスするワークロードを特定し、v1 API を使用するように、これらのアプリケーションを更新する必要があります。

影響を受ける可能性のあるワークロードを特定する

移行が必要になる可能性のあるワークロードを特定するには、さまざまな手法を使用できます。これらの手法では、誤検出が発生する可能性があります。誤検出が発生した場合は、さらに調査して、対応が必要ないことを確認する必要があります。

分析情報と推奨事項を使用する

クラスタが最小バージョン以降を実行している場合は、分析情報と推奨事項を使用して、v1alpha2 API を使用するクラスタを見つけることができます。詳細については、影響を受けるクラスタを特定するをご覧ください。

Google Cloud コンソールで分析情報を表示する場合は、サイドバー パネル [非推奨の CRI v1alpha2 API からワークロードを移行する] を確認してください。このパネルの [確認するワークロード] テーブルには、影響を受ける可能性があるワークロードが一覧表示されます。このリストには、containerd ソケットパス(/var/run/containerd/containerd.sock/run/containerd/containerd.sock など)を含む hostPath ボリュームがある GKE で管理されていないワークロードが含まれます。

次の点を理解することが重要です。

  • 検証するワークロードのリストには誤検出が含まれている可能性があります。このリストは調査にのみ使用してください。このリストにワークロードが表示されていても、そのワークロードが非推奨の API を使用しているとは限りません。また、誤検出があっても、自動アップグレードは一時停止しません。一時停止は、実際に観測された非推奨 API の使用に基づいてのみ行われます。
  • このリストは空であるか、不完全である可能性があります。非推奨の API を使用するワークロードが短期間で終了し、GKE が定期的なチェックを実行したときに実行されていなかった場合、リストが空または不完全である可能性があります。推奨事項自体が存在するということは、クラスタ内の少なくとも 1 つのノードで CRI v1alpha2 API の使用が検出されたことを意味します。非推奨の API の使用が 14 日間検出されなかった後、自動アップグレードが再開されます。

そのため、次の方法で実際の API 使用状況を確認し、さらに調査することをおすすめします。

影響を受けるサードパーティ ワークロードを確認する

クラスタにデプロイされたサードパーティ ソフトウェアについて、それらのワークロードが CRI v1alpha2 API を使用していないことを確認します。必要に応じて各ベンダーに問い合わせて、それらのソフトウェアの互換性があるバージョンを確認してください。

kubectl を使用する

次のコマンドは、containerd ソケットにアクセスするワークロードを検索して、影響を受ける可能性のあるワークロードを見つける際に役立ちます。これは、 Google Cloud コンソールの推奨事項の [確認するワークロード] テーブルで使用されるロジックと同様のロジックを使用します。ソケットのパスを含む hostPath ボリュームがある、GKE で管理されていないワークロードを返します。このクエリは、推奨事項と同様に、誤検出を返すか、有効期間の短いワークロードを見逃す可能性があります。

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

kubectl get pods --all-namespaces -o json | \
jq -r '
  [
    "/", "/var", "/var/","/var/run", "/var/run/",
    "/var/run/containerd", "/var/run/containerd/", "/var/run/containerd/containerd.sock",
    "/run", "/run/", "/run/containerd", "/run/containerd/",
    "/run/containerd/containerd.sock"
  ] as $socket_paths |
  [
    "kube-system", "kube-node-lease", "istio-system", "asm-system",
    "gatekeeper-system", "config-management-system", "config-management-monitoring",
    "cnrm-system", "hnc-system", "gke-managed-system", "gke-gmp-system",
    "gmp-system", "gke-managed-cim"
  ] as $excluded_namespaces |
  .items[] |
  select(
    (.spec.volumes[]?.hostPath.path as $p | $socket_paths | index($p))
    and
    ([.metadata.namespace] | inside($excluded_namespaces) | not)
  ) |
  .metadata.namespace + "/" + .metadata.name
'
eBPF トレースを使用して API 呼び出し元を特定する

CRI v1alpha2 API を呼び出すワークロードをより確実に特定するには、次の 2 つの専用 DaemonSet をデプロイします。

  • containerd-socket-tracer は、containerd ソケットへの接続を開くプロセスを、Pod とコンテナの詳細とともにログに記録します。
  • cri-v1alpha2-api-deprecation-reporter は、CRI v1alpha2 API が最後に呼び出された日時を記録します。

これらのツールは、Extended Berkeley Packet Filter(eBPF)を使用して containerd ソケットへの接続をトレースし、接続と実際の非推奨 API 呼び出しを関連付けます。

これらの 2 つのツールのタイムスタンプを関連付けることで、非推奨の API 呼び出しを行っているワークロードを正確に特定できます。この方法は、実際のソケット接続と API 使用状況を監視するため、hostPath ボリュームのみを確認するよりも信頼性が高くなります。

これらのツールのデプロイと使用の方法、ログの解釈方法の詳細については、containerd ソケット接続のトレースをご覧ください。

これらのツールを使用しても非推奨の API 呼び出しのソースを特定できず、推奨事項がアクティブなままの場合は、サポートを受けるをご覧ください。

上記の方法またはコードベースの検査によって、CRI v1alpha2 API を使用しているワークロードを特定したら、v1 API を使用するようにコードを更新する必要があります。

アプリケーション コードを更新する

アプリケーションを更新するには、アプリケーションが k8s.io/cri-api/pkg/apis/runtime/v1alpha2 クライアント ライブラリをインポートしている箇所を削除し、API の v1 バージョンを使用するようにコードを変更します。このステップでは、インポートパスを変更し、コードが API を呼び出す方法を更新します。

たとえば、次の golang コードをご覧ください。このコードでは、非推奨のライブラリを使用しています。

  package main

  import (
    ...

    runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
  )

  func foo() {
    ...

    client := runtimeapi.NewRuntimeServiceClient(conn)
    version, err := client.Version(ctx, &runtimeapi.VersionRequest{})

    ...
  }

ここで、アプリケーションは v1alpha2 ライブラリをインポートし、RPC の発行に使用します。RPC が containerd ソケットへの接続を使用する場合、このアプリケーションが原因で GKE はクラスタの自動アップグレードを一時停止します。

アプリケーション コードを検索して更新する手順は次のとおりです。

  1. 次のコマンドを実行して v1alpha2 インポートパスを検索し、問題のある golang アプリケーションを特定します。

      grep -r "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
    

    このコマンドの出力で、ファイルで v1alpha2 ライブラリが使用されていることが示されている場合は、ファイルを更新する必要があります。

    たとえば、次のアプリケーション コードを置き換えます。

      runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
    
  2. v1 を使用するようにコードを更新します。

      runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
    

非推奨の containerd 構成プロパティから移行する

CRI プラグイン内の containerd 構成プロパティ、registry.authsregistry.configsregistry.mirrors は非推奨であり、containerd 2.2 で削除されます。GKE バージョンはまだ発表されていません。ただし、registry.configs.tls は、containerd 2.0 ですでに削除されています。

ワークロードを特定する

移行が必要なワークロードを特定するには、さまざまな手法を使用できます。

分析情報と推奨事項を使用する

最初のアプローチとして、分析情報と推奨事項を使用して、非推奨の containerd 構成プロパティを使用しているクラスタを見つけることができます。これには、最低限の GKE バージョンを必要とします。このアプローチの詳細については、影響を受けるクラスタを特定するをご覧ください。

Google Cloud コンソールで分析情報を表示する場合は、サイドバー パネル [非推奨の CRI レジストリ認証フィールドから containerd 構成を移行する] または [非推奨の CRI レジストリ ミラー フィールドから containerd 構成を移行する] を確認してください。containerd 構成にアクセスする可能性があるワークロードを見つけるには、[確認するワークロード] セクションを確認してください。

kubectl を使用する

kubectl を使用してワークロードを特定することもできます。

次の属性を持つワークロードを調べて、containerd 構成を変更するワークロードを見つけます。

  • containerd 構成を含む hostPath Volume を含むワークロード
  • 特権アクセス(spec.containers.securityContext.privileged: true)を持つコンテナがあり、ホストプロセス ID(PID)Namespace(spec.hostPID: true)を使用するワークロード

このコマンドは誤検出を返す可能性があります。ワークロードがこれらのディレクトリ内の containerd 構成以外のファイルにアクセスする可能性があるからです。またこのコマンドでは、containerd 構成ファイルに、他のあまり一般的でない方法でアクセスしているワークロードは検出できない可能性があります。

次のコマンドを実行して、DaemonSet を確認します。

kubectl get daemonsets --all-namespaces -o json | \
jq -r '
  [
    "/", "/etc", "/etc/",
    "/etc/containerd", "/etc/containerd/",
    "/etc/containerd/config.toml"
  ] as $host_paths |
  [
    "kube-system", "kube-node-lease", "istio-system", "asm-system",
    "gatekeeper-system", "config-management-system", "config-management-monitoring",
    "cnrm-system", "hnc-system", "gke-managed-system", "gke-gmp-system",
    "gmp-system", "gke-managed-cim"
  ] as $excluded_namespaces |
  .items[] |
  select(
    ([.metadata.namespace] | inside($excluded_namespaces) | not)
    and
    (
      (any(.spec.template.spec.volumes[]?.hostPath.path; IN($host_paths[])))
      or
      (
        .spec.template.spec.hostPID == true and
        any(.spec.template.spec.containers[]; .securityContext?.privileged == true)
      )
    )
  ) |
  .metadata.namespace + "/" + .metadata.name
'

CRI レジストリの auths プロパティまたは configs.auth プロパティから移行する

ワークロードがコンテナ イメージを pull するために非公開レジストリに対して認証を行う際に containerd 構成の auths プロパティまたは configs.auth プロパティを使用する場合は、それらのイメージを使用するワークロードを imagePullSecrets フィールドに移行する必要があります。詳細については、非公開レジストリからイメージを pull するをご覧ください。

非推奨の auths プロパティまたは configs.auth プロパティを使用するワークロードを特定して移行するには、次の手順を確認してください。

レジストリの認証情報を見つける

レジストリの認証情報は、次のいずれかの方法で見つけることができます。

  • GKE ノードに接続し、/etc/containerd/config.toml ファイルにある CRI レジストリの auths セクションと configs.auth セクションを確認します。
  • containerd 構成ファイルを変更するワークロードを見つけ、前述のワークロードを特定する方法を使ってどのような認証情報が含まれているかを確認します。GKE は、そのシステム ワークロードにこれらの設定を使用しません。

registry.configs.auth プロパティを使用する場合、認証情報は次のようになります。

  [plugins."io.containerd.grpc.v1.cri".registry.configs."$REGISTRY_DOMAIN".auth]
    username = "example-user"
    password = "example-password"

構成で指定されているレジストリ ドメインごとに、これらの認証情報を収集します。

imagePullSecrets フィールドを使用するようにワークロードを更新する
  1. 非公開レジストリからイメージを pull するの手順に沿って、前のセクションの認証情報を含む Secret を作成します。
  2. 次のコマンドを実行して、imagePullSecrets フィールドに移行する必要があるワークロードを特定します。

    kubectl get pods -A -o json |
    jq -r ".items[] |
      select(.spec.containers[] |
            .image | startswith(\"$REGISTRY_DOMAIN\")) |
      .metadata.namespace + \"/\" + .metadata.name"
    

    このレジストリ ドメインのイメージを使用するワークロードで使用される Namespace ごとに Secret を作成する必要があります。

  3. 前の手順で作成した Secret を使用して、ワークロードの imagePullSecrets フィールドを更新します。

    多数のワークロードを移行する必要がある場合は、MutatingAdmissionWebhook を実装して imagePullSecrets フィールドを追加することもできます。

レジストリ認証の設定を停止するように containerd 構成を更新する

imagePullSecrets フィールドを使用するようにワークロードを移行した後、containerd 構成を変更するワークロードを、レジストリ認証の設定を停止するように更新する必要があります。構成を変更することが確認されたワークロードについては、レジストリ認証の設定を停止するようにワークロードを変更します。

新しいノードプールをテストし、ワークロードを新しいノードプールに移行する

ワークロードで問題が発生するリスクを軽減するには、次の操作を行います。

  1. 新しいノードプールを作成します。
  2. 新しいノードプールのノードに、containerd 構成を変更する更新ワークロードをスケジュールします。
  3. ノードプール間でワークロードを移行するの手順に沿って、残りのワークロードを新しいノードプールに移行します。

CRI レジストリの configs.tls プロパティから移行する

ワークロードで registry.configs.tls プロパティを使用している場合は、それらのワークロードを、プライベート CA 証明書を使用して非公開レジストリにアクセスするように移行する必要があります。

構成の DaemonSet から移行するの手順に沿って操作します。このプロセスは次の手順で行います。

  1. containerd 構成を変更するワークロードを、TLS 詳細の設定を停止するように更新します。
  2. 証明書を Secret Manager に保存します。
  3. 証明書を参照するランタイム構成ファイルを作成します。
  4. 新しいノードプールを作成し、非公開レジストリからホストされたイメージを使用するワークロードが想定どおりに動作することを確認します。
  5. 構成を新しいクラスタに適用してそのクラスタでワークロードの実行を開始するか、構成を既存のクラスタに適用します。構成を既存のクラスタに適用すると、他の既存のワークロードが停止する可能性があります。これら 2 つのアプローチの詳細については、ランタイム構成ファイルを作成するをご覧ください。

移行後、必ず registry.configs フィールドへの変更の適用を停止してください。停止しないと、containerd で問題が発生する可能性があります。

サポートを受ける

非推奨の API 呼び出しのソースを特定できず、推奨事項がアクティブなままの場合は、次の手順を検討してください。

  • このドキュメントに問題のソリューションが見当たらない場合は、サポートを受けるで、次のトピックに関するアドバイスなど、詳細なヘルプをご覧ください。