題幹與適用場景
Kubernetes v1.35 在啟用 RestartAllContainers 動作後,為容器提供 restartPolicyRules。規則可以把退出碼映射到重啟動作,但 Pod 仍然有生命週期和就緒契約。應把它當作失敗分類機制,而不是探針或告警的替代品。
假設工作 Pod 有三個不同故障域的容器。擷取器可能因暫時憑證刷新失敗而恢復;代理設定錯誤應讓運維看到並告警;回報器的本地狀態損壞時,可能需要重啟整個 Pod。
面試官考察點
面試官關注明確的失敗分類、版本和功能閘意識,以及防止重啟迴圈掩蓋事故的方案。強回答會把退出碼連接到責任人、就緒狀態、退避、指標和灰度安全。
普通回答給每個容器都加規則。強回答會說明哪些退出碼屬於穩定應用語義,哪些只是偶然的程序細節,以及如何證明每個容器的狀態適合單獨恢復。
回答前需要釐清的問題
- 所有叢集保證哪些 Kubernetes 版本和功能閘?
- 退出碼由應用契約控制,還是由執行時和 shell 包裝器產生?
- 容器狀態可丟棄、有檢查點,還是與 Pod 其他容器耦合?
- 同一退出碼重複出現時,應退避、替換 Pod,還是升級告警?
- 一個容器重啟期間,哪些訊號定義使用者可用性?
如果退出碼沒有經過測試的應用契約,應先使用統一重啟策略並完善程序契約。如果狀態耦合,單獨重啟可能讓 Pod 內部出現不一致。
30 秒回答框架
「我會先確認 Kubernetes 版本和功能閘,再為每個容器定義退出碼語義。只重啟無狀態的暫時失敗;讓永久設定錯誤保持可見;共享狀態損壞時替換 Pod。我會記錄規則命中、重啟次數、退避、就緒狀態和重複退出碼告警,先灰度一個工作負載,若錯誤率或重啟迴圈上升就回滾。」
分步驟深入解答
- 確認前提。 核對 v1.35 行為、
RestartAllContainers、准入策略,以及控制器和觀測系統是否理解新欄位。 - 定義退出碼責任。 保留少量有文件的類別,例如暫時刷新、永久設定和不可恢復狀態。測試包裝器,避免訊號被意外改寫。
- 選擇最小安全動作。 擷取器的暫時碼可重啟;代理設定錯誤保持 NotReady 並告警;共享狀態無效時替換 Pod。
- 保護依賴關係。 以依賴契約控制就緒,協調終止鉤子,容器狀態未預熱前不要接收流量。
- 控制重複。 結合重啟次數、指數退避和重複碼告警。持續重啟最終必須變成運維可見的失敗。
- 漸進發布。 先灰度一個工作負載,對比重啟迴圈率、恢復時間、錯誤率和 Pod churn,護欄穩定後再擴大。
替代方案包括單容器內 supervisor、把獨立故障域拆成不同 Deployment,或使用替換 Pod 的控制器。選擇能保留狀態並讓故障可見的最簡單邊界。
高品質示範回答
「對擷取器,退出碼 42 表示短暫憑證刷新失敗;它沒有持久本地狀態,可以安全重啟。設定錯誤保持 NotReady 並通知負責人,重啟只會重複同一失敗。回報器發現本地檢查點損壞時,我會終止 Pod,讓乾淨卷或新 Pod 一致恢復。規則先在功能閘後的單個 canary 工作負載啟用,告警關注重複命中和重啟迴圈;如果恢復時間或錯誤率退化就移除策略。」
常見錯誤
- 錯誤表現: 把所有非零退出都當作暫時失敗 → 失敗原因: 永久故障變成靜默重啟迴圈 → 修正方法: 定義並測試退出碼語義。
- 錯誤表現: 忽略功能閘和叢集版本差異 → 失敗原因: 同一清單在環境中行為不同 → 修正方法: 加入准入和發布檢查。
- 錯誤表現: 單獨重啟耦合狀態的容器 → 失敗原因: 其他容器保留不相容狀態 → 修正方法: 替換 Pod 或協調恢復。
- 錯誤表現: 只監控重啟次數 → 失敗原因: 使用者仍報錯但指標看似健康 → 修正方法: 結合就緒與服務 SLO。
追問及應對
如果退出碼 42 來自 shell 包裝器,映像更新後改變了怎麼辦?
把退出碼當作 API。固定並測試包裝器,記錄責任邊界,契約變化時阻斷發布,不能默默繼承執行時特定碼。
如何避免重啟迴圈掩蓋事故?
告警關注重複命中、重啟速率、退避飽和和就緒丟失。達到有限嘗試次數後升級為 Pod 替換或運維可見失敗。
什麼時候整個 Pod 重啟更安全?
狀態共享、初始化順序重要,或一個容器損壞會使同伴失效時,替換 Pod 更安全。可接受更大範圍重啟以避免部分恢復不一致。
如何回滾這個功能?
在工作負載模板停用策略,恢復舊的重啟行為並確認舊副本收斂。保留退出碼契約和儀表板,確保回滾仍可觀測。