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

Azure國際帳號服務 AKS容器部署失敗解決方法

微軟雲Azure / 2026-07-01 16:48:40

前言:失敗不止一次,原因也不止一種

把容器部署到 AKS,本質上是把「一個應用」在正確的時機、正確的身份、正確的網路與正確的資源上啟動。部署失敗看似只有一條錯誤訊息,但背後常常是多個環節同時出了問題:映像沒有被拉取、權限不對、DNS 解析失敗、Pod 沒地方被排程、探針把容器一直重啟……你越快跳過猜測,越快回到資料本身,就越容易在短時間內修好。

下面我用一套「由外到內」的排查流程來講:先看事件與狀態鎖定失敗階段,再逐段驗證映像、身份、權限、網路與 Pod 啟動行為。每個步驟都會附上你可以直接用來判斷的依據與常見修復方向。

第一章:先判斷失敗屬於哪一層

你需要把問題分到正確的桶裡。AKS 的部署失敗通常出現在以下階段:

  • YAML/資源建立階段:ConfigMap/Secret 不存在、欄位格式錯誤、命名空間或資源引用錯。
  • 排程階段:Pod Pending,原因多半是節點資源不足、節點選擇器/容忍策略不匹配、PVC 尚未綁定。
  • 映像拉取階段:Pod 事件顯示 ImagePullBackOff、ErrImagePull。
  • 啟動階段:容器啟動後馬上崩潰,事件顯示 CrashLoopBackOff。
  • 可用性階段:容器在跑,但 Readiness/Liveness 探針失敗,服務一直不可用。

Azure國際帳號服務 你不必一次看完所有指標,但要至少抓住「失敗類型」。下面用最常用的命令與現象來教你怎麼定位。

第一步:看 Pod 與事件(事件是最可靠的敘事者)

部署完成後,第一件事不是翻 log,而是先看狀態和事件。

典型流程:

  • kubectl get pods -n <ns>
  • kubectl describe pod <pod-name> -n <ns>(重點找 Events)
  • kubectl logs <pod-name> -n <ns> --all-containers(只在排到「啟動階段」時才重要)

Azure國際帳號服務kubectl describe 的 Events 裡,你往往會直接看到例如:

  • Failed to pull image401 Unauthorized403 Forbidden
  • Back-off pulling image
  • FailedScheduling0/xx nodes are available
  • Readiness probe failedLiveness probe failed
  • CrashLoopBackOff 前面通常也會有 exit code 訊息或 mount 失敗

你要做的是:把錯誤字串對應到上面那五層之一,接著只針對那層深入。

第二步:確認資源引用是否一致(命名空間與 Secret 最常坑)

很多「部署失敗」其實只是宣告寫得看似合理,運行時卻引用錯地方。最常見的坑有三類:

  • 命名空間不一致:Deployment 在 ns-a,Secret 卻在 ns-b。
  • Azure國際帳號服務 Secret 名稱/欄位錯:Secret 內 key 名稱不是你在容器環境變數裡引用的那個。
  • ImagePullSecrets 設定在錯的層級:你設定在某個 ServiceAccount 或 Deployment template 位置,但實際 Pod 沒拿到。

建議做法:檢查 Deployment(或 StatefulSet)的 spec.template.spec 內實際使用的是哪個 serviceAccountName,以及 imagePullSecrets 是否存在。

第二章:映像拉取失敗(ImagePullBackOff / ErrImagePull)

這類錯誤最常見也最好解。你看到 ImagePullBackOff,本質上就是節點上的 kubelet 拉不到映像。

常見原因分成四大類:映像名稱錯、Registry 權限不對、網路/憑證問題、或是宣告了錯誤的 imagePullSecrets。

原因一:鏡像標籤錯或命名規則錯

有些團隊會把版本策略混用:有的推的是 :1.2.3,有的用 :latest,還有的用 git SHA。Deployment 寫死某個 tag,結果那個 tag 根本不存在,就會直接拉取失敗。

排查:

  • 在 ACR(或你使用的 Registry)確認該 tag 是否存在。
  • 確認完整映像路徑:<registry>/<repository>:<tag>
  • 檢查大小寫(某些 repository 在平台上大小寫不同會導致找不到)。

修復:更新 Deployment 的 image tag,或把 CI/CD 推送規則調整到與部署一致。

原因二:ACR 權限或身份(Managed Identity / Service Principal)不對

如果你用 ACR,最常見的方式是:

  • imagePullSecrets 提供憑證(docker config json)
  • Azure國際帳號服務 或用 AKS 的 Managed Identity + RBAC 讓節點/Pod 有權拉映像

你要先確認自己用哪種。

如果你用 imagePullSecrets

  • Secret 是否真的存在於該命名空間
  • Secret 的 .dockerconfigjson 是否包含正確 registry 權限
  • Deployment template 內是否指定了 imagePullSecrets

修復通常是重新建立 Secret,或修正 Deployment 對 Secret 的引用。

如果你用 Managed Identity / ACR pull 權限

  • 確認 ACR 中給予正確的身份角色(例如 AcrPull)
  • 確認 AKS cluster 的 identity 設定是否生效(有些情境需要重新部署或確保設定連動)
  • 確認你不是只把權限給了節點 identity,卻在 Pod 端使用了不同的身份路徑

修復方向:補齊 ACR 權限角色,或用對應方式授權正確的 identity。

原因三:Registry 被限制在私網 / 網路連線不足

當 ACR 開啟了私有 endpoint、或你部署在限制 egress 的網路環境,節點到 Registry 的連線就可能失敗。

典型現象:

  • Events 內可能出現 time out、connection refused、或解析失敗
  • 同樣的 cluster 在不同網段可能表現不同

修復方向通常包括:

  • 檢查 DNS 解析是否能把 registry hostname 解析到正確的私網 IP
  • 檢查 Network Security Group(NSG)與防火牆規則是否允許到 Registry 的連線
  • 若用私有 endpoint,確認是否有對應的 VNet integration 與 routing 設定

你可以先用簡單測試驗證解析與連線(例如在同一 VNet 環境的測試 Pod 或節點環境做 nslookup/curl 類行為),再回到 Kubernetes 層修。

原因四:TLS / CA 憑證問題

如果你使用自簽憑證 registry 或內部 TLS 終止方式不同,節點可能因憑證信任鏈缺失導致無法完成 HTTPS 連線。

Events 可能出現 x509 相關錯誤。修復通常是把對應的 CA 憑證配置到節點信任或在容器映像中安裝憑證,具體做法視你的網路與安全策略而定。

第三章:Pod 無法排程(Pending / FailedScheduling)

如果 Pod 卡在 Pending,先不要急著去看 log,因為容器根本可能還沒啟動。你需要看的第一個地方是 kubectl describe pod 的 FailedScheduling。

原因一:節點資源不足(CPU/Memory requests 過高)

最常見的狀況是 requests 設得過高,導致叢集沒有任何節點能滿足。

排查:

  • kubectl describe pod ... 中是否顯示 insufficient cpu/memory
  • kubectl top nodes 觀察節點是否長期接近滿載

修復方向:

  • Azure國際帳號服務 調整 Deployment 的 resources.requestslimits
  • 檢查 HPA/VPA 是否影響到 requests(有些自動化會在運行期改變策略)
  • 啟用或調整 cluster autoscaler:讓叢集在需求上來時擴容

原因二:nodeSelector / affinity / tolerations 不匹配

你可能在 YAML 中加入 nodeSelector、或使用 affinity 把 Pod 綁到特定節點池;同時你可能還設了容忍(tolerations),結果導致只有很少甚至沒有節點符合條件。

排查:

  • 看 FailedScheduling 的訊息裡是否包含 nodeSelector/taint-related 字樣
  • 確認節點池的 labels 是否匹配
  • 確認 taint key/value 與 toleration 設定一致

修復:調整 node pool labels 或放寬 affinity/toleration,至少在測試環境先讓排程恢復。

原因三:PVC 尚未綁定(尤其是 StatefulSet)

如果你用 PersistentVolumeClaim,Pod 可能因為 PVC 未綁定或等待 provision 而 Pending。

排查:

  • kubectl get pvc -n <ns>
  • kubectl describe pvc <pvc> -n <ns> 看 events

修復方向取決於存儲類型與 CSI 設定:storageclass 是否存在、是否能動態 provision、以及是否有配額限制。

第四章:容器啟動失敗(CrashLoopBackOff)

當你看到 CrashLoopBackOff,代表容器已被嘗試啟動,但很快退出。這通常比 Pending 更好處理,但也更需要你看 log。

第一步:看前一次崩潰 log(--previous)

容器重啟時,當前 log 可能只顯示啟動片段。用:

  • kubectl logs <pod> -n <ns> -c <container> --previous

Azure國際帳號服務 找出程式退出原因,例如:

  • 找不到環境變數或設定檔
  • DB 連線失敗(DNS/憑證/網路策略)
  • 權限問題(無法寫入目錄、檔案系統權限)
  • 缺少依賴(例如動態載入的證書或字型)

原因一:ConfigMap/Secret 沒掛載成功或 key 名稱錯

這類錯常常被忽略,因為容器啟動到一半才讀設定,然後因為設定缺失而退出。

排查方式:

  • kubectl describe pod 看是否有 Volume mount 失敗
  • 進一步確認檔案/環境變數是否存在:如果你能臨時加一個 sleep 進入容器或用 debug image,就能快速確認

修復:對齊 key 名稱與路徑,並確認 Secret 在正確命名空間。

原因二:容器無法連線到外部服務(DNS/網路/憑證)

你會看到應用 log 顯示連線 timeout、憑證錯誤、或連線被拒絕。

常見根因:

  • 外部 endpoint 解析錯誤(DNS 指向錯誤 IP)
  • NSG/防火牆阻擋出站流量
  • 應用使用的 CA 憑證不存在(TLS 握手失敗)

修復方向:

  • 在同一命名空間用簡易測試 Pod 驗證 DNS 與連線
  • 調整出站規則或 Private Endpoint 連線策略
  • 補齊憑證或調整應用信任設定

原因三:應用啟動慢,但探針太快(導致重啟)

有時不是程式真的掛了,而是探針過於激進,導致 Liveness 把容器殺掉。

你需要檢查 Deployment 的:

  • livenessProbereadinessProbe
  • initialDelaySecondstimeoutSecondsfailureThreshold

修復:把初始延遲與容忍次數調大,並確保 readiness 的條件對應「服務已準備好接流量」,而不是只要進程啟動就算。

原因四:檔案系統權限(非 root 使用者無法寫入)

越來越多鏡像以非 root 方式運行。若你的應用需要寫入 /tmp 或某個掛載資料夾,但安全設定沒放行,就會在啟動時退出。

Azure國際帳號服務 排查:

  • log 裡是否出現 permission denied
  • 檢查 securityContext:runAsUserfsGroup、以及 volume 的權限策略

修復:調整 securityContext,或在映像中準備好目錄權限,或對需要的掛載點設定適當 fsGroup。

第五章:探針失敗(Readiness/Liveness)與服務不可用

這類問題最折磨,因為 Pod 可能是 Running,但服務一直不通。你會看到:

  • Pod 為 Running,但 Ready=false
  • Events 顯示 readiness probe failed
  • Ingress 或 Service 的流量沒有真正打到容器

探針設計的兩個原則

第一,Readiness 是「能接流量」。你要確保 readinessProbe 代表的是依賴資源都已就緒,例如連到 DB 成功、必要緩存載入完成等。若 readiness 只做了簡單的端點回傳 200,但 DB 其實不可用,你會在上線後才發現服務假活。

第二,Liveness 是「判斷要不要重啟」。livenessProbe 不能過於敏感,否則瞬間的網路抖動就會讓 Pod 不斷重啟。

常見修復:調整探針路徑、端口與協定

很多探針失敗其實是設定錯誤:

  • probe 指到錯的 port
  • path 寫錯(例如從 /health 變成 /healthz
  • 協定不一致(HTTP 換成 HTTPS)
  • Azure國際帳號服務 容器還沒啟動就被探測

你可以直接從容器內部驗證探測端點:若你有 shell 訪問,確認回應內容與狀態碼。

超時與閾值:把「短暫慢」變成「可容忍」

若你的服務啟動需要載入模型、初始化連線或跑迁移,初始階段可能會超過 probe timeout。

修復策略:

  • 增大 initialDelaySeconds
  • 增大 timeoutSeconds
  • 增大 failureThreshold
  • 必要時把 readiness 和 liveness 分別設計(readiness 允許啟動期較寬鬆,liveness 更保守)

Azure國際帳號服務 第六章:ServiceAccount 與權限(RBAC / Workload Identity / Pull 權限)

當你看到的是權限相關錯誤,或應用 log 出現 403/Access denied,多數情況是 Kubernetes RBAC 或 Azure 資源層權限不對。

在 AKS 裡,影響權限的常見元素有:

  • Deployment template 中的 serviceAccountName
  • ServiceAccount 對應的 ClusterRole/RoleBinding
  • 若使用 Workload Identity:Federated credential 與 Azure RBAC 是否正確綁定
  • 若需要拉取 ACR:節點/Pod 的拉取權限是否有給到

排查順序:先看 Kubernetes 層,再看 Azure 層

你可以用以下順序思考:

  • Pod 是否能成功啟動到容器?若連映像都拉不到,先處理 registry 權限。
  • 容器啟動後操作的是 Kubernetes API 還是 Azure 服務?如果是 Kubernetes API,查 RBAC。
  • 如果是 Azure 服務(例如 Key Vault、Storage、Event Hub),查 Workload Identity 或 MI 的 RBAC。

修復方式對應也不同:RBAC 缺少就補角色綁定;Workload Identity 缺少就補綁定與對應 Azure RBAC。

Azure國際帳號服務 第七章:一份可直接照做的部署失敗修復清單

當你站在事故現場,最需要的是「不要漏步驟」。下面我把前面章節的精華整理成可操作清單。你每次遇到部署失敗,照順序跑一遍,通常很快就能收斂原因。

Azure國際帳號服務 清單 1:快速確認症狀

  • Pod 狀態是 Pending / ImagePullBackOff / CrashLoopBackOff / Running 但 Ready=false?
  • kubectl describe pod 讀 Events:記下第一個致命錯誤句。
  • 若是 CrashLoop:用 kubectl logs --previous 找退出原因。

清單 2:若是 ImagePullBackOff

  • 確認 image 完整路徑與 tag 是否存在。
  • 確認 imagePullSecrets 或 serviceAccount 對應的 pull 權限是否在正確命名空間。
  • 若用 ACR:檢查 ACR 授權(AcrPull)給到的是正確 identity。
  • 檢查網路:DNS、出站規則、私有 endpoint 連通性。
  • 如有 TLS 問題:補憑證或調整 trust store。

清單 3:若是 Pending / FailedScheduling

  • 檢查 FailedScheduling 的不足資源原因(cpu/memory)。
  • 檢查 nodeSelector/affinity/tolerations 是否導致無節點可用。
  • 若有 PVC:檢查 PVC events 與 storageclass。
  • 視情況調整 requests 或開啟/調整 autoscaler。

清單 4:若是 CrashLoopBackOff

  • kubectl logs --previous:找程式退出訊息與 exit code 對應原因。
  • 檢查 ConfigMap/Secret key、volume mount 是否正確。
  • 檢查外部連線:DB、API、Redis 是否能解析與連線。
  • 檢查檔案權限與 securityContext。
  • 檢查探針是否過敏(啟動慢被重啟)。

清單 5:若是 Ready=false 或探針失敗

  • 確認 probe port/path/協定正確。
  • 調整 initialDelaySeconds/timeoutSeconds/failureThreshold。
  • readiness 對應「可接流量」,liveness 對應「要不要重啟」。
  • 檢查服務依賴是否在 readiness 階段已就緒。

第八章:如何讓部署更穩定,少遇到同一類錯

修好不代表長期穩。真正省時間的是建立能提前暴露問題的機制。

把「健康檢查」當成產品的一部分

很多團隊只在上線後才補 health endpoint。建議做法是把 readiness/liveness 端點與依賴檢查明確定義:例如 readiness 只在 DB 連線成功且必要資料已載入後回應 200;liveness 只關注程式是否進入不可恢復狀態。

CI/CD 做鏡像存在性與基本運行測試

部署前做兩件事很划算:

  • 確保 ACR 中該 tag 已存在(避免人為輸入錯 tag)。
  • 用最小化的方式跑容器啟動測試(例如啟動後檢查 health endpoint 回應)。

這能把一大半的 ImagePull 與啟動錯誤提前擋掉。

用一致的資源命名與環境變數介面

ConfigMap/Secret 的 key 改了但部署沒改,很常見。建議用嚴格的介面契約:例如環境變數名稱固定、Secret key 名固定,並在 PR 規範中檢查變更。

Azure國際帳號服務 資源 requests/limits 用資料而不是感覺

requests 過高會導致排程失敗,limits 過低會造成 OOM 重啟。你可以從過去版本的觀測指標(CPU/memory)推估 requests,然後用少量 buffer 方式調整。

結語:把排查變成流程,你就不會被錯誤牽著走

AKS 容器部署失敗並不可怕,可怕的是把有限時間拿去猜測。正確做法是用狀態與事件把問題分層,再進入對應層級驗證:映像與權限、網路連通、排程條件、容器啟動行為、以及探針與依賴就緒。當你把每次事故都歸檔成「症狀—原因—修復」,下一次同類問題就會變成快速套用的經驗,而不是重來一次的痛。

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