1. 概述kubelet运行机制分析
在Kubernetes集群中,每个Node节点(又称Minion)上都会启动一个Kubelet服务进行。该进程用于处理Master节点下发到本节点的任务,管理Pod及Pod中的容器。每个Kubelet进程会在API Server上注册节点自身信息,定期向Master节点汇报节点资源的使用情况,并通过cAdvise监控容器和节点资源。
1.1. 节点管理
节点通过设置Kubelet的启动参数“--register-node”,来决定是否想API Server注册自己。如果该参数值为true,那么Kubelet将试着通过API Server注册自己。作为自注册,Kubelet启动时还包含下列参数:
--api-servers Master节点API Server的位置;
--kubeconfig 告诉Kubelet在哪儿可以找到用于访问API Server的证书;
--cloud-provider 告诉Kubelet如何从云服务商(IAAS)哪里读取到和自己相关的元数据
当前每个Kubelet被授予创建和修改任何节点的权限。但是在实践中,它仅仅创建和修改自己。
Kubelet在启动时通过API Server注册节点信息,并定时向API Server发送节点新消息,API Server在接收到这些信息后,将这些信息写入etcd。通过Kubelet的启动参数“--node-status-update-frequency”设置Kubelet每隔多少时间向API Server报告节点状态,默认为10秒。
1.2. Pod管理
kubelet有几种方式获取自身Node上所需要运行的Pod清单。但本文只讨论通过API Server监听etcd目录,同步Pod列表的方式。
kubelet通过API Server Client使用WatchAndList的方式监听etcd中/registry/nodes/${当前节点名称}和/registry/pods的目录,将获取的信息同步到本地缓存中。
kubelet监听etcd,执行对Pod的操作,对容器的操作则是通过Docker Client执行,例如启动删除容器等。
kubelet创建和修改Pod流程:
为该Pod创建一个数据目录。
从API Server读取该Pod清单。
为该Pod挂载外部卷(External Volume)
下载Pod用到的Secret。
检查运行的Pod,执行Pod中未完成的任务。
-
先创建一个Pause容器,该容器接管Pod的网络,再创建其他容器。Pod中容器的处理流程:
- 比较容器hash值并做相应处理。
- 如果容器被终止了且没有指定重启策略,则不做任何处理。
- 调用Docker Client下载容器镜像,调用Docker Client运行容器。
为Pod中的每个容器做如下处理:
为容器计算一个hash值,然后用容器的名字去Docker查询对应容器的hash值。若查到容器,且两者hash值不同,则停止Docker中容器的进程,并停止与之关联的Pause容器进程;若两者相同,则不做任何处理;
如果容器被终止了,且容器没有指定的restartPolicy(重启策略),则不做任何处理;
调用Docker Client下载容器镜像,调用Docker Client运行容器。
1.3. 容器健康检查
Pod通过两类探针来检查容器的健康状态。
一个是LivenessProbe探针,用于判断容器是否健康,告诉Kubelet一个容器什么时候处于不健康的状态。如果LivenessProbe探针探测到容器不健康,则Kubelet将删除该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含LivenessProbe探针,那么Kubelet认为该容器的LivenessProbe探针返回的值永远是”Seccess“;
另一类是ReadinessProbe探针,用于判断容器是否启动完成,且准备接受请求。如果ReadinessProbe探针检测到失败,则Pod的状态将被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的IP地址的Endpoint条目。
Kubelet定期调用容器的LivenessProbe探针来诊断容器的健康状况。LivenessProbe包好一下三种实现方式:
ExecAction:在容器内部执行一个命令,如果该命令的退出状态吗为0,则表示容器健康。
TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,如果端口能被访问,则表示容器健康。
HTTPGetAction:通过容器的IP地址和端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于等于400,则认为容器状态健康。
LivenessProbe探针包含在Pod定义的spec.containers.{某个容器}中。
1.4. cAdvisor资源监控
cAdvisor是一个开源的分析容器资源使用率和性能特性的代理工具。它是因为容器而产生的,因此自然支持Docker容器。在Kubernetes项目中,cAdvisor被集成到Kubernetes代码中。cAdvisor自动查找所有在其所在节点上的容器,自动采集CPU、内存、文件系统和网络使用的统计信息。cAdvisor通过它所在节点机的Root容器,采集并分析该节点机的全面的使用情况。
2. 结构分析
如下图所示,Kubelet正常运行。 除了需要包含自身模块外,还会依赖部分第三方模块协同工作。
- Apiserver观察者是kubelet创建的,作为和Apiserver连结的通道。以将本地的状态信息向集群同步和获取集群整体配置信息。
- 本地数据管理,是将收集到的数据在本地内存中进行维护使用。
- 本地数据采集是依赖于第三方的如cadvisor模块收集管理的。
- 具体的容器化是由docker或rkt管理。
- kubelet的 管理模块集合 主要是负责将本地采集到的数据同步到集群和根据获取到的集群配置信息对本地的容器等实体进行管理。
3.流程分析
如下图所示
- kubelet启动流程首先获取命令行参数
- 尝试加载配置文件
- 创建连接apiserver的client
- NewMainKubelet 创建本节点的各个资源管理,主要是pod的管理
- BirthCry 通知集群该kubelet上线
- StartGarbageCollection 创建垃圾回收服务
- startKubelet 启动kubelet业务
- 创建协程执行 ListenAndServe 监听外部的http请求
- 创建协程执行run并调用 syncLoop循环监听Apiserver的配置变化
- 当接收到Apiserver的变化信息时,以添加pod为例
- 调用distpatchWork 创建 pod
- 调用probeManager的add为该pod添加存活检查支持