海外雲在線 海外雲在線 立即諮詢

GCP帳號充值代辦 Google Cloud GKE容器部署失敗排查

谷歌雲GCP / 2026-07-01 15:25:09

前言:先別急著改,先把失敗「定性」

在 GKE 上部署容器失敗,最大問題不是你不會修,而是你一開始就把精力平均灑在所有可能性上:鏡像是不是壞的、ServiceAccount 權限夠不夠、網路能不能通、資源是否不夠、掛載卷是否正確、就緒探針是不是判斷錯了……最後常見的結局是「改了很多,但不知道改到哪裡有用」。

更務實的做法是:先把失敗定性成幾類,再對應到合理的排查路徑。GKE 的錯誤訊息雖然複雜,但其實具有規律。你只要抓住其中幾個關鍵字,就能快速縮小範圍。

本文以「部署失敗排查」為主線,提供一套從現象到根因的通用流程。你不一定每一次都遇到全部情況,但這套流程能讓你在 30 分鐘內看出大方向。

第一章:快速判斷失敗類型(先看 Pod 狀態)

大多數問題最後都會落在 Pod 上。先用最直接的方式看狀態,而不是急著看部署 YAML。

1. Pod 一直 Pending:多半是排程或資源、網路或卷問題

如果 Pod 長時間是 Pending,常見原因包括:

  • 節點資源不足(CPU/Memory 不夠)
  • 節點選擇器與容忍(nodeSelector、nodeAffinity、taints/tolerations)不匹配
  • PV/StorageClass 無法供應
  • 事件顯示拉不下鏡像前就卡住(偶爾也會先呈現 Pending)
  • 叢集網路/子網路配置導致節點無法正確加入或 Pod 網路未就緒

下一步不是猜,而是看事件。

GCP帳號充值代辦 2. Pod 出現 ImagePullBackOff 或 ErrImagePull:優先懷疑鏡像路徑與憑證

這類錯誤非常典型。你會看到類似 ImagePullBackOffErrImagePullunauthorizedmanifest unknowndenied

常見根因:

  • 鏡像名稱/Tag 寫錯(尤其是版本號或路徑)
  • 鏡像私有,需要正確的 ImagePullSecret 或 Workload Identity 配置
  • 雲端端點或權限未授權(例如 Artifact Registry/Container Registry 權限不足)
  • 節點無法連到鏡像服務(網路 egress、DNS、代理、VPC Service Controls 等)

3. Pod 是 CrashLoopBackOff:大多是啟動參數、程式啟動失敗或探針設定

當你看到 CrashLoopBackOff,要先確認是容器真的崩潰,還是被探針重啟。

常見原因:

  • GCP帳號充值代辦 程式需要環境變數/設定檔,但 ConfigMap/Secret 掛載失敗或 key 名稱不正確
  • 應用啟動命令錯誤、工作目錄錯、依賴檔缺失
  • 探針(liveness/readiness/startup)設定不合理,導致還沒就緒就被殺掉
  • 資源不足導致 OOMKilled

4. Pod Running 但 Service 不通:通常是 Service/Ingress/防火牆或容器監聽錯誤

不少人會以為部署成功就結束了,但對外服務不通通常是下一層問題。這時候你要回頭看:

  • Service selector 是否匹配 Pod labels
  • 容器監聽的 port 是否和 Service targetPort 對得上
  • Ingress path/host 規則是否正確
  • NetworkPolicy 是否阻擋
  • GCP帳號充值代辦 防火牆/負載平衡器健康檢查是否失敗

第二章:用事件與日誌把線索「串起來」

GKE 不是只有 Pod 狀態,事件(Events)與日誌是你最好的推理工具。你要做的不是看一堆輸出,而是找「第一個明確錯誤」。

1. 先看事件:kubectl describe pod

對單一 Pod 跑 kubectl describe pod,你通常會看到事件區塊列出類似:

  • Failed to pull image:原因通常非常明確
  • FailedScheduling:事件會指出不可行的原因,例如 node selector/Insufficient cpu
  • FailedMount:指向卷與權限/路徑
  • Readiness probe failed:指向探針 URL/端口/逾時

重要的是:事件是時間序列。不要只看最後一行,把「最早出錯」的那條當作主線。

2. 再看容器日誌:kubectl logs

日誌能揭露程式啟動階段發生的真正錯誤。常見做法是先看最後一次失敗:

  • kubectl logs <pod>
  • 如果有重啟,查上一個容器:kubectl logs --previous

另外,如果你使用了多容器 Pod,記得指定 -c。很多人只看主容器日誌,卻忽略 sidecar 才是失敗點。

3. Pod 沒起來就看不到日誌:改看 initContainer 或事件

如果 Pod 在 initContainer 階段失敗,你的主容器日誌可能根本不存在。這時候要查:

  • 事件:Failed to pull image、FailedMount、Back-off restarting failed container 等
  • 描述:initContainers 區塊的狀態

這能把排查範圍從「應用本身」縮到「啟動前步驟」。

第三章:鏡像與憑證失敗(最常見的第一類)

很多部署失敗不是雲端複雜,而是鏡像拉不下來。你應該把鏡像排查放在最前面,因為它能快速結束一半問題。

1. 檢查鏡像 reference:Tag、digest、路徑

請確認 Deployment/PodSpec 裡的 image 字串完全正確。常見踩雷:

  • 容器映像登記在 Artifact Registry,但你寫成了 Container Registry 格式
  • Tag 拼寫錯,或使用了尚未 push 的版本
  • 大小寫錯誤(某些系統會在特定情況下敏感)
  • 工作流程用 digest,但你改回了 tag(tag 可能被覆蓋或回收)

GCP帳號充值代辦 建議做法是:確認你推上去的鏡像「完整名稱」與部署中的一致。

2. 如果是私有鏡像:ImagePullSecret / Workload Identity

私有鏡像常見是權限不足。GKE 現代化常用 Workload Identity,而不是一直塞 ImagePullSecret。兩者都要確認:

  • 若用 ImagePullSecret:Secret 是否存在於同一個 namespace?是否正確?
  • 若用 Workload Identity:KSA(Kubernetes Service Account)是否映射到 GCP Service Account?角色是否授予(例如讀取 Artifact Registry)?

你可以透過事件中的 unauthorizeddenied 字樣判斷方向。遇到此類錯誤,優先處理憑證與權限,而不是去動應用程式。

3. 網路導致「看似權限問題」的鏡像拉取失敗

有些環境使用 Private Cluster、限制 egress、或有 VPC Service Controls,導致節點其實無法連到鏡像服務。這時候你可能看到類似超時、解析失敗或不可達。

排查可從:

  • 節點子網與路由是否允許出站
  • DNS 解析是否正常
  • 是否需要 Cloud NAT
  • 是否有 firewall 規則阻擋

先把基礎網路跑通,後續才談權限與配置。

第四章:資源與排程(Pending 最容易被低估)

Pending 常常不只是「資源不夠」。你需要看排程被卡在哪一步。

1. FailedScheduling:nodeSelector / affinity / tolerations

如果 Deployment 使用 nodeSelector 或 affinity,請檢查它與集群節點標籤是否一致。同時如果節點上有 taint,你的 Pod 必須有 toleration 才能調度到該節點。

事件中的 0/... 以及理由能直接告訴你哪個條件不滿足。例如:

  • didn't match Pod's node affinity/selector
  • had taint ... that the pod didn't tolerate

2. Insufficient cpu/memory:資源請求是否過高

請求(requests)過大是常見原因。尤其是你把 requests 設得接近 limits,結果一旦節點縮容或自動擴縮節奏不同,就容易卡住。

處理方式一般是:

  • 調整 requests/limits,讓 requests 反映「實際需要」而不是估算
  • 確認 HPA/Cluster Autoscaler 目標設定
  • 檢查節點池大小、autoscaling 上限與最小值

3. Storage 供應失敗:PVC/PV 相關事件

若使用 PVC,Pending 有時是因為 StorageClass 供應器或參數錯誤。事件可能提示:

  • provisioning failed
  • no storage class
  • permission denied

這類問題不要只看 Pod,去看 PVC、StorageClass,以及相關的 provisioner 日誌或事件。

第五章:掛載卷、環境變數與 Secret/ConfigMap

很多 CrashLoopBackoff 或啟動失敗,都源自「配置沒有如你想像」。部署成功到容器啟動,配置錯了照樣會炸。

1. ConfigMap/Secret key 不存在:找不到檔案或環境變數

如果你用 envFromenv 取某個 key,key 名稱若不匹配,就會讓應用拿到空值或啟動失敗。這在事件層面未必明顯,通常要看容器日誌。

如果你用 volumeMount 指向檔名,則掛載的檔案也可能不在預期路徑。

2. 檔案權限問題:容器無法讀取掛載目錄

某些應用需要讀取特定路徑,但掛載卷預設權限可能不符合。你會在日誌看到例如 permission denied、read-only file system 等。

處理常見做法包括:

  • 調整 Secret/ConfigMap 掛載方式(items、mode)
  • 如果使用 CSI,檢查 mount options
  • 在應用啟動命令前處理權限(例如 initContainer 改權限)

3. 依賴啟動順序:initContainer 沒做完

如果 initContainer 負責拉取模型、初始化資料庫、或等待外部服務,失敗會直接阻止主容器啟動。你需要看 initContainer 的事件與日誌,因為這通常是最早的錯誤點。

第六章:探針設定錯誤(看似應用問題,其實是調度邏輯)

探針(liveness/readiness/startup)是一個常見「部署後才爆炸」的來源。容器其實能跑,但被探針判定為不健康而一直重啟。

1. Readiness 探針失敗:服務永遠不進流量

Readiness 失敗不一定讓 Pod 重啟,但會導致 Service 對外不可用。你會看到:

  • Pod 狀態可能是 Running
  • 但 endpoints 可能不包含該 Pod

檢查方向:

  • 探針的 port 是否正確
  • 路徑是否正確(例如 healthz vs /health)
  • 應用是否需要特定 header 或基礎路徑
  • time out、period、failureThreshold 是否太短

2. Liveness 探針失敗:一直 CrashLoopBackOff

如果 liveness 間隔太短或容器啟動需時間較長,你會看到反覆重啟。常見做法:

  • 加入 startupProbe,先讓應用有緩衝時間
  • 調整 liveness initialDelaySeconds、periodSeconds
  • 若探針依賴外部服務,外部服務緩慢時要考慮容錯

3. 探針對應的端點在容器內能不能被連到

不要只相信你寫的 URL。容器內端點可能綁到不同介面或不同 port。這在日誌裡可能沒有明顯錯誤,只能通過探針結果與應用實際監聽行為確認。

若你能臨時進入容器(debug),用容器內的方式測試 health endpoint 會最快。

第七章:Service、Ingress 與負載平衡健康檢查

GCP帳號充值代辦 當 Pod 本身看起來是 Running,但外部流量不通,問題通常在服務層。

1. Service 不通:selector 與 labels 不匹配

Service 的 selector 必須與 Pod labels 匹配,否則流量永遠找不到後端。這類問題很常見,尤其是你複製了 YAML,改了 labels 卻忘了改 selector。

排查方向:

  • 確認 Deployment/Pod template metadata.labels
  • GCP帳號充值代辦 確認 Service selector
  • 確認 targetPort 與容器 port 名稱或數字一致

2. Ingress 不通:規則主機名/路徑不匹配或證書問題

Ingress 常見問題包括:

  • host 規則與實際請求主機名不同
  • pathType 與路徑匹配行為不如預期
  • TLS 證書未正確配置或域名不一致

負載平衡器層面通常也會有健康檢查狀態。若後端健康檢查失敗,Ingress 對外也會直接出現 502/503。

3. NetworkPolicy:讓你「看似部署成功」卻永遠互通不了

如果你的環境啟用了 NetworkPolicy,預設可能是拒絕所有入站或出站。這會導致服務之間互相無法訪問。你需要確認:

  • 是否有 Ingress policy 限制來源
  • 是否有 Egress policy 限制外部呼叫
  • 是否需要允許探針流量(有些情況會被誤封)

第八章:權限、IAM 與 GCP 服務整合問題

當應用需要存取其他 GCP 服務(例如存取 Cloud Storage、Secret Manager、BigQuery、Pub/Sub),部署可能表面成功,但應用一啟動就報權限錯誤,最後變成 CrashLoopBackoff。

1. Workload Identity 映射錯誤:請先對齊 Service Account

在 Workload Identity 下,容器內使用的身份來自 KSA 映射到 GCP Service Account。若映射錯了或缺角色,應用就會看到 permission denied。

你要做的是把以下幾個點對齊:

  • KSA 名稱與 namespace
  • 映射到哪個 GCP Service Account
  • GCP Service Account 是否授予正確角色(最低權限)

2. 範圍與環境不一致:同一套 code 在不同環境就失敗

常見情況是 dev/prod 用不同的 project、不同的 Artifact Registry/Storage bucket,結果權限在某個環境缺失。排查時要特別注意環境變數(PROJECT_ID、BUCKET_NAME、TOPIC 等)是不是也一起更新。

3. 使用 Secret Manager 時:secret 名稱或版本錯

若應用從 Secret Manager 拉取密鑰,但 secret id 不存在、版本不對、或沒有讀取權限,就會直接啟動失敗。這類錯誤通常出現在容器日誌的最前幾行。

第九章:一套可重複的排查流程(建議你照著走)

GCP帳號充值代辦 下面是一套「從部署失敗到找到根因」的固定流程。你下次遇到類似問題,只要把輸入替換成你的資源名稱即可。

步驟 1:確定你卡在哪個階段

  • kubectl 看 Pod 狀態:Pending / ImagePullBackOff / CrashLoopBackOff / Running 但不通

GCP帳號充值代辦 步驟 2:看同一個 Pod 的 Events,找最早明確錯誤

  • kubectl describe pod
  • 抓到第一個 Failed 原因當主線

步驟 3:若容器有啟動,先看日誌

  • kubectl logs(必要時加 --previous)
  • 關注的是應用啟動第一段失敗的訊息,不要只看最後一行

步驟 4:按錯誤類型對應處理

  • ImagePull 類:鏡像 reference、憑證、網路出站
  • Pending 類:排程條件、資源、PVC 供應
  • CrashLoop 類:啟動命令、配置、探針、權限、依賴服務
  • 不通類:Service selector/ports、Ingress 規則、健康檢查、NetworkPolicy

GCP帳號充值代辦 步驟 5:每修一次,都用「具體證據」驗證

  • 修完 ImagePull:確認 Pod 不再報 unauthorized/manifest unknown
  • 修完探針:確認 readiness 變成 True,endpoint 開始出現
  • 修完權限:確認應用日誌不再 permission denied

不要靠「我覺得應該好了」來收工。GKE 的驗證最好落在 Pod 狀態與事件、以及對外服務的回應上。

第十章:常見「坑」總結(你可以用來自我檢查)

以下是我在實務中最常見、也最容易浪費時間的坑。你可以把它當成自查清單。

坑 1:tag 寫對了,但 registry 還是錯專案/區域

Artifact Registry 的位置(region)與 project 都會影響可用性。Tag 正確只是必要條件,不是充分條件。

坑 2:Service selector 不是筆誤,而是 labels 結構不同

例如 Pod labels 是 app.kubernetes.io/name,但 Service selector 寫成 app。看起來差不多,但永遠不匹配。

GCP帳號充值代辦 坑 3:資源 requests 設太大,導致 autoscaling 沒跟上

Cluster Autoscaler 不是萬能。requests 過大會讓擴容策略來不及或擴不到合適的節點大小。

GCP帳號充值代辦 坑 4:探針路徑對了,卻忘了容器內 base path 或路由規則

很多框架有固定的路由前綴,例如 /api/health。你只要漏掉一段就會一直 readiness 失敗。

GCP帳號充值代辦 坑 5:Workload Identity 看似設定了,但缺少 Artifact Registry 讀取角色

有些人先解決了容器能啟動(因為部分動作不用權限),但後面拉模型或拉資料時才爆權限錯誤。這就會變成後續服務失敗。

結語:把排查變成「可學習的流程」

GKE 的部署失敗排查,真正難的不是技術點太多,而是資訊散落在狀態、事件、日誌、資源定義和雲端權限裡。你要做的,是讓每次排查都有固定路徑:先定性,再看第一個錯誤,再用日誌驗證,再對應類型處理。

當你把這套流程內化,你會發現自己不再依賴運氣,而是能用證據一步一步把根因挖出來。下一次容器部署失敗時,不用再盲目改 YAML,你只要回到「先看 Pod 狀態與事件」這個起點,就能更快到達正確答案。

如果你願意把你遇到的具體錯誤訊息(例如事件中的 Failed 原因、ImagePullBackOff 的細節、或 CrashLoopBackOff 的日誌片段)貼出來,我也可以幫你把排查路徑縮到最短。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系