kubelet是在每个 Node 节点(包括master节点)上运行的主要 “节点代理”,默认监听10250端口,kubelet主要完成如下一些任务。
每个kubelet进程会在API server上注册节点信息,定期向master节点汇报几点资源使用情况,并通过cAdvisor监控节点和容器的资源。其中pod管理中主要包含获取Pod清单信息,kubelet获取pod清单信息主要通过三种方式
1.文件(File):kubelet周期性地监视此路径下的文件是否有更新。 监视周期默认为 20s,且可通过参数进行配置。启动参数--config指定配置目录下的文件(默认是/etc/Kubernetes/manifests/),该文件每隔20s检查一次。
2.HTTP 端点(HTTP endpoint):利用命令行参数指定 HTTP 端点。 此端点的监视周期默认为 20 秒,也可以使用参数进行配置。
3.HTTP 服务器(HTTP server):kubelet 还可以侦听 HTTP 并响应简单的 API (目前没有完整规范)来提交新的清单。
4.API Server:通过API Server监听etcd目录,同步pod清单。
接下来看看静态文件方式,通过命令ps -ef | grep kubelet 查看进程的配置文件地址
查看该配置文件,可以看到有staticPodPath目录,查看该目录可以看到一些pod的yaml文件,这些pod都是运行在集群上pod,kubelet可以通过获取该目录下文件达到控制pod的目的。
节点管理主要包括节点自注册和节点状态更新,有三种方式管理节点
1.kubelet可以通过设置启动参数--register-node来确定是否向API Server注册自己
2.如果kubelet没有选择自注册模式,则需要用户配置Node资源信息,同时告知kubelet集群上API Server的位置
3.kubelet启动时通过API Server注册节点信息,并定时向API Server发送节点新信息,API Server在接收到信息后,将信息写入etcd。
Kubelet是核心组件之一,那么在pod启动过程中,kubelet是如何协助完成pod创建的呢?具体如下图所示(备注下图来源于训练营课程课件)
1.APIServer接收到创建pod的请求,将该请求写入etcd
2.Scheduler通过watch(new pod)的方式监听APIServer的请求,当发现有new pod请求时,给pod寻找合适的node,并将这些信息与pod绑定,即bindpod。
3.APIServer收到bindpod信息后,写入etcd
4.Kubelet通过watch(bound pod)方式监听APIServer的请求,当发现有bound pod请求时,调用Containerd(Container Runtime Interface)启动Sandbox pod,然后拉去pod的image,创建和启动container,在启动Sandbox容器进程时,Containerd调用网络插件为pod添加网络配置。
通过上图可以发现在启动pod过程中还启动了一个sandbox容器进程,那么该容器进程在哪里启动的,为什么要启动该进程呢?通过命令查看pod启动的容器进程信息 docker ps|grep podname,如下图所示,查看nginx pod的容器进程,nginx pod的状态是1/1,说明pod中定义的container个数是1,但是查看容器进程,可以看到是2个,上面这个就是sandbox容器进程
为什么要启动sandbox容器进程呢?如其名称一样,sandbox的作用是为应用提供隔离稳定的环境,这里的sandbox也是起到这个作用。例如如下场景
场景一:pod启动后,会调用系统命令cgroup相关实现Resource limit的属性设置,如果pod启动后,container发生了重启,如果不保存这些信息,那么container重启后又需要调用系统命令完成资源限制控制,这些都是对系统资源的消耗,故有了sandbox可以减少调用系统命令频率
场景二:pod在启动过程中需要设置网络信息,如果有sandbox那么可以提前设置网络配置进行保存,在pod启动过程中,就可以更快的启动pod。
以上就是启动sandbox容器进程的原因,为了更好的理解pod启动流程,下图是一个pod启动过程中涉及的task list(备注:下图来源于训练营课程课件),通过下图可以更好的理解pod启动过程。