本文将从如下方面介绍kubelet创建pod的过程,kubernetes(后面简称k8s)主要有三种管理(创建)pod的方式:,k8s推荐使用controller来管理pod,这符合k8s管理pod的习惯,便于使用k8s相关功能,比如弹性扩缩容,pod故障自动拉起等。 我们也以controller管理的pod为例,简单梳理下k8s创建及调度pod流程,如下图,,Kubelet 有点和controller类似,也是通过list-watch相关信息,或者轮询本地pod相关信息及事件,来触发相关动作,使pod处于”期望状态”,并且向apiserver上报本node(宿主机)及node里所有pod的状态信息。,kubelet 不同于其他controller的一点就是,它是部署在每个node节点上的agent,它需要与apiserver 打交道同样也需要与cri(contain-runtime-interface)打交道来管理node上的容器。所以它需要通过apiserver来watch到对本地pod变更的事件,也需要不断轮询pod状态信息,将状态及时同步给apiserver,所以Kubelet整体工作逻辑是loop监听各类生产者产生的消息或者定时触发消息,来调用相应的消费者(不同的子模块)完成不同的操作,比如watch 到apiserver的请求,PLEG(pod lifecycle event generator)产生的事件,定时触发的任务等,,a.如果pod updateType 为podkill,立即执行并返回(走pod删除流程),b.pod准入检查检查pod是否能运行在本节点,c.更新状态给 status manager ,status manager将pod状态上报给apiserver,d.检查网络插件是否就绪,e.创建并更新pod cgroups配置,f.为pod创建对应的目录:pod目录,volume目录,g.等待pod sepc中的volme都被attach/mount,h.从apiserver中获取pull secrets,i.调用 containerRuntime 的 SyncPod 方法开始创建容器
复制代码,其中创建sandbox是关键,sandbox可以理解为pod的运行环境,是业务pod的父容器,在k8s里就是pause 容器,所有容器创建前都需要创建pause容器。首先会生成podsandbox相关配置:如dnsconfig,podhostname,设置sysctl,cgroups以及namespace,然后会调用CRI(container-runtime-interface)来调用底层container runtime来真实操作容器,之后还会调用CNI插件来为容器设置网络。,我们目前container-runtime为docker,docker并不支持CRI,所以要想调用docker 操作容器,k8s内置了dockershim来调用docker,dockershim可以理解为一个满足CRI标准的容器运行时,kubelet通过grpc call 来调用dockershim,dockershim收到kubelet的请求后,将其转化为REST API请求,再发送给docker daemon,docker daemon 在通过组装请求,调用docker API来完成container的最终创建、启动等相关操作。,这块有两个地方需要说明下:,1是为啥会有dockershim? 这里有个小故事,首先k8s再具有一定市场规模后,想与docker 解耦,不想强依赖docker,同时为了支持多种container-runtime,故制定了CRI,只有满足CRI,kubelet便可以直接完成调用来管理container,然而docker一开始并不支持CRI,故k8s想了个这种的方式,开发了一个dockershim(docker "垫片")来转发请求,这样k8s也完成了对docker的解耦,当然这看起来较繁琐且影响性能,故在kubernetes 1.24后,kubernetes宣布启用dockershim,需要我们在该版本后主动配置container-runtime。,2.docker这面也很早就做了应对,docker抽离出了支持CRI标准的containerd,通过containerd来管理容器。,所以如下图,调用docker API创建容器后,docker还会调用docker-containerd来管理创建容器,docker-containerd通过docker-containerd-shim来间接管理container,这样一个好处就是升级或重启docker,我们的业务容器依然可以正常运行,最终docker-containerd-shim通过runc来创建container,runc是docker做的基于oci的实现就是以前的libcontainer,用于容器创建。,,我们通过实战,开启debug日志来看下kubelet在创建pod时做了哪些工作,注:日志仅保留主要输出及过滤敏感信息,以上就是详解kubelet 创建pod流程代码图解及日志说明的详细内容,更多关于kubelet创建pod流程的资料请关注其它相关文章!