問題とスコープ
あるチームでは、Pod起動時にリポジトリがマウントにクローンされるようgitRepoボリュームを使用しています。Kubernetes v1.36ではこのボリュームプラグインが完全に無効化され、フィーチャーゲートによる回避策も提供されません。移行を設計してください:ワークロードとリポジトリの依存関係のインベントリ調査、initコンテナ、外部同期ツール、またはビルド時パッケージングの選択、そしてコミットの整合性、認証情報、ネットワーク動作、更新セマンティクス、ロールバックの検証を行います。
Kubernetesのドキュメントには、gitRepoは何年も前から非推奨とされており、以前の実装では攻撃者がノード上でrootとしてコードを実行できる可能性があったと記載されています。v1.36でプラグインが無効化された後は、古いPodを再スケジュールしても互換性は回復しません。APIの変更、イメージリリース、およびランタイムでの取得パスを切り離して整理してください。
コンテキストと境界
ボリュームプラグインのライフサイクル、Podの起動順序、サプライチェーンの信頼性、および移行の検証に焦点を当てます。Gitホスティング、イメージレジストリ、ネットワーク下り(egress)、シークレット管理はプラットフォーム側の依存関係です。コミットの固定、最小権限の認証情報、ネットワーク障害ポリシー、および鮮度(freshness)の目標を明記してください。
面接官がテストしていること
gitRepoをイメージレイヤーやConfigMapではなく、ボリュームプラグインとして認識しているか。- ビルド時パッケージング、initコンテナ、継続的同期ツールを再現性、鮮度、障害セマンティクスの観点から比較できるか。
- プライベートリポジトリ、known hosts、トークン、プロキシ、およびコミットの整合性を適切に扱えるか。
- アップグレード前のスキャン、アドミッションブロック、カナリアノード、およびロールバックを設計できるか。
- emptyDirの共有、マウント権限、読み取り専用での利用、および起動時の依存関係を説明できるか。
30秒の回答
「Pod、テンプレート、ジェネレータをスキャンしてgitRepoを検出し、リポジトリ、リビジョン、マウントパス、認証情報、鮮度の要件を記録します。固定コンテンツはビルド時に不変イメージへパッケージ化すべきです。ランタイムでの取得が必要な場合、最小権限のinitコンテナが固定コミットをemptyDirに書き込み、メインコンテナがそれを読み取り専用でマウントします。継続的な更新には、アトミックなバージョン切り替え、旧バージョンの保持、整合性チェックを備えた制御された同期ツールが必要です。アップグレード前にポリシーで新規利用をブロックし、古いテンプレートを削除する前にカナリア再起動でネットワーク障害とロールバックをテストします。」
ステップごとの解決策
- 実際の依存関係を棚卸しする。 Pod、Deployment、StatefulSet、Job、Helmチャート、Kustomize、ジェネレータ、アドミッションのミューテーションを検索して
gitRepoを特定します。リポジトリ、リビジョン、パス、起動時読み取り、リポジトリサイズ、更新間隔、認証情報ソース、egressパスを記録します。
- 鮮度セマンティクスを分類する。 固定の設定やテンプレートはビルド時にパッケージ化します。起動時に必要なコンテンツにはinitコンテナを使用します。実行中に変更が必要なコンテンツに対してのみ同期ツールの使用を検討します。「起動ごとの取得」と「ホットアップデート」は異なる要件です。
- ビルド時にパッケージ化する。 信頼できるCIネットワーク内で、コミットダイジェストによって取得し、コンテンツをスキャンして不変イメージをビルドし、出所情報(provenance)を付与します。起動がGitの可用性に依存しないようイメージダイジェストでデプロイし、ロールバック時には以前のダイジェストに戻します。
- initコンテナによる代替を採用する。 initコンテナに専用のServiceAccountまたはSecretを付与し、認証情報を読み取り専用でマウントし、固定コミットを
emptyDirに書き込みます。メインコンテナは同じディレクトリを読み取り専用でマウントします。取得に失敗した場合は、不完全なコンテンツを公開するのではなく、PodがReady状態にならないようにします。
volumes:
- name: repo-data
emptyDir: {}
initContainers:
- name: fetch-repo
image: platform/git-sync:approved
volumeMounts:
- name: repo-data
mountPath: /work
containers:
- name: app
volumeMounts:
- name: repo-data
mountPath: /app/config
readOnly: trueこれは構造上のガイダンスに過ぎません。イメージ、認証情報のプロジェクション、ネットワークポリシー、検証コマンド、および取得コマンドは、本番環境で使用する前にプラットフォーム標準に従って確定する必要があります。
- 必要に応じて同期ツールを運用する。 ホットアップデートには、制御されたサイドカーまたは外部同期ツールを使用します。一時ディレクトリに取得し、コミット、ファイルマニフェスト、権限を検証した上で、バージョンディレクトリをアトミックに切り替えます。失敗した場合は現在有効なバージョンを保持します。アプリケーション側でリロードまたは定義された再起動ウィンドウをサポートする必要があります。
- サプライチェーンを保護する。 長寿命のトークンをPodスペックやログに決して含めないでください。リポジトリ、ブランチ、egressを制限し、TLS、known hosts、コミット署名、または信頼できるダイジェストを検証します。同期ツールはrootとしてホストパスを変更してはならず、アプリケーションのマウントは読み取り専用にする必要があります。
- カナリア、ブロック、およびロールバック。 アップグレード前にCI出力をスキャンし、ValidatingAdmissionPolicyを使用して、移行用の許可リストを維持しつつ新規の
gitRepoPodをブロックします。少数のノードセットでワークロードを再起動し、コールドスタート、ネットワーク障害、プライベートリポジトリの認証情報ローテーション、再スケジュール、スケーリングをテストします。新しいイメージが安定した後にのみ古いテンプレートを削除します。ロールバックでは古いイメージや同期ツールを復元し、無効化されたv1.36のプラグインを復元しようとしてはなりません。
模範回答
APIオブジェクトおよびレンダリングされたPodテンプレート内のgitRepoを棚卸しし、各ワークロードを固定コンテンツ、起動時取得、またはホットアップデートに分類します。固定コンテンツはCIでビルドされた不変イメージに含め、ダイジェストでデプロイします。起動時コンテンツは、最小権限のinitコンテナを使用して固定コミットをemptyDirに書き込み、メインコンテナから読み取り専用でマウントします。ホットアップデートでは、一時ディレクトリで新バージョンを検証してアトミックに切り替え、失敗時には旧バージョンを保持する同期ツールを使用します。
すべてのパスで、リポジトリ、コミット、認証情報、ネットワーク、権限の境界をバインドします。トークンはスペックやログから排除し、取得されたコンテンツはTLS、known hosts、コミットまたはイメージの出所情報を検証します。アップグレード前にテンプレートをスキャンして新規のgitRepoをブロックします。その後、起動時間、取得失敗、コンテンツダイジェスト、Ready状態、ロールバックの成功を観察しながら、カナリア再起動と再スケジュールを実施します。v1.36ではプラグインが完全に無効化されるため、ロールバックはフィーチャーゲートではなく、代替手段または古いクラスターバージョンを使用する必要があります。
よくある間違い
- 間違い: ConfigMapにリポジトリURLを配置し、更新を期待する → 失敗する理由: ConfigMapはGitの取得やバージョンの検証を行わない → 修正策: ビルド時のパッケージング、initコンテナ、または同期ツールに責務を割り当てる。
- 間違い: initコンテナにデフォルトブランチを取得させる → 失敗する理由: 再起動の再現性がなくなり、ロールバックが証明不能になる → 修正策: コミットを固定し、そのダイジェストと出所情報を記録する。
- 間違い: ホスト共有パスに対してrootとして同期ツールを実行する → 失敗する理由: ノードの攻撃対象領域が拡大し、Podの分離がバイパスされる → 修正策: Podローカルのボリューム、非root実行、最小権限、および読み取り専用での利用を採用する。
- 間違い: アプリケーションが読み取り中のディレクトリを上書きする → 失敗する理由: アプリケーションが不完全なツリーを読み取る可能性がある → 修正策: 一時ディレクトリで検証し、バージョンをアトミックに切り替える。
- 間違い: v1.36以降で
GitRepoVolumeDriverを再度有効化しようとする → 失敗する理由: プラグインは完全に無効化されており、セキュリティリスクが残る → 修正策: 移行を継続しながら、代替手段またはクラスターのバージョンをロールバックする。
フォローアップの質問と回答
コミットが固定されている場合でもコンテンツを検証する理由は何ですか?
コミットの固定によって参照は安定しますが、リポジトリ、依存関係、またはビルド環境が信頼できることの証明にはなりません。CIでは署名、出所情報、ファイルマニフェスト、マルウェアスキャン、イメージダイジェストを引き続き検証し、その証跡をリリースに紐付ける必要があります。
プライベートリポジトリの認証情報はどこに配置すべきですか?
対象のネームスペースとリポジトリにスコープを絞った専用のSecretまたは外部シークレットプロバイダを使用します。環境変数またはマウントされたファイルを介して注入し、イメージ、アノテーション、ログには絶対に含めず、ローテーションと失効をサポートします。
initコンテナが失敗すると何が起こりますか?
Podは利用可能にならず、メインコンテナは正常に起動しません。理由を公開し、リトライとバックオフを適用し、古いイメージやウォームアップされたキャッシュが有効なビジネスフォールバックを提供するかどうかを判断します。
ホットアップデートで不完全なコンテンツの読み取りを防ぐにはどうすればよいですか?
新しいバージョンディレクトリに取得し、コミット、マニフェスト、権限のチェックを完了してから、シンボリックリンクのアトミックなリネームまたは切り替えを行います。アプリケーションにはリロードの規約または再起動ポリシーが必要であり、切り替えに失敗した場合は現在のバージョンが保持されます。
見落とされたgitRepoの使用をどのように検出しますか?
APIオブジェクト、Helm/Kustomizeのソース、レンダリングされた出力、およびアドミッションのミューテーションをスキャンします。アップグレード後に非推奨や未知のフィールドに関するエラーを監視し、新しいテンプレートによってプラグインが再導入されないようCIでのスキャンを継続します。
参考資料
- Kubernetes v1.36 先取り情報 (Kubernetes Blog)
- ボリュームのドキュメント (Kubernetes Documentation)
- Projected Volumeの設定 (Kubernetes Documentation)
- Kubernetes 非推奨ポリシー (Kubernetes Documentation)
面接チェックリスト
固定、起動時取得、ホットアップデートの各セマンティクスを区別し、それぞれについてイメージ、initコンテナ、同期ツール、権限、検証、カナリア、およびロールバックを設計します。
1行のまとめ
gitRepoの移行とは、暗黙的なノード側のGitクローンを、再現可能で最小権限かつ検証可能なコンテンツ配信チェーンに置き換えることです。
継続的な練習
リポジトリに数ギガバイトのモデルと頻繁に変更される設定が含まれている場合、コストと一貫性の観点からイメージレイヤー、オブジェクトストレージ、initコンテナ、および同期ツールを比較してください。