課題とスコープ
あるJobのPodには、バッチコンテナ、ログ転送コンテナ、および設定同期コンテナが含まれています。バッチコンテナは終了したものの、ログコンテナが実行されたままになりJobが未完了のままです。また、同期コンテナはバッチが開始する前に設定を準備する必要があります。Kubernetesネイティブサイドカーのセマンティクスが、末尾のログ損失やバージョン依存の動作を回避しつつ、起動、終了、およびJobの完了をどのように解決するかを説明してください。
ここでのコンポーネントやタイミングは面接用の前提条件であり、すべてのクラスタにおけるデフォルトではありません。この質問は、バックエンドプラットフォーム、クラウドネイティブランタイム、およびSREのロールに適しています。その核となるスキルはPodライフサイクルの信頼性であるため、backendに属します。
面接官が評価するポイント
第一に、通常のcontainers、initContainers、およびネイティブサイドカーを区別できるか?ネイティブサイドカーは、初期化完了後も存続できるようにする再起動ポリシーとともにinitコンテナセクションで定義されます。
第二に、Jobの完了動作を説明できるか?ネイティブサイドカーは、通常のコンテナが完了した後に終了処理が行われ、従来の長時間実行サイドカーのようにJobを未完了のまま保持することはありません。
第三に、依存関係とシグナルを処理できるか?同期サイドカーはメインコンテナが起動する前にReadinessを報告する必要があり、終了時にはメインコンテナの後にシグナルを受信し、有界な強制停止パスを持つ必要があります。
第四に、障害に対処できるか?サイドカーの起動失敗、再起動ループ、ログバックエンドの利用不可、およびメインコンテナの早期障害に対して、明示的なリトライ、デグラデーション、およびオブザーバビリティのルールが必要です。
第五に、互換性を計画できるか?ネイティブサイドカーのセマンティクスを解釈できないクラスタは、マニフェストを拒否するか古い動作を実行する可能性があります。機能ゲート、バージョンチェック、およびフォールバック用マニフェストを使用します。
事前に確認すべき質問
- どのKubernetesバージョンおよびアドミッションポリシーがネイティブサイドカーをサポートしているか?
- 設定同期は1回限りの初期化か、それともジョブ実行中の継続的な更新か?
- ログはどこに配信される必要があり、末尾ログの損失はどの程度許容されるか?
- メインコンテナ、サイドカー、およびJobのリトライ終了コードはどのように定義されているか?
- Podは
restartPolicy: NeverとOnFailureのどちらを使用しているか? - サイドカー間に順序依存性や共有ボリュームの競合はあるか?
30秒の回答フレームワーク
「早期に起動して存続し続ける必要があるコンテナをinitContainersに配置し、サイドカーの再起動ポリシーを設定し、同期プロセスが検証済み設定の準備完了をシグナルするようにします。メインコンテナの完了後、コントローラーがネイティブサイドカーを終了させるためJobが完了できるようになります。ロギングサイドカーはSIGTERMを処理して入力を停止し、強制タイムアウト前にバッファをフラッシュします。古いクラスタではバージョン検出と従来のコンテナフォールバックを使用します。順序性、終了コード、末尾ログの完全性、リトライ、およびJobの完了レイテンシを検証します。」
ステップごとの回答
ステップ 1: ネイティブサイドカーのサポートを検証する
Kubernetesは、ネイティブサイドカーをコンテナレベルのrestartPolicy: Alwaysを伴うinitContainersで表現し、初期化後も実行を継続できるようにします。APIサーバーのバージョン、feature gates、admission controllers、およびデプロイツールを確認してください。kubectlクライアントのバージョンだけでは不十分です。
ステップ 2: 起動順序を定義する
initコンテナは順番に起動します。ネイティブサイドカーは起動後に実行を継続でき、後続の初期化およびメインコンテナを進めることができます。同期サイドカーは、「ファイルが書き込まれ、権限が正しく、バージョンが検証された」ことをReadiness条件とする必要があります。メインコンテナは、共有ボリュームを読み取る前にその条件を確認しなければなりません。
initContainers:
- name: config-sync
image: example/config-sync:v2
restartPolicy: Always
readinessProbe:
exec:
command: ["/bin/sh", "-c", "test -f /work/config.ready"]
- name: migrate
image: example/migrate:v4
command: ["/bin/sh", "-c", "./migrate && touch /work/migrate.done"]
containers:
- name: batch
image: example/batch:v7ステップ 3: 終了とログのフラッシュを設計する
メインコンテナが完了した後、ロギングサイドカーは終了シグナルを受け取り、決められた時間枠内でバッファリングされたログを送信する必要があります。SIGTERMを処理し、入力を受け付けず、フラッシュし、配信を確認して終了する必要があります。最も長いフラッシュ時間をカバーするようにterminationGracePeriodSecondsを設定します。その後のSIGKILLは末尾ログを失う可能性があるため、その状態を記録してアラートを発報します。
ステップ 4: 障害とリトライを定義する
同期サイドカーが再起動した場合、メインコンテナが不完全な設定を読み込んではいけません。Readiness、プローブの失敗、およびアトミックな共有ボリューム置換が連携して機能します。メインコンテナが失敗した場合、JobコントローラーはbackoffLimitを適用します。サイドカーの再起動が新しいビジネス試行としてカウントされてはなりません。メインの終了コード、Podフェーズ、Job条件、およびサイドカーの状態を個別に記録します。
ステップ 5: Job完了セマンティクスを処理する
ネイティブサイドカーはすべての通常コンテナが完了した後に終了されるため、従来の常駐サイドカーのようにJobが開いたままになることはありません。サイドカーが早期に失敗した場合は、図に依存するのではなく、結合テストでReadiness、再起動、およびJob条件に関する実際のクラスタ動作を検証します。
ステップ 6: 古いクラスタをサポートする
バージョンのゲート機構を使用します。サポートされていないクラスタは従来のcontainersマニフェストを受け取り、ラッパーがメインコンテナの終了時にロギングプロセスを終了するように指示します。マニフェストは相互排他的に保ちます。移行中は、Jobの完了時間、失敗の理由、および末尾ログの完全性を監視します。
ステップ 7: リソースとセキュリティを検証する
サイドカーはPodのネットワーク、ボリューム、およびリソースクォータを共有します。ログの急増によってバッチ処理がリソース枯渇しないように、同期コンテナとロギングコンテナに個別のrequestsとlimitsを設定します。設定の読み取りやログの書き込みに必要な最小限のServiceAccount権限のみを付与します。プローブで認証情報を公開してはならず、一時ファイルには制限付きの権限が必要です。
模範回答
「まず、APIサーバーおよびアドミッションチェーンでネイティブサイドカーのサポートを確認します。同期プロセスはrestartPolicy: AlwaysとともにinitContainersに配置され、メインコンテナが進む前にバージョンを検証し、アトミックに設定を書き込みます。1回限りのマイグレーションは通常のinitコンテナのままにします。ロギングサイドカーはメインコンテナの後に終了処理を行い、入力を停止し、決められた猶予期間内にフラッシュして配信を確認し、強制終了が発生した場合はアラートを発報します。
メインの終了コード、サイドカーの再起動、Pod条件、Jobのバックオフ、および末尾ログの損失を個別に記録します。古いクラスタでは、ロガーに終了をシグナルするラッパーを含む従来のコンテナフォールバックマニフェストを選択します。カナリア検証により、順序性、Job完了レイテンシ、リトライ、アトミックな設定、リソース制限、およびログの完全性を確認します。」
よくある間違い
containersで通常のサイドカーを使用する → Jobが永久に待機する可能性がある → ネイティブセマンティクスまたは明示的な終了調整を使用する。- 継続的な同期プロセスを1回限りのinitにする → ジョブ実行中に更新できない → 最初にライフサイクルの要件を定義する。
- アトミックな書き込みなしでReadinessを使用する → メインプロセスが部分的な状態を読み込む → 一時ファイルを検証してからリネームする。
- フラッシュ時間枠を無視する → SIGKILLにより末尾ログが失われる → 最悪の配信状況を想定して正常終了の時間を確保する。
- サイドカーの失敗をビジネスの失敗としてカウントする → リトライのメトリクスが誤解を招くものになる → コンテナとJobの状態を分離する。
- すべてのクラスタがそのフィールドをサポートしていると仮定する → 古いバージョンでは拒否されるか動作が変化する → バージョンゲートとフォールバックマニフェストを使用する。
- サイドカーのリソースを無制限にしておく → ログのバーストがバッチ処理を圧迫する → 独立したrequests、limits、およびアラートを設定する。
- 共有ボリュームに過剰な権限を与える → 設定やログが改ざんされる可能性がある → 最小権限のIDとファイルモードを使用する。
フォローアップ質問
フォローアップ 1: なぜネイティブサイドカーはinitContainersで定義されるのですか?
これにより、初期化の順序付けが維持される一方で、コンテナレベルの再起動ポリシーによりサイドカーが起動後もアクティブな状態を維持できるようになります。後続のコンテナは必要な初期化条件を待機し、コントローラーはJob完了時にサイドカーの終了を処理します。
フォローアップ 2: サイドカーは常にログの送信を完了できますか?
いいえ。ネットワーク障害、スロットリング、または短い猶予期間によりデータが失われる可能性があります。有界なフラッシュ処理、耐久性のあるバッファリングやリトライを使用し、末尾ログの完全性と損失アラートを計測してください。
フォローアップ 3: メインコンテナが失敗した後も同期を継続すべきですか?
リトライセマンティクスによります。その試行において設定が不変である場合は、新規の書き込みを停止して診断情報を保持します。各リトライで新しいバージョンが必要な場合は、新しいPodまたは明示的なバージョンポリシーにその更新を担当させます。単一の試行内容を暗黙的に変更してはなりません。
フォローアップ 4: 起動順序をどのようにテストしますか?
同期プロセスを遅延させ、部分的な状態を書き込み、強制的に検証失敗を引き起こして、メインコンテナが起動しないことを確認します。次に完了マーカーを書き込み、完全なバージョンが読み込まれることを確認します。再起動、共有ボリュームの可視性、およびプローブの競合状態をテストします。
フォローアップ 5: 古いクラスタのフォールバックの整合性をどのように保ちますか?
デリバリーパイプラインにバージョン選択を組み込み、相互排他的なマニフェストを生成して、両方に対して同じJob契約テストを実行します。アプリケーションが実行時にKubernetesバージョンを推測するべきではありません。
フォローアップ 6: Jobが真に完了したことをどのように把握しますか?
Job条件、メインの終了コード、Podフェーズ、サイドカーの終了理由、およびログ配信確認マーカーを組み合わせて確認します。SucceededのPod単体では、失われた末尾ログや同期の失敗が隠れてしまう可能性があります。