K8s-kubelet如何啟動一個pod


先看看k8s中pod創建流程:

1、客戶端提交創建請求,通過API Server的Restful API,或者用kubectl命令行工具。支持的數據類型包括JSON和YAML。

2、API Server處理用戶請求,存儲Pod數據到etcd。

3、kube-scheduler通過API Server查看未綁定的Pod。嘗試為Pod分配主機。

4、kube-scheduler通過預選算法過濾掉不符合要求的主機。比如Pod指定了所需要的資源量,那么可用資源比Pod需要的資源量少的主機會被過濾掉,端口被占用的也被過濾掉;

5、kube-scheduler通過優選算法給主機打分,對預選篩選出的符合要求的主機進行打分,在主機打分階段,調度器會考慮一些整體優化策略,比如把一個deployment類型的pod分布到不同的主機上,使得資源均衡;或者將兩個親和的服務分配到同一個主機上。

6、選擇主機:選擇打分最高的主機,進行binding(調用apiserver將pod和node綁定)操作,結果存儲到etcd中。

7、kubelet監聽Api Server,根據調度結果執行Pod創建操作:綁定成功后,scheduler會調用API Server的API在etcd中創建一個bound pod對象,描述在一個工作節點上綁定運行的所有pod信息。運行在每個工作節點上的kubelet也會定期與etcd同步bound pod信息,一旦發現應該在該工作節點上運行的bound pod對象沒有更新,則調用Docker API創建並啟動pod內的容器。

8、kubelet調用CNI(Docker 運行或通過 rkt)運行 Pod 的容器。並周期性的對容器生命周期進行探測。(健康檢查readness-隔離、liveness-重啟)

kubelet的整體架構圖

 

 

 

kubelet啟動時,將前面組件一個個啟動,最后主函數SyncLoop負責監控pod的狀態,當接收到請求就會執行添加,更新,刪除等等操作.

添加一個pod流程

以下通過源碼邏輯圖來展示

首先,要啟動一個pod必須先創建PodConfig,在啟動時,創建Kubelet的時候創建,PodConfig.Updates是一個chan,接收pod和指令.

 

 

 

其次,PodConfig.Updates接收的方式有三種:

        第一種方式是通過pod文件來創建,默認是在"/etc/kubernetes/manifests/",只要檢查到里面有pod文件就會生成pod和指令.

        第二種方式是設置http的url,通過url獲取到數據來生成pod和指令.

 

上面兩種方式生成的叫static pod,kubulet會將static pod的狀態匯報給api server,api server為該static pod創建一個mirror pod與之匹配.

static pod資料:[www.cnblogs.com/leaderjs/p/…]

        第三種方式是通過apiserver監聽etcd目錄,當從apiserver獲取到pod和指令時,將pod和指令經過Merge等操作,最后傳送到PodConfig.Updates.



 

 

 

開頭說的,一直循環的syncLoop會一直監聽,當PodConfig.Updates獲取到pod和添加指令,就會傳送到上圖的configCh中,判斷u.Op是一個添加指令,就會執行handler.HandlerPodAddtions(u.Pods)函數.

然后,掛載pod所需要的volumes,下載pod的secret, ...... ,通過docker/rkt來運行pod中的容器,kubelet 會通過 CRI 調用 container runtime 創建 pod 中的 container。

如上圖函數調用,每個操作的最后一步都是發送grpc的請求出去,那這些請求去了哪里?

 

kubelet調用CPI流程


 

 

kubelet的兩個gRPC服務

ImageService提供了從鏡像倉庫拉取、查看、和移除鏡像的RPC。

RuntimeSerivce包含了Pods和容器生命周期管理的RPC,以及跟容器交互的調用(exec/attach/port-forward)。

貼一下兩個服務的protobuf客戶端請求接口:

 

 

 

 

 

CRI工作流程圖

 

 

一個單塊的容器運行時能夠管理鏡像和容器(例如:Docker和Rkt),並且通過同一個套接字同時提供這兩種服務。這個套接字可以在Kubelet里通過標識–container-runtime-endpoint和–image-service-endpoint進行設置。

k8s默認是使用docker,如果需要更改,需要修改 kubelet 啟動參數:

Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock" 

還有配置文件/etc/containerd/config.toml

 

在 K8s 中創建 RuntimeClass(以kata為例)

apiVersion: node.k8s.io/v1beta1  # RuntimeClass is defined in the node.k8s.io API group
kind: RuntimeClass 
metadata:
  name: kata  
handler: kata  # 這里與containerd配置文件中的 [plugins.cri.containerd.runtimes.{handler}] 匹配

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM