iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0

當事情不如預期:你的第一堂除錯課

在前面的步驟中,如果一切順利,你應該能成功訪問前後端服務。但現實世界裡,很多時候我們會遇到各種意外狀況。這一節要教你的不是如何避免問題,而是當問題發生時,如何有系統地追蹤和解決它們

場景一:kubectl 說「無法連接到叢集」

症狀:當你執行任何 kubectl 指令時,得到類似 The connection to the server localhost:8080 was refused 的錯誤。

診斷思路:kubectl 不知道該連接到哪個叢集,或者連接資訊有誤。

解方:檢查你的叢集憑證

# 查看當前 kubectl 使用的叢集設定
kubectl config view

# 確認當前使用的 context
kubectl config current-context

# 查看所有可用的 context
kubectl config get-contexts

kubectl 的所有叢集連接資訊都儲存在 ~/.kube/config 這個檔案裡。當你用 Kind 建立叢集時,Kind 會自動在這個檔案中寫入一個名為 kind-kind 的 context(如果你的叢集名稱是預設的 kind)。這個 context 包含了三個關鍵資訊:叢集的 API Server 地址、認證憑證,以及使用者資訊。

如果你在管理多個叢集,可以用以下指令切換:

kubectl config use-context kind-kind

你可以直接查看這個設定檔的內容來理解它的結構:

cat ~/.kube/config

你會看到 clustersuserscontexts 三個主要區塊。這個設計讓你可以靈活地管理多個叢集的連接資訊,而不需要每次都手動指定憑證路徑。

場景二:服務部署了,但網頁打不開

症狀:執行 kubectl apply -k . 沒有報錯,但訪問 http://frontend.127.0.0.1.sslip.io 時得到 404 或連接超時。

診斷思路:服務可能沒有正常啟動,或者 Ingress 規則沒有正確生效。我們需要逐層檢查:Pod → Service → Ingress。

第一步:檢查 Pod 狀態

# 列出所有 Pod 及其狀態
kubectl get pods -o wide

# 如果發現某個 Pod 狀態不是 Running,檢查詳細資訊
kubectl describe pod 

describe 指令是你的除錯利器。它會顯示該資源的完整生命週期事件,包括最關鍵的 Events 區塊。常見的問題會在這裡顯露:

  • ImagePullBackOff:無法拉取 Docker 映像。在 Kind 環境中,這通常不是網路問題,而是你忘記將映像載入到 Kind 的內部 registry。Kind 叢集運行在 Docker 容器中,它無法直接訪問你本機 Docker 的映像庫。

    解決方法:

    # 將本機映像載入到 Kind 叢集
    kind load docker-image <your-image-name>:<tag>
    
    # 例如:
    kind load docker-image frontend:latest
    kind load docker-image backend:v1.0
    
  • CrashLoopBackOff:容器啟動後立刻崩潰,需要查看應用程式的日誌(見下一步)

  • Pending:Pod 無法被調度,可能是資源不足或節點選擇器有問題

第二步:查看應用程式日誌

如果 Pod 狀態是 Running 但服務仍然異常,問題可能出在應用程式本身。日誌是應用程式與你溝通的最直接方式。

# 查看 Pod 的即時日誌
kubectl logs 

# 如果 Pod 內有多個容器,需要指定容器名稱
kubectl logs  -c 

# 持續追蹤日誌(類似 tail -f)
kubectl logs -f 

# 查看前一次容器啟動的日誌(當容器反覆重啟時特別有用)
kubectl logs  --previous

實戰技巧:如果你的後端服務無法正常運作,先用 kubectl logs 查看是否有報錯訊息。很多時候,應用程式已經清楚地告訴你問題在哪裡,比如無法連接資料庫、環境變數缺失、端口已被佔用等等。

你也可以同時查看多個 Pod 的日誌:

# 查看某個 Deployment 下所有 Pod 的日誌
kubectl logs -l app=frontend -f

# 查看某個 Namespace 下所有 Pod 的日誌
kubectl logs --all-containers=true -n default

第三步:確認 Service 是否正常

# 列出所有 Service
kubectl get services

# 查看特定 Service 的詳細資訊
kubectl describe service 

describe 的輸出中,注意 Endpoints 這一欄。它應該顯示後端 Pod 的 IP 地址列表。如果這裡是空的,代表 Service 的選擇器(selector)沒有匹配到任何 Pod。這時你需要:

  1. 檢查 Service 的 selector 標籤是否與 Pod 的標籤一致
  2. 確認 Pod 確實處於 Running 狀態

第四步:檢查 Ingress 規則

# 列出所有 Ingress 規則
kubectl get ingress

# 查看 Ingress 的詳細配置
kubectl describe ingress 

Ingress 的 Rules 區塊定義了 Hostname 到 Service 的映射關係。確保你在瀏覽器輸入的網址與 Ingress 規則中的 host 欄位完全匹配(包括子域名)。另外,Backend 欄位顯示的 Service 名稱和 Port 必須與實際部署的 Service 一致。

場景三:繞過 Ingress,直接測試服務

症狀:你懷疑問題出在 Ingress 或網路配置上,想要直接驗證 Service 本身是否能正常工作。

診斷思路:使用 port-forward 建立一條從你本機到 Pod 或 Service 的直接隧道,繞過所有的 Ingress 和網路規則。

解方:使用 Port Forward

# 將本機的 8080 端口轉發到某個 Pod 的 80 端口
kubectl port-forward pod/ 8080:80

# 或者直接轉發到 Service(推薦,因為 Service 會自動負載均衡)
kubectl port-forward service/ 8080:80

# 例如:測試後端服務
kubectl port-forward service/backend 8080:80

執行這個指令後,終端會保持運行狀態,你可以打開瀏覽器訪問 http://localhost:8080 來直接測試服務。如果這時服務能正常回應,那麼問題確實出在 Ingress 或 DNS 配置上;如果還是無法訪問,問題就在應用程式本身或 Service 的配置。

進階用法

# 轉發到 Deployment(會自動選擇其中一個 Pod)
kubectl port-forward deployment/ 8080:80

# 指定 namespace
kubectl port-forward -n  service/ 8080:80

# 監聽所有網路介面(讓同網段的其他設備也能訪問)
kubectl port-forward --address 0.0.0.0 service/ 8080:80

這個工具在除錯時非常有用,因為它讓你能快速隔離問題:是應用層的問題,還是網路層的問題。

場景四:服務時好時壞,無法穩定訪問

症狀:有時候網頁能開,有時候不能,或者後端 API 偶爾會回傳錯誤。

診斷思路:可能是某些 Pod 有問題,但 K8s 的負載均衡機制讓你的請求在健康和不健康的 Pod 之間跳來跳去。

解方:找出有問題的 Pod

# 查看所有 Pod 的重啟次數
kubectl get pods

# 找出最近頻繁重啟的 Pod
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

RESTARTS 欄位顯示的數字如果持續增加,代表該 Pod 反覆崩潰。這時你需要:

  1. kubectl describe pod <pod-name> 查看為什麼它會重啟
  2. kubectl logs <pod-name> --previous 查看崩潰前的日誌

除錯心法:由外而內,逐層檢查

當你遇到問題時,建議按照以下順序進行診斷:

  1. 網路層:DNS 是否正確解析?Ingress Controller 是否正常運行?
  2. 路由層:Ingress 規則是否正確配置?Service 是否能找到對應的 Pod?
  3. 應用層:Pod 狀態是否健康?應用程式日誌是否有錯誤訊息?
  4. 資源層:是否有足夠的 CPU 和記憶體資源?

最重要的工具就這四個

  • kubectl get:快速查看資源狀態
  • kubectl describe:深入了解資源配置和事件歷史
  • kubectl logs:直接看應用程式告訴你什麼
  • kubectl port-forward:繞過網路層,直接測試服務

掌握了這些,你就有能力面對絕大多數在本地 K8s 環境中會遇到的問題。記住,除錯不是在背指令,而是在培養一種系統性思考的能力:當一個複雜系統出問題時,如何有條理地縮小問題範圍,直到找出根本原因。


上一篇
Day27-[Hand-on]建立第一個K8s cluster
下一篇
Day29-與AI共同除錯的心得
系列文
開發環境設定指南及工具分享29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言