前言

作为云原生的从业人员,k8s是不可逾越的一座大山。笔者经过一年有余的k8s操作实践后,决定定期阅读分析k8s源码,以加深对这门技术的理解和应用。本文在编写前参考了kubelet 启动流程分析,这篇文章对于kubelet的源码有比较清晰的介绍,笔者第一遍的kubelet源码阅读,是参照这篇文章梳理的脉络逐步进行的。这篇文章的行文思路和文章结构也可以让新入手的读者能够对整个kubelet的源码轮廓有清晰的认知。笔者写作的目的是为了梳理自己在阅读源码中的一些心得体会,期望能够在字里行间能够带给大家一些感悟。

何为kubelet

kubelet 是在每个节点上运行的主要 “节点代理”。它可以使用以下方式之一向 API 服务器注册:

  • 主机名(hostname);
  • 覆盖主机名的参数;
  • 特定于某云驱动的逻辑,云端产商提供的注册方式 kubelet 是基于 PodSpec 来工作的。每个 PodSpec 是一个描述 Pod 的 YAML 或 JSON 对象。 kubelet 接受通过各种机制(主要是通过 apiserver)提供的一组 PodSpec,并确保这些 PodSpec 中描述的容器处于运行状态且运行状况良好。

kubelet 不管理不是由 Kubernetes 创建的容器。 除了来自 API 服务器的 PodSpec 之外,还可以通过以下两种方式将容器清单(manifest)提供给 kubelet。

  • 文件(File):利用命令行参数传递路径。kubelet 周期性地监视此路径下的文件是否有更新。 监视周期默认为 20s,且可通过参数进行配置。
  • HTTP 端点(HTTP endpoint):利用命令行参数指定 HTTP 端点。 此端点的监视周期默认为 20 秒,也可以使用参数进行配置。
    kubelet官网描述

kubelet 是 Kubernetes 用于管理集群节点上容器的核心组件之一。每个节点上都运行一个 kubelet 进程,它负责与 Kubernetes API Server 通信,接收关于要在该节点上创建哪些容器的指令,并确保这些容器按照预期方式运行

kubelet的具体功能

1.容器生命周期管理:Kubelet 负责创建、启动、停止和销毁节点上的容器。它会根据来自 Kubernetes 控制平面的指令,确保容器按照所定义的规范正确地运行。
2.资源管理和调度:Kubelet 监视节点上的资源使用情况,并将这些信息报告给 Kubernetes 控制平面。它还负责根据调度策略将容器分配到适当的节点上,并确保节点上的资源得到合理利用。
3.健康检查和自愈性:Kubelet 定期对节点上的容器进行健康检查,如果发现容器出现故障或异常情况,会尝试重启容器或采取其他恢复措施,以确保容器的可用性。
4.资源监控和日志收集:Kubelet 收集节点上容器的资源使用情况和日志,并将这些信息发送到 Kubernetes 控制平面,供集群管理员和开发人员进行监控和故障排查。
5.容器网络管理:Kubelet 负责为容器配置网络。它会为每个容器创建网络命名空间,并在容器启动时设置容器的网络配置,以确保容器可以与其他容器和外部网络进行通信。

kubelet的组成部分

在这里插入图片描述

上图展示了 kubelet 组件中的模块以及模块间的划分。

  • 1、PLEG(Pod Lifecycle Event Generator) PLEG 是 kubelet 的核心模块,PLEG 会一直调用 container runtime 获取本节点 containers/sandboxes 的信息,并与自身维护的 pods
    cache 信息进行对比,生成对应的 PodLifecycleEvent,然后输出到 eventChannel 中,通过
    eventChannel 发送到 kubelet syncLoop 进行消费,然后由 kubelet syncPod 来触发 pod
    同步处理过程,最终达到用户的期望状态。
  • 2、cAdvisor cAdvisor(https://github.com/google/cadvisor)是 google 开发的容器监控工具,集成在 kubelet 中,起到收集本节点和容器的监控信息,大部分公司对容器的监控数据都是从 cAdvisor 中获取的
    ,cAvisor 模块对外提供了 interface 接口,该接口也被
    imageManager,OOMWatcher,containerManager 等所使用。
  • 3、OOMWatcher 系统 OOM 的监听器,会与 cadvisor 模块之间建立 SystemOOM,通过 Watch方式从 cadvisor 那里收到的 OOM 信号,并产生相关事件。
  • 4、probeManager probeManager 依赖于 statusManager,livenessManager,containerRefManager,会定时去监控 pod
    中容器的健康状况,当前支持两种类型的探针:livenessProbe 和readinessProbe。
    livenessProbe:用于判断容器是否存活,如果探测失败,kubelet 会 kill 掉该容器,并根据容器的重启策略做相应的处理。
    readinessProbe:用于判断容器是否启动完成,将探测成功的容器加入到该 pod 所在 service 的 endpoints
    中,反之则移除。readinessProbe 和 livenessProbe 有三种实现方式:http、tcp 以及 cmd。
  • 5、statusManager statusManager 负责维护状态信息,并把 pod 状态更新到 apiserver,但是它并不负责监控 pod 状态的变化,而是提供对应的接口供其他组件调用,比如 probeManager。
  • 6、containerRefManager 容器引用的管理,相对简单的Manager,用来报告容器的创建,失败等事件,通过定义 map 来实现了 containerID 与 v1.ObjectReferece 容器引用的映射。
  • 7、evictionManager 当节点的内存、磁盘或 inode 等资源不足时,达到了配置的 evict 策略, node 会变为 pressure 状态,此时 kubelet 会按照 qosClass 顺序来驱赶 pod,以此来保证节点的稳定性。可以通过配置
    kubelet 启动参数 --eviction-hard= 来决定 evict 的策略值。
  • 8、imageGC imageGC 负责 node 节点的镜像回收,当本地的存放镜像的本地磁盘空间达到某阈值的时候,会触发镜像的回收,删除掉不被 pod 所使用的镜像,回收镜像的阈值可以通过
    kubelet 的启动参数 --image-gc-high-threshold 和 --image-gc-low-threshold
    来设置。
  • 9、containerGC containerGC 负责清理 node 节点上已消亡的 container,具体的 GC 操作由runtime 来实现。
  • 10、imageManager 调用 kubecontainer 提供的PullImage/GetImageRef/ListImages/RemoveImage/ImageStates 方法来保证pod
    运行所需要的镜像。
  • 11、volumeManager 负责 node 节点上 pod 所使用 volume 的管理,volume 与 pod 的生命周期关联,负责 pod 创建删除过程中 volume 的 mount/umount/attach/detach
    流程,kubernetes 采用 volume Plugins 的方式,实现存储卷的挂载等操作,内置几十种存储插件。
  • 12、containerManager 负责 node 节点上运行的容器的 cgroup 配置信息,kubelet 启动参数如果指定 --cgroups-per-qos 的时候,kubelet 会启动 goroutine 来周期性的更新 pod 的 cgroup 信息,维护其正确性,该参数默认为 true,实现了 pod 的Guaranteed/BestEffort/Burstable 三种级别的
    Qos。
  • 13、runtimeManager containerRuntime 负责 kubelet 与不同的 runtime 实现进行对接,实现对于底层 container 的操作,初始化之后得到的 runtime 实例将会被之前描述的组件所使用。可以通过
    kubelet 的启动参数 --container-runtime 来定义是使用docker 还是 rkt,默认是 docker。
  • 14、podManager podManager 提供了接口来存储和访问 pod 的信息,维持 static pod 和 mirror pods 的关系,podManager 会被statusManager/volumeManager/runtimeManager
    所调用,podManager 的接口处理流程里面会调用 secretManager 以及 configMapManager。
    kubelet 架构浅析

第一次笔者看到这么多的组成成分还有一些畏惧,但后续阅读源码的过程中可以看出,不同组件的执行逻辑是封装在固定的结构体中实现的,可以独立阅读,所以大家可以现有一个大体的组成轮廓,后续有机会笔者会逐步更新各个组件具体的能力和源码分析。

阅读前期准备

  • 源码环境准备:参考笔者之前的文章:https://blog.csdn.net/weixin_38757398/article/details/134737988
  • 基础的技术栈储备:golang,client-go,cobra
    其中,cobra可以参考笔者之前的文章入门: https://blog.csdn.net/weixin_38757398/article/details/134843258

至此,kubelet源码阅读的前期准备工作已经就绪

预告

下一篇文章将分析kubelet的启动流程
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐