先看看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}] 匹配