Kubernetes Kubelet 深度解析

Kubelet:Kubernetes 集群的节点基石

Kubelet 是在 Kubernetes 集群中每个 节点(Node) 上运行的核心代理(Agent)。它的根本职责是确保在节点上运行的 容器(Containers) 符合 控制平面(Control Plane) 通过 PodSpec 定义的期望状态。可以将其视为控制平面指令在具体节点上的执行者状态汇报者,是连接 Master 与 Worker 节点的关键桥梁,负责 Pod 的生命周期管理、节点资源监控与汇报等核心任务。理解 Kubelet 的工作原理对于深入掌握 Kubernetes 的运行机制至关重要。


Kubelet 核心架构与交互接口

Kubelet 内部包含多个协同工作的管理器和循环,并通过标准的 API 接口与集群其他组件及外部系统交互。

Kubelet API 服务

Kubelet 暴露了若干 HTTP API 端点,用于不同的交互场景:

  • 认证与授权的 HTTPS API (默认端口 :10250):这是 Kubelet 最主要的 API 服务端口,用于接收来自 API Server 的指令,例如创建、删除、更新 Pod。API Server 通过此端口向 Kubelet 下发任务。同时,Kubelet 也通过此端口对外提供节点和 Pod 的详细信息查询,但访问此端口需要严格的认证和授权(通常使用 TLS 证书)。kubectl exec, kubectl logs 等命令最终也会通过 API Server 代理将请求转发到 Kubelet 的这个端口。
  • 非认证的只读 HTTP API (默认端口 :10255):此端口提供一个无需认证即可访问的只读接口,主要用于获取 Pod 和节点的基本状态信息(如 /pods, /stats 等)。由于其安全性较低,已不推荐在生产环境中使用,并且在较新版本的 Kubernetes 中可能默认禁用。外部监控系统(如 Prometheus)有时会配置为从这个端口拉取指标,但更推荐使用 Metrics Server 或者通过 :10250 端口的安全接口获取。
  • 健康检查 HTTP API (默认端口 :10248):这个端口主要提供 Kubelet 自身的健康状态检查端点,通常是 /healthz。监控系统或负载均衡器可以调用此接口来判断 Kubelet 进程是否存活且正常工作。

这些 API 是 Kubelet 与外界沟通的窗口,特别是 :10250 端口,承载了 Kubelet 与控制平面交互的核心流量。


Kubelet 内部核心组件剖析

Kubelet 内部由多个并发运行的管理器(Manager)和控制循环(Loop)构成,它们各司其职,共同维护节点的 Pod 运行状态。

syncLoop: 核心协调循环

syncLoop 是 Kubelet 的心脏,它是一个持续运行的控制循环(Reconciliation Loop)。其核心任务是将节点上 Pod 的实际状态与期望状态进行同步

  • 获取期望状态syncLoop 主要通过 Watch 机制监听 API Server,获取分配给本节点的 Pod 的配置信息(期望状态)。此外,它还可以从静态 Pod 目录(由 --pod-manifest-path 参数指定,通常是 /etc/kubernetes/manifests/)或远程 HTTP URL(由 --manifest-url 参数指定)读取 Pod 定义。
  • 获取实际状态:通过 PLEG (Pod Lifecycle Event Generator)容器运行时接口 (CRI) 获取节点上当前实际运行的 Pod 和容器状态。
  • 状态比较与动作执行syncLoop 对比期望状态和实际状态的差异。如果发现不一致(例如,需要创建新 Pod、删除旧 Pod、重启容器等),它会计算出需要执行的操作,并将这些操作分发给 PodWorker 进行处理。这个过程体现了 Kubernetes 声明式 API 的核心思想:用户只定义期望状态,由控制器(这里是 Kubelet 的 syncLoop)负责驱动系统达到该状态。

PodWorker: Pod 操作执行单元

PodWorker 负责具体执行 syncLoop 决策出的 Pod 相关操作。它通常管理一个 Goroutine 池,并发地处理各个 Pod 的创建、更新和删除任务。例如,当需要创建一个 Pod 时,PodWorker 会调用容器运行时接口 (CRI) 来创建 Sandbox 和容器、设置网络、挂载卷等。这种并发处理机制提高了 Kubelet 管理大量 Pod 的效率。

容器运行时接口 (CRI) Shim

Kubelet 本身不直接操作容器(如 Docker、containerd、CRI-O)。它通过 容器运行时接口 (Container Runtime Interface, CRI) 这个抽象层与具体的容器运行时进行交互。CRI 定义了一套标准的 gRPC 接口,包括 RuntimeService(管理 Pod Sandbox 和容器生命周期)和 ImageService(管理容器镜像)。Kubelet 调用这些 gRPC 接口,由运行在节点上的 CRI Shim(如 cri-containerd, cri-o)负责将 CRI 请求翻译成底层容器运行时的具体命令。这种设计使得 Kubernetes 可以灵活地支持多种容器运行时,实现了 Kubelet 与容器运行时的解耦。

PLEG (Pod Lifecycle Event Generator): Pod 生命周期事件生成器

PLEG 是 Kubelet 中一个至关重要的、但有时也容易引发性能问题的模块。它的主要职责是持续监测节点上容器的真实状态,并将变化以事件的形式通知给 syncLoop

  • 工作机制:PLEG 定期(默认为 1 秒)通过 CRI 调用容器运行时的 ListContainers 或类似接口,获取节点上所有容器的当前状态。然后,它会与自己维护的内部缓存进行比较,识别出状态发生变化的容器(如启动、停止、死亡等)。对于检测到的变化,PLEG 会生成相应的 Pod 生命周期事件,并将这些事件发送到一个内部通道,供 syncLoop 消费。

  • 为何需要 PLEG:虽然容器运行时本身会产生事件,但这些事件可能丢失或不及时。PLEG 通过**主动轮询(Relist)**的方式,确保 Kubelet 能够可靠地感知到容器的最终状态,即使错过了某些瞬时事件。

  • 性能考量:频繁的 relist 操作(尤其是在节点上 Pod 数量非常多时)会对容器运行时和 Kubelet 自身造成显著的性能压力。如果 relist 操作耗时过长(例如超过 PLEG 的检查周期),可能导致 Kubelet 无法及时更新 Pod 状态,甚至误判节点为 NotReady。这就是为什么 Kubernetes 会建议限制每个节点的最大 Pod 数量 (maxPods) 的原因之一。

    1
    2
    3
    4
    # KubeletConfiguration 示例片段,限制节点 Pod 数量
    apiVersion: kubelet.config.k8s.io/v1beta1
    kind: KubeletConfiguration
    maxPods: 110 # 默认值,可根据节点规格调整

ProbeManager: 容器健康探测器

ProbeManager 负责执行 Pod 定义中配置的 Liveness Probe (存活探针)Readiness Probe (就绪探针)Startup Probe (启动探针)

  • Liveness Probe:用于判断容器是否仍在正常运行。如果探测失败,Kubelet 会根据 Pod 的 restartPolicy 杀死并尝试重启该容器。这有助于自动恢复陷入死锁或无响应状态的应用。
  • Readiness Probe:用于判断容器是否已准备好接收外部流量。如果探测失败,Kubernetes Service Controller 会将该 Pod 的 Endpoint 从相应的 Service 中移除,使其暂时不接收新的请求,直到探测成功。这确保了流量只会被发送到真正准备就绪的实例。
  • Startup Probe:用于处理启动时间较长的应用。在 Startup Probe 成功之前,Liveness 和 Readiness Probe 不会执行。这可以防止启动过程中的应用被 Liveness Probe 误杀。

ProbeManager 根据探针配置(如检查方式 - HTTP GET, TCP Socket, Exec Command,以及频率、超时、阈值等),周期性地执行检查,并将结果反馈给 Kubelet 的状态管理系统。

cAdvisor: 容器与节点资源监控

cAdvisor (Container Advisor) 是 Google 开源的一个用于监控容器资源使用和性能的工具,它被内嵌在 Kubelet 的二进制文件中运行。cAdvisor 负责收集本节点上所有容器以及节点本身的资源使用数据(CPU、内存、文件系统、网络等)。

  • 数据来源:cAdvisor 主要通过读取 Linux 内核提供的 cgroups 文件系统(位于 /sys/fs/cgroup)和 /proc 文件系统来获取精确的资源使用信息。
  • 数据用途
    • Kubelet 通过 cAdvisor 获取的数据来更新 Pod 和节点的状态信息(如资源使用量),并汇报给 API Server。
    • 调度器 (Scheduler) 使用这些信息来做出更优的 Pod 调度决策。
    • 水平 Pod 自动伸缩器 (HPA) 依赖这些指标来判断是否需要增减 Pod 副本。
    • Kubelet 的 EvictionManager 也使用这些数据来判断节点资源是否紧张。
    • 可以通过 Kubelet 的 /metrics/cadvisor 端点(通常在 :10250 端口,需要认证)或只读端口 :10255(如果启用)暴露这些指标,供 Prometheus 等监控系统采集。

StatusManager: 状态管理器

StatusManager 负责管理和同步 Pod 的状态信息。它从 Kubelet 内部的其他组件(如 PLEG、ProbeManager)收集 Pod 的最新状态,并将其定期(通过心跳)更新到 API Server。API Server 随后将这些状态持久化到 etcd 中。用户通过 kubectl get pod 等命令看到的就是由 StatusManager 汇报的状态。如果 Kubelet 与 API Server 长时间失联,StatusManager 无法更新状态,控制平面中的 Node Controller 最终会将该节点标记为 NotReady

EvictionManager: 资源驱逐管理器

EvictionManager 负责监控节点的资源状况(如内存、磁盘空间、inode 使用率),并在资源低于预设的驱逐阈值 (Eviction Thresholds) 时,主动**驱逐(Evict)**节点上的 Pod 以回收资源,防止节点因资源耗尽而变得不稳定。

  • 驱逐信号 (Eviction Signals):常见的信号包括 memory.available, nodefs.available (节点根文件系统可用空间), imagefs.available (容器镜像存储文件系统可用空间), nodefs.inodesFree (节点根文件系统可用 inode)。

  • 驱逐阈值 (Eviction Thresholds):可以配置硬驱逐 (Hard Eviction) 阈值(一旦达到立即触发驱逐)和软驱逐 (Soft Eviction) 阈值(达到后会有一个宽限期,若资源仍未恢复则触发驱逐)。

  • 驱逐策略:当需要驱逐时,EvictionManager 会根据 Pod 的 QoS (Quality of Service) 等级Guaranteed > Burstable > BestEffort)和资源使用情况来决定驱逐的优先级。通常优先驱逐 BestEffort 级别的 Pod,或者超出其资源请求(Request)最多的 Burstable Pod。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # KubeletConfiguration 示例片段,配置硬驱逐阈值
    apiVersion: kubelet.config.k8s.io/v1beta1
    kind: KubeletConfiguration
    evictionHard:
    memory.available: "100Mi" # 当可用内存低于 100Mi 时触发驱逐
    nodefs.available: "10%" # 当节点根文件系统可用空间低于 10% 时触发驱逐
    imagefs.available: "15%" # 当镜像文件系统可用空间低于 15% 时触发驱逐
    nodefs.inodesFree: "5%" # 当节点根文件系统可用 inode 低于 5% 时触发驱逐
    # evictionSoft: ... # 可选,配置软驱逐阈值及宽限期

VolumeManager: 存储卷管理器

VolumeManager 负责 Pod 所需存储卷 (Volume)挂载 (Mount)卸载 (Unmount) 操作。它与 CSI (Container Storage Interface) 驱动程序交互,管理各种类型的持久化和非持久化存储卷。

  • 挂载流程:在 Pod 启动前,VolumeManager 会确保所有声明的卷都已准备就绪 (Attach, if necessary)挂载 (Mount) 到节点上的指定路径。然后,这些路径会被传递给容器运行时,以便在容器内部进行绑定挂载 (bind mount)。
  • 卸载流程:当 Pod 被删除时,VolumeManager 负责卸载这些卷,并在必要时执行清理 (Detach) 操作。
  • 关键作用:确保有状态应用能够正确地访问其持久化数据。

ImageGC 与 DiskSpaceManager: 镜像与磁盘空间管理

  • ImageGC (Image Garbage Collector):负责自动清理节点上未被任何运行中或最近创建的 Pod 使用的容器镜像。它根据配置的策略(如基于镜像使用时间和磁盘空间占用率的阈值)来决定回收哪些镜像,以防止节点磁盘被不再需要的镜像占满。
  • DiskSpaceManager:与 ImageGC 类似,但更广泛地监控节点磁盘空间(特别是容器可写层和空目录卷使用的空间),并在必要时触发容器日志清理或其他磁盘清理操作,协同 EvictionManager 工作。

CertificateManager: 证书管理器

CertificateManager 负责管理 Kubelet 用于与 API Server 进行 TLS 安全通信所需的客户端证书。它可以配置为自动请求和轮换 (rotate) 这些证书,确保 Kubelet 与控制平面之间的通信始终是加密且经过认证的,增强了集群的安全性。


Kubelet 管理 Pod 的完整流程

理解 Kubelet 如何接收指令并最终运行一个 Pod 是掌握其工作方式的关键。

  1. Pod 期望状态来源

    • API Server (主要来源):Kubelet 通过 Watch 机制实时监听 API Server 上与其 nodeName 匹配的 Pod 对象创建、更新和删除事件。这是最常用和动态的方式。
    • 静态 Pod (Static Pods):Kubelet 可以配置一个本地文件目录 (--pod-manifest-path)。它会周期性扫描此目录下的 YAML 或 JSON 文件,并将这些文件定义的 Pod 直接在本节点上运行,无需 API Server 的介入。这类 Pod 通常用于运行集群关键组件(如 API Server、etcd 自身,如果它们以 Pod 形式部署的话),确保即使在控制平面不可用时,这些基础服务也能在节点上启动。
    • HTTP URL:类似静态 Pod,Kubelet 可以配置一个 URL (--manifest-url),周期性地从该 URL 拉取 Pod 定义文件。
    • (不推荐) HTTP 接口:Kubelet 曾支持通过其 HTTP 接口直接提交 Pod 定义,但这种方式已被弃用。
  2. syncLoop 消费与处理

    • syncLoop 从上述来源获取到 Pod 的期望状态 (Desired State)
    • 它通过 PLEG 和 CRI 获取 Pod 的实际状态 (Actual State)
    • 调用内部的 computePodActions 函数,比较期望状态和实际状态,生成需要执行的操作(如 SyncPod, KillPod)。
    • 将这些操作分发给 PodWorker
  3. PodWorker 执行操作

    • PodWorker 接收到 SyncPod 指令后,开始执行 Pod 的创建或更新流程。
    • 调用 CRI
      • 创建 Pod Sandbox:首先调用 CRI 的 RunPodSandbox 接口。CRI Shim 会创建一个基础的隔离环境,通常是一个非常轻量级的 “pause” 容器。这个 Pause 容器的核心作用是持有 Pod 共享的网络命名空间 (net ns),以及可能的 IPC 命名空间 (ipc ns) 和 PID 命名空间 (pid ns)。Pod 内的所有应用容器都将加入到这个 Pause 容器的命名空间中,从而实现它们之间的网络互通(共享同一个 IP 和端口空间)和 IPC 通信。
      • 配置网络:Sandbox 创建后,Kubelet 会调用 CNI (Container Network Interface) 插件(通过 CRI 触发)。CNI 插件负责为 Pod Sandbox 分配 IP 地址、设置网络路由等网络相关的配置,将其接入集群网络。
      • 挂载卷VolumeManager 介入,确保 Pod 所需的存储卷(通过 CSI (Container Storage Interface) 或内置的 Volume 插件)被正确挂载到节点上的预期位置,供后续容器使用。
      • 拉取镜像:为每个应用容器调用 CRI 的 PullImage 接口,确保所需的容器镜像存在于本地。
      • 创建容器:为每个应用容器调用 CRI 的 CreateContainer 接口,在 Pod Sandbox 的共享命名空间内创建容器实例,但不启动。
      • 启动容器:最后,为每个应用容器调用 CRI 的 StartContainer 接口,启动容器内的进程。
    • PodWorker 接收到 KillPod 指令后,会逆向执行上述流程,调用 CRI 接口停止容器、删除容器、卸载卷、删除 Sandbox 等。
  4. 状态反馈

    • 在整个过程中以及 Pod 运行期间,PLEG、ProbeManager 等组件持续监控状态。
    • StatusManager 汇总这些状态,并定期通过心跳上报给 API Server,更新 etcd 中的 Pod 对象状态。
    • 用户或其他控制器可以通过查询 API Server 获取 Pod 的最新状态(如 Pending, Running, Succeeded, Failed, Unknown)以及更详细的 ConditionsContainerStatuses

节点管理与自注册

Kubelet 不仅管理 Pod,也负责将自身所在的物理机或虚拟机注册为 Kubernetes 集群的一个 Node 资源,并持续维护该 Node 的状态。

  1. 节点自注册 (Node Self-Registration)

    • 通过启动参数 --register-node=true (默认值),Kubelet 在启动时会自动尝试向 API Server 注册自己。它会收集节点信息(如操作系统、内核版本、CPU/内存容量、容器运行时版本等),创建一个 Node 对象,并提交给 API Server。
    • 如果 API Server 中已存在同名的 Node 对象,Kubelet 会尝试更新它。
    • 自注册需要 Kubelet 拥有与 API Server 通信的凭证(通常是 kubeconfig 文件,由 --kubeconfig 参数指定)以及在 API Server 上创建/更新 Node 对象的权限。
  2. 手动注册节点

    • 如果设置 --register-node=false,或者 Kubelet 没有权限自注册,管理员就需要手动创建 Node 对象
    • 管理员需要准备一个 Node 对象的 YAML 或 JSON 定义文件,包含节点的名称(必须与 Kubelet 启动时通过 --hostname-override 指定或自动获取的主机名一致)、标签、容量等信息,然后使用 kubectl apply -f node.yaml 创建。
    • 即使是手动注册,Kubelet 仍然需要配置 --kubeconfig 以便与 API Server 通信,汇报节点状态和接收 Pod 任务。
  3. 节点状态更新与心跳

    • 无论如何注册,Kubelet 都会定期(由 --node-status-update-frequency 控制,默认 10 秒)向 API Server 发送心跳,更新 Node 对象的 status 字段。
    • 状态信息包括:
      • Node Conditions:描述节点当前状态的关键标志,如 Ready (节点是否健康且可调度 Pod), MemoryPressure, DiskPressure, PIDPressure (节点是否存在资源压力)。这些 Condition 由 Kubelet 根据内部监控(如 EvictionManager 的信号)动态更新。
      • Node Capacity & Allocatable:节点的总资源容量和可供 Pod 分配的资源量。
      • Node Info:操作系统、内核版本、容器运行时版本等静态信息。
    • Node Controller 在控制平面会监控这些心跳。如果一个节点在一段时间内(由 --node-monitor-grace-period 控制,默认 40 秒)没有发送心跳,Node Controller 会将该节点的 Ready Condition 标记为 Unknown;如果更长时间(由 --node-monitor-period 相关配置决定)没有响应,可能会标记为 False,并触发驱逐该节点上的 Pod 等操作。

总结

Kubelet 作为 Kubernetes 数据平面的核心组件,其内部结构复杂而精巧。它通过一系列管理器和控制循环,与 API Server容器运行时 (CRI)网络插件 (CNI)存储插件 (CSI) 紧密协作,忠实地执行控制平面的指令,管理 Pod 的完整生命周期,监控并维护节点的健康状态和资源使用情况。深入理解 Kubelet 的核心机制(如 syncLoop、PLEG、CRI 交互、资源管理与驱逐、状态汇报)以及其关键配置(如 maxPods, evictionHard, cgroupDriver),对于诊断集群问题、优化节点性能以及进行更高级的 Kubernetes 开发和运维至关重要。 Kubelet 是将声明式的 Pod 定义转化为节点上实际运行的容器的关键执行者,是 Kubernetes 分布式系统稳定运行的基石之一。


Kubernetes Kubelet 深度解析
https://mfzzf.github.io/2025/03/21/kubernetes-kubelet/
作者
Mzzf
发布于
2025年3月21日
许可协议