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