Chuyển đến nội dung chính

第11課:工作負載故障排除

Pod 狀態除錯(CrashLoopBackOff、ImagePullBackOff、Pending)。 Deployment 故障排除。容器日誌與事件分析。

Pod 狀態與故障排除流程

1. Pod 狀態除錯

狀態原因診斷
Pending排程失敗(資源不足、Taint、Affinity)kubectl describe pod(Events)
ImagePullBackOff映像檔不存在或沒有存取權限確認映像檔名稱、Tag、Secret
CrashLoopBackOff容器啟動後崩潰(應用程式錯誤)kubectl logs pod
CreateContainerConfigErrorConfigMap/Secret 不存在kubectl describe pod
Init:ErrorInit Container 失敗kubectl logs pod -c init-container

2. 系統化除錯流程

# 步驟1:確認 Pod 狀態
kubectl get pods -o wide

# 步驟2:查看 Pod 詳情和事件
kubectl describe pod POD_NAME

# 步驟3:查看容器日誌
kubectl logs POD_NAME
kubectl logs POD_NAME -c CONTAINER   # 多容器 Pod
kubectl logs POD_NAME --previous     # 前一次執行的日誌

# 步驟4:進入容器除錯
kubectl exec -it POD_NAME -- sh
kubectl exec -it POD_NAME -c CONTAINER -- sh

# 步驟5:使用除錯容器
kubectl debug -it POD_NAME --image=busybox --target=CONTAINER

3. CrashLoopBackOff 除錯

# 常見原因:
# 1. 應用程式啟動錯誤
kubectl logs pod-name
kubectl logs pod-name --previous   # ← 重點!看前一次崩潰日誌

# 2. 指令或參數錯誤
kubectl get pod pod-name -o yaml | grep -A5 command

# 3. 健康檢查失敗
# livenessProbe 太嚴格 → Pod 被 kubelet 殺掉
kubectl describe pod pod-name | grep -A10 Liveness

# 4. 資源限制(OOMKilled)
kubectl describe pod pod-name | grep -A5 "Last State"
# Reason: OOMKilled → 增加 memory limits

4. ImagePullBackOff 除錯

# 常見原因:
# 1. 映像檔名稱/Tag 錯誤
# 2. 私有倉庫需要 imagePullSecret
# 3. 網路問題

# 確認映像檔
kubectl describe pod pod-name | grep "Image:"
kubectl describe pod pod-name | grep -A5 "Events:"

# 私有倉庫需要 Secret:
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=user \
  --docker-password=pass

# Pod 中使用:
spec:
  imagePullSecrets:
  - name: regcred

5. Deployment 故障排除

# Deployment 更新卡住
kubectl rollout status deployment/my-app
# 等待中...

# 檢查 ReplicaSet
kubectl get replicaset
kubectl describe replicaset RS_NAME

# 回滾到上一個版本
kubectl rollout undo deployment/my-app

# 檢查更新歷史
kubectl rollout history deployment/my-app

6. 速查表

問題關鍵指令
Pod 為何 Pendingkubectl describe pod → Events
容器為何崩潰kubectl logs pod --previous
OOMKilledkubectl describe pod → Last State
映像檔拉取失敗確認映像檔名稱 + imagePullSecret
Deployment 更新卡住kubectl rollout undo deploy/NAME

7. 練習題

Q1:Pod 狀態是 CrashLoopBackOff,kubectl logs pod-name 顯示為空。下一步應該做什麼?

  • A) 刪除 Pod
  • B) 使用 kubectl logs pod-name --previous 查看前一次執行的日誌 ✓
  • C) 增加 CPU 資源
  • D) 重新啟動節點

解析:--previous 顯示前一次容器實例的日誌。CrashLoopBackOff 表示容器不斷重啟,當前日誌可能為空是因為容器剛重啟。前一次的日誌通常包含錯誤訊息。

Q2:kubectl describe pod 的 Events 顯示 "0/3 nodes are available: 3 Insufficient cpu"。Pod 狀態是什麼?如何解決?

  • A) CrashLoopBackOff — 增加記憶體
  • B) Pending — 叢集沒有足夠的 CPU 資源,需新增節點或減少 Pod 的 CPU request ✓
  • C) ImagePullBackOff — 修正映像檔名稱
  • D) Error — 重新部署應用程式

解析:資源不足的排程錯誤會導致 Pod 維持 Pending。解決方式:增加節點以提供更多 CPU 資源,或降低 Pod 的 resources.requests.cpu。使用 kubectl top nodes 確認節點資源使用量。

Q3:Pod 的 Last State 顯示 "Reason: OOMKilled"。表示什麼?

  • A) CPU 使用超過限制
  • B) 記憶體使用超過 limits.memory,容器被 OOM Killer 終止 ✓
  • C) 磁碟空間不足
  • D) 網路連線逾時

解析:OOMKilled(Out of Memory Killed)表示容器的記憶體使用量超過 spec.containers[].resources.limits.memory。解決方式:增加 memory limits 或修復應用程式的記憶體洩漏。