自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Kubernetes 官方出品調(diào)試工具上手指南(無需安裝,開箱即用)

系統(tǒng) Linux
本文介紹了 Kubectl debug 和臨時(shí)容器等調(diào)試方法。一起來看看吧。

[[408037]]

 調(diào)試容器化工作負(fù)載和 Pod 是每位使用 Kubernetes 的開發(fā)人員和 DevOps 工程師的日常任務(wù)。通常情況下,我們簡單地使用 kubectl logs 或者 kubectl describe pod 便足以找到問題所在,但有時(shí)候,一些問題會(huì)特別難查。這種情況下,大家可能會(huì)嘗試使用 kubectl exec,但有時(shí)候這樣也還不行,因?yàn)?Distroless 等容器甚至不允許通過 SSH 進(jìn)入 shell。那么,如果以上所有方法都失敗了,我們要怎么辦?

更好的方法

其實(shí)我們只需要使用更合適的工具。如果在 Kubernetes 上調(diào)試工作負(fù)載,那么合適的工具就是 kubectl debug。 這是不久前添加的一個(gè)新命令(v1.18),允許調(diào)試正在運(yùn)行的 pod。它會(huì)將名為 EphemeralContainer(臨時(shí)容器)的特殊容器注入到問題 Pod 中,讓我們查看并排除故障。kubectl debug 看起來非常不錯(cuò),但要使用它需要臨時(shí)容器,臨時(shí)容器到底是什么?

臨時(shí)容器其實(shí)是 Pod 中的子資源,類似普通 container。但與普通容器不同的是,臨時(shí)容器不用于構(gòu)建應(yīng)用程序,而是用于檢查。 我們不會(huì)在創(chuàng)建 Pod 時(shí)定義它們,而使用特殊的 API 將其注入到運(yùn)的行 Pod 中,來運(yùn)行命令并檢查 Pod 環(huán)境。除了這些不同,臨時(shí)容器還缺少一些基本容器的字段,例如 ports、resources。

那么我們?yōu)槭裁床恢苯邮褂没救萜??這是因?yàn)槲覀儾荒芟?Pod 添加基本容器,它們應(yīng)該是一次性的(需要隨時(shí)刪除或重新創(chuàng)建),這會(huì)導(dǎo)致難以重現(xiàn)問題 Pod 的錯(cuò)誤,排除故障也會(huì)很麻煩。這就是將臨時(shí)容器添加到 API 的原因——它們允許我們將臨時(shí)容器添加到現(xiàn)有 Pod,從而檢查正在運(yùn)行的 Pod。

雖然臨時(shí)容器是作為 Kubernetes 核心的 Pod 規(guī)范的一部分,但很多人可能還沒有聽說過。這是因?yàn)榕R時(shí)容器處于早期 Alpha 階段,這意味著默認(rèn)情況下不啟用。Alpha 階段的資源和功能可能會(huì)出現(xiàn)重大變化,或者在 Kubernetes 的某個(gè)未來版本中被完全刪除。因此,要使用它們必須在 kubelet 中使用Feature Gate(功能門)顯式啟用。

Configuring Feature Gates

現(xiàn)在如果確定要試用 kubectl debug,那么如何啟用臨時(shí)容器的功能門?這取決于集群設(shè)置。 例如,現(xiàn)在使用kubeadm啟動(dòng)創(chuàng)建集群,那么可以使用以下集群配置來啟用臨時(shí)容器: 

  1. apiVersion: kubeadm.k8s.io/v1beta2  
  2. kind: ClusterConfiguration  
  3. kubernetesVersion: v1.20.2  
  4. apiServer:  
  5.   extraArgs:  
  6.     feature-gates: EphemeralContainers=true 

在以下示例中,為了簡單和測試目的,我們使用 KinD(Docker 中的 Kubernetes)集群,這允許我們指定要啟用的功能門。創(chuàng)建我們的測試集群: 

  1. # File: config.yaml  
  2. # Run:  kind create cluster --config ./config.yaml --name kind --image=kindest/node:v1.20.2  
  3. kind: Cluster  
  4. apiVersion: kind.x-k8s.io/v1alpha4  
  5. featureGates:  
  6.   EphemeralContainers: true  
  7. nodes: 
  8.  - role: control-plane 

隨著集群的運(yùn)行,我們需要驗(yàn)證其有效性。最簡單方法是檢查 Pod API,它現(xiàn)在應(yīng)該包含臨時(shí)容器部分以及通常容器: 

  1. ~ $ kubectl explain pod.spec.ephemeralContainers  
  2. KIND:     Pod 
  3. VERSION:  v1  
  4. RESOURCE: ephemeralContainers <[]Object>  
  5. DESCRIPTION: 
  6.       List of ephemeral containers run in this pod.... 
  7.  ... 

現(xiàn)在都有了,可以開始使用 kubectl debug。從簡單的例子開始: 

  1. ~ $ kubectl run some-app --image=k8s.gcr.io/pause:3.1 --restart=Never  
  2. ~ $ kubectl debug -it some-app --image=busybox --target=some-app  
  3. Defaulting debug container name to debugger-tfqvh. 
  4. If you don't see a command prompt, try pressing enter.  
  5. / #  
  6. # From other terminal...  
  7. ~ $ kubectl describe pod some-app  
  8. ...  
  9. Containers:  
  10.   some-app:  
  11.     Container ID:   containerd://60cc537eee843cb38a1ba295baaa172db8344eea59de4d75311400436d4a5083
  12.     Image:          k8s.gcr.io/pause:3.1  
  13.     Image ID:       k8s.gcr.io/pause@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea 
  14. ...  
  15. Ephemeral Containers:  
  16.   debugger-tfqvh:  
  17.     Container ID:   containerd://12efbbf2e46bb523ae0546b2369801b51a61e1367dda839ce0e02f0e5c1a49d6  
  18.     Image:          busybox 
  19.     Image ID:       docker.io/library/busybox@sha256:ce2360d5189a033012fbad1635e037be86f23b65cfd676b436d0931af390a2ac  
  20.     Port:           <none>  
  21.     Host Port:      <none>  
  22.     State:          Running  
  23.       Started:      Mon, 15 Mar 2021 20:33:51 +0100  
  24.     Ready:          False  
  25.     Restart Count:  0  
  26.     Environment:    <none>  
  27.     Mounts:         <none> 

我們首先啟動(dòng)一個(gè)名為 some-app 的 Pod 來進(jìn)行“調(diào)試”。然后針對這個(gè) Pod 運(yùn)行 kubectl debug,指定 busybox 為臨時(shí)容器的鏡像,并作為原始容器的目標(biāo)。此外,還需要包括 -it 參數(shù),以便我們立即附加到容器獲得 shell 會(huì)話。

在上面的代碼中可以看到,如果我們在 Pod 上運(yùn)行 kubectl debug 后對其進(jìn)行描述,那么它的描述將包括具有之前指定為命令選項(xiàng)值的臨時(shí)容器部分。

Process Namespace Sharing

kubectl debug 是非常強(qiáng)大的工具,但有時(shí)向 Pod 添加一個(gè)容器還不足以獲取 Pod 的另一個(gè)容器中運(yùn)行的應(yīng)用程序相關(guān)信息。當(dāng)故障容器不包括必要的調(diào)試工具甚至 shell 時(shí),可能就是這種情況。在這種情況下,我們可以使用 Process Sharing(進(jìn)程共享)來使用注入的臨時(shí)容器檢查 Pod 的原有容器。

進(jìn)程共享的一個(gè)問題是它不能應(yīng)用于現(xiàn)有的 Pod,因此我們必須創(chuàng)建一個(gè)新 Pod,將其 spec.shareProcessNamespace 設(shè)置為 true,并將一個(gè)臨時(shí)容器注入其中。這樣有點(diǎn)麻煩,尤其是需要調(diào)試多個(gè) Pod 或容器,亦或者需要重復(fù)執(zhí)行該操作時(shí)。幸運(yùn)的是,kubectl debug 可以使用 --share-processes 做到: 

  1. ~ $ kubectl run some-app --image=nginx --restart=Never  
  2. ~ $ kubectl debug -it some-app --image=busybox --share-processes --copy-to=some-app-debug  
  3. Defaulting debug container name to debugger-tkwst.  
  4. If you don't see a command prompt, try pressing enter.  
  5. / # ps ax  
  6. PID   USER     TIME  COMMAND  
  7.     1 root      0:00 /pause  
  8.     8 root      0:00 nginx: master process nginx -g daemon off;  
  9.    38 101       0:00 nginx: worker process  
  10.    39 root      0:00 sh  
  11.    46 root      0:00 ps ax  
  12. ~ $ cat /proc/8/root/etc/nginx/conf.d/default.conf   
  13. server {  
  14.     listen       80;  
  15.     listen  [::]:80;  
  16.     server_name  localhost;  
  17. ... 

上面的代碼表明,通過進(jìn)程共享,我們可以看到 Pod 中另一個(gè)容器內(nèi)的所有內(nèi)容,包括其進(jìn)程和文件,這對于調(diào)試來說非常方便。另外,除了 --share-processes 還包括了 --copy-to=new-pod-name,這是因?yàn)槲覀冃枰獎(jiǎng)?chuàng)建一個(gè)新的 Pod,其名稱由該 flag 指定。如果我們從另一個(gè)終端列出正在運(yùn)行的 Pod,我們將看到以下內(nèi)容: 

  1. # From other terminal:  
  2. ~ $ kubectl get pods  
  3. NAME             READY   STATUS    RESTARTS   AGE  
  4. some-app         1/1     Running   0          23h  
  5. some-app-debug   2/2     Running   0          20s 

這就是我們在原始應(yīng)用程序 Pod 上的新調(diào)試 Pod。與原始容器相比,它有 2 個(gè)容器,因?yàn)樗€包括臨時(shí)容器。此外,如果想在任何時(shí)候驗(yàn)證 Pod 中是否允許進(jìn)程共享,那么可以運(yùn)行: 

  1. ~ $ kubectl get pod some-app-debug -o json  | jq .spec.shareProcessNamespace  
  2. true 

好好使用

既然我們已經(jīng)啟用了功能并且知道命令是如何工作的,那就試著使用它并調(diào)試一些應(yīng)用程序。 想象這樣一個(gè)場景——我們有一個(gè)問題應(yīng)用程序,我們需要在它的容器中對網(wǎng)絡(luò)相關(guān)的問題進(jìn)行故障排除。該應(yīng)用程序沒有我們可以使用的必要的網(wǎng)絡(luò) CLI 工具。為了解決這個(gè)問題,我們通過以下方式使用 kubectl debug: 

  1. ~ $ kubectl run distroless-python --image=martinheinz/distroless-python --restart=Never  
  2. ~ $ kubectl exec -it distroless-python -- /bin/sh  
  3. # id  
  4. /bin/sh: 1: id: not found  
  5. # ls  
  6. /bin/sh: 2: ls: not found  
  7. # env  
  8. /bin/sh: 3: env: not found  
  9.  
  10. ...  
  11. kubectl debug -it distroless-python --image=praqma/network-multitool --target=distroless-python -- sh  
  12. Defaulting debug container name to debugger-rvtd4.  
  13. If you don't see a command prompt, try pressing enter.  
  14. / # ping localhost  
  15. PING localhost(localhost (::1)) 56 data bytes  
  16. 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.025 ms  
  17. 64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.044 ms  
  18. 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.027 ms 

在啟動(dòng)一個(gè) Pod 之后,我們首先嘗試將 shell 會(huì)話放入它的容器中,這看起來有效,但是實(shí)際上我們嘗試運(yùn)行一些基本命令時(shí),將看到那里什么都沒有。所以,我們要使用 praqma/network-multitool 將臨時(shí)容器注入到 Pod 中,該鏡像包含了 curl、ping、telnet 等工具,現(xiàn)在我們可以進(jìn)行所有必要的故障排除。

在上面的例子中,我們進(jìn)入 Pod 的另一個(gè)容器中就足夠了。但有時(shí)可能需要直接查看有問題的容器。這種情況下,我們可以像這樣使用進(jìn)程共享: 

  1. ~ $ kubectl run distroless-python --image=martinheinz/distroless-python --restart=Never  
  2. ~ $ kubectl debug -it distroless-python --image=busybox --share-processes --copy-to=distroless-python-debug  
  3. Defaulting debug container name to debugger-l692h.  
  4. If you don't see a command prompt, try pressing enter.  
  5. / # ps ax  
  6. PID   USER     TIME  COMMAND  
  7.     1 root      0:00 /pause  
  8.     8 root      0:00 /usr/bin/python3.5 sleep.py  # Original container is just sleeping forever  
  9.    14 root      0:00 sh  
  10.    20 root      0:00 ps ax  
  11. / # cat /proc/8/root/app/sleep.py   
  12. import time 
  13. print("sleeping for 1 hour")  
  14. time.sleep(3600) 

在這里,我們再次運(yùn)行使用 Distroless 鏡像的容器。我們無法在它的 shell 中做任何事情。我們運(yùn)行 kubectl debug 以及 --share-processes --copy-to=...,它創(chuàng)建了一個(gè)新的 Pod,帶有額外的臨時(shí)容器,可以訪問所有進(jìn)程。當(dāng)我們列出正在運(yùn)行的進(jìn)程時(shí),能看到應(yīng)用程序容器的進(jìn)程有 PID 8,可以用它來探索文件和環(huán)境。為此,我們需要通過 /proc/<PID>/... 目錄,這個(gè)例子中是 /proc/8/root/app/...。

另一種常見情況是應(yīng)用程序在容器啟動(dòng)時(shí)不斷崩潰,這讓調(diào)試非常困難,因?yàn)闆]有足夠的時(shí)間將 shell 會(huì)話導(dǎo)入容器并運(yùn)行故障排除命令。在這種情況下,解決方案是創(chuàng)建具有不同入口點(diǎn)、命令的容器,這可以阻止應(yīng)用程序立即崩潰并允許我們調(diào)試: 

  1. ~ $ kubectl get pods  
  2. NAME                READY   STATUS             RESTARTS   AGE  
  3. crashing-app        0/1     CrashLoopBackOff   1          8s  
  4. ~ $ kubectl debug crashing-app -it --copy-to=crashing-app-debug --container=crashing-app -- sh  
  5. If you don't see a command prompt, try pressing enter.  
  6. # id  
  7. uid=0(root) gid=0(root) groups=0(root)  
  8.  
  9. ...  
  10. # From another terminal  
  11. ~ $ kubectl get pods  
  12. NAME                READY   STATUS             RESTARTS   AGE  
  13. crashing-app        0/1     CrashLoopBackOff   3          2m7s  
  14. crashing-app-debug  1/1     Running            0          16s 

調(diào)試集群節(jié)點(diǎn)

本文主要關(guān)注 Pod 及其容器的調(diào)試,但任何集群管理員都知道常常需要調(diào)試的是節(jié)點(diǎn)而不是 Pod。幸運(yùn)的是,kubectl debug 允許通過創(chuàng)建 Pod 來調(diào)試節(jié)點(diǎn),該 Pod 將在指定節(jié)點(diǎn)上運(yùn)行,節(jié)點(diǎn)的根文件系統(tǒng)安裝在 /root 目錄中。我們甚至可以用 chroot 訪問主機(jī)二進(jìn)制文件,這本質(zhì)上充當(dāng)了節(jié)點(diǎn)的 SSH 連接: 

  1. ~ $ kubectl get nodes  
  2. NAME                 STATUS   ROLES                  AGE   VERSION  
  3. kind-control-plane   Ready    control-plane,master   25h   v1.20.2  
  4. ~ $ kubectl debug node/kind-control-plane -it --image=ubuntu 
  5.  Creating debugging pod node-debugger-kind-control-plane-hvljt with container debugger on node kind-control-plane.  
  6. If you don't see a command prompt, try pressing enter.  
  7. root@kind-control-plane:/# chroot /host  
  8. # head kind/kubeadm.conf  
  9. apiServer:  
  10.   certSANs:  
  11.   - localhost  
  12.   - 127.0.0.1  
  13.   extraArgs:  
  14.     feature-gates: EphemeralContainers=true  
  15.     runtime-config: ""  
  16. apiVersion: kubeadm.k8s.io/v1beta2  
  17. clusterName: kind  
  18. controlPlaneEndpoint: kind-control-plane:6443 

在上面的代碼中,我們首先確定了想要調(diào)試的節(jié)點(diǎn),然后使用 node/... 作為參數(shù)顯式運(yùn)行 kubectl debug 以訪問我們集群的節(jié)點(diǎn)。在那之后,當(dāng)連接到Pod后,我們使用 chroot /host 突破 chroot,并完全進(jìn)入主機(jī)。最后,為了驗(yàn)證是否真的可以看到主機(jī)上的所有內(nèi)容,我們了查看一部分的 kubeadm.conf,最終看到我們在文章開頭配置的內(nèi)容 feature-gates: EphemeralContainers=true。

小結(jié)

能夠快速有效地調(diào)試應(yīng)用程序和服務(wù)可以節(jié)省大量時(shí)間,但更重要的是,它能極大地幫助解決那些如果不立即解決可能最終會(huì)花費(fèi)大量資金的問題。 這就是為什么 kubectl debug 之類的工具能隨意使用非常重要,即使它們尚未正式發(fā)布或默認(rèn)啟用。如果啟用臨時(shí)容器不是一種選擇,那么嘗試替代調(diào)試方法可能是一個(gè)好主意,例如使用包含故障排除工具的應(yīng)用程序鏡像的調(diào)試版本;或臨時(shí)更改 Pod 的容器命令以阻止其崩潰。 

 

責(zé)任編輯:龐桂玉 來源: 奇妙的Linux世界
相關(guān)推薦

2013-12-26 15:14:38

Android SDK運(yùn)行調(diào)試

2021-01-26 08:37:18

MobXVueReact

2023-04-04 10:09:09

2014-06-24 09:41:56

Android Stu教程

2024-01-29 00:36:50

Backstage設(shè)施工具

2023-03-08 21:25:58

開源工具庫開箱

2016-06-20 10:20:22

Docker云計(jì)算

2021-11-26 09:40:37

EclipseIDEA開發(fā)

2014-01-22 10:00:10

Android SDKAndroid開發(fā)

2013-12-04 13:27:56

Android SDK項(xiàng)目

2013-12-04 14:44:41

Android SDK用戶交互

2013-12-26 15:40:33

Android SDK項(xiàng)目

2009-10-10 13:21:02

服務(wù)器測試工具

2023-05-26 08:02:11

工具函數(shù)庫模塊

2013-11-01 09:37:19

Android系統(tǒng)架構(gòu)工具

2014-06-06 14:25:03

iOS 8SwiftWWDC2014

2012-08-01 17:39:17

2023-05-06 13:56:02

工具函數(shù)庫業(yè)務(wù)

2013-12-26 14:52:52

Android SDK物理設(shè)備

2021-01-19 06:16:05

前端Babel 技術(shù)熱點(diǎn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號