新聞中心
本文轉(zhuǎn)載自微信公眾號「云原生百寶箱」

成都創(chuàng)新互聯(lián)主要從事網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務越城,10余年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:18982081108
這篇內(nèi)容主要探討了 Kubernetes 的調(diào)試功能,介紹了 kubectl debug 和 kubectl superdebug。它們支持容器掛載并且能夠調(diào)試一些需要排查問題的 Pod。文章指出了在 Kubernetes 中使用 kubectl exec 命令的限制,并介紹了 kubectl debug 的作用,它能創(chuàng)建一個新的容器來調(diào)試運行中的容器,并且能夠在同一個 Pod 內(nèi)共享系統(tǒng)資源。此外,還提到了 ephemeral containers,它們在調(diào)試過程中可以臨時運行在現(xiàn)有的 Pod 中,支持一些排查操作。最后,文章還提及了一些非 Kubernetes 本地調(diào)試容器的方法,包括使用 Docker Engine 或者一些基于 Linux namespaces 的工具。
使用 kubectl exec 執(zhí)行命令
如果你在 Kubernetes 上運行軟件,你有時會想要調(diào)試所部署的應用。對于習慣使用虛擬機的人來說,一種簡單的調(diào)試方法是連接到正在運行的 Pod 并進行分享:
kubectl exec -it podname -c containername -- bash這通常有效并且非常有用。然而,至少有兩個 Kubernetes“最佳實踐”限制了 exec 在現(xiàn)實世界中的用處:
? 不以 root 身份運行。容器以盡可能少的權(quán)限運行,甚至可以使用隨機 UID 運行。
? 最小鏡像。鏡像盡可能小,極端情況下將二進制文件安裝到distroless 鏡像中。[1]
當應用這些最佳實踐時,使用kubectl exec連接到容器要么是不可能的,要么會讓你陷入不適合調(diào)試的貧瘠荒地般的環(huán)境。
調(diào)試容器
調(diào)試正在運行的容器的 Kubernetes 原生答案是使用kubectl debug。
debug 命令將一個新容器附加到正在運行的 pod 中。這個新容器可以以不同的用戶身份從你選擇的任何鏡像運行。由于調(diào)試容器與其目標容器在同一 Pod 中運行(因此在同一節(jié)點上),因此兩個容器之間的隔離不需要是絕對的。調(diào)試容器可以與同一 Pod 中運行的其他容器共享系統(tǒng)資源。
考慮要檢查pod容器postpod中運行的 PostgreSQL 數(shù)據(jù)庫的 CPU 使用情況。Pod 不以 root 身份運行,并且 Postgres 鏡像沒有類似top或htop安裝的工具——換句話說,該kubectl exec命令沒什么用處。你可以運行以下命令:
kubectl debug -it \
--container=debug-container \
--image=alpine \
--target=postcont \
postpod你將以 root 身份登錄(這是 Alpine 鏡像的默認設(shè)置),并且可以輕松安裝你最喜歡的交互式進程查看器 htop ( apt add htop)。你與容器postcont共享相同的進程命名空間,并且可以查看甚至殺死在那里運行的所有進程!當你退出該進程時,臨時容器也將停止存在。
注意:你可以通過按 CTRL+P 或 CTRL+D 斷開與臨時容器/bash 會話的連接,而無需退出(終止)它。然后你可以稍后使用 重新連接到它kubectl attach。
注意:kubectl debug提供的功能比此處概述的更多,例如使用修改后的啟動命令復制 Pod 或啟動可訪問節(jié)點文件系統(tǒng)的“節(jié)點”Pod。
臨時容器
上面的命令kubectl debug通過創(chuàng)建一個稱為臨時容器[2]東西來工作。這些容器應該在現(xiàn)有Pod 中臨時運行,以支持故障排除等操作。
“普通”容器和臨時容器之間的區(qū)別很小。沒有什么能真正阻止臨時容器長期運行。我認為,通過查看 Kubernetes 在誕生之初所做的基礎(chǔ)架構(gòu)選擇,可以最好地理解擁有臨時容器的原因:
? Pod 應該是一次性且可更換的,并且支持這一點,
? Pod 規(guī)范是不可變的。
當 Kubernetes 主要用于部署無狀態(tài)工作負載時(當 Pod 本身可以被認為是短暫的)時,這非常有意義。在這個 Kubernetes無所不能的新世界中,它可能會受到限制。Pod 規(guī)范保持不變,但 Kubernetes 將臨時容器建模為Pod 的子資源。與“普通”容器不同,臨時容器不是 Pod規(guī)范的一部分,即使它們是 pod 的一部分。這種微妙的區(qū)別讓每個人都高興????!
臨時容器仍然相對較新;
它們自 Kubernetes v1.25(2022 年 8 月)處于Stable狀態(tài),自 v1.23(2021 年 12 月)是Beta狀態(tài),自 v1.22(2021 年 8 月)是Alpha狀態(tài)。
掛載卷
內(nèi)置命令kubectl debug非常有用。它允許你將臨時容器添加到正在運行的 Pod,可以選擇與正在運行的容器共享其進程命名空間。但是,如果你希望用于kubectl debug檢查或修改正在運行的容器的文件系統(tǒng)的任何部分,那么你就不走運了 - 調(diào)試 Pod 的文件系統(tǒng)與你連接到的容器的文件系統(tǒng)是脫節(jié)的。
幸運的是,我們可以做得更好。這個想法很簡單:
? 檢索正在運行的目標容器的規(guī)格。
? 將臨時容器修補到 Pod 中。將其配置為與目標容器共享相同的進程命名空間,并另外包含相同的卷掛載。
沒有用于創(chuàng)建臨時容器的 kubectl 命令,因此我們需要向 K8s API 發(fā)送 PATCH 請求來創(chuàng)建它。該kubectl proxy命令允許訪問 K8s API。
這個過程并不完全是用戶友好的,因此將過程包裝到腳本或 kubectl 插件中是有意義的。你可以在此處找到此類腳本的示例實現(xiàn):
https://github.com/JonMerlevede/kubectl-superdebugkubectl debug 的擴展將目標容器的卷規(guī)格附加到臨時調(diào)試 pod 中……
kubectl superdebug
請注意,此方法和腳本可以輕松擴展以從目標容器復制環(huán)境變量規(guī)范。
如果將此腳本另存為kubectl-superdebug并使其在你的路徑上可用,則可以kubectl superdebug從任何地方運行它,如下所示:
kubectl superdebug \
--container=debug-container \
--image=alpine \
--target=postcont \
postpod你可能還想擴展此腳本以將目標容器的其他方面復制到調(diào)試容器中,例如對環(huán)境變量的引用。
這完成了調(diào)試運行容器的 Kubernetes 原生方法的概述,應該可以滿足大多數(shù)人的需求。
非 Kubernetes 原生方法
Kubernetes 不提供以 root 身份連接到正在運行的容器(除非主進程以 root 身份運行)或從另一個容器訪問容器的根文件系統(tǒng)的方法。這并不意味著這些事情不可能做到。畢竟,Kubernetes 只是一個位于容器化引擎之上的容器編排器。如果由于某種原因確實有必要的話,通??梢酝ㄟ^刪除抽象層來做任何你想做的事情。只要確保你必須...
如果你使用 Docker 引擎并且可以直接從節(jié)點或通過節(jié)點上運行的特權(quán)容器訪問你的引擎,那么你可以docker exec --user作為你選擇的用戶運行和執(zhí)行進程。
諸如kubectl ssh和 之類的插件kubectl exec-user實現(xiàn)了這種方法。不幸的是, containerd[3]和CRI-O[4]等現(xiàn)代引擎不再提供--user標志功能——這意味著這些插件無法在現(xiàn)代 Kubernetes 安裝上運行。
然而,即使是這些現(xiàn)代引擎通常也只是與 Linux 命名空間交互。你可以通過輸入適當?shù)?Linux 命名空間集在任何你想要的“容器”中運行命令。kpexec[5]工具實現(xiàn)了這種方法。它在與目標容器相同的節(jié)點上啟動一個特權(quán) Pod,然后確定要定位的 (Linux) 命名空間,在這些 (Linux) 命名空間中執(zhí)行命令,最后將其輸出流式傳輸?shù)侥愕慕K端。作為一個額外的好處,它可以在目標容器的文件系統(tǒng)之上覆蓋一組可用于調(diào)試的工具。
與 kubectl exec 不同,kpexec 可以運行具有不同 uid/gid 甚至不同功能的命令作為容器的主進程。它與containerd和cri-o兼容。kpexec 采用某種重量級且脆弱的方法,可能與你的集群的安全配置不兼容。如果 kubectl (super)debug 無法滿足你的需求,則值得考慮。
請注意,kpexec 使用nsenter命令直接執(zhí)行到命名空間中。它與無處不在的容器運行時 runc 兼容,但與Kata Containers[6]等運行時不兼容。
在這篇文章中,我們研究了兩種調(diào)試運行容器的 Kubernetes 原生方法:kubectl exec和kubectl debug。我們研究了kubectl debug工作原理,并提出了kubectl superdebug一種變體,kubectl debug它啟動一個與目標容器共享相同卷和相同進程命名空間的臨時容器。最后,我們回顧了一些非 Kubernetes 原生的容器調(diào)試方法。
引用鏈接
[1] distroless 鏡像中。: https://github.com/GoogleContainerTools/distroless
[2] 臨時容器: https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/
[3] containerd: https://containerd.io/
[4] CRI-O: https://cri-o.io/
[5] kpexec: https://github.com/ssup2/kpexec[6] Kata Containers: https://katacontainers.io/
標題名稱:容器故障?別慌:debug不行,還有superdebug
文章鏈接:http://m.fisionsoft.com.cn/article/djhcjgj.html


咨詢
建站咨詢
