排解 CrashLoopBackOff 事件

如果 Google Kubernetes Engine (GKE) 中的 Pod 停滯在 CrashLoopBackOff 狀態,表示一或多個容器會重複啟動然後結束。這種情況可能會導致應用程式不穩定或完全無法使用。

請使用這個頁面診斷及解決根本原因,這些原因通常屬於資源限制、存活探查問題、應用程式錯誤或設定錯誤等類別。排解這些問題有助於確保應用程式穩定運作,並持續提供給使用者。

如果您是應用程式開發人員,想找出並修正應用程式層級的問題 (例如編碼錯誤、不正確的進入點、設定檔問題或連線至依附元件的問題),這項資訊就非常重要。平台管理員和營運人員可以找出並解決平台相關問題,例如資源耗盡 (OOMKilled)、節點中斷或設定錯誤的存活探查。如要進一步瞭解 Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。

瞭解 CrashLoopBackOff 事件

如果 Pod 停滯在 CrashLoopBackOff 狀態,表示其中的容器會重複啟動、當機或結束。這個 CrashLoop 會觸發 Kubernetes 嘗試按照 restartPolicy 重新啟動容器。每次重新啟動失敗後,下一次嘗試前的「BackOff」BackOff延遲時間會以指數方式增加 (例如 10 秒、20 秒、40 秒),最多為五分鐘。

雖然這項事件表示容器內有問題,但也是很有價值的診斷信號。CrashLoopBackOff 事件會確認 Pod 建立的許多基礎步驟 (例如指派給節點和提取容器映像檔) 都已完成。這項知識可讓您專注於調查容器的應用程式或設定,而非叢集基礎架構。

發生 CrashLoopBackOff 狀態的原因是 Kubernetes (具體來說是 kubelet) 會根據 Pod 的重新啟動政策處理容器終止作業。週期通常會遵循下列模式:

  1. 容器會啟動。
  2. 容器會結束。
  3. kubelet 會觀察已停止的容器,並根據 Pod 的 restartPolicy 重新啟動容器。
  4. 這個週期會重複,容器會在指數輪詢延遲時間增加後重新啟動。

Pod 的 restartPolicy 是這項行為的關鍵。預設政策 Always 是造成這個迴圈最常見的原因,因為即使容器成功結束,只要容器因任何原因結束,就會重新啟動。OnFailure 政策較不可能造成迴圈,因為只會在結束代碼非零時重新啟動,而 Never 政策則完全避免重新啟動。

找出 CrashLoopBackOff 事件的徵兆

狀態為 CrashLoopBackOff 的 Pod 是 CrashLoopBackOff 事件的主要指標。

不過,您可能會遇到一些較不明顯的 CrashLoopBackOff 事件症狀:

  • 工作負載的健康狀態良好的副本數量為零。
  • 健康副本大幅減少。
  • 已啟用水平 Pod 自動調度資源功能的工作負載擴充速度緩慢,或無法擴充。

如果 system 工作負載 (例如記錄或指標代理程式) 處於 CrashLoopBackOff 狀態,您可能也會注意到下列徵兆:

  • 部分 GKE 指標未回報。
  • 部分 GKE 資訊主頁和圖表有間隙。
  • Pod 層級網路的連線問題。

如果發現任何這些較不明顯的徵兆,下一步應確認是否發生 CrashLoopBackOff 事件。

確認 CrashLoopBackOff 事件

如要確認及調查 CrashLoopBackOff 事件,請從 Kubernetes 事件和容器的應用程式記錄檔中收集證據。這兩個來源提供的問題觀點不同,但可互補:

  • Kubernetes 事件會確認 Pod 發生當機。
  • 容器的應用程式記錄可顯示容器內程序失敗的原因。

如要查看這項資訊,請選取下列其中一個選項:

控制台

如要查看 Kubernetes 事件和應用程式記錄,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 選取要調查的工作負載。「總覽」或「詳細資料」分頁會顯示工作負載狀態的詳細資訊。

  3. 在「受管理的 Pod」區段中,按一下有問題的 Pod 名稱。

  4. 在 Pod 詳細資料頁面中,調查下列事項:

    • 如要查看 Kubernetes 事件的詳細資料,請前往「Events」(事件) 分頁標籤。
    • 如要查看容器的應用程式記錄,請前往「記錄」分頁標籤。您可以在這個頁面查看應用程式專屬的錯誤訊息或堆疊追蹤。

kubectl

如要查看 Kubernetes 事件和應用程式記錄,請按照下列步驟操作:

  1. 查看叢集中所有 Pod 的執行狀態:

    kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME       READY  STATUS             RESTARTS  AGE
    POD_NAME   0/1    CrashLoopBackOff   23        8d
    

    在輸出內容中,查看下列資料欄:

    • Ready:查看有多少容器已準備就緒。在本例中,0/1 表示一個預期容器中,有零個容器處於就緒狀態。這個值明顯表示有問題。
    • Status:尋找狀態為 CrashLoopBackOff 的 Pod。
    • Restarts:值偏高表示 Kubernetes 持續嘗試啟動容器,但都失敗。
  2. 找出失敗的 Pod 後,請說明該 Pod,查看與 Pod 狀態相關的叢集層級事件:

    kubectl describe pod POD_NAME -n NAMESPACE_NAME
    

    更改下列內容:

    • POD_NAME:您在 kubectl get 指令輸出內容中識別的 Pod 名稱。
    • NAMESPACE_NAME:Pod 的命名空間。

    輸出結果會與下列內容相似:

    Containers:
    container-name:
    ...
      State:          Waiting
        Reason:       CrashLoopBackOff
      Last State:     Terminated
        Reason:       StartError
        Message:      failed to create containerd task: failed to create shim task: context deadline exceeded: unknown
        Exit Code:    128
        Started:      Thu, 01 Jan 1970 00:00:00 +0000
        Finished:     Fri, 27 Jun 2025 16:20:03 +0000
      Ready:          False
      Restart Count:  3459
    ...
    Conditions:
    Type                        Status
    PodReadyToStartContainers   True
    Initialized                 True
    Ready                       False
    ContainersReady             False
    PodScheduled                True
    ...
    Events:
    Type     Reason   Age                     From     Message
    ----     ------   ----                    ----     -------
    Warning  Failed   12m (x216 over 25h)     kubelet  Error: context deadline exceeded
    Warning  Failed   8m34s (x216 over 25h)   kubelet  Error: context deadline exceeded
    Warning  BackOff  4m24s (x3134 over 25h)  kubelet  Back-off restarting failed container container-name in pod failing-pod(11111111-2222-3333-4444-555555555555)
    

    在輸出內容中,查看下列欄位是否有 CrashLoopBackOff 事件的跡象:

    • State:容器的狀態可能顯示 Waiting,並附上原因 CrashLoopBackOff
    • Last State:先前終止的容器狀態。尋找 Terminated 狀態,並查看結束代碼,確認是否發生當機 (結束代碼不為零) 或意外成功結束 (結束代碼為零)。
    • Events:叢集本身採取的動作。尋找容器啟動的相關訊息,接著是有效性探測失敗或類似 Back-off restarting failed container 的退避警告。
  3. 如要進一步瞭解 Pod 失敗的原因,請查看應用程式記錄:

    kubectl logs POD_NAME --previous
    

    --previous 標記會從先前終止的容器擷取記錄,您可以在其中找到顯示當機原因的特定堆疊追蹤或錯誤訊息。目前的容器可能太新,因此尚未記錄任何記錄。

    在輸出內容中,找出導致程序結束的應用程式專屬錯誤。如果您使用自訂應用程式,最適合解讀這些錯誤訊息的對象是撰寫應用程式的開發人員。如果您使用預先建構的應用程式,這些應用程式通常會提供自己的偵錯說明。

使用 Pod 當機循環問題的互動式應對手冊

確認 CrashLoopBackOff 事件後,即可開始使用互動式應對手冊排解問題:

  1. 前往 Google Cloud 控制台的「GKE Interactive Playbook - Crashlooping Pods」(GKE 互動式應對手冊 - Pod 的當機循環情況) 頁面。

    前往 Crashlooping Pods

  2. 在「叢集」清單中,選取要進行疑難排解的叢集。如果找不到叢集,請在「篩選」欄位中輸入叢集名稱。

  3. 在「命名空間」清單中,選取要進行疑難排解的命名空間。如果找不到命名空間,請在「篩選器」欄位中輸入命名空間。

  4. 請詳閱各節內容,協助回答下列問題:

    1. 找出應用程式錯誤:哪些容器重新啟動?
    2. 調查記憶體不足問題:是否有設定錯誤或應用程式相關錯誤?
    3. 調查節點服務中斷情形:是否因節點資源服務中斷而讓容器重新啟動?
    4. 調查有效性探測失敗問題:有效性探測是否會停止容器?
    5. 找出變更事件的關聯性:容器停止運作前發生了什麼事?
  5. 選用步驟:如要接收未來 CrashLoopBackOff 事件的通知,請在「未來緩解措施提示」部分中,選取「建立快訊」

如果使用劇本後問題仍未解決,請參閱本指南的其餘部分,進一步瞭解如何解決 CrashLoopBackOff 事件。

解決 CrashLoopBackOff 事件

以下各節將協助你解決 CrashLoopBackOff 事件最常見的原因:

解決資源耗盡問題

CrashLoopBackOff 事件通常是由記憶體不足 (OOM) 問題所導致。如果 kubectl describe 輸出內容顯示下列項目,即可確認是否為這個原因:

Last State: Terminated
  Reason: OOMKilled

如要瞭解如何診斷及解決 OOM 事件,請參閱「排解 OOM 事件」。

解決有效性探測失敗問題

存活探測器kubelet 執行的定期健康狀態檢查。如果探測失敗次數達到指定次數 (預設為三次),kubelet 會重新啟動容器,如果探測持續失敗,可能會導致 CrashLoopBackOff 事件。

確認是否為 liveness 探測造成問題

如要確認是否因存活探查失敗而觸發 CrashLoopBackOff 事件,請查詢 kubelet 記錄。這些記錄通常會包含明確的訊息,指出探測失敗和後續的重新啟動作業。

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面。

    前往記錄檔探索工具

  2. 在查詢窗格中輸入下列查詢,篩選出與即時探查相關的任何重新啟動:

    resource.type="k8s_node"
    log_id("kubelet")
    jsonPayload.MESSAGE:"failed liveness probe, will be restarted"
    resource.labels.cluster_name="CLUSTER_NAME"
    

    CLUSTER_NAME 替換為叢集名稱。

  3. 查看輸出內容。如果有效性探測失敗是 CrashLoopBackOff 事件的原因,查詢會傳回類似以下的記錄訊息:

    Container probe failed liveness probe, will be restarted
    

確認是存活探查導致CrashLoopBackOff事件後,請繼續排解常見原因:

檢查有效性探測設定

探針設定錯誤是 CrashLoopBackOff 事件的常見原因。檢查探針資訊清單中的下列設定:

  • 驗證探測類型:探測的設定必須與應用程式回報健康狀態的方式相符。舉例來說,如果應用程式有健康狀態檢查網址 (例如 /healthz),請使用 httpGet 探測類型。如果健康狀態是透過執行指令判斷,請使用 exec 探查類型。舉例來說,如要檢查網路通訊埠是否已開啟並接聽,請使用 tcpSocket 探查類型。
  • 檢查探針參數
    • 路徑 (適用於 httpGet 探測器類型):請確認 HTTP 路徑正確無誤,且應用程式會透過該路徑提供健康狀態檢查。
    • 通訊埠:確認探針中設定的通訊埠是否確實由應用程式使用及公開。
    • 指令 (適用於 exec 探測類型):確認指令存在於容器中,成功時會傳回 0 的結束代碼,並在設定的 timeoutSeconds 期間內完成。
    • 逾時:請確認 timeoutSeconds 值是否足夠讓應用程式回應,尤其是在啟動或負載期間。
    • 初始延遲 (initialDelaySeconds):檢查初始延遲是否足以讓應用程式在探查開始前啟動。

詳情請參閱 Kubernetes 說明文件中的「設定有效性、完備性和啟動探測器」。

檢查 CPU 和磁碟 I/O 使用率

資源爭用會導致探測逾時,這是造成存活探測失敗的主要原因。如要確認資源用量是否導致即時性探查失敗,請嘗試下列解決方案:

  • 分析 CPU 使用率:在探查間隔期間,監控受影響容器的 CPU 使用率,以及容器執行的節點。您應追蹤的重要指標是 kubernetes.io/container/cpu/core_usage_time。容器或節點的 CPU 使用率過高,可能會導致應用程式無法及時回應探測。
  • 監控磁碟 I/O:檢查節點的磁碟 I/O 指標。您可以使用 compute.googleapis.com/guest/disk/operation_time 指標評估磁碟作業耗費的時間,並依讀取和寫入作業分類。磁碟 I/O 偏高可能會大幅減緩容器啟動、應用程式初始化或整體應用程式效能,導致探查逾時。

處理大規模部署作業

如果同時部署大量 Pod (例如透過 ArgoCD 等 CI/CD 工具),新 Pod 突然大量湧入可能會導致叢集資源過載,進而耗盡控制層資源。資源不足會延遲應用程式啟動,並導致有效性探測在應用程式準備就緒前,反覆失敗。

如要解決這個問題,請嘗試下列解決方案:

  • 實作交錯部署:實作策略,分批或在較長的時間內部署 Pod,避免節點資源過度使用。
  • 重新設定或擴充節點:如果無法交錯部署,請考慮使用速度更快或更大的磁碟升級節點,或使用 Persistent Volume Claims,以便更妥善地處理增加的 I/O 需求。確認叢集自動調度功能設定正確無誤。
  • 等待並觀察:在某些情況下,如果叢集資源不足的程度不嚴重,工作負載可能會在大幅延遲後 (有時會延遲 30 分鐘以上) 部署完畢。

解決暫時性錯誤

應用程式在啟動或初始化期間可能會發生暫時性錯誤或速度變慢,導致探查最初失敗。如果應用程式最終恢復正常,請考慮增加存活探查資訊清單中 initialDelaySecondsfailureThreshold 欄位定義的值。

處理探查資源用量

在極少數情況下,有效性探測的執行本身可能會耗用大量資源,進而觸發資源限制,導致容器因 OOM 終止。請確保探查指令輕量化。輕量型探針的執行速度和可靠性較高,因此能更準確地回報應用程式的實際健康狀態。

解決應用程式設定錯誤的問題

應用程式設定錯誤會導致許多 CrashLoopBackOff 事件。如要瞭解應用程式停止的原因,請先檢查結束代碼。這段程式碼會決定疑難排解路徑:

  • 結束碼 0 表示成功結束,但這對長時間執行的服務來說並不正常,且指出容器的進入點或應用程式設計有問題。
  • 非零的結束代碼表示應用程式當機,因此您應著重於設定錯誤、依附元件問題或程式碼中的錯誤。

尋找退出代碼

如要找出應用程式的結束代碼,請按照下列步驟操作:

  1. 描述 Pod:

    kubectl describe pod POD_NAME -n NAMESPACE_NAME
    

    更改下列內容:

    • POD_NAME:有問題的 Pod 名稱。
    • NAMESPACE_NAME:Pod 的命名空間。
  2. 在輸出結果中,查看相關容器的 Last State 區段下方的 Exit Code 欄位。如果結束代碼為 0,請參閱「排解成功結束 (結束代碼 0)」。如果結束代碼不是 0,請參閱「排解應用程式當機問題 (非零結束代碼)」。

排解成功結束 (結束代碼 0) 的問題

結束代碼 0 通常表示容器程序已順利完成。雖然這是以工作為基礎的 Job 所需的結果,但對於 Deployment、StatefulSet 或 ReplicaSet 等長時間執行的控制器,這可能表示有問題。

這些控制器會確保 Pod 一律處於執行狀態,因此會將任何結束視為需要修正的失敗。kubelet 會遵循 Pod 的 restartPolicy (預設為 Always) 強制執行這項行為,即使容器成功結束,也會重新啟動。這項動作會建立迴圈,最終觸發 CrashLoopBackOff 狀態。

非預期成功結束的最常見原因如下:

  • 容器指令未啟動持續性程序:容器只會在初始程序 (commandentrypoint) 執行時保持運作。如果這項程序不是長期執行的服務,容器會在指令完成後立即結束。舉例來說,["/bin/bash"] 這類指令會立即結束,因為沒有要執行的指令碼。如要解決這個問題,請確保容器的初始程序會啟動持續執行的程序。

  • 工作佇列空白時,Worker 應用程式會結束:許多 Worker 應用程式的設計都是檢查佇列是否有工作,如果佇列空白,就會乾淨利落地結束。如要解決這個問題,您可以改用 Job 控制器 (專為執行至完成的作業設計),或是修改應用程式的邏輯,以持續性服務的形式執行。

  • 應用程式因缺少或無效的設定而結束:如果應用程式缺少必要的啟動指令 (例如指令列引數、環境變數或重要設定檔),可能會立即結束。

    如要解決這個問題,請先檢查應用程式記錄檔,找出與設定載入或缺少參數相關的特定錯誤訊息。然後,請確認下列事項:

    • 應用程式引數或環境:確保所有必要的命令列引數和環境變數都正確傳遞至容器,符合應用程式的預期。
    • 設定檔存在與否:確認所有必要的設定檔都位於容器內的預期路徑。
    • 設定檔內容:驗證設定檔的內容和格式,找出語法錯誤、缺少必填欄位或值不正確等問題。

    常見的例子是,應用程式設定為從以 ConfigMap 磁碟區掛接的檔案讀取資料。如果 ConfigMap 未附加、為空白或金鑰名稱有誤,應用程式可能會在設定遺失時停止運作,並顯示 0 的結束代碼。在這種情況下,請確認下列設定: - Pod 磁碟區定義中的 ConfigMap 名稱與實際名稱相符。 - ConfigMap 中的鍵與應用程式預期在已掛接磁碟區中找到的檔案名稱相符。

排解應用程式當機問題 (非零結束代碼)

如果容器以非零的程式碼結束,Kubernetes 會重新啟動容器。如果導致錯誤的根本問題持續存在,應用程式會再次當機,然後重複這個週期,最終進入 CrashLoopBackOff 狀態。

非零的結束代碼清楚指出應用程式本身發生錯誤,因此您應將偵錯工作導向應用程式的內部運作和環境。以下是導致終止的常見問題:

  • 設定錯誤:非零的結束代碼通常表示應用程式設定或執行環境有問題。檢查應用程式是否有下列常見問題:

    • 缺少設定檔:應用程式可能找不到或無法存取必要的設定檔。
    • 設定無效:設定檔可能含有語法錯誤、不正確的值或不相容的設定,導致應用程式當機。
    • 權限問題:應用程式可能缺少讀取或寫入設定檔的必要權限。
    • 環境變數:環境變數有誤或缺漏可能會導致應用程式故障或無法啟動。
    • 無效的 entrypointcommand:容器的 entrypointcommand 欄位中指定的指令可能不正確。如果可執行檔的路徑有誤,或是容器映像檔中沒有該檔案,新部署的映像檔就可能發生這個問題。這類設定錯誤通常會導致 128 結束代碼。
    • 不受控的映像檔更新 (:latest 標記):如果工作負載映像檔使用 :latest 標記,新的 Pod 可能會提取更新的映像檔版本,進而造成重大變更。

      為確保一致性和可重現性,請務必在正式環境中使用特定且不可變動的映像檔標記 (例如 v1.2.3) 或 SHA 摘要 (例如 sha256:45b23dee08...)。這項做法可確保每次都提取完全相同的圖片內容。

  • 依附元件問題:如果應用程式無法連線至依附的其他服務,或無法驗證或沒有足夠的存取權,可能會停止運作。

    • 外部服務無法使用:應用程式可能依賴外部服務 (例如資料庫或 API),但因網路連線問題或服務中斷而無法連線。如要排解這個問題,請連線至 Pod。詳情請參閱 Kubernetes 說明文件的「偵錯執行中的 Pod」。

      連線至 Pod 後,您可以執行指令來檢查檔案或資料庫的存取權,或是測試網路。舉例來說,您可以使用 curl 等工具嘗試連線至服務的網址。這項操作可協助您判斷問題是由網路政策、DNS 還是服務本身所造成。

    • 驗證失敗:應用程式可能因憑證錯誤而無法向外部服務驗證。檢查容器的記錄檔,查看是否有 401 Unauthorized (憑證無效) 或 403 Forbidden (權限不足) 等訊息,這通常表示 Pod 的服務帳戶缺少必要的 IAM 角色,無法發出外部 Google Cloud服務呼叫。

      如果您使用 GKE Workload Identity Federation,請確認主體 ID 具有執行工作所需的權限。如要進一步瞭解如何使用 GKE Workload Identity Federation,為主體授予 IAM 角色,請參閱「設定授權和主體」。此外,您也應確認 GKE 中繼資料伺服器的資源用量未超過限制

    • 逾時:應用程式等待外部服務回應時可能會逾時,導致當機。

  • 應用程式專屬錯誤:如果設定和外部依附元件似乎正確無誤,錯誤可能出現在應用程式的程式碼中。檢查應用程式記錄,確認是否有下列常見的內部錯誤:

    • 未處理的例外狀況:應用程式記錄可能包含堆疊追蹤記錄或錯誤訊息,指出未處理的例外狀況或其他程式碼相關錯誤。
    • 死結或活結:應用程式可能陷入死結,也就是多個程序互相等待完成作業。在這種情況下,應用程式可能不會結束,但會無限期停止回應。
    • 通訊埠衝突:如果應用程式嘗試繫結至其他程序已使用的通訊埠,可能無法啟動。
    • 不相容的程式庫:應用程式可能依附於缺少或與執行階段環境不相容的程式庫或依附元件。

    如要找出根本原因,請檢查容器記錄檔中是否有特定錯誤訊息或堆疊追蹤記錄。您可以根據這項資訊決定是否要修正應用程式程式碼、調整資源限制,或修正環境設定。如要進一步瞭解記錄,請參閱「關於 GKE 記錄」。

後續步驟