本文将从以下几个方面介绍库伯莱创建pod的过程。
Kubernetes调度pod介绍kubelet创建pod代码图解(本文重点介绍)kubelet调用cri创建容器描述(本文重点介绍)通过日志分析kubelet实际创建日志的全过程(本文重点介绍)
Kubernetes调度pod简介kubernetes(以下简称k8s)主要有三种方式来管理(创建)pod:
一种是直接声明创建一个裸pod,另一种是通过控制器声明创建一个pod:例如deployments、replicationcontrollers、daemonsets或replicasets,另一种是static(静态)pod,很少使用。pod的声明文件一般放在对应的kubernetes/manifest目录下,通常用来创建apiserver、controller-manager、scheduler等k8s管理组件的pod。K8s推荐使用控制器管理pod,符合k8s管理pod的习惯,使用k8s相关功能也比较方便,比如弹性伸缩、pod故障自动解除等。我们也以controller管理的pod为例,简单梳理一下k8s下创建和调度pod的流程,如下图所示。
请求客户端apiserver创建副本集。apiserver通过认证、鉴权、准入后,请求的相关信息会持久化到etcdController-manager管理的replicaset控制器中。通过list-watch机制,观察复制集的创建请求。如果通过标签选择器发现集群中与该复制集相关联的pod的当前状态与预期状态不一致,它将进行协调并向apiserver发起pod创建请求。调度器通过list-watch机制找到未绑定的pod,通过预选和优化策略算法,计算出pod最终可以调度的节点,并通过apiserver将数据更新到etcdKubelet。如果通过list-watch在该节点上发现新的pod绑定,将启动创建pod的相关过程。
Kubelet创建pod代码和插图
Kubelet kubelet的介绍有点类似于controller,它通过使用list-watch的相关信息或者轮询本地pod的相关信息和事件来触发相关动作,从而使pod处于& rdquo预期状态& rdquo,并向apiserver报告该节点(主机)和该节点中所有pod的状态信息。
Kubelet与其他控制器不同的是,它是部署在每个节点上的代理,需要处理apiserver和CRI(contain -Runtime -Interface)来管理节点上的容器。因此,它需要通过apiserver观察本地pod的变化,还需要不断轮询pod状态信息,以便及时将状态同步到apiserver。因此,Kubelet的整体工作逻辑是,loop监控各个生产者产生的消息或者定时触发消息来调用相应的消费者(不同的子模块)完成不同的操作。比如watch对apiserver的请求,PLEG(Pod life cycle Event Generator)生成的事件,某个时间触发的任务等。
Kubelet创建并启动pod进程。
kubelet 创建pod代码调用的图示
kubelet创建pod的详细说明1.kubelet将列出并监视命名空间下所有绑定到该节点的pod,并将信息传递到updatechannel中。kubelet的SyncLoop下的syncloop方法(这是Kubelet控制常规事物的主循环函数:同步接收、更新和处理与pod变化相关的信息)会监控多方消息,会监控所有消息源来触发相应的操作。此方法将从以前的listwatch接收updatechannel信息。交给相应的处理程序:如pod创建:调用HandlePodAdditions进行处理,2。搬运舱将由搬运舱附加装置进行分类、判断和检查。调用dispatchWork后,将一个pod的操作分配给podWorkers进行异步操作(pod创建、删除、更新)处理3。异步操作将调用kubelet syncPod (syncPod是用于单个pod同步的事务脚本。)方法,syncpod将在创建pod之前做一些准备工作。a .如果pod updateType是podkill,立即执行并返回(经历pod删除过程)。
B.pod访问检查检查pod是否可以在此节点中运行。
C.向状态管理器更新状态,状态管理器向apiserver报告pod状态。
D.检查网络插件是否就绪。
E.创建和更新pod cgroups配置
F.为pod创建相应的目录:pod目录、卷目录
G.等待pod sepc中的volme被连接/安装。
H.从apiserver获取拉机密
I .调用containerRuntime的SyncPod方法开始创建容器复制代码。
4.4.containerRuntime的SyncPod会做以下主要工作:a .创建沙箱
b.创造短暂的容器
c.创建初始化容器
D.创建普通容器复制代码
关键是创建沙箱,沙箱可以理解为pod的运行环境,业务pod的父容器,k8s中的暂停容器。所有容器都需要在创建之前创建。首先会生成podsandbox配置:比如dnsconfig,podhostname,设置sysctl,cgroups和namespace。
然后会调用CRI(container -runtime -interface)调用底层容器运行时来实际操作容器,然后会调用CNI插件来为容器设置网络。
5.我们来看看创建沙箱的步骤:runpodssandbox(DS * DS * docker service)runpodssandbox一个cri实现?所以在dockershim下,dockershim是一个内置在kubelet中的cri实现,用来连接kubelet和docker,dockershim翻译成docker & quot垫片”,非常生动)。Kubelet通过grp调用所调用的dockershim实现容器的创建和管理。a .调用docker API为沙箱拉映像。(kubelet的沙盒图像:defaultSandboxImage = " k8s.gcr.io/pause:3.2")
B.调用docker创建沙盒容器。
c.创建沙盒检查点。
D.调用docker启动沙盒容器。
e.重写docker生成的resolv.conf文件。
F.为沙盒设置网络。调用cni插件为容器设置网络。
Kubelet调用cri说明我们目前的container -运行时是docker,docker不支持CRI,所以要调用docker操作容器,k8s内置了dockershim来调用docker,可以理解为符合CRI标准的容器运行时。Kubelet通过grpc调用dockershim。收到kubelet的请求后,dockershim将其转换为REST API请求,然后发送给docker daemon。docker守护进程调用docker API,通过组装请求来完成容器的最终创建、启动等相关操作。
这篇文章中有两个地方需要解释:
1为什么会有dockershim?这里有一个小故事。第一,k8s有一定市场规模后,想和docker脱钩,但又不想强烈依赖docker。同时,为了支持各种container -运行时,它制定了CRI。只有遇到CRI,kubelet才能直接完成调用来管理容器。但是docker一开始并不支持CRI,于是k8s想到了这个办法,开发了一个dockershim(docker“垫片”)来转发请求,于是k8s也完成了docker的解耦。当然,这看起来很麻烦,而且会影响性能。所以在kubernetes 1.24之后,kubernetes宣布启用dockershim,我们需要在这个版本之后主动配置container -运行时。
2.docker也很早就做出了回应。docker推出了支持CRI标准的containerd,并通过containerd管理容器。
所以如下图所示,在调用docker API创建容器后,docker还会调用docker-containerd来管理容器的创建。docker-containerd通过docker-containerd-shim间接管理容器,所以一个好处就是升级或者重启docker。我们的业务容器仍然可以正常运行。最后,docker-containerd-shim通过runc创建了容器。runc是docker做的基于oci的实现,是以前的libcontainer,用于容器创建。
Kubelet创建pod的整体架构图(container -runtime = & quot;docker & quot,目前大多数企业应该使用这种方法)
库伯莱创建pod日志说明,通过实战,打开调试日志,我们可以看到库伯莱在创建pod时做了什么。
注意:日志只保留主输出和过滤的敏感信息。
1.收到新的pod创建时间后,将其写入update channel channel I 0921 18:10:00.486345 26075 config . go:414]接收新的pod“ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;
2.syncLoop:收到添加事件I 0921 18:10:00.757557 26075 kube let . go:2007]sync loop(Add," api & quot):ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)
3.访问验证pod拟合成功I 0921 18:10:00 759786 26075预测。go:986]pod:ops lk 1-xxxfitsuccess . node:xx . xx . 10.9资源丰富。
4.转移到syncPod,sync pod type = create i0921 18:10:00.759956 26075 ku belet . go:1498]sync pod " xxx-3995-11ed -80a 8-48df 37244930 & quot;updateType:{{ }类型。SyncPodType=create)
5.获取pod状态I 0921 18:10:00.760128 26075 kube let _ pods . go:1529]生成“ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)”的状态I 0921 18:10:00.760148 26075 kube let _ pods . go:1494]pod等待& gt0,pending I 0921 18:10:00.760174 26075 kube let . go:1603]apiPodStatus。阶段:待定窗格:& quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;
6.配置cgroupConfig,设置cpu,内存I 0921 18:10:00.760200 26075 kube let _ resources . go:149]Pod的最新CGroup配置:" ops lk 1-5 sfjn _ lktest 01(739 E1 C1 a -3175-11ed -aff 8-48df 37244926)& quot;are kube let . cgroupresource { CPU shares:XXX,cpuQuota:xxx,memoryLimit:xxx,memoryLimitSwap:xxx}。
7.等待与pod相关的卷连接和装载I 0921 18:10:00.768211 26075 volume _ manager . go:350]等待为POD " ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)连接和装载卷& quot
8.与apiserver同步状态,先GET再Patchi 0921 18:10:00.791361 26075 round _ trippers . go:419]curl -k -v -xget & # 39;https://XXX/API/v1/namespaces/lktest 01/pods/ops lk 1-XXX & # 39;I 0921 18:10:00.794250 26075 round _ trippers . go:419]curl -k -v -x patch & # 39;https://XXX/API/v1/namespaces/lktest 01/pods/ops lk 1-XXX/status & # 39;I 0921 18:10:00.798998 26075 Status _ manager . go:506]pod & quot;ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;已成功更新:(1,{阶段:待定条件:[{类型:已初始化
9.根据预期状态开始调整,调和Pod“Ready & quot;如果必要的话。触发协调的同步窗格。I 0921 18:10:00.799365 26075 kube let . go:2020]sync loop(RECONCILE,& quotapi & quot):& quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;
10 .安装卷10921 18:10:02.177479 26075 operation _ generator . go:506]安装卷。卷& quot的WaitForAttach成功音量& quot设备路径& quot/dev/mapper/docker -XXX _ 3995 _ 11ed _ 80a 8 _ 48df 37244930 & quot;I 0921 18:10:03.136754 26075 operation _ generator . go:527]mount volume。卷& quot的MountDevice成功音量& quot设备安装路径& quot/export/kube let/pods/xxx-3995-11ed -80a 8-48df 37244930/volumes/kubernetes . io ~ LVM/volume & quot;I 0921 18:10:03.136851 26075 operation _ generator . go:567]挂载卷。卷& quot的安装成功音量& quot(唯一名称:& quotflex volume -kubernetes . io/LVM/XXX _ 3995 _ 11ed _ 80a 8 _ 48df 37244930 & quot;)pod & quotops lk 1-XXX & quot;
1.卷已连接,已安装完成I 0921 18:10:03.168555 26075 volume _ manager . go:384]所有卷都已连接并安装到pod " ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;
12.调用containerRuntime的SyncPod方法开始创建容器I 0921 18:10:03.168568 26075 kuberruntime _ manager . go:468]syncing pod " ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;:& ampPod{}
13.创建沙盒容器:设置cgroup parent,runpodsandbox,调用网络插件CNI设置podi 0921 18:10:03.168833 26075 kuberruntime _ manager . go:398]没有pod的沙盒" ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;都能找到。需要重新开始& quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;I 0921 18:10:03.168885 26075 kuberuntime _ manager . go:605]sync pod收到新的pod & quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;,将为iti 0921 18:10:03 . 168891 26075 kuberuntime _ manager . go:614]为& quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;,将启动新的one i0921 18:10:03.168901 26075 kuberuntime _ manager . go:841]停止pod的应用程序容器:& quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;. I 0921 18:10:03.168913 26075 kuberuntime _ manager . go:666]为pod & quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;I 0921 18:10:03.170818 26075 docker _ service . go:460]将cgroup parent设置为:& quot/kube pods/burstable/pod xxx-3995-11ed -80a 8-48df 37244930 & quot;I 0921 18:10:03.170827 26075 docker _ sandbox . go:108]runpod sandbox pod name:opslk 1-XXX PodUID:xxx-3995-11ed -80a 8-48df 37244930 NameSpace:lktest 01 I 0921 18:10:04.297831 26075 plugins . go:377]调用网络插件cni设置podops lk 1-XXX _ lktest 01 & quot;I 0921 18:10:04.298323 26075 manager . go:1011]已添加容器:& quot/kube pods/burst able/pod xxx-3995-11ed -80a 8-48df 37244930/805 DDA 102 e 017247685240 C2 f 740295396 edcb 7071 dfe 211979215 EAC 0870 e0b & quot;I 0921 18:10:04.298535 26075 container . go:448]开始整理集装箱& quot/kube pods/burst able/pod xxx-3995-11ed -80a 8-48df 37244930/805 DDA 102 e 017247685240 C2 f 740295396 edcb 7071 dfe 211979215 EAC 0870 e0b & quot;I 0921 18:10:04.298693 26075 CNI . go:337]获取netns路径/proc/26876/ns/neti 0921 18:10:04.298701 26075 CNI . go:338]使用podns路径lktest 01 I 0921 18:04.298820 26075 CNI . go:307]关于添加805 DDA 102 e 017247685240 C2 f 740295396 edcb 7071 dfe 211979215 EAC 0870 e0b & quot;对于pod & quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;I 0921 18:10:04.396981 26075 kuberuntime _ manager . go:699]确定了ip & quotxx . xx . 226.17 & quot;对于pod & quotops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)& quot;沙盒更改后
14.创建常规容器I 0921 18:10:04.397114 26075 kuberruntime _ manager . go:750]在pod ops lk 1-XXX _ lktest 01(xxx-3995-11ed -80a 8-48df 37244930)I 0921 18:10:04.398859 26075 kuberruntime _ Container . go:108v1。object reference { Kind:& quot;Pod & quot,命名空间:& quotlktest01 & quot,名称:& quotops lk 1-XXX & quot;} I 0921 18:10:04.398883 26075 kuberuntime _ container . go:117]确定是否重启旧容器。pod:ops lk 1-XXX _ lktest 01 PodIP:podsboxid:NameSpace:lktest 01 I 0921 18:10:04.398888 26075 kuber untime _ container . go:258]pod:ops lk 1-XXX默认KeepRootDirForPod:true i0921 18:10:04.398935 26075 server . go:471]事件(v1 .object reference { Kind:& quot;Pod & quot,命名空间:& quotlktest01 & quot,名称:& quotops lk 1-XXX & quot;,UID:& quot;xxx-3995-11ed -80a 8-48df 37244930 & quot;,API version:& quot;v1 & quot,资源版本:& quot19846024411 & quot,field path:& quot;规格容器{ opslk } & quot})
这是kubelet的pod创建过程的代码图和日志描述的细节。更多kubelet的pod创建过程,请关注主机频道zhujipindao的其他相关文章。com!
评论前必须登录!
注册