Pod 生命周期
此頁面描述 Pod 的生命週期。Pod 遵循定義的生命週期,從 Pending
階段 開始,如果其至少一個主要容器啟動正常,則移至 Running
,然後根據 Pod 中是否有任何容器終止失敗,而經歷 Succeeded
或 Failed
階段。
如同個別的應用程式容器,Pod 被認為是相對短暫的 (而非持久的) 實體。Pod 會被建立、指派唯一 ID (UID),並排程在節點上執行,它們會保留在這些節點上直到終止 (根據重新啟動策略) 或刪除。如果 節點 故障,則在該節點上執行 (或排程在該節點上執行) 的 Pod 會被標記為刪除。控制平面會在逾時期間後標記 Pod 以進行移除。
Pod 生命周期
當 Pod 正在執行時,kubelet 能夠重新啟動容器以處理某些類型的故障。在 Pod 內部,Kubernetes 追蹤不同的容器狀態,並判斷要採取什麼行動以使 Pod 再次恢復健康。
在 Kubernetes API 中,Pod 既有規格也有實際狀態。Pod 物件的狀態包含一組 Pod 條件。如果對您的應用程式有用,您也可以將自訂就緒資訊注入到 Pod 的條件資料中。
Pod 在其生命週期中只會排程一次;將 Pod 指派給特定節點稱為綁定,而選擇要使用哪個節點的過程稱為排程。一旦 Pod 被排程並綁定到節點,Kubernetes 就會嘗試在該節點上執行該 Pod。Pod 會在該節點上執行直到停止,或者直到 Pod 被終止;如果 Kubernetes 無法在選定的節點上啟動 Pod (例如,如果節點在 Pod 啟動之前崩潰),則該特定 Pod 永遠不會啟動。
您可以使用 Pod 排程就緒 來延遲 Pod 的排程,直到其所有排程閘道都被移除。例如,您可能想要定義一組 Pod,但只在所有 Pod 都已建立後才觸發排程。
Pod 和故障恢復
如果 Pod 中的其中一個容器故障,則 Kubernetes 可能會嘗試重新啟動該特定容器。請閱讀 Pod 如何處理容器問題 以了解更多資訊。
然而,Pod 可能會以叢集無法恢復的方式故障,在這種情況下,Kubernetes 不會嘗試進一步修復 Pod;相反地,Kubernetes 會刪除 Pod,並依賴其他元件來提供自動修復。
如果 Pod 被排程到一個 節點,然後該節點故障,則 Pod 會被視為不健康,而 Kubernetes 最終會刪除該 Pod。由於資源不足或節點維護而導致的驅逐,Pod 無法倖存。
Kubernetes 使用更高等級的抽象概念,稱為控制器,來處理管理相對可拋棄式 Pod 實例的工作。
給定的 Pod(由 UID 定義)永遠不會「重新排程」到不同的節點;相反地,該 Pod 可以被新的、幾乎相同的 Pod 取代。 如果您建立一個替換 Pod,它甚至可以具有與舊 Pod 相同的名稱(如 .metadata.name
),但替換 Pod 將具有與舊 Pod 不同的 .metadata.uid
。
Kubernetes 不保證現有 Pod 的替換 Pod 會排程到與被替換的舊 Pod 相同的節點。
關聯的生命週期
當某事物被認為與 Pod 具有相同的生命週期時,例如卷,這表示該事物只要該特定的 Pod(具有該確切的 UID)存在就存在。 如果該 Pod 因任何原因被刪除,即使建立了一個相同的替換 Pod,相關的事物(在本例中為卷)也會被銷毀並重新建立。
圖 1。
一個多容器 Pod,包含一個檔案提取器 Sidecar 和一個網頁伺服器。 Pod 使用一個臨時的 emptyDir
卷,用於容器之間的共享儲存。
Pod 階段
Pod 的 status
欄位是一個 PodStatus 物件,其中有一個 phase
欄位。
Pod 的階段是 Pod 在其生命週期中所處位置的簡單、高階摘要。 階段並非旨在成為容器或 Pod 狀態觀察的全面彙整,也並非旨在成為全面的狀態機。
Pod 階段值的數量和含義受到嚴格保護。 除了此處記錄的內容外,不應對具有給定 phase
值的 Pod 做出任何假設。
以下是 phase
的可能值
值 | 描述 |
---|---|
Pending | Pod 已被 Kubernetes 叢集接受,但一個或多個容器尚未設定並準備好執行。 這包括 Pod 等待排程的時間,以及透過網路下載容器映像檔所花費的時間。 |
Running | Pod 已繫結到一個節點,並且所有容器都已建立。 至少有一個容器仍在執行,或正在啟動或重新啟動的過程中。 |
Succeeded | Pod 中的所有容器都已成功終止,且不會重新啟動。 |
Failed | Pod 中的所有容器都已終止,且至少有一個容器以失敗告終。 也就是說,容器以非零狀態結束,或被系統終止,且未設定為自動重新啟動。 |
Unknown | 由於某些原因,無法取得 Pod 的狀態。 此階段通常由於與 Pod 應執行的節點通訊時發生錯誤而發生。 |
注意
當 Pod 反覆啟動失敗時,CrashLoopBackOff
可能會出現在某些 kubectl 指令的 Status
欄位中。 同樣地,當 Pod 正在刪除時,Terminating
可能會出現在某些 kubectl 指令的 Status
欄位中。
請務必不要將 Status(kubectl 為使用者直覺顯示的欄位)與 Pod 的 phase
混淆。 Pod 階段是 Kubernetes 資料模型和Pod API 的明確組成部分。
NAMESPACE NAME READY STATUS RESTARTS AGE
alessandras-namespace alessandras-pod 0/1 CrashLoopBackOff 200 2d9h
Pod 會被授予一個寬限期以優雅地終止,預設為 30 秒。 您可以使用 --force
旗標來強制終止 Pod。
自 Kubernetes 1.27 起,kubelet 會將已刪除的 Pod(靜態 Pod 和沒有終止器 (finalizer) 的強制刪除的 Pod 除外)轉換為終端階段(Failed
或 Succeeded
,取決於 Pod 容器的結束狀態),然後再從 API 伺服器中刪除它們。
如果節點死機或與叢集的其餘部分斷線,Kubernetes 會套用策略,將遺失節點上所有 Pod 的 phase
設定為 Failed。
容器狀態
除了整體 Pod 的階段之外,Kubernetes 還追蹤 Pod 內每個容器的狀態。 您可以使用容器生命週期掛鉤,以觸發在容器生命週期的特定時間點執行的事件。
一旦排程器將 Pod 指派給節點,kubelet 就會開始使用容器執行期為該 Pod 建立容器。 有三種可能的容器狀態:Waiting
、Running
和 Terminated
。
若要檢查 Pod 容器的狀態,您可以使用 kubectl describe pod <Pod 名稱>
。 輸出會顯示該 Pod 內每個容器的狀態。
每個狀態都有特定的含義
Waiting
如果容器未處於 Running
或 Terminated
狀態,則為 Waiting
。 處於 Waiting
狀態的容器仍在執行完成啟動所需的操作:例如,從容器映像檔登錄檔提取容器映像檔,或套用 Secret 資料。 當您使用 kubectl
查詢處於 Waiting
狀態的容器的 Pod 時,您還會看到一個 Reason 欄位,以摘要說明容器處於該狀態的原因。
Running
Running
狀態表示容器正在執行且沒有問題。 如果配置了 postStart
掛鉤,則它已執行並完成。 當您使用 kubectl
查詢處於 Running
狀態的容器的 Pod 時,您還會看到有關容器何時進入 Running
狀態的資訊。
Terminated
處於 Terminated
狀態的容器已開始執行,然後執行完成或因某些原因失敗。 當您使用 kubectl
查詢處於 Terminated
狀態的容器的 Pod 時,您會看到該容器執行期間的原因、結束代碼以及開始和結束時間。
如果容器配置了 preStop
掛鉤,則此掛鉤會在容器進入 Terminated
狀態之前執行。
Pod 如何處理容器問題
Kubernetes 使用 Pod spec
中定義的restartPolicy
來管理 Pod 內的容器故障。 此策略決定 Kubernetes 如何回應由於錯誤或其他原因而退出的容器,這屬於以下順序
- 初始當機: Kubernetes 根據 Pod
restartPolicy
嘗試立即重新啟動。 - 重複當機: 在初始當機之後,Kubernetes 對後續重新啟動套用指數退避延遲,如
restartPolicy
中所述。 這可防止快速、重複的重新啟動嘗試使系統過載。 - CrashLoopBackOff 狀態: 這表示退避延遲機制目前對處於當機迴圈中的給定容器生效,該容器反覆失敗並重新啟動。
- 退避重設: 如果容器成功執行一段時間(例如,10 分鐘),Kubernetes 會重設退避延遲,將任何新的當機視為第一次當機。
實際上,當描述或列出 Pod 時,CrashLoopBackOff
是一種條件或事件,可能會被視為 kubectl
指令的輸出,當 Pod 中的容器無法正確啟動,然後在迴圈中持續嘗試並失敗時。
換句話說,當容器進入當機迴圈時,Kubernetes 會套用容器重新啟動策略中提及的指數退避延遲。 此機制可防止故障容器因持續失敗的啟動嘗試而使系統不堪負荷。
CrashLoopBackOff
可能由以下問題引起
- 導致容器退出的應用程式錯誤。
- 組態錯誤,例如不正確的環境變數或遺失的組態檔。
- 資源限制,容器可能沒有足夠的記憶體或 CPU 來正確啟動。
- 如果應用程式未在預期時間內開始提供服務,則健康檢查失敗。
- 容器存活探針或啟動探針傳回 探針章節中提及的
Failure
結果。
為了調查 CrashLoopBackOff
問題的根本原因,使用者可以
- 檢查日誌: 使用
kubectl logs <Pod 名稱>
檢查容器的日誌。 這通常是診斷導致當機問題的最直接方法。 - 檢查事件: 使用
kubectl describe pod <Pod 名稱>
查看 Pod 的事件,這可以提供有關組態或資源問題的提示。 - 檢閱組態: 確保 Pod 組態(包括環境變數和掛載的卷)正確,並且所有必要的外部資源都可用。
- 檢查資源限制: 確保容器有足夠的 CPU 和記憶體分配。 有時,增加 Pod 定義中的資源可以解決問題。
- 偵錯應用程式: 應用程式程式碼中可能存在錯誤或組態錯誤。 在本機或開發環境中執行此容器映像檔可以幫助診斷特定於應用程式的問題。
容器重新啟動策略
Pod 的 spec
有一個 restartPolicy
欄位,其可能值為 Always、OnFailure 和 Never。 預設值為 Always。
Pod 的 restartPolicy
適用於 Pod 中的應用程式容器和常規初始化容器。Sidecar 容器 忽略 Pod 層級的 restartPolicy
欄位:在 Kubernetes 中,Sidecar 定義為 initContainers
內部的條目,其容器層級的 restartPolicy
設定為 Always
。 對於以錯誤退出的初始化容器,如果 Pod 層級的 restartPolicy
為 OnFailure
或 Always
,則 kubelet 會重新啟動初始化容器
Always
: 在任何終止後自動重新啟動容器。OnFailure
: 僅在容器以錯誤(非零結束狀態)退出時重新啟動容器。Never
: 不會自動重新啟動已終止的容器。
當 kubelet 根據配置的重新啟動策略處理容器重新啟動時,這僅適用於在同一 Pod 內且在同一節點上執行的替換容器的重新啟動。 在 Pod 中的容器退出後,kubelet 會使用指數退避延遲(10 秒、20 秒、40 秒、…)重新啟動它們,上限為 300 秒(5 分鐘)。 一旦容器在沒有任何問題的情況下執行了 10 分鐘,kubelet 就會重設該容器的重新啟動退避計時器。Sidecar 容器和 Pod 生命週期說明了在其中指定 restartpolicy
欄位時 init containers
的行為。
可配置的容器重新啟動延遲
Kubernetes v1.32 [alpha]
(預設啟用:false)啟用 alpha 功能閘道 KubeletCrashLoopBackOffMax
後,您可以重新配置容器啟動重試之間的最大延遲,預設值為 300 秒(5 分鐘)。 此配置是使用 kubelet 組態在每個節點上設定的。 在您的 kubelet 組態中,在 crashLoopBackOff
下,將 maxContainerRestartPeriod
欄位設定在 "1 秒"
和 "300 秒"
之間。 如上文容器重新啟動策略中所述,該節點上的延遲仍將從 10 秒開始,並在每次重新啟動時以 2 倍指數增加,但現在將限制為您配置的最大值。 如果您配置的 maxContainerRestartPeriod
小於預設初始值 10 秒,則初始延遲將改為設定為配置的最大值。
請參閱以下 kubelet 組態範例
# container restart delays will start at 10s, increasing
# 2x each time they are restarted, to a maximum of 100s
kind: KubeletConfiguration
crashLoopBackOff:
maxContainerRestartPeriod: "100s"
# delays between container restarts will always be 2s
kind: KubeletConfiguration
crashLoopBackOff:
maxContainerRestartPeriod: "2s"
Pod 狀況
Pod 具有 PodStatus,其中包含 PodConditions 陣列,Pod 已經或尚未通過這些狀況。 Kubelet 管理以下 Pod 狀況
PodScheduled
: Pod 已排程到節點。PodReadyToStartContainers
: (beta 功能;由預設值啟用)Pod 沙箱已成功建立且網路已配置。ContainersReady
: Pod 中的所有容器都已就緒。Initialized
: 所有初始化容器都已成功完成。Ready
: Pod 可以服務請求,並且應新增至所有相符 Service 的負載平衡池。
欄位名稱 | 描述 |
---|---|
類型 | 此 Pod 狀況的名稱。 |
狀態 | 指示該狀況是否適用,可能的值為 "True "、"False " 或 "Unknown "。 |
lastProbeTime | 上次探測 Pod 狀況的時間戳記。 |
lastTransitionTime | Pod 上次從一個狀態轉換到另一個狀態的時間戳記。 |
原因 | 機器可讀、UpperCamelCase 文字,指示狀況上次轉換的原因。 |
訊息 | 人類可讀的訊息,指示有關上次狀態轉換的詳細資訊。 |
Pod 就緒狀態
Kubernetes v1.14 [stable]
您的應用程式可以將額外的回饋或訊號注入 PodStatus:Pod 就緒狀態。 若要使用此功能,請在 Pod 的 spec
中設定 readinessGates
,以指定 kubelet 評估 Pod 就緒狀態的其他狀況清單。
就緒閘道由 Pod 的 status.condition
欄位的目前狀態決定。 如果 Kubernetes 在 Pod 的 status.conditions
欄位中找不到此類狀況,則該狀況的狀態預設為 "False
"。
以下是一個範例
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
- type: Ready # a built in PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
- type: "www.example.com/feature-1" # an extra PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
containerStatuses:
- containerID: docker://abcd...
ready: true
...
您新增的 Pod 狀況必須具有符合 Kubernetes 標籤鍵格式的名稱。
Pod 就緒狀態的狀態
kubectl patch
指令不支援修補物件狀態。 若要為 Pod 設定這些 status.conditions
,應用程式和Operator 應使用 PATCH
動作。 您可以使用 Kubernetes 用戶端程式庫來編寫程式碼,以設定自訂 Pod 狀況以實現 Pod 就緒狀態。
對於使用自訂狀況的 Pod,僅當以下兩個陳述都適用時,該 Pod 才被評估為就緒
- Pod 中的所有容器都已就緒。
readinessGates
中指定的所有狀況均為True
。
當 Pod 的容器皆為 Ready 狀態,但至少有一個自訂條件遺失或為 False
時,kubelet 會將 Pod 的狀況設定為 ContainersReady
。
Pod 網路就緒狀態
Kubernetes v1.29 [beta]
注意
在這個條件的早期開發階段,其名稱為PodHasNetwork
。在 Pod 被排程到節點上之後,它需要被 kubelet 允許 (admitted),並且掛載任何所需的儲存卷。一旦這些階段完成,kubelet 會與容器執行階段 (使用 容器執行階段介面 (CRI)) 協同工作,為 Pod 設定執行階段沙箱並配置網路。如果啟用了 PodReadyToStartContainersCondition
功能閘道 (在 Kubernetes 1.32 中預設為啟用),則 PodReadyToStartContainers
條件將會被新增到 Pod 的 status.conditions
欄位中。
當 Kubelet 偵測到 Pod 沒有已配置網路的執行階段沙箱時,PodReadyToStartContainers
條件會被設定為 False
。這會在以下情境中發生:
- 在 Pod 生命週期的早期,當 kubelet 尚未開始使用容器執行階段為 Pod 設定沙箱時。
- 在 Pod 生命週期的後期,當 Pod 沙箱因以下原因而被摧毀時:
- 節點重新啟動,但 Pod 並未被驅逐 (evicted)
- 對於使用虛擬機器進行隔離的容器執行階段,Pod 沙箱虛擬機器重新啟動,這時需要建立新的沙箱和全新的容器網路配置。
在執行階段外掛程式成功完成 Pod 的沙箱建立和網路配置後,kubelet 會將 PodReadyToStartContainers
條件設定為 True
。在 PodReadyToStartContainers
條件被設定為 True
之後,kubelet 才能開始拉取容器映像檔並建立容器。
對於具有初始化容器 (init containers) 的 Pod,在初始化容器成功完成 (在執行階段外掛程式成功建立沙箱和配置網路之後發生) 後,kubelet 會將 Initialized
條件設定為 True
。對於沒有初始化容器的 Pod,kubelet 會在沙箱建立和網路配置開始之前,將 Initialized
條件設定為 True
。
容器探針
探針 是由 kubelet 在容器上定期執行的診斷。為了執行診斷,kubelet 要麼在容器內執行程式碼,要麼發出網路請求。
檢查機制
有四種不同的方法可以使用探針檢查容器。每個探針都必須明確定義以下四種機制之一:
exec
- 在容器內部執行指定的命令。如果命令以狀態碼 0 退出,則診斷被視為成功。
grpc
- 使用 gRPC 執行遠端程序呼叫。目標應實作 gRPC 健康檢查。如果回應的
status
為SERVING
,則診斷被視為成功。 httpGet
- 針對 Pod 的 IP 位址,在指定的埠口和路徑上執行 HTTP
GET
請求。如果回應的狀態碼大於或等於 200 且小於 400,則診斷被視為成功。 tcpSocket
- 針對 Pod 的 IP 位址,在指定的埠口上執行 TCP 檢查。如果埠口是開啟的,則診斷被視為成功。如果遠端系統 (容器) 在開啟連線後立即關閉連線,這也算作健康。
注意
與其他機制不同,exec
探針的實作每次執行時都涉及多個進程的建立/fork。因此,在具有較高 Pod 密度的叢集中,較低的 initialDelaySeconds
、periodSeconds
間隔,使用 exec 機制配置任何探針可能會在節點的 CPU 使用率上引入額外負擔。在這種情況下,請考慮使用替代的探針機制以避免額外負擔。探針結果
每個探針都有三種結果之一:
成功
- 容器通過了診斷。
失敗
- 容器未通過診斷。
Unknown
- 診斷失敗 (不應採取任何動作,kubelet 將進行進一步檢查)。
探針類型
kubelet 可以選擇性地在執行中的容器上執行三種類型的探針並對其做出反應:
livenessProbe (存活探針)
- 指示容器是否正在執行。如果存活探針失敗,kubelet 會終止容器,並且容器將受到其重新啟動策略的約束。如果容器未提供存活探針,則預設狀態為
Success
。 readinessProbe (就緒探針)
- 指示容器是否已準備好回應請求。如果就緒探針失敗,端點控制器會從所有符合 Pod 的服務的端點中移除 Pod 的 IP 位址。初始延遲之前的就緒預設狀態為
Failure
。如果容器未提供就緒探針,則預設狀態為Success
。 startupProbe (啟動探針)
- 指示容器內的應用程式是否已啟動。如果提供了啟動探針,則在啟動探針成功之前,所有其他探針都會被停用。如果啟動探針失敗,kubelet 會終止容器,並且容器將受到其重新啟動策略的約束。如果容器未提供啟動探針,則預設狀態為
Success
。
有關如何設定存活、就緒或啟動探針的更多資訊,請參閱設定存活、就緒和啟動探針。
何時應該使用存活探針?
如果您的容器中的進程能夠在遇到問題或變得不健康時自行崩潰,您不一定需要存活探針;kubelet 將根據 Pod 的 restartPolicy
自動執行正確的動作。
如果您希望在探針失敗時終止並重新啟動您的容器,則請指定存活探針,並將 restartPolicy
指定為 Always 或 OnFailure。
何時應該使用就緒探針?
如果您希望僅在探針成功時才開始向 Pod 發送流量,請指定就緒探針。在這種情況下,就緒探針可能與存活探針相同,但是規格中就緒探針的存在意味著 Pod 將在沒有接收任何流量的情況下啟動,並且僅在探針開始成功後才開始接收流量。
如果您希望您的容器能夠自行關閉以進行維護,您可以指定一個就緒探針,該探針檢查專用於就緒狀態的端點,該端點與存活探針不同。
如果您的應用程式對後端服務有嚴格的依賴性,您可以同時實作存活探針和就緒探針。存活探針在應用程式本身健康時通過,但就緒探針還會額外檢查每個必需的後端服務是否可用。這有助於您避免將流量導向只能回應錯誤訊息的 Pod。
如果您的容器需要在啟動期間處理載入大量資料、組態檔案或遷移,您可以使用啟動探針。但是,如果您想要檢測應用程式是已失敗還是仍在處理其啟動資料之間的差異,您可能更喜歡就緒探針。
注意
如果您希望在 Pod 被刪除時能夠排空請求,您不一定需要就緒探針;在刪除時,無論就緒探針是否存在,Pod 都會自動將自身置於未就緒狀態。Pod 在等待 Pod 中的容器停止時,會保持在未就緒狀態。何時應該使用啟動探針?
啟動探針對於具有容器需要很長時間才能進入服務狀態的 Pod 非常有用。您可以為探測容器啟動時配置一個單獨的配置,而不是設定較長的存活間隔,這樣可以允許比存活間隔更長的時間。
如果您的容器通常在超過 initialDelaySeconds + failureThreshold × periodSeconds
的時間內啟動,您應該指定一個啟動探針,該探針檢查與存活探針相同的端點。periodSeconds
的預設值為 10 秒。然後,您應該將其 failureThreshold
設定得足夠高,以允許容器啟動,而無需更改存活探針的預設值。這有助於防止死鎖。
Pod 的終止
由於 Pod 代表在叢集節點上執行的進程,因此允許這些進程在不再需要時優雅地終止 (而不是被 KILL
信號突然停止且沒有機會清理) 非常重要。
設計目標是讓您能夠請求刪除並知道進程何時終止,同時也能夠確保刪除最終完成。當您請求刪除 Pod 時,叢集會記錄並追蹤在允許強制終止 Pod 之前的預期寬限期。有了強制關閉追蹤,kubelet 會嘗試優雅關閉。
通常,對於 Pod 的優雅終止,kubelet 會向容器執行階段發出請求,嘗試透過首先向每個容器中的主要進程發送 TERM (又名 SIGTERM) 信號 (帶有寬限期逾時) 來停止 Pod 中的容器。停止容器的請求由容器執行階段非同步處理。不保證這些請求的處理順序。許多容器執行階段都遵循容器映像檔中定義的 STOPSIGNAL
值,如果不同,則發送容器映像檔配置的 STOPSIGNAL 而不是 TERM。一旦寬限期到期,KILL 信號將被發送到任何剩餘的進程,然後 Pod 將從 API 伺服器 中刪除。如果在等待進程終止時 kubelet 或容器執行階段的管理服務重新啟動,叢集將從頭開始重試,包括完整的原始寬限期。
Pod 終止流程,以範例說明
您使用
kubectl
工具手動刪除特定的 Pod,預設寬限期為 30 秒。API 伺服器中的 Pod 會更新一個時間點,超過該時間點 Pod 被視為「死亡」,以及寬限期。如果您使用
kubectl describe
檢查您正在刪除的 Pod,則該 Pod 會顯示為「Terminating」。在 Pod 執行的節點上:一旦 kubelet 看到 Pod 已被標記為終止 (已設定優雅關閉持續時間),kubelet 就會開始本機 Pod 關閉程序。如果 Pod 的其中一個容器定義了
preStop
hook,並且 Pod spec 中的terminationGracePeriodSeconds
未設定為 0,則 kubelet 會在容器內部執行該 hook。預設的terminationGracePeriodSeconds
設定為 30 秒。如果
preStop
hook 在寬限期到期後仍在執行,則 kubelet 會請求一個小的、一次性的 2 秒寬限期延長。注意
如果preStop
hook 需要比預設寬限期允許的時間更長才能完成,您必須修改terminationGracePeriodSeconds
以適應這種情況。kubelet 觸發容器執行階段向每個容器內部的進程 1 發送 TERM 信號。
如果 Pod 定義了任何邊車容器,則存在特殊排序。否則,Pod 中的容器會在不同的時間且以任意順序接收 TERM 信號。如果關閉順序很重要,請考慮使用
preStop
hook 來同步 (或切換到使用邊車容器)。
在 kubelet 開始優雅關閉 Pod 的同時,控制平面會評估是否要從 EndpointSlice (和 Endpoints) 物件中移除正在關閉的 Pod,這些物件代表具有已配置選擇器的服務。ReplicaSets 和其他工作負載資源不再將正在關閉的 Pod 視為有效的、服務中的副本。
關閉緩慢的 Pod 不應繼續提供常規流量,而應開始終止並完成處理開啟的連線。某些應用程式需要超越完成開啟的連線,並且需要更優雅的終止,例如,會話排空和完成。
代表終止中 Pod 的任何端點都不會立即從 EndpointSlices 中移除,並且從 EndpointSlice API (和舊版 Endpoints API) 公開指示終止狀態的狀態。終止中的端點始終將其
ready
狀態設為false
(為了向後相容於 1.26 之前的版本),因此負載平衡器不會將其用於常規流量。如果需要排空終止中 Pod 的流量,則可以將實際的就緒狀態檢查為條件
serving
。您可以在教學課程Pod 和端點終止流程中找到有關如何實作連線排空的更多詳細資訊
強制 Pod 終止
預設情況下,所有刪除操作都會在 30 秒內優雅地完成。kubectl delete
命令支援 --grace-period=<seconds>
選項,讓您可以覆寫預設值並指定自己的值。
將寬限期設定為 0
會強制且立即地從 API 伺服器刪除 Pod。如果 Pod 仍在節點上執行,則此強制刪除會觸發 kubelet 開始立即清理。
使用 kubectl 時,您必須指定額外的旗標 --force
以及 --grace-period=0
,才能執行強制刪除。
如果您需要強制刪除屬於 StatefulSet 的 Pod,請參閱關於從 StatefulSet 刪除 Pod的工作文件。
Pod 關閉與 Sidecar 容器
如果您的 Pod 包含一個或多個 Sidecar 容器 (具有 Always 重新啟動策略的 init 容器),kubelet 將延遲向這些 Sidecar 容器發送 TERM 訊號,直到最後一個主要容器完全終止。Sidecar 容器將以它們在 Pod spec 中定義的相反順序終止。這確保了 Sidecar 容器在不再需要之前,繼續為 Pod 中的其他容器提供服務。
這表示主要容器的緩慢終止也會延遲 Sidecar 容器的終止。如果在終止程序完成之前寬限期到期,Pod 可能會進入強制終止。在這種情況下,Pod 中所有剩餘的容器將同時終止,並具有短暫的寬限期。
類似地,如果 Pod 具有超出終止寬限期的 preStop
hook,則可能會發生緊急終止。一般而言,如果您已使用 preStop
hook 來控制終止順序而沒有 Sidecar 容器,您現在可以移除它們,並允許 kubelet 自動管理 Sidecar 終止。
Pod 的垃圾收集
對於失敗的 Pod,API 物件會保留在叢集的 API 中,直到人員或 控制器 程序明確地移除它們。
Pod 垃圾收集器 (PodGC) 是控制平面中的一個控制器,當 Pod 的數量超過配置的閾值 (由 kube-controller-manager 中的 terminated-pod-gc-threshold
決定) 時,它會清除已終止的 Pod (階段為 Succeeded
或 Failed
)。這避免了隨著時間推移 Pod 被建立和終止而導致的資源洩漏。
此外,PodGC 還會清除滿足以下任何條件的 Pod
- 是孤立的 Pod - 綁定到不再存在的節點,
- 是未排程的終止中 Pod,
- 是終止中 Pod,綁定到被
node.kubernetes.io/out-of-service
污點標記為非就緒的節點。
除了清理 Pod 之外,如果 PodGC 處於非終止階段,它還會將其標記為失敗。此外,PodGC 在清理孤立 Pod 時會新增 Pod 中斷狀況。請參閱 Pod 中斷狀況 以取得更多詳細資訊。
接下來
取得關於將處理常式附加到容器生命週期事件的實務經驗。
取得關於配置 Liveness、Readiness 和 Startup Probes的實務經驗。
深入瞭解 容器生命週期 Hook。
深入瞭解 Sidecar 容器。
有關 API 中 Pod 和容器狀態的詳細資訊,請參閱涵蓋 Pod 的
status
的 API 參考文件。