使用 kubectl debug 排查 Kubernetes Pod 與 Node 問題

在 Kubernetes 中排查問題時,最常用的工具通常是 kubectl logskubectl describekubectl execkubectl port-forward。這些指令已經能處理大部分日常除錯情境,但如果容器映像檔本身很精簡,裡面沒有 curlpsnetstattcpdump 等工具,或是需要進一步查看 Node 層級的狀態,就會遇到一些限制。

kubectl debug 是 Kubernetes 提供的除錯指令,可以在不重新打包應用程式映像檔的情況下,建立臨時的除錯環境。它常見的用途包含:複製既有 Pod 來建立 debug Pod、在 Pod 中加入 ephemeral container,以及在指定 Node 上建立 debug pod。這篇文章會用 Tomcat 服務作為範例,示範如何使用 kubectl debug 進行常見的場景排查。


測試環境

這次範例使用 Minikube 建立 Kubernetes 叢集,並在叢集中部署一個 Tomcat 服務。可以先用以下指令確認目前資源狀態:

1
kubectl get all

從畫面可以看到目前有一個 tomcat-deployment 建立出來的 Pod,狀態是 Running,並且透過 tomcat-service 暴露 8080/TCP。接著在 Pod 內執行 curl http://localhost:8080,可以看到 Tomcat 回傳的 HTML 內容,代表應用程式本身在容器內已經正常啟動。

這個狀態很適合拿來示範 kubectl debug:服務目前可以正常運作,但當我們想進一步排查容器內部狀態、確認檔案結構或測試網路連線時,就可以透過 debug Pod 建立一個臨時除錯入口。

為什麼不只用 kubectl exec?

kubectl exec 可以直接進入正在執行的 container,例如:

1
kubectl exec -it pod/tomcat-deployment-78cb588f95-j8dw4 -- sh

如果 container 內本來就有需要的 shell 與除錯工具,這個方式很直覺。不過在實務環境中,應用程式映像檔常常會刻意保持精簡,甚至只包含執行程式所需的檔案。這時候直接 exec 進去,可能會遇到工具不足、無法安裝套件,或是不想影響原本工作負載的情況。

kubectl debug 的價值就在這裡:它讓我們可以建立一個臨時除錯環境,把排查動作和原本的應用程式容器分開。這樣既不需要修改原始映像檔,也能在問題發生時快速進入可操作的環境。

場景一:在既有 Pod 加入除錯容器

當問題發生在正在執行的 Pod 上,而且需要使用更多網路或系統工具時,可以透過 kubectl debug 在既有 Pod 中加入一個臨時的 ephemeral container。這個方式不需要修改原本應用程式映像檔,也不需要重新部署 Deployment,很適合用來快速補上除錯工具。

以下範例使用 nicolaka/netshoot 作為除錯映像檔,並透過 --target=tomcat 指定要觀察的目標 container。Netshoot 的官方專案可以參考:nicolaka/netshoot

1
kubectl debug -it pod/tomcat-deployment-78cb588f95-j8dw4 --image=nicolaka/netshoot --target=tomcat

這個指令可以拆成幾個部分來看:

片段 說明
-it 以互動模式進入 debug container
pod/tomcat-deployment-78cb588f95-j8dw4 指定要除錯的 Pod
--image=nicolaka/netshoot 使用內建多種網路工具的 Netshoot 映像檔
--target=tomcat 指定要對應的目標 container

畫面中可以看到 kubectl debug 會提示正在 targeting container tomcat,接著建立預設名稱類似 debugger-zrng4 的除錯容器。進入後會看到 Netshoot 的歡迎畫面,代表我們已經在同一個 Pod 脈絡中取得一個額外的工具箱。

nicolaka/netshoot 常用於網路排查,映像檔中包含許多實用工具,例如 curldignslookupipsstcpdump 等。當原本的 Tomcat container 沒有這些工具時,就可以透過這種方式快速確認 DNS、Service 連線、Pod 網路與目標 Port 狀態。

需要注意的是,畫面中也出現了 If you don't see processes from this container it may be because the container runtime doesn't support this feature. 的提示。這表示是否能從 debug container 看到目標 container 的程序,會受到 container runtime 與叢集設定影響。不過即使無法完整看到程序資訊,對於網路連線、DNS 與基本環境排查來說,ephemeral container 仍然非常實用。

場景二:複製 Pod 建立 debug Pod

如果希望保留原本 Pod 的設定,但不要直接操作正在服務流量的 Pod,可以使用 --copy-to 建立一個新的 debug Pod。以下指令會複製既有 Tomcat Pod,並建立名為 my-debug-pod 的除錯用 Pod:

1
kubectl debug pod/tomcat-deployment-78cb588f95-j8dw4 -it --copy-to=my-debug-pod --container=tomcat -- sh

這個指令可以拆成幾個部分來看:

片段 說明
pod/tomcat-deployment-78cb588f95-j8dw4 指定要除錯的來源 Pod
-it 以互動模式進入除錯環境
--copy-to=my-debug-pod 複製來源 Pod,建立新的 debug Pod
--container=tomcat 指定要除錯的 container 名稱
-- sh 進入 container 後執行 sh

執行後,kubectl debug 會建立新的 Pod,並把終端機連進 container。畫面中進入 shell 後執行 ls,可以看到 Tomcat 映像檔中的檔案與目錄,例如 binconfliblogswebapps 等。這代表我們已經進入一個和原本 Tomcat 容器相同脈絡的除錯環境。

這種方式適合用在以下情境:

情境 說明
不想直接操作正式 Pod 透過複製 Pod 建立臨時除錯環境,降低誤操作風險
需要查看容器檔案結構 確認設定檔、部署內容或工作目錄是否符合預期
想重現容器內行為 在相近環境中執行 shell 指令,觀察應用程式所在環境
排查啟動後狀態 查看容器內檔案、環境變數或應用程式產生的暫存內容

需要注意的是,透過 --copy-to 建立出來的是新的 Pod,不是原本那個正在提供服務的 Pod。因此它很適合用來做探索與驗證,但如果問題只存在於原本 Pod 的即時狀態,例如某個處理中的連線、記憶體內容或暫存程序,就不一定能完整重現。

場景三:在 Node 上建立 debug pod

有些問題不是單一 Pod 造成的,而是和 Node 本身有關,例如節點狀態異常、容器執行環境、網路設定或主機檔案系統。這時可以使用 kubectl debug node 在指定 Node 上建立 debug pod。

先確認目前叢集中的 Node:

1
kubectl get nodes

接著對 minikube 這個 Node 建立除錯環境:

1
kubectl debug node/minikube -it --image=ubuntu

從畫面可以看到,kubectl debug 建立了 node-debugger-minikube-228wd 這個 debugging pod,並使用 ubuntu 映像檔作為除錯容器。進入 shell 後執行 ls,可以看到 Linux 系統常見的目錄,例如 binbootdevetcprocsysusrvar 等。

kubectl debug node 適合用在需要從 Node 角度觀察問題的情境,例如:

情境 說明
檢查 Node 基本狀態 查看檔案系統、程序資訊或系統目錄
排查網路問題 在 Node 上安裝或使用網路工具確認連線狀態
檢查容器執行環境 觀察 Node 上和容器運行相關的資訊
排查節點層級問題 當多個 Pod 在同一個 Node 上出現異常時,可從 Node 角度切入

這種方式很方便,但權限也相對敏感。因為它是在 Node 上建立除錯用的 Pod,操作時要避免修改主機上的重要檔案,也建議只在受控的測試環境或明確授權的叢集中使用。

debug session 的紀錄提醒

執行 kubectl debug 時,畫面會出現以下提示:

1
All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt.

這表示在 debug session 中輸入的指令與輸出內容都可能被記錄到 container logs。除錯時應避免直接輸入密碼、Token、金鑰或其他敏感資訊;如果一定要檢查和敏感資料相關的設定,也應盡量只確認檔案是否存在、環境變數名稱是否正確,而不是把完整內容印出來。

清理 debug Pod

完成除錯後,記得清理臨時建立的 debug Pod,避免叢集中留下不必要的資源。可以先查看 Pod 清單:

1
kubectl get pods

如果前面建立了 my-debug-pod,可以使用下列指令刪除:

1
kubectl delete pod my-debug-pod

kubectl debug node 建立的 debug pod 名稱會出現在指令輸出中,例如畫面中的 node-debugger-minikube-228wd。完成操作後,也可以用 kubectl delete pod 清掉:

1
kubectl delete pod node-debugger-minikube-228wd

如果有指定 namespace,記得加上 -n <namespace>,避免刪除時找不到資源。

小結

kubectl debug 很適合用在一般 logsdescribeexec 不足以排查問題的情境。當我們不想直接改動正在服務的 Pod,可以使用 --copy-to 複製出一個 debug Pod;當問題看起來和 Node 有關,則可以使用 kubectl debug node 從節點角度進行觀察。

實務上可以把排查順序整理成以下流程:

階段 建議指令 目的
查看狀態 kubectl get podskubectl get all 確認資源是否存在、狀態是否正常
查看事件 kubectl describe pod <pod-name> 檢查排程、拉取映像檔、probe 或事件異常
查看日誌 kubectl logs <pod-name> 確認應用程式是否拋出錯誤
進入容器 kubectl exec -it <pod-name> -- sh 在容器內執行基本檢查
加入除錯容器 kubectl debug -it pod/<pod-name> --image=nicolaka/netshoot --target=<container-name> 在既有 Pod 補上臨時工具容器
建立 debug Pod kubectl debug pod/<pod-name> -it --copy-to=<debug-pod> 複製 Pod 進行隔離式除錯
除錯 Node kubectl debug node/<node-name> -it --image=ubuntu 從節點層級排查問題

只要記得除錯完成後清理臨時資源,並避免在 debug session 中輸入敏感資訊,kubectl debug 就會是 Kubernetes 問題排查中非常實用的一個工具。