設問とコンテキスト
あなたは希望レプリカ数(desired replica count)が 5 である Deployment 管理のサービスを運用しています。クラスターのアップグレード中にノードを drain する必要があり、チームは複数のレプリカを一度に失うことを懸念しています。面接官は、PodDisruptionBudget を設計またはレビューし、ローリングリリース、ノード障害、直接的な Pod 削除に対するその影響を説明するよう求めます。
これは Kubernetes の可用性の境界と運用上の推論力をテストするものです。PDB は、自発的な中断(voluntary disruptions) によって選択されたレプリカが同時に利用不可になる数を制限します。これはレプリカコントローラーではなく、あらゆる障害に対する保証でもありません。優れた回答は、希望レプリカ数、セレクター、エビクションのエントリポイント、および残余キャパシティを結びつけて説明します。
面接官が評価しているポイント
- 自発的な中断と非自発的な中断を区別できているか。
minAvailableとmaxUnavailableの相互排他的なセマンティクスを説明できるか。- PDB がコントローラーの希望レプリカ数と正確な Pod セレクターに依存していることを理解しているか。
- drain の再試行、カバーされない削除パス、ローリングアップデートの境界を説明できるか。
- レプリカ数、トポロジー、プローブ、キャパシティを可用性設計に組み込んでいるか。
最初に確認すべき質問
- サービスは Deployment、StatefulSet、またはその他のサポートされているコントローラーによって管理されていますか?
- セレクターはこのワークロードのみにマッチしますか?広すぎるセレクターは、無関係な Pod を 1 つのバジェットに混在させる可能性があります。
- ノードの drain やスケールダウンから保護しようとしていますか、それとも電源喪失ですか?PDB は後者を防ぐことはできません。
- レプリカは十分なキャパシティと正しい readiness を持ってゾーン間に分散されていますか?PDB はエビクションを制限しますが、キャパシティを作成するわけではありません。
- メンテナンスはどのくらいの時間待機できますか?バジェットが厳しすぎるとメンテナンスウィンドウが長くなり、緩すぎるとキャパシティが低下します。
30秒の回答フレームワーク
「PDB は、Eviction API を介して行われる自発的な中断リクエストを制限します。5 つのレプリカがある場合、minAvailable: 4 または maxUnavailable: 1 を使用して、一度に失われる数を最大 1 つに抑えるよう表現できますが、これらのフィールドは相互に排他的です。バジェットはワークロードの希望レプリカ数と正確なセレクターに依存し、ノード障害、Deployment の直接削除、アプリケーションのローリングアップデートを完全に阻止するものではありません。drain が拒否された場合は、バジェット、正常なレプリカ、キャパシティ、エビクションパスを調査しつつ、残りの可用性設計にはレプリカ数、トポロジー、プローブを活用します。」
深掘りした回答
中断の分類
ノードの drain、ノードのメンテナンス、一部のクラスターのスケールダウンアクションは、通常 Eviction API を介して Pod の移動を要求します。これらは自発的な中断であるため、PDB はエビクションを一時的に拒否できます。電源喪失、カーネル障害、ネットワークの隔離は非自発的な中断です。PDB はこれらを防ぐことはできず、結果として利用不可になった Pod もバジェットの状態に影響を与えます。
相互排他的なフィールドの説明
minAvailable は、エビクション後にマッチする Pod がいくつ利用可能な状態で残らなければならないかを指定します。maxUnavailable は、エビクション後にマッチする Pod がいくつ利用不可になることが許容されるかを指定します。これらを両方設定することはできません。希望レプリカ数が 5 の場合、minAvailable: 4 と maxUnavailable: 1 はその規模では同様の意図を表現しますが、割合(パーセンテージ)はスケールや端数処理によって変化するため、希望数とバージョンセマンティクスを明記してください。
希望レプリカ数とセレクターへの依存関係を示す
コントロールプレーンは、Pod の owner references を通じて管理対象のワークロードを見つけ、.spec.replicas から意図された数を導出します。セレクターは Deployment または StatefulSet のラベルと一致させ、絞り込んでおく必要があります。複数のアプリケーションにマッチするセレクターは共有バジェットを作成してしまいます。サポートされている親リソースがない場合、Kubernetes は合計を確実に導出できません。
設定例を用いて境界を示す
この例では、ワークロードが 5 つのレプリカを意図している場合に、自発的エビクションによって選択された Pod が利用不可になるのを最大 1 つまで許可します。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: checkout-api
spec:
maxUnavailable: 1
selector:
matchLabels:
app: checkout-apiこれは、常に 4 つの正常な Pod が存在することを保証するものではありません。レプリカがすでに異常である可能性や、ノードが突然故障する可能性があります。ロールアウトの前に、セレクター、readiness、希望レプリカ数、マルチゾーンのキャパシティを検証してください。
drain の拒否と再試行を説明する
現在エビクションが許可されていない場合、正常なレプリカがすでに minAvailable を下回っている場合、またはバジェットコントローラーがステータスを計算できない場合、Eviction API はリクエストを拒否することがあります。kubectl drain は、Pod が終了するかタイムアウトに達するまで、失敗したリクエストを定期的に再試行します。トラブルシューティングは、PDB のステータス、選択された Pod、正常な数、readiness の失敗、およびメンテナンスタスクが実際に Eviction API を使用しているかの確認から始めます。
ローリングアップデートと直接削除を区別する
Deployment および StatefulSet のローリングアップデートは、独自の更新戦略によって管理されます。PDB はそれらのルールの完全な代替にはなりません。また、PDB は Pod や Deployment の直接削除をすべて制約できるわけではありません。リリースシステムは、リリースの安全性をすべて PDB に任せるのではなく、maxUnavailable、maxSurge、readiness、ロールバック動作を組み合わせる必要があります。
PDB 外での信頼性の追加
PDB がカバーするのは 1 つの中断クラスのみです。ノードやゾーンの障害に耐えるには、十分なレプリカ数、トポロジー分散(topology spread)、キャパシティのヘッドルーム、正しい readiness と liveness、グレースフルシャットダウン(graceful termination)、接続のドレインも必要です。クォーラムベースのステートフルサービスの場合はクォーラムの要件からバジェットを導出し、ステートレスサービスの場合は実際のトラフィック、復旧時間、キャパシティテストで可用性を検証します。
質の高い模範解答
「Deployment は 5 つのレプリカを求めているため、まず PDB セレクターが checkout-api にのみ一致していること、および readiness とゾーン間キャパシティが適切であることを確認します。自発的エビクションで 4 つの利用可能なレプリカを残す必要がある場合は、minAvailable: 4 または maxUnavailable: 1 を使用できます。これらは相互に排他的であり、スケーリングの挙動に基づいて絶対値または割合を選択します。
PDB は、Eviction API を使用するノードの drain、メンテナンス、および一部のスケールダウンアクションを保護します。電源喪失、カーネル障害、直接的な Pod 削除を止めることはできず、ローリングアップデートは主に Deployment の戦略によって制御されます。drain が拒否された場合は、正常なレプリカ、バジェットのステータス、セレクター、readiness の失敗、キャパシティ、エビクションパスを調査します。kubectl drain はタイムアウトまで再試行する可能性があります。
PDB は、レプリカ数、トポロジー分散、readiness、グレースフルシャットダウン、リリースのロールバックと組み合わせて検証します。バジェットが厳しすぎるとメンテナンスがブロックされ、緩すぎると最小キャパシティを侵害する可能性があるため、しきい値は画一的な割合ではなく、トラフィックと障害訓練から導き出すべきです。」
よくある間違い
- PDB がノード障害を防ぐと主張する: 自発的および非自発的な中断が混同されています → 主張を Eviction API のパスに限定してください。
minAvailableとmaxUnavailableの両方を設定する: これらのフィールドは相互に排他的です → バジェットの表現方法を 1 つ選択してください。- 現在の Pod のみカウントする: バジェットは希望レプリカ数を使用します → owner references と
.spec.replicasを確認してください。 - ネームスペース全体を選択する: 無関係なアプリが 1 つのバジェットを共有してしまいます → 絞り込んだワークロードセレクターを使用してください。
- PDB がローリングアップデートや直接削除を保護すると述べる: コントローラーと削除パスには個別のセマンティクスがあります → 各ポリシーと権限パスを確認してください。
- drain がブロックされたときに PDB を削除する: キャパシティリスクが高まる可能性があります → まず正常なレプリカ、プローブ、バジェットステータス、キャパシティを確認してください。
- トポロジーやキャパシティを考慮せずに PDB を設定する: 生き残った Pod が 1 つの障害ドメインを共有する可能性があります → ゾーン、ヘッドルーム、訓練を組み合わせてください。
- 割合を固定のレプリカ数として扱う: スケーリングによって意味が変わります → 希望スケール、端数処理、オートスケーリングの挙動を明確にしてください。
フォローアップの質問と回答
フォローアップ 1: 5 つのレプリカに対して minAvailable: 80% は何を意味しますか?
Kubernetes の割合と端数処理ルールによって算出された利用可能数を要求します。常に正確に 4 であると思い込まず、現在の API セマンティクスを確認し、スケーリング後の挙動を観察してください。
フォローアップ 2: なぜ drain によってサービスが依然として利用不可になることがあるのですか?
PDB は受け入れられる自発的エビクションを制限するだけです。すでに異常な Pod を修復したり、キャパシティを作成したり、単一ゾーンへの集中を解消したり、アプリケーションに接続の移動を許容させたりすることはできません。readiness、トポロジー、キャパシティ、グレースフルシャットダウンをまとめて検証する必要があります。
フォローアップ 3: kubectl delete pod は PDB によってブロックされますか?
ブロックされると思い込んではいけません。Kubernetes のドキュメントには、Pod や Deployment を直接削除すると PDB の保護をバイパスできることが記載されているため、権限、監査、リリースプロセスによってそのパスを制限する必要があります。
フォローアップ 4: PDB で許可された中断(allowed disruptions)が 0 と表示されています。まずバジェットを緩和すべきですか?
まずセレクター、希望レプリカ数、正常なレプリカ、readiness の失敗、コントローラーのステータスを調査してください。盲目的にバジェットを緩和すると、健全性の問題が隠れてしまう可能性があります。メンテナンスで一時的な変更がどうしても必要な場合は、キャパシティとロールバックを評価し、作業枠を記録した上でポリシーを元に戻します。
フォローアップ 5: ステートフルサービスとステートレスサービスの違いは何ですか?
ステートフルサービスは、クォーラムまたは整合性プロトコルの最小レプリカ数を維持し、リバランスと復旧を検証する必要があります。ステートレスサービスは通常、残余キャパシティ、レイテンシ、接続のドレインに重点を置きます。どちらの可用性の主張も、レプリカ数だけで成り立つものではありません。
フォローアップ 6: PDB が効果的であることをどのように検証しますか?
管理されたメンテナンス時間枠内で、Eviction API とノードの drain を実行し、拒否、再試行、終了猶予時間、トラフィック、エラー、復旧時間を観察します。また、ノード障害や直接削除のパスもテストし、チームが PDB の境界を「すべての障害に対する保証」と誤認しないようにします。