K8S之kubelet介绍

2022-03-29 15:55:21 浏览数 (1)

一、总体概述:

一旦Pod被调度到对应的宿主机之后,后续要做的事情就是创建这个Pod,并管理这个Pod的生命周期,这里面包括:Pod的增删改查等操作,在K8S里面这部分功能是通过kubelet 这个核心组件来完成的。

对于一个Pod来说,它里面一般会存在多个容器,每个容器里面可以关联不同的镜像,进而运行不同的程序,如此以来:Pod的创建就需要下面的几个核心事件:

  1. 感知Pod被创建的命令,并清楚的知道这个Pod创建出来的话需要哪一些具体的信息,而这部分信息的获取是kubelet与k8s交互才能获取到的。
  2. kubelet在获取到这部分数据之后,会根据这些资源信息(包括:cpu、mem、network、image等)操作宿主机来完成资源的分配,网络的构建,并下载镜像到本地,进而将pod启动起来。

这就说明kubelet的功能需要分成两类: 一类:k8s进行交互,获取pod相关的数据,监控当前的Pod变化的事件。 二类:kubelet操作当前宿主机的资源信息,并启动Pod。

二、kubelet与K8S交互部分:

kubelet 本身,也是按照“控制器”模式来工作的,工作原理如下所示:

kubelet 的工作核心,就是一个控制循环SyncLoop,驱动这个控制循环运行的事件,包括四种:

代码语言:javascript复制
1.Pod 更新事件
2.Pod 生命周期变化
3.kubelet 本身设置的执行周期
4.定时的清理事件

SyncLoop 需要处理的数据的来源:是kubelet注册到k8s里面的informer获取的。对于kubelet 来说,它启动的时候,要做的第一件事情,就是设置 Listers,也就是注册它所关心的各种事件的 Informer。

kubelet 还负责维护着很多其他的子控制循环,比如 Volume Manager、Image Manager、Node Status Manager 等等,这些控制循环的责任,就是通过控制器模式,完成 kubelet 的某项具体职责。

例如:Node Status Manager,就负责响应 Node 的状态变化,然后将 Node 的状态收集起来,并通过 Heartbeat 的方式上报给 APIServer。CPU Manager,就负责维护该 Node 的 CPU 核的信息,以便在 Pod 通过 cpuset 的方式请求 CPU 核的时候,能够正确地管理 CPU 核的使用量和可用量。 kubelet 通过 Watch 机制,监听了与自己相关的 Pod 对象的变化:

  1. 这个 Watch 的过滤条件是该 Pod 的 nodeName 字段与自己相同,kubelet 会把这些 Pod 的信息缓存在自己的内存里。
  2. 当一个 Pod 完成调度、与一个 Node 绑定起来之后, 这个 Pod 的变化就会触发 kubelet 在控制循环里注册的 Handler,也就是上图中的 HandlePods 部分。
  3. 通过检查该 Pod 在 kubelet 内存里的状态,kubelet 就能够判断出这是一个新调度过来的 Pod,从而触发 Handler 里 ADD 事件对应的处理逻辑。(备注:在具体的处理过程当中,kubelet 会启动一个名叫 Pod Update Worker 的、单独的 Goroutine 来完成对 Pod 的处理工作。)

例如:ADD 事件,kubelet 就会为这个新的 Pod 生成对应的 Pod Status,检查 Pod 所声明使用的 Volume 是不是已经准备好。然后,调用下层的容器运行时,开始创建这个 Pod 所定义的容器。

三、kubelet操作宿主机启动部分

kubelet 调用下层容器运行时的执行过程,并不会直接调用 Docker 的 API,而是通过一组叫作 CRI(Container Runtime Interface,容器运行时接口)的 gRPC 接口来间接执行的。kubelet 实际上就会调用一个叫作 GenericRuntime 的通用组件来发起创建 Pod 的 CRI 请求。Kubernetes 通过虚拟出一个CRI shim(例如:dockershim)让容器项目能够自主开发,进而为k8s提供一个统一的容器抽象层,使得下层容器运行时可以自由地对接进入 Kubernetes 当中。

CRI是Container Runtime Interface(容器运行时接口)的简写,CRI解耦了kubelet与容器运行时,让kubelet无需重新编译就可以支持多种容器运行时,kubelet将通过CRI接口来跟第三方容器运行时进行通信,来操作容器与镜像。实现了 CRI 接口的容器运行时通常称为 CRI shim, 这是一个 gRPC Server,监听在本地的 unix socket 上;而 kubelet 作为 gRPC 的客户端来调用 CRI 接口,来进行Pod 和容器、镜像的生命周期管理。另外,容器运行时需要自己负责管理容器的网络,推荐使用 CNI。

CRI shim 的能力:将 Kubernetes 发出的 CRI 请求,转换成对 containerd 的调用,然后创建出 runC 容器,runC 项目,负责执行设置容器 Namespace、Cgroups 和 chroot 等基础操作的组件的操作。

对于CRI shim来说主要针对的是下面runtimeService和imageService两类操作,Pod运行时会通过调用这些接口来把容器运行起来,如下所示:

例如:kubectl run 创建了一个名叫 foo 的Pod(备注:Pod里面包括了 A、B 两个容器)。这个 Pod 的信息最后来到 kubelet,kubelet 就会按照图中所示的顺序来调用 CRI 接口,这些接口里面会封装好对于cpu、mem、网络等资源的操作,而这部分操作无非就是调用操作系统内核的对应接口来完成。

参考文档:

极客时间:深入剖析 Kubernetes

K8S权威指南第5版

https://blog.csdn.net/alex_yangchuansheng/article/details/119686419

0 人点赞