Kubernetes 從提交 deployment 到 pod 運(yùn)行的全過程
當(dāng)用戶向 Kubernetes 提交了一個(gè)創(chuàng)建 deployment 的請(qǐng)求后,Kubernetes 從接收請(qǐng)求直至創(chuàng)建對(duì)應(yīng)的 pod 運(yùn)行這整個(gè)過程中都發(fā)生了什么呢?
kubernetes 架構(gòu)簡(jiǎn)述
在搞清楚從 deployment 提交到 pod 運(yùn)行整個(gè)過程之前,我們有先來看看 Kubernetes 的集群架構(gòu):
上圖與下圖相同:
如圖所示,k8s 集群分為 control plane 控制平面和 node 節(jié)點(diǎn)。
control plane 控制平面(也稱之為主節(jié)點(diǎn))主要包含以下組件:
- kube-api-server: 顧名思義,負(fù)責(zé)處理所有 api,包括客戶端以及集群內(nèi)部組件的請(qǐng)求。
- etcd: 分布式持久化存儲(chǔ)、事件訂閱通知。只有 kube-api-server 直接操作 etcd,其它所有組件都是與 kube-api-server 進(jìn)行相互。
- scheduler: 處理 pod 的調(diào)度,將 pod 綁定到具體的 node 節(jié)點(diǎn)。
- controller manager: 控制器,處理各種資源對(duì)象。
- cloud controller manager: 對(duì)接云服務(wù)商的控制器。
node 節(jié)點(diǎn),專門部署用戶的應(yīng)用程序(與控制平面隔離,避免影響到 k8s 的核心組件),主要包含以下組件:
- kubelet: 管理節(jié)點(diǎn)上的 pod 以及狀態(tài)檢查和上報(bào)。
- kube-proxy: 進(jìn)行流量的路由轉(zhuǎn)發(fā)(目前是通過操作節(jié)點(diǎn)的 iptables 或者 ipvs 實(shí)現(xiàn))。
- CRI: 容器運(yùn)行時(shí)接口。
從 Deployment 到 Pod
從 Deployment 到 Pod 的整個(gè)過程如下圖所示:
1. 請(qǐng)求發(fā)送到 kube-api-server
請(qǐng)求發(fā)送到 kube-api-server,然后會(huì)進(jìn)行認(rèn)證、鑒權(quán)、變更、校驗(yàn)等一系列過程,最后將 deployment 的數(shù)據(jù)持久化存儲(chǔ)至 etcd。
在這個(gè)過程我們可以通過 mutation admission 的 webhook 自主地對(duì)資源對(duì)象進(jìn)行任意的變更,比如注入 sidecar 等等。
2. controller manager 處理
controller manager 組件針對(duì)不同的資源對(duì)象有不同的處理部分。
針對(duì) Deployment,由于其并不直接管理 Pod,而是 Deployment 管理 ReplicaSet,ReplicaSet 再管理 Pod:
因此其中涉及到 controller manager 中的兩個(gè)部分:
- deployment controller
- replicaset controller
(1) 先是 deployment controller 監(jiān)聽到 deployment 的創(chuàng)建事件,然后進(jìn)行相關(guān)的處理,最后創(chuàng)建 replicaset。
(2) 然后 replicaset controller 監(jiān)聽到 replicaset 的創(chuàng)建事件,進(jìn)行相關(guān)處理后,最后創(chuàng)建 pod。
3. scheduler 調(diào)度
scheduler 接受到 pod 需要調(diào)度的事件后,進(jìn)行一系列調(diào)度邏輯處理,最后選擇一個(gè)合適的 node 節(jié)點(diǎn),將 pod 綁定到這個(gè)節(jié)點(diǎn)上(所謂的節(jié)點(diǎn)調(diào)度在這里只是修改 pod 數(shù)據(jù),對(duì)其中的 nodeName 進(jìn)行賦值)。
具體的調(diào)度算法比較復(fù)雜,涉及強(qiáng)制性調(diào)度、親和與反親和、污點(diǎn)和容忍、以及硬件資源計(jì)算、優(yōu)先級(jí)等等,本文不做展開。
4. 節(jié)點(diǎn) kubelet 處理
調(diào)度完成后,pod 被綁定的 node 節(jié)點(diǎn)上的 kubelet 同樣通過 kube-api-server 會(huì)接受到相應(yīng)的事件,然后 kubelet 會(huì)進(jìn)行 pod 的創(chuàng)建。
在這個(gè)過程中 kubelet 會(huì)分別調(diào)用 CRI、CNI、CSI:
- CRI(Container Runtime Interface): 容器運(yùn)行時(shí)接口,CRI 插件負(fù)責(zé)執(zhí)行拉取鏡像、創(chuàng)建、刪除容器等操作。CRI 的幾種常用插件:
- containerd
- CRI-O
- Docker Engine
- CNI(Container Network Interface): 容器網(wǎng)絡(luò)接口,CNI 插件負(fù)責(zé)給 pod 分配 IP 地址,確保 pod 能夠與集群內(nèi)的其它 pod 進(jìn)行通信。CNI 的幾種常用插件:
- Cilium
- Calico
- CSI(Container Storage Interface): 容器存儲(chǔ)接口,CSI 插件負(fù)責(zé)與外部存儲(chǔ)提供者通信,執(zhí)行卷的附加、掛載等操作。
所謂的接口其實(shí)只是定義了通信的規(guī)范或者標(biāo)準(zhǔn)(使用的是 grpc 協(xié)議),具體的實(shí)現(xiàn)則是交給了插件。
至此,Kubernetes 從創(chuàng)建 deployment 到 pod 運(yùn)行的全過程就是這樣了。