如何使用“Kubectl Debug”調查 Kubernetes 容器問題


Kubernetes 徽標

診斷運行 Kubernetes 工作負載的問題可能很棘手。 您可能很幸運,並通過 kubectl logs 命令。 但在某些情況下,無法避免實時調試會話,您可以通過交互方式與 Pod 互動以發現問題。

kubectl debug 命令 通過在 Pod 中提供一個新的臨時容器來簡化這些調試任務。 這可用於檢查 Pod 的環境,以便您可以開始對現有容器中出現的問題進行故障排除。

準備使用 Kubectl 調試

kubectl debug 與 Kubernetes 和 Kubectl 的 v1.18 一起發布。 它依賴於 臨時容器 在您的集群中可用。 臨時容器成為 Kubernetes v1.23 中的測試版功能,現在默認啟用。 您需要手動啟用 特徵門 如果您的集群運行較舊的 Kubernetes 版本。

臨時容器專為臨時任務而設計,您需要將額外容器臨時連接到現有 Pod。 這對於您希望準確檢查 Pod 而不影響實時容器實例的調試操作非常理想。

大多數容器鏡像缺乏調試工具; 將它們安裝在正在運行的容器中會改變其環境並可能導致副作用。 將臨時容器附加到 Pod 是一種更安全的調試方式,可為您提供乾淨的工作環境。 您可以使用包含您需要的所有工具的較重的圖像。

儘管臨時容器成為其宿主 Pod 的一部分,但仍有一些差異需要注意。 臨時容器不支持端口綁定、探測或資源預留,因為它們本質上只是臨時的。 它們永遠不會自動重新啟動,並且一旦創建就無法更改。 提供了受支持功能的完整列表 在文檔中.

使用 Kubectl 調試

在繼續之前,創建一個用於測試目的的基本部署:

$ kubectl create deployment nginx --image=nginx:latest
deployment.apps/nginx created

接下來使用 get pods 命令查找部署的 Pod 的名稱:

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-55649fd747-qsnr2   1/1     Running   0          5s

我們部署的 Pod 被稱為 nginx-55649fd747-qsnr2.

現在您可以使用 kubectl debug 在 Pod 中啟動調試會話的命令:

$ kubectl debug -it --image=ubuntu:20.04 nginx-55649fd747-qsnr2

該命令的語法類似於 kubectl createkubectl debug. 提供給命令的未命名參數標識要附加到的現有 Pod。 這 --image 參數指定用於新容器的圖像。 我們正在使用 ubuntu:20.04 在這裡獲取對 Ubuntu Linux 發行版中包含的熟悉命令的訪問權限。

-it 標誌相當於 --stdin --tty. 包含這些參數將為容器分配一個 TTY,附加到它,並連接終端的標準輸入流。 這為您在新容器中提供了一個交互式外殼。

現在,您可以在臨時容器中執行調試任務。

複製 Pod

另一種使用方式 kubectl debug 是一個 --copy-to 爭論。 這會創建目標 Pod 的副本並將臨時容器添加到副本中。 原始 Pod 完好無損。

$ kubectl debug -it --image=ubuntu:20.04 --copy-to nginx-debug nginx-555649fd747-qsnr2

此功能為您提供更大的保證,即在調試期間所做的更改不會直接影響您的生產應用程序。

複製 Pod 還可以讓您激活進程命名空間共享。 這使您的 Pod 中的現有進程對您的臨時容器可見。 它不能與現有容器一起使用,因為它們 spec.shareProcessNamespace 字段通常設置為 false. 跑步 kubectl debug--copy-to--share-processes flag 將在復制的 Pod 上啟用進程共享,使此過程更加直觀:

$ kubectl debug -it --image=ubuntu:20.04 --copy-to nginx-debug --share-processes nginx-555649fd747-qsnr2

您的臨時 Ubuntu 容器可見的進程列表現在將包含一個 NGINX 進程:

$ ps ax
PID   USER     TIME  COMMAND
    1 root      0:00 /pause
    9 root      0:00 nginx: master process nginx -g daemon off;

此過程仍在 Pod 中的單獨 NGINX 容器中運行。 命名空間共享還通過以下方式提供對目標容器文件系統的訪問 /proc

$ ls /proc/9/root/etc/nginx
conf.d fastcgi_params mime.types modules nginx.conf ...

因此,以這種方式複制 Pod 是一個強大的調試工具。 您可以使用使用熟悉工具準備的單獨容器輕鬆檢查 Pod 的文件和進程。

可選參數

--copy-to 默認情況下,標誌始終保持原始 Pod 不變。 您可以使操作充當替代品,而不是使用 --replace. 這將停止第一個 Pod。

$ kubectl debug -it --image=ubuntu:20.04 --copy-to nginx-debug --replace nginx-555649fd747-qsnr2

Kubernetes 會將復制的 Pod 調度到任何可用的節點。 如果您想確保一致的測試環境,這可能會出現問題。 添加 --same-node 會將副本安排到現有 Pod 的節點,從而消除集群中機器之間可能存在的任何差異。

$ kubectl debug -it --image=ubuntu:20.04 --copy-to nginx-debug --same-node nginx-555649fd747-qsnr2

另一個有用的選擇是 --env 在臨時容器中設置額外的環境變量。 您可能需要使用它來配置調試工具或覆蓋從目標 Pod 繼承的值。

$ kubectl debug -it --image=ubuntu:20.04 --copy-to nginx-debug --env EDITOR=/usr/bin/nano nginx-555649fd747-qsnr2

最後,請記住由 kubectl debug 不必是交互式的。 您可以使用以下命令輕鬆地對 Pod 運行一次性命令 kubectl exec– 類似的語法。 這 --attach 支持參數來控制當您不運行時您的 shell 是否連接到容器 -i (--stdin)。

$ kubectl debug --image=ubuntu:20.04 --copy-to nginx-debug --share-processes --attach true nginx-555649fd747-qsnr2 -- ls /proc/9/root/etc/nginx
conf.d fastcgi_params mime.types modules nginx.conf ...

結論

臨時容器和 kubectl debug 命令為 Kubernetes 工作負載提供簡化的調試體驗。 您可以使用與常規容器不同的映像在 Pod 內運行命令。 這使您可以訪問未包含在應用程序映像中的調試工具。

kubectl debug 還可以創建 Pod 的副本並與原始 Pod 共享它們的進程。 這種機制讓您可以從您完全控制的單獨臨時容器中檢查目標 Pod 容器中的進程。 當您需要詢問正在運行的進程時,它提供了更高級的調試選項。



發佈留言