使用 kubectl exec 執(zhí)行指令
如果您在 Kubernetes 上運行軟件,您會想要在某些時候去調(diào)試您所部署的軟件的一些方面。對于習(xí)慣于使用虛擬機(jī) (VMs) 的人來說能自然使用的一種簡單的調(diào)試方法,就是連接到一個正在運行的 pod,然后進(jìn)行解譯:
kubectl exec -it podname -c containername -- bash
這通常行之有效,而且非常管用。然而,至少有兩種 Kubernetes "最佳實踐 "限制了 exec 的實用性:
不以 root 用戶身份運行。容器盡可能以最少的特權(quán)運行,甚至可能使用隨機(jī)的用戶標(biāo)識符 (UID) 運行。
最小化鏡像。鏡像盡可能小,你甚至可以將二進(jìn)制文件寫入到 distroless image。
當(dāng)應(yīng)用這些最佳實踐時,使用kubectl exec連接到您的容器要么不可行,要么進(jìn)入到不適合進(jìn)行調(diào)試的環(huán)境。
kubectl exec 指令不允許指定用戶標(biāo)志或能力以啟動進(jìn)程,而是會從目標(biāo)容器的主指令中復(fù)制這些設(shè)置。
調(diào)試容器
在解決運行容器問題時,Kubernetes 提供了一種原生化調(diào)試策略,即使用kubectl debug。調(diào)試指令會在運行中的 pod 中啟動一個新的容器。這個新容器能夠以不同的用戶身份以及從您選擇的任何鏡像去運行。由于調(diào)試容器與目標(biāo)容器位于同一個 pod 中運行(因此在同一個節(jié)點上),兩者之間不需要絕對的隔離。調(diào)試容器可以與同一 pod 中運行的其他容器共享系統(tǒng)資源。
考慮去檢查在 podpostpod中的容器postcont里運行的 PostgreSQL 數(shù)據(jù)庫的 CPU 使用情況。這個 pod 并不以 root 用戶身份運行,并且 Postgres 鏡像沒有安裝類似 top 或 htop 的工具,也就是說,kubectl exec指令幾乎沒有作用。您可以按照以下的指令去運行:
kubectl debug -it --container=debug-container --image=alpine --target=postcont postpod
您將以 root 身份登錄(這是 Alpine 鏡像的默認(rèn)設(shè)置),并可以輕松安裝您最喜歡的交互式進(jìn)程查看器 htop (apt add htop)。您與postcont容器共享同一個進(jìn)程命名空間,可以查看并甚至終止在此運行的所有進(jìn)程!當(dāng)您退出進(jìn)程時,臨時容器也會終止。
如果希望調(diào)試容器與postcont共享相同的進(jìn)程命名空間,即使postcont是在postpod中運行的唯一容器,指定--target是不具備選擇性的 (non-optional)。
您可以按 CTRL+P CTRL+D 斷開與臨時容器/bash 會話 (session) 的連接,而無需退出 (終止) 它。再使用kubectl attach即可重新連接。
kubectl debug提供的功能比這里概述的更多,比如使用一個修改后的啟動指令復(fù)制 pods,或通過訪問節(jié)點文件系統(tǒng)的啟動一個 "節(jié)點 (node) " pod。
原理解釋
以上的kubectl debug指令是通過創(chuàng)建臨時容器 (ephemeral container) 來實現(xiàn)。這些容器應(yīng)在現(xiàn)有 pod 中臨時運行,以支持故障排除等操作?!捌胀ā比萜骱团R時容器之間的區(qū)別很小。而查看 Kubernetes 在創(chuàng)立之初所做的基礎(chǔ)架構(gòu)選擇最能讓我們理解使用臨時容器的原因:
Pod 應(yīng)該是一次性的、可替換的,并且 Pod 規(guī)范也是不可改變的。
當(dāng) Kubernetes 主要用于部署無狀態(tài)工作負(fù)載時,這一點更加合理——因為此時 pod 本身會被認(rèn)為是臨時的。在這個 Kubernetes 中它可能會受到限制。Pod 規(guī)范保持不變,但 Kubernetes 會將臨時容器作為 Pod 的子資源建模。與“普通”容器不同,臨時容器不屬于 Pod 規(guī)范的一部分。
掛載卷 (volumes)
內(nèi)置指令kubectl debug非常有用。它允許您在運行的 pod 中添加一個臨時容器,并可選擇與運行中的容器共享進(jìn)程命名空間。不過,如果您希望使用kubectl debug來檢查或修改運行中容器文件系統(tǒng)的某個部分,那就不走運了——因為調(diào)試 pod 的文件系統(tǒng)與您將其連接到的容器的文件系統(tǒng)是分離的。幸運的是,我們可以做的更好。原理很簡單:
讀取正在運行的目標(biāo)容器的規(guī)范。
將一個臨時容器填充到 pod 中。將其配置成與目標(biāo)容器共享相同的進(jìn)程命名空間,并包含相同的卷掛載。
因為沒有用于創(chuàng)建臨時容器的 kubectl 命令,所以我們需要構(gòu)建一個 PATCH 請求到 K8s API 來創(chuàng)建它。kubectl proxy指令允許訪問 K8s API。這一過程對用戶來說并不太友好,因此將這一過程封裝到腳本或 kubectl 插件中是合理的。您可以在這里找到這樣一個腳本實現(xiàn)示例:
https://github.com/JonMerlevede/kubectl-superdebug?source=post_page-----2ba160c47ef5------
需要注意的是,這種方法和腳本可以很容易地擴(kuò)展到從目標(biāo)容器中復(fù)制環(huán)境變量的規(guī)范。如果您將此腳本保存為kubectl-superdebug,并將其放在您的路徑上,就可以在任何地方以kubectl superdebug的形式運行,如下所示:
還可以嘗試擴(kuò)展此腳本,將目標(biāo)容器的其他方面復(fù)制到調(diào)試容器中,例如環(huán)境變量引用。
至此,Kubernetes 本機(jī)調(diào)試運行中的容器的方法概述就完成了,應(yīng)該能滿足大多數(shù)人的需求。
非 Kubernetes 原生方法
Kubernetes 不提供以 root 身份連接到正在運行的容器的方法(除非主進(jìn)程以 root 身份運行),也不提供從另一個容器訪問容器根文件系統(tǒng)的方法。但這并不意味著這些事情不可能做到。畢竟, Kubernetes 只是一個位于容器化引擎之上的容器編排器。如果出于某種原因,確實有必要的話,您通??梢酝ㄟ^移除抽象層來做任何您想做的事。
如果您使用的是 Docker 引擎,并且可以直接從節(jié)點或通過節(jié)點上運行的特權(quán)容器訪問您的引擎,那么您就可以運行docker exec --user,并以您選擇的用戶身份執(zhí)行一個進(jìn)程。
kubectl ssh和kubectl exec-user等插件實現(xiàn)了這種方法。但遺憾的是,containerd 和 CRI-O 等現(xiàn)代引擎不再提供--user這樣標(biāo)志功能,這意味著這些插件無法在當(dāng)下的 Kubernetes 安裝上運行。
不過,即使是這些現(xiàn)代引擎,通常也只是與 Linux 命名空間接口。通過輸入相應(yīng)的 Linux 命名空間集,您可以在任何您想要的“容器”中運行指令。kpexec 工具實現(xiàn)了這種方法。它在與目標(biāo)容器相同的節(jié)點上啟動一個有權(quán)限的 pod,然后確定要針對哪些 (Linux) 命名空間,在這些 (Linux) 命名 空間中執(zhí)行命令,最后將其輸出流式傳輸?shù)侥慕K端。作為額外的收獲,它還能在目標(biāo)容器的文 件系統(tǒng)之上疊加一套用于調(diào)試的工具。
與 kubectl exec 不同,kpexec 可以使用不同的 uid/gid 運行指令,甚至可以使用與容器主進(jìn)程不同的功能。它與 containerd 和 cri-o 兼容。只是 kpexec 采用的方法有些笨重和脆弱,可能與集群的安全配置不兼容。但如果 kubectl (super) 調(diào)試無法滿足您的需求,則值得考慮它。
需要注意,kpexec 使用 nsenter 是直接在命名空間中執(zhí)行指令的。它與無處不在的容器運行時 runc 兼容,但與 Kata Containers 等運行時不兼容。
借助 Appilot 對話式診斷 K8s
Appilot 是一款面向 DevOps 場景的開源 AI 助手,它可以充分利用 AI 大語言模型的能力讓用戶直接輸入自然語言進(jìn)一步簡化應(yīng)用部署與管理體驗。用戶可以根據(jù)自身的需求和使用習(xí)慣,將 Appilot 集成到任意平臺,進(jìn)而實現(xiàn)通過輸入自然語言即可調(diào)用后端平臺的能力,輕松完成 Kubernetes debug 工作。
-
指令
+關(guān)注
關(guān)注
1文章
604瀏覽量
35591 -
AI
+關(guān)注
關(guān)注
87文章
29438瀏覽量
267760 -
容器
+關(guān)注
關(guān)注
0文章
491瀏覽量
22015 -
DEBUG
+關(guān)注
關(guān)注
3文章
89瀏覽量
19814
原文標(biāo)題:K8s容器debug高級技巧
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論