偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

[[408037]]

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

更好的方法

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

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

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

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

Configuring Feature Gates

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

  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)該包含臨時容器部分以及通常容器: 

  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> 

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

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

Process Namespace Sharing

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

進(jìn)程共享的一個問題是它不能應(yīng)用于現(xiàn)有的 Pod,因此我們必須創(chuàng)建一個新 Pod,將其 spec.shareProcessNamespace 設(shè)置為 true,并將一個臨時容器注入其中。這樣有點(diǎn)麻煩,尤其是需要調(diào)試多個 Pod 或容器,亦或者需要重復(fù)執(zhí)行該操作時。幸運(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 中另一個容器內(nèi)的所有內(nèi)容,包括其進(jìn)程和文件,這對于調(diào)試來說非常方便。另外,除了 --share-processes 還包括了 --copy-to=new-pod-name,這是因?yàn)槲覀冃枰獎?chuàng)建一個新的 Pod,其名稱由該 flag 指定。如果我們從另一個終端列出正在運(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 個容器,因?yàn)樗€包括臨時容器。此外,如果想在任何時候驗(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)用程序。 想象這樣一個場景——我們有一個問題應(yīng)用程序,我們需要在它的容器中對網(wǎng)絡(luò)相關(guān)的問題進(jìn)行故障排除。該應(yīng)用程序沒有我們可以使用的必要的網(wǎng)絡(luò) CLI 工具。為了解決這個問題,我們通過以下方式使用 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 

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

在上面的例子中,我們進(jìn)入 Pod 的另一個容器中就足夠了。但有時可能需要直接查看有問題的容器。這種情況下,我們可以像這樣使用進(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)建了一個新的 Pod,帶有額外的臨時容器,可以訪問所有進(jìn)程。當(dāng)我們列出正在運(yùn)行的進(jìn)程時,能看到應(yīng)用程序容器的進(jìn)程有 PID 8,可以用它來探索文件和環(huán)境。為此,我們需要通過 /proc/<PID>/... 目錄,這個例子中是 /proc/8/root/app/...。

另一種常見情況是應(yīng)用程序在容器啟動時不斷崩潰,這讓調(diào)試非常困難,因?yàn)闆]有足夠的時間將 shell 會話導(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é)省大量時間,但更重要的是,它能極大地幫助解決那些如果不立即解決可能最終會花費(fèi)大量資金的問題。 這就是為什么 kubectl debug 之類的工具能隨意使用非常重要,即使它們尚未正式發(fā)布或默認(rèn)啟用。如果啟用臨時容器不是一種選擇,那么嘗試替代調(diào)試方法可能是一個好主意,例如使用包含故障排除工具的應(yīng)用程序鏡像的調(diào)試版本;或臨時更改 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

2025-05-28 15:46:13

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ì)算

2014-01-22 10:00:10

Android SDKAndroid開發(fā)

2021-11-26 09:40:37

EclipseIDEA開發(fā)

2013-12-04 13:27:56

Android SDK項(xiàng)目

2013-12-26 15:40:33

Android SDK項(xiàng)目

2013-12-04 14:44:41

Android SDK用戶交互

2023-05-26 08:02:11

工具函數(shù)庫模塊

2013-11-01 09:37:19

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

2009-10-10 13:21:02

服務(wù)器測試工具

2014-06-06 14:25:03

iOS 8SwiftWWDC2014

2012-08-01 17:39:17

2013-12-04 14:29:18

Android SDK應(yīng)用程序

2013-12-26 15:47:59

Android SDK應(yīng)用程序
點(diǎn)贊
收藏

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