這篇內(nèi)容主要探討了 Kube.NETes 的調(diào)試功能,介紹了 kubectl debug 和 kubectl superdebug。它們支持容器掛載并且能夠調(diào)試一些需要排查問題的 Pod。文章指出了在 Kubernetes 中使用 kubectl exec 命令的限制,并介紹了 kubectl debug 的作用,它能創(chuàng)建一個新的容器來調(diào)試運(yùn)行中的容器,并且能夠在同一個 Pod 內(nèi)共享系統(tǒng)資源。此外,還提到了 ephemeral contAIners,它們在調(diào)試過程中可以臨時運(yùn)行在現(xiàn)有的 Pod 中,支持一些排查操作。最后,文章還提及了一些非 Kubernetes 本地調(diào)試容器的方法,包括使用 Docker Engine 或者一些基于 linux namespaces 的工具。
使用 kubectl exec 執(zhí)行命令
如果你在 Kubernetes 上運(yùn)行軟件,你有時會想要調(diào)試所部署的應(yīng)用。對于習(xí)慣使用虛擬機(jī)的人來說,一種簡單的調(diào)試方法是連接到正在運(yùn)行的 Pod 并進(jìn)行分享:
kubectl exec -it podname -c containername -- bash
這通常有效并且非常有用。然而,至少有兩個 Kubernetes“最佳實(shí)踐”限制了 exec 在現(xiàn)實(shí)世界中的用處:
• 不以 root 身份運(yùn)行。容器以盡可能少的權(quán)限運(yùn)行,甚至可以使用隨機(jī) UID 運(yùn)行。
• 最小鏡像。鏡像盡可能小,極端情況下將二進(jìn)制文件安裝到distroless 鏡像中。[1]
當(dāng)應(yīng)用這些最佳實(shí)踐時,使用kubectl exec連接到容器要么是不可能的,要么會讓你陷入不適合調(diào)試的貧瘠荒地般的環(huán)境。
調(diào)試容器
調(diào)試正在運(yùn)行的容器的 Kubernetes 原生答案是使用kubectl debug。
debug 命令將一個新容器附加到正在運(yùn)行的 pod 中。這個新容器可以以不同的用戶身份從你選擇的任何鏡像運(yùn)行。由于調(diào)試容器與其目標(biāo)容器在同一 Pod 中運(yùn)行(因此在同一節(jié)點(diǎn)上),因此兩個容器之間的隔離不需要是絕對的。調(diào)試容器可以與同一 Pod 中運(yùn)行的其他容器共享系統(tǒng)資源。
考慮要檢查pod容器postpod中運(yùn)行的 PostgreSQL 數(shù)據(jù)庫的 CPU 使用情況。Pod 不以 root 身份運(yùn)行,并且 Postgres 鏡像沒有類似top或htop安裝的工具——換句話說,該kubectl exec命令沒什么用處。你可以運(yùn)行以下命令:
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)程命名空間,并且可以查看甚至殺死在那里運(yùn)行的所有進(jìn)程!當(dāng)你退出該進(jìn)程時,臨時容器也將停止存在。
注意:你可以通過按 CTRL+P 或 CTRL+D 斷開與臨時容器/bash 會話的連接,而無需退出(終止)它。然后你可以稍后使用 重新連接到它kubectl attach。
注意:kubectl debug提供的功能比此處概述的更多,例如使用修改后的啟動命令復(fù)制 Pod 或啟動可訪問節(jié)點(diǎn)文件系統(tǒng)的“節(jié)點(diǎn)”Pod。
臨時容器
上面的命令kubectl debug通過創(chuàng)建一個稱為臨時容器[2]東西來工作。這些容器應(yīng)該在現(xiàn)有Pod 中臨時運(yùn)行,以支持故障排除等操作。
“普通”容器和臨時容器之間的區(qū)別很小。沒有什么能真正阻止臨時容器長期運(yùn)行。我認(rèn)為,通過查看 Kubernetes 在誕生之初所做的基礎(chǔ)架構(gòu)選擇,可以最好地理解擁有臨時容器的原因:
• Pod 應(yīng)該是一次性且可更換的,并且支持這一點(diǎn),
• Pod 規(guī)范是不可變的。
當(dāng) Kubernetes 主要用于部署無狀態(tài)工作負(fù)載時(當(dāng) Pod 本身可以被認(rèn)為是短暫的)時,這非常有意義。在這個 Kubernetes無所不能的新世界中,它可能會受到限制。Pod 規(guī)范保持不變,但 Kubernetes 將臨時容器建模為Pod 的子資源。與“普通”容器不同,臨時容器不是 Pod規(guī)范的一部分,即使它們是 pod 的一部分。這種微妙的區(qū)別讓每個人都高興