<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你知道 kubectl exec 的運行機制是什么嗎?

          共 7516字,需瀏覽 16分鐘

           ·

          2021-10-02 21:16


          看到一篇關于 Kubectl 運行的機制,覺得寫得非常不錯,圖文并茂很形象,就翻譯成了中文記錄一下,原文地址:

          • https://erkanerol.github.io/post/how-kubectl-exec-works/[1]

          上周五,我的一位同事問了一個有關如何使用 go-client 在 Pod 中執(zhí)行命令的問題。我不知道答案,我注意到我從未想過“ kubectl exec”中的機制。我有一些想法,但是我不 100%確定。我需要通過實踐來找到答案,在閱讀了一些博客,文檔和源代碼后,我學到了很多東西。在這篇博客中,我將分享我的理解和發(fā)現。

          Setup

          我克隆了https://github.com/ecomm-integration-ballerina/kubernetes-cluster,以便在MacBook中創(chuàng)建k8s集群。我修改Kubelet配置中節(jié)點的IP地址,因為默認配置不允許我運行kubectl exec。您可以在這里[2]找到根本原因。

          下文提到的關于機器的對應關系如下:

          • any machine = MacBook
          • master IP = 192.168.205.10
          • work IP = 192.168.205.11
          • API server 端口 = 6443

          Component

          • kubectl exec:當我們在機器上運行“ kubectl exec…”時,可以在任何有權限訪問 K8s API 服務上運行。
          • API Server[3]:API Server上的組件,用于公開 Kubernetes API。它是 Kubernetes 控制平面的前端。
          • kubelet[4]:在集群中每個節(jié)點上運行的代理。確保容器在容器中運行。
          • container runtime[5]:負責運行容器的軟件。例如:docker,cri-o,containerd…
          • kernel:工作節(jié)點中操作系統(tǒng)的內核,負責管理進程。
          • target container:作為 Pod 的一部分并在其中一個工作程序節(jié)點上運行的容器。

          Findings

          1. Client 端

          在默認名稱空間中創(chuàng)建容器

          #?any?machine
          $?kubectl?run?exec-test-nginx?--image=nginx

          然后運行 exec 命令并sleep 5000進行觀察

          #?any?machine
          $?kubectl?exec?-it?exec-test-nginx-6558988d5-fgxgg?--?sh
          #?sleep?5000

          我們可以觀察到 kubectl 過程(在這種情況下為 pid = 8507)

          #?any?machine
          $?ps?-ef?|grep?kubectl
          501??8507??8409???0??7:19PM?ttys000????0:00.13?kubectl?exec?-it?exec-test-nginx-6558988d5-fgxgg?--?sh

          當我們檢查該進程的網絡活動時,我們可以看到它與 API Server(192.168.205.10.6443)有連接

          #?any?machine
          $?netstat?-atnv?|grep?8507
          tcp4???????0??????0??192.168.205.1.51673????192.168.205.10.6443????ESTABLISHED?131072?131768???8507??????0?0x0102?0x00000020
          tcp4???????0??????0??192.168.205.1.51672????192.168.205.10.6443????ESTABLISHED?131072?131768???8507??????0?0x0102?0x00000028

          讓我們檢查一下代碼。kubectl 使用子資源創(chuàng)建一個 POST 請求,exec并發(fā)送一個 rest 請求。

          2. API Server 端

          我們可以在 API 服務端觀察請求。

          handler.go:143]?kube-API?Server:?POST?"/api/v1/namespaces/default/pods/exec-test-nginx-6558988d5-fgxgg/exec"?satisfied?by?gorestful?with?webservice?/api/v1
          upgradeaware.go:261]?Connecting?to?backend?proxy?(intercepting?redirects)?https://192.168.205.11:10250/exec/default/exec-test-nginx-6558988d5-fgxgg/exec-test-nginx?command=sh&input=1&output=1&tty=1
          Headers:?map[Connection:[Upgrade]?Content-Length:[0]?Upgrade:[SPDY/3.1]?User-Agent:[kubectl/v1.12.10?(darwin/amd64)?kubernetes/e3c1340]?X-Forwarded-For:[192.168.205.1]?X-Stream-Protocol-Version:[v4.channel.k8s.io?v3.channel.k8s.io?v2.channel.k8s.io?channel.k8s.io]]

          請注意,http 請求包括協(xié)議升級請求。SPDY[6]允許將單獨的 stdin / stdout / stderr / spdy-error 流通過單個 TCP 連接進行多路復用。

          API 服務收到請求并將其綁定到 PodExecOptions

          為了能夠采取必要的措施,API Server 需要知道應該請求哪個 node。

          當然,端點是從節(jié)點信息派生的。

          發(fā)現了,Kubelet 具有可node.Status.DaemonEndpoints.KubeletEndpoint.Port連接 API 服務的端口。

          master/node 之間的通信 > master 集群通信 > API Server 到 kubelet[7]

          這些連接在 kubelet 的 HTTPS 端點處終止。默認情況下,API 服務不驗證 kubelet 的服務證書,這使得連接容易遭受中間人攻擊,不安全的公共網絡。

          現在,API 服務知道了端點并打開了連接。

          讓我們檢查 master 上發(fā)生了什么。

          首先,得到 worker 節(jié)點的 ip。正是192.168.205.11在這種情況下。

          #?any?machine
          $?kubectl?get?nodes?k8s-node-1?-o?wide
          NAME?????????STATUS???ROLES????AGE???VERSION???INTERNAL-IP??????EXTERNAL-IP???OS-IMAGE?????????????KERNEL-VERSION??????CONTAINER-RUNTIME
          k8s-node-1???Ready???????9h????v1.15.3???192.168.205.11???????????Ubuntu?16.04.6?LTS???4.4.0-159-generic???docker://17.3.3

          然后獲取 kubelet 端口。在這個例子中是10250

          #?any?machine
          $?kubectl?get?nodes?k8s-node-1?-o?jsonpath='{.status.daemonEndpoints.kubeletEndpoint}'
          map[Port:10250]

          然后檢查網絡。是否存在到工作節(jié)點(192.168.205.11)的連接?可以看到,當我殺死 exec 進程時,它消失了,所以我知道它正是由于 exec 命令而由 API Server 設置的

          #?master?node
          $?netstat?-atn?|grep?192.168.205.11
          tcp????????0??????0?192.168.205.10:37870????192.168.205.11:10250????ESTABLISHED
          ...
          API 服務到 Kubelet

          現在,kubectl 和 API Server 之間的連接仍然打開,并且 API Server 和 kubelet 之間還有另一個連接。

          3. Worker 節(jié)點

          讓我們通過連接到 Worker 節(jié)點并檢查正在發(fā)生的事情。

          首先,我們也可以在此處觀察連接。第二行。192.168.205.10是 master 的 IP。

          #?worker?node
          $?netstat?-atn?|grep?10250
          tcp6???????0??????0?:::10250????????????????:::*????????????????????LISTEN
          tcp6???????0??????0?192.168.205.11:10250????192.168.205.10:37870????ESTABLISHED

          那我們的 sleep 命令呢?可以通過 ps 命令找到!!!

          #?worker?node
          $?ps?-afx
          ...
          31463??????????Sl?????0:00??????\_?docker-containerd-shim?7d974065bbb3107074ce31c51f5ef40aea8dcd535ae11a7b8f2dd180b8ed583a?/var/run/docker/libcontainerd/7d974065bbb3107074ce31c51
          31478?pts/0????Ss?????0:00??????????\_?sh
          31485?pts/0????S+?????0:00??????????????\_?sleep?5000
          ...
          • kubelet 如何做到的?
          • kubelet 有一個守護程序,該守護程序通過 10250 端口與 API Server 通信。
          • kubelet 計算執(zhí)行請求的響應端點。

          不要混淆。它不返回命令的結果。它返回一個通信端點。

          kubelet 實現的RuntimeServiceClient接口是 Container Runtime Interface 的一部分。

          它僅使用 gRPC 通過 Container Runtime Interface 調用方法。

          container runtime 負責實施 RuntimeServiceServer

          Kubelet到容器運行時

          如果是這樣,我們需要觀察 kubelet 與容器運行時之間的聯系。對?讓我們檢查。

          在運行 exec 命令之前和之后運行此命令,并檢查 diff。

          #?worker?node
          $?ss?-a?-p?|grep?kubelet
          ...
          u_str??ESTAB??????0??????0???????*?157937????????????????*?157387????????????????users:(("kubelet",pid=5714,fd=33))
          ...

          嗯 在 kubelet(pid = 5714)與某個組件通過 UNIX 套接字建立了新連接。正是 DOCKER(pid = 1186)。

          #?worker?node
          $?ss?-a?-p?|grep?157387
          ...
          u_str??ESTAB??????0??????0???????*?157937????????????????*?157387????????????????users:(("kubelet",pid=5714,fd=33))
          u_str??ESTAB??????0??????0??????/var/run/docker.sock?157387????????????????*?157937????????????????users:(("dockerd",pid=1186,fd=14))
          ...

          這是運行我們的命令的 docker 守護進程(pid = 1186)。

          #?worker?node.
          $?ps?-afx
          ...
          ?1186??????????Ssl????0:55?/usr/bin/dockerd?-H?fd://
          17784??????????Sl?????0:00??????\_?docker-containerd-shim?53a0a08547b2f95986402d7f3b3e78702516244df049ba6c5aa012e81264aa3c?/var/run/docker/libcontainerd/53a0a08547b2f95986402d7f3
          17801?pts/2????Ss?????0:00??????????\_?sh
          17827?pts/2????S+?????0:00??????????????\_?sleep?5000
          ...

          4. Docker runtime

          讓我們檢查 cri-o 的源代碼以了解它如何發(fā)生。邏輯在 docker 中相似。

          它具有一個實現 RuntimeServiceServer 的服務器。

          在鏈的最后, container runtime 在 work 節(jié)點中執(zhí)行命令。

          容器運行時到內核

          最后,kernel 執(zhí)行命令

          內核輸入

          注意事項

          • API Server 也可以初始化與 kubelet 的連接。
          • 這些連接將一直持續(xù)到交互式執(zhí)行程序結束。
            • kubectl 和 API Server 之間的連接
            • API Server 和 kubelet 之間的連接
            • kubelet 與 container runtime 之間的連接
          • kubectl 或 API Server 無法在 work 節(jié)點中運行任何內容。kubelet 可以運行,但也可以與 container runtime 時交互以進行此類操作。

          參考

          • https://groups.google.com/forum/#!topic/kubernetes-dev/Cjia36v39vM[8]
          • https://medium.com/@joatmon08/playing-with-kubeadm-in-vagrant-machines-part-2-bac431095706[9]
          • https://serverfault.com/questions/252723/how-to-find-other-end-of-unix-socket-connection[10]

          引用鏈接

          [1]

          https://erkanerol.github.io/post/how-kubectl-exec-works/: https://erkanerol.github.io/post/how-kubectl-exec-works/

          [2]

          這里: https://medium.com/@joatmon08/playing-with-kubeadm-in-vagrant-machines-part-2-bac431095706

          [3]

          API Server: https://kubernetes.io/docs/concepts/overview/components/#kube-apiserver

          [4]

          kubelet: https://kubernetes.io/docs/concepts/overview/components/#kubelet

          [5]

          container runtime: https://kubernetes.io/docs/concepts/overview/components/#container-runtime

          [6]

          SPDY: https://www.wikiwand.com/en/SPDY

          [7]

          master/node 之間的通信 > master 集群通信 > API Server 到 kubelet: https://kubernetes.io/docs/concepts/architecture/master-node-communication/#apiserver-to-kubelet

          [8]

          https://groups.google.com/forum/#!topic/kubernetes-dev/Cjia36v39vM: https://groups.google.com/forum/#!topic/kubernetes-dev/Cjia36v39vM

          [9]

          https://medium.com/@joatmon08/playing-with-kubeadm-in-vagrant-machines-part-2-bac431095706: https://medium.com/@joatmon08/playing-with-kubeadm-in-vagrant-machines-part-2-bac431095706

          [10]

          https://serverfault.com/questions/252723/how-to-find-other-end-of-unix-socket-connection: https://serverfault.com/questions/252723/how-to-find-other-end-of-unix-socket-connection


          原文鏈接:https://izsk.me/2021/01/10/Kubernetes-how-does-kubectl-work/


          你可能還喜歡

          點擊下方圖片即可閱讀

          記一次 Kubernetes 中嚴重的安全問題

          云原生是一種信仰???

          關注公眾號

          后臺回復?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



          點擊?"閱讀原文"?獲取更好的閱讀體驗!


          發(fā)現朋友圈變“安靜”了嗎?

          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99re首页| 三级黄色电影网站 | 日韩黄色在线电影 | 777偷窥盗摄00000 | 插菊综合网 |