一、基本功能

(1)Kubelet的工作内容

Kubelet是唯一一直作为常规系统组件来运行的组件,他的工作就是创建Pod实例并监控。当Schedule选择好要调度的节点,并通过Api-Server更新Pod资源的定义信息后,目标节点的Kubelet会监听到Api-Server发来的通知,然后创建并运行Pod的容器。随后他会持续监控运行的容器,实时向Api-Server报告他们的状态、事件和资源消耗。

Kubelet也是运行容器存活探针的组件,当探针报错时,他会重启容器。最后一点,当Pod从Api-Server删除时,Kubelet会终止容器,并通知Api-Server,Pod已经被终止了。

Kubelet运行静态Pod

前面我们说到,Kubelet在哪创建什么Pod完全是由Api-Server通知给他的。实际上他还能主动的创建Pod,它可以通过本地指定目录下的Pod资源清单来运行Pod。这也就解释了前面埋的点,为什么可以提前以Pod的形式部署Control Plane的组件。

在kubernetes集群中,每个Node节点(又称Minion)上都会启动一个kubelet服务进程。该进程用于处理Master节点下发到本节点的任务,管理Pod和其中的容器。每个kubelet进程会在API Server上注册节点自身信息,定期向Master节点汇报节点资源的使用情况,并通过cAdvisor监控容器和节点资源。


二、Kubelet和容器交互

在 Kubernetes1.5 之前 Docker 作为第一个容器运行时,Kubelet 通过内嵌 dockershim操作容器API,在 v1.6.0 后, Kubernetes开始默认启用 CRI(容器运行时接口)。

 CRI 为 kubelet 提供一套抽象的容器调度的接口,CRI 主要承接 kubelet 对容器的操作。CRI 得通信协议是 gRPC,当时主要考虑到性能问题。加入 CRI 后 kubelet 的架构如下图所示。

Kubernetes底层原理 五  kubelet_Server

kubelet 启动时便会初始化 CRI 客户端 ,与容器运行时建立连接并确认 CRI 的版本。CRI 容器运行时主要描述了三种服务的行为 Sandbox、Container、Image。

创建 pod 的过程中,都会通过 CRI 与容器运行时进行交互

创建 sandbox

创建容器

拉取镜像

CRI 提供了一种标准化的接口,用于与底层容器运行时进行交互。这对与发展和状大 Kubernetes 生态系统非常重要:

Kubernetes 控制平面与容器管理的具体实现解耦,可以独立升级或者切换容器运行时,方便扩展和优化。

Kubernetes 作为一个跨云、跨平台和多环境的容器编排系统,在不同的环境和场景下使用不同的容器平台。CRI 的出现,保证平台的多样性和灵活性。

CRI接口可以分为两组:

  • RuntimeService:主要是跟容器相关的操作,比如创建、启动、删除容器,执行exec命令等
  • ImageManagerService:主要是容器镜像相关的操作,比如拉取镜像、删除镜像等

Kubernetes底层原理 五  kubelet_Server_02

CRI设计的一个重要原则,就是确保这个接口本身,只关注容器,不关注Pod,在CRI的设计里并没有一个直接创建Pod或者启动Pod的接口

三、节点管理

通过设置kubelet的启动参数“--register-node”,来决定是否自动主动地向API Server注册自己,默认为true。

当前每个kubelet被授予创建和修改任务节点的权限,但实践中,它仅仅创建和修改自己。未来将会限制这一权限,仅允许它修改和创建其所在节点的权限。

在集群运行过程中,如果遇到资源不足的情况,则用户很容易通过添加机器及利用kubelet的自注册模式来实现扩容。

如果系统管理员希望手动创建节点信息,则可以通过设置--register-node=false即可。

四、Pod管理

kubelet通过以下几种方式获取自身Node上所需要运行的Pod清单。

文件:kubelet启动参数"--config"指定的配置文件目录下的文件,通过--file-check-frequency设置检查该文件目录的时间间隔,默认为20s。

HTTP端点(URL):通过"--manifest-url"参数设置,通过--http-check-frequency设置检查时间间隔,默认为20s。

API Server:kubelet通过API Server监听etcd目录,同步Pod列表。

kubelet监听etcd,所以针对Pod的操作将会被kubelet监听到。如果发现有新的绑定到本节点的Pod,则按照Pod清单的要求创建该Pod。


如果发现本地Pod被修改,则kubelet会做出相应的修改,比如删除Pod中的某个容器时,则通过Docker Client删除该容器。

如果发现删除本节点的Pod,则删除相应的Pod,并通过Docker Client删除Pod中的容器。

kubelet读取监听到的信息,如果是创建和修改Pod任务,则做如下处理:

1)为该Pod创建一个数据目录。

2)从API Server读取该Pod清单。

3)为该Pod挂载外部卷(External Volume)

4)下载Pod用到的Secret。

5)检查已运行在节点中的Pod,如果该Pod没有容器或Pause容器没有启动,则先停止Pod里所有容器的进程。如果在Pod中有需要删除的容器,则删除这些容器。

6)用"kubernetes/pause"镜像为每个Pod创建一个容器。该Pause容器用于接管Pod中所有其它容器的网络。

7)为Pod中的每个容器做如下处理:

为容器计算一个hash值,然后用容器的名字去查询对应Docker容器的hash值。这里的hash值可以理解为是依据容器的定义文件所生成的。对比两个hash值,发现有不同则会停止Docker中容器的进程,并停止与之关联的Pause容器的进程。若二者相同,则不做任何处理。

如果容器被终止了,且没有指定restartPolicy重启策略,则不做任何处理。

调用Docker Client下载容器镜像,调用Docker Client运行容器。

五、容器健康状态检查

LivenessProbe

用于判断容器是否存活(running状态)。

如果LivenessProbe探针探测到容器非健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应处理。

如果容器不包含LivenessProbe探针,则kubelet认为该探针的返回值永远为“success”。

ReadinessProbe

  • 用于判断容器是否启动完成(read状态),可以接受请求。
  • 如果ReadnessProbe探针检测失败,则Pod的状态将被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的Endpoint。