Kubernetes v1.34:更精細地控制容器重啟
隨著 Kubernetes 1.34 的釋出,引入了一個新的 Alpha 功能,使你能夠更精細地控制 Pod 內的容器重啟。此功能名為 容器重啟策略與規則(Container Restart Policy and Rules),允許你為每個容器單獨指定重啟策略,從而覆蓋 Pod 的全域性重啟策略。此外,它還允許你根據容器的退出碼有條件地重啟單個容器。此功能在 Alpha 特性門控 ContainerRestartRules
之後可用。
這是一個被長期請求的功能。讓我們深入瞭解它的工作原理以及如何使用它。
單一重啟策略的問題
在此功能之前,restartPolicy
是在 Pod 級別設定的。這意味著 Pod 中的所有容器共享相同的重啟策略(Always
、OnFailure
或 Never
)。雖然這適用於許多用例,但在其他情況下可能會受到限制。
例如,考慮一個包含主應用容器和一個執行某些初始設定的 Init 容器的 Pod。你可能希望主容器在失敗時總是重啟,但 Init 容器應該只執行一次並且永不重啟。使用單一的 Pod 級重啟策略,這是不可能的。
引入按容器重啟策略
透過新的 ContainerRestartRules
特性門控,你現在可以為 Pod 規約中的每個容器指定一個 restartPolicy
。你還可以定義 restartPolicyRules
以根據退出碼控制重啟。這為你提供了處理複雜場景所需的精細控制。
使用場景
讓我們看一些現實生活中的使用場景,在這些場景中,按容器重啟策略可能是有益的。
訓練作業的就地重啟
在機器學習研究中,編排大量長期執行的 AI/ML 訓練工作負載是很常見的。在這些場景中,工作負載故障是不可避免的。當工作負載因可重試的退出碼而失敗時,你希望容器能夠快速重啟,而無需重新排程整個 Pod,這會消耗大量的時間和資源。對失敗的容器進行“就地”重啟對於更好地利用計算資源至關重要。容器只應在因可重試錯誤失敗時才“就地”重啟;否則,容器和 Pod 應終止並可能被重新排程。
現在,這可以透過容器級的 restartPolicyRules
來實現。工作負載可以以不同的程式碼退出,以表示可重試和不可重試的錯誤。有了 restartPolicyRules
,工作負載可以快速就地重啟,但僅限於錯誤是可重試的情況。
一次性嘗試的 Init 容器
Init 容器通常用於為主容器執行初始化工作,例如設定環境和憑據。有時,你希望主容器總是被重啟,但如果初始化失敗,你不想重試。
透過容器級的 restartPolicy
,這現在成為可能。Init 容器可以只執行一次,其失敗將被視為 Pod 失敗。如果初始化成功,主容器可以總是被重啟。
具有多個容器的 Pod
對於執行多個容器的 Pod,你可能對每個容器有不同的重啟要求。一些容器可能有明確的成功定義,並且只應在失敗時重啟。其他容器可能需要總是被重啟。
現在,透過容器級的 restartPolicy
,這成為可能,允許單個容器具有不同的重啟策略。
如何使用它
要使用此新功能,你需要在執行 Kubernetes 1.34+ 的 Kubernetes 叢集控制平面和工作節點上啟用 ContainerRestartRules
特性門控。啟用後,你可以在容器定義中指定 restartPolicy
和 restartPolicyRules
欄位。
以下是一些示例
示例 1:根據特定退出碼重啟
在此示例中,僅當容器因可重試錯誤(由退出碼 42 表示)而失敗時,容器才應重啟。
為實現此目的,該容器的 restartPolicy
為 Never
,並有一條重啟策略規則,告訴 Kubernetes 如果容器以退出碼 42 退出,則就地重啟該容器。
apiVersion: v1
kind: Pod
metadata:
name: restart-on-exit-codes
annotations:
kubernetes.io/description: "This Pod only restart the container only when it exits with code 42."
spec:
restartPolicy: Never
containers:
- name: restart-on-exit-codes
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'sleep 60 && exit 0']
restartPolicy: Never # Container restart policy must be specified if rules are specified
restartPolicyRules: # Only restart the container if it exits with code 42
- action: Restart
exitCodes:
operator: In
values: [42]
示例 2:一個只嘗試一次的 Init 容器
在此示例中,一個 Pod 在初始化成功後應該總是被重啟。但是,初始化應該只嘗試一次。
為實現此目的,Pod 的重啟策略為 Always
。init-once
這個 Init 容器將只嘗試一次。如果它失敗,Pod 將會失敗。這使得 Pod 在初始化失敗時會失敗,但在初始化成功後也能保持執行。
apiVersion: v1
kind: Pod
metadata:
name: fail-pod-if-init-fails
annotations:
kubernetes.io/description: "This Pod has an init container that runs only once. After initialization succeeds, the main container will always be restarted."
spec:
restartPolicy: Always
initContainers:
- name: init-once # This init container will only try once. If it fails, the Pod will fail.
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'echo "Failing initialization" && sleep 10 && exit 1']
restartPolicy: Never
containers:
- name: main-container # This container will always be restarted once initialization succeeds.
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'sleep 1800 && exit 0']
示例 3:具有不同重啟策略的容器
在此示例中,有兩個具有不同重啟要求的容器。一個應該總是被重啟,而另一個只應在失敗時重啟。
這是透過在兩個容器上使用不同的容器級 restartPolicy
來實現的。
apiVersion: v1
kind: Pod
metadata:
name: on-failure-pod
annotations:
kubernetes.io/description: "This Pod has two containers with different restart policies."
spec:
containers:
- name: restart-on-failure
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'echo "Not restarting after success" && sleep 10 && exit 0']
restartPolicy: OnFailure
- name: restart-always
image: docker.io/library/busybox:1.28
command: ['sh', '-c', 'echo "Always restarting" && sleep 1800 && exit 0']
restartPolicy: Always
瞭解更多
路線圖
更多用於重啟 Pod 和容器的動作和訊號即將到來!值得注意的是,有計劃增加對重啟整個 Pod 的支援。關於這些功能的規劃和討論正在進行中。歡迎與 SIG Node 社群分享反饋或請求!
歡迎你的反饋!
這是一個 Alpha 功能,Kubernetes 專案希望聽到你的反饋。請試用它。此功能由 SIG Node 推動。如果你有興趣幫助開發此功能、分享反饋或參與任何其他正在進行的 SIG Node 專案,請與 SIG Node 社群聯絡!
你可以透過多種方式聯絡 SIG Node
- Slack: #sig-node
- 郵件列表
- 開放的社群問題/PR