先看看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接收的方式有三種:
第二種方式是設置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。
貼一下兩個服務的protobuf客戶端請求接口:

CRI工作流程圖
一個單塊的容器運行時能夠管理鏡像和容器(例如:Docker和Rkt),並且通過同一個套接字同時提供這兩種服務。這個套接字可以在Kubelet里通過標識–container-runtime-endpoint和–image-service-endpoint進行設置。
k8s默認是使用docker,如果需要更改,需要修改 kubelet 啟動參數:
還有配置文件/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}] 匹配