containerd 1.x からの移行:何が変わり、どう確認するか
containerd 1.x はサポート終了を迎え、Kubernetes も対応を打ち切りました。2.x への移行で実際に何が壊れるのか、アップグレード前にどう調べるか。
containerd 2.0 は 2024 年末にリリースされ、当時、プロジェクト自身の助言は「急がなくてよい」というものでした。1.x のブランチは、かなり長い間サポートされる予定でした。その猶予期間はすでに終わっています。containerd 1.7 の延長サポートは 2026 年 9 月に終了し、Kubernetes 1.35 は containerd 1.x をサポートする最後の Kubernetes リリースです。それ以降は 2.x が必要です。クラスターが今も containerd 1.x を使っているなら、このアップグレードはもはや任意ではありません。このガイドでは、実際に何が変わったかと、移行前に影響範囲を確認する方法を説明します。
containerd はデーモンとは別に API をバージョン管理するようになった
2.0 以降、デーモンのバージョンと gRPC API のバージョンは同じ番号ではなくなりました。containerd は 2.0 に上がりましたが、API 自体には破壊的変更がなく、1.x 系(1.8 に移行)のままです。Go クライアントライブラリも、独自のパッケージパスに移動しました。実際には、API や Go クライアントを直接使う統合のほとんどは、書き直しではなく、インポートパスを更新するだけで済みます。containerd のメンテナーは、少なくとも 1 つのダウンストリームツールの移行が、まさにインポートパスの検索と置換だけだったと報告しています。
2.0 で実際に削除されたもの
- Docker schema 1 イメージのサポート。デフォルトで無効になりました。schema 1 は 2014 年に schema 2 に、2017 年に OCI イメージ形式に取って代わられました。数年以上前のイメージで再ビルドされていないものは、schema 1 の候補です。containerd は schema 1 イメージを、そのまま保存するのではなく、pull 時に変換します。したがって、まだ必要なイメージの実際的な対処法は、一度 pull してからレジストリに push し直すことで、その過程で変換が行われます。
- CRI v1alpha2 API のサポート。Kubernetes 自体は 1.23 リリースで安定版の CRI v1 API に移行しており、現代の kubelet はすでに v1 を使っています。実際にリスクがあるのは、サードパーティのツール、つまり監視エージェント、セキュリティスキャナー、CRI ソケットと直接通信するその他のもので、更新されていない可能性があります。containerd ソケットをバインドマウントしているものや、特権で実行されているものを、最初に確認する価値があります。
- 最も古い 2 つの shim 実装(
io.containerd.runtime.v1.linuxとio.containerd.runc.v1)。io.containerd.runc.v2だけが残りました。これは何年も前からデフォルトだったため、ほとんどのクラスターでは動作に変化はなく、何も使っていなかったコードパスが削除されただけです。 aufssnapshotter。アップストリームにないカーネルのファイルシステムに依存していました。置き換えは、昔からのデフォルトであるoverlayfsで、aufs 用に意図的に構成していなかった場合は、何もする必要はありません。- io_uring ベースのシステムコール。それに関連するカーネルの CVE を受けて、デフォルトで拒否されます。影響を受けるワークロードは、失敗するのではなく、同じ機能のために古いシステムコールのパスにフォールバックするはずですが、containerd はここにある他の変更のように、事前に検出することはできません。
これとは別に、古い dlopen 方式の Go プラグインの仕組みと、レガシーな CRI レジストリミラーおよび設定オプションは、2.0 で非推奨となり、その後の 2.x リリースで削除されました。同様の理由からです。実際の利用が少なく、明確な代替手段があるためです(後者には hosts.toml 形式のレジストリ設定)。
実際に何の影響を受けるかを調べる
containerd には非推奨サービスがあり、削除予定の機能が実際にノード上で使われた最初の時点で、タイムスタンプ付きの警告を記録します。推測ではなく実際の使用時にのみ記録されるため、きれいなレポートは、きれいなアップグレードを意味します。
ctr deprecations list
ctr deprecations list --format json # 他のツールへの入力用
これは 1.x の機能(1.6 と 1.7 のパッチリリースにバックポート)であり、2.0 の機能ではありません。まさにそのため、これが有用なのです。何かをアップグレードする前に、現在のクラスターで、これから離れようとしているランタイム上で確認してください。containerd はデーモンの再起動時にこの状態をクリアするため、最近 containerd を再起動したりノードを再構築したりした場合は、実際の使用パターンが再び表面化するよう、しばらくワークロードを動かしてください。
現実的なアップグレードの手順
- まず最新の 1.7.x パッチリリースにします。そうすれば非推奨サービスが正確になり、アップグレードと無関係なバグ修正を混同しません。
- 実際の使用パターンが表れるのに十分な時間、本番トラフィックを流してから、フリート全体で
ctr deprecations listを確認します。 - 表示されたものを修正します。schema 1 イメージを変換または置き換え、まだ CRI v1alpha2 を呼び出しているツールを更新し、非推奨のレジストリ構文がないか設定を確認します(ほとんどは自動的に移行され、古い構文は移行期間中、2.x デーモンでも引き続き動作します)。
- 再度実行して、非推奨の一覧がきれいになっていることを確認します。
- まずテストクラスターまたは一部のノードを 2.x にアップグレードし、その後に広く展開します。
マネージド Kubernetes プロバイダーを使っている場合は、プロバイダー自身がこれらの非推奨警告を表示しているかを確認してください。プロバイダーによっては、それをノードの状態やコンソールに反映し、自動アップグレードの判断に組み込んでいます。そうなっていれば、各ノードに SSH で入る必要がなくなります。
ここで扱っていないことが出てきたときの参照先
containerd プロジェクトは、2.0 のすべての変更とその代替をまとめた完全な表を、詳細なリリースノートとともに、containerd.io とプロジェクトの GitHub リポジトリで公開しています。このガイドでカバーしていないことについては、それが正式な情報源であり、直接質問するなら CNCF Slack の #containerd チャンネルも利用できます。