云原生学习路线导航页(持续更新中)
本文是 kubernetes 的控制面组件 kubelet 系列文章第二篇,主要讲解了 kubelet 架构中的核心功能层,包括核心管理模块的 PLEG、cAdvisor、GPUManager、OOMWatcher、ProbeManager、DiskSpaceManager、EvictionManager;运行时协调模块的 syncLoop、PodWorker,以及容器生命周期管理模块的 StatusManager、VolumeManager、ImageGC、ContainerGC、ImageManager、CertificateManager,对每个组件都做了详细讲解
- 希望大家多多 点赞 关注 评论 收藏,作者会更有动力继续编写技术文章
ContainerStarted
、ContainerDied
等),驱动 Pod 状态同步和更新。容器状态监控
Running
、Exited
、Unknown
)事件生成
ContainerStarted
:容器启动。ContainerDied
:容器终止。ContainerChanged
:容器配置变更(如资源限制更新)。状态同步
relist
过程。ListPodSandboxes
和 ListContainers
接口,获取所有 Pod 和容器的当前状态。relist
的结果进行对比,识别状态变化。Running
变为 Exited
生成 ContainerDied
)。性能瓶颈
relist
耗时越长。ListPodSandboxes
和 ListContainers
的速度影响 PLEG 效率。网络延迟:
监控指标
kubelet_pleg_relist_interval_seconds
:记录每次 relist
的耗时。kubelet_pleg_relist_latency_microseconds
:历史分位数统计。kubelet_pleg_last_seen_seconds
:容器状态最后一次被记录的时间戳。relist
是否按时完成。relist
耗时超过 3分钟(默认阈值),kubelet 会报告 PLEG is not healthy 事件,并标记节点为 NotReady
。资源监控
数据暴露
/metrics/cadvisor
提供标准的 Prometheus 指标。/api/v1.3/containers
)。多运行时支持
/sys/fs/cgroup
)获取资源使用数据。cpuacct.stat
读取,内存使用从 memory.usage_in_bytes
读取。/containers/json
)获取容器元数据(ID、名称、标签)。cAdvisor 的架构分为以下核心模块
/metrics/cadvisor
端点暴露。指标类别 | 示例指标名 | 说明 |
---|---|---|
CPU | container_cpu_usage_seconds_total |
容器累计 CPU 使用时间(秒) |
内存 | container_memory_working_set_bytes |
容器工作集内存(常驻内存) |
磁盘 I/O | container_fs_reads_bytes_total |
容器累计读取字节数 |
网络 | container_network_receive_bytes_total |
容器累计接收的网络字节数 |
进程 | container_processes |
容器内运行的进程数 |
nvidia-device-plugin
)与 kubelet 通信,注册节点上的 GPU 设备信息(如 GPU 数量、型号等)。nvidia.com/gpu: 4
)上报至 Kubernetes API Server,供调度器使用。Allocate
接口分配具体 GPU 设备,并生成容器启动所需的配置(如环境变量、设备挂载路径)。nvidia-container-runtime
或 CDI(Container Device Interface)
,将 GPU 驱动和 CUDA 库注入容器,确保容器内应用可访问 GPU。cgroups
)实时采集内存使用情况,并在检测到 OOM 事件时推送信号至 OOMWatcher。PodLifecycleEvent
事件,通过 eventChannel
发送至 Kubelet 的 syncLoop
主控制循环。/var/log/messages
中的 OOM-Kill 日志,并通知 OOMWatcher。State.OOMKilled
状态),cAdvisor 通过容器运行时接口(CRI)获取状态变更并触发事件。Event
对象),通过 StatusManager
上报至 API Server,同时触发 syncLoop
同步状态。Always
),Kubelet 调用容器运行时重启容器。EvictionManager
),释放节点内存资源。--eviction-hard
设置内存驱逐阈值(如 memory.available<1Gi
),提前触发资源回收。--container-runtime
和 --runtime-request-timeout
优化容器响应速度。--anonymous-auth=false
),防止未授权用户通过 Kubelet API 获取敏感 OOM 事件信息。默认truememory.available
(可用内存)nodefs.available
(根文件系统可用空间)imagefs.available
(容器运行时存储镜像的磁盘空间)pid.available
(可用进程数)MemoryPressure
或 DiskPressure
,并通过 kube-apiserver 同步至集群调度器,阻止新 Pod 调度到问题节点。eviction-soft-grace-period
(默认 1m30s),再终止 Pod。--eviction-minimum-reclaim
指定的资源量(如 500Mi 内存),避免频繁触发驱逐。eviction-pressure-transition-period
(默认 5m)延迟节点压力状态的解除,避免调度器频繁调整。nodefs
空间。MemoryPressure
或 DiskPressure
状态阻止新 Pod 调度,例如:
MemoryPressure
时拒绝 BestEffort PodDiskPressure
时拒绝所有 Pod--eviction-hard
:硬驱逐阈值(需谨慎设置,避免过度驱逐)。--eviction-soft-grace-period
:软驱逐宽限期(平衡服务可用性与资源压力)。--eviction-max-pod-grace-period
:Pod 终止最大宽限期(覆盖 Pod 自身配置)。kubectl describe node
查看节点压力事件。--v=4
)观察驱逐决策过程。syncLoop
是 kubelet 的核心事件驱动循环,负责 监听多种事件源 并协调 Pod 的实际状态与期望状态一致。PodWorker
、StatusManager
)。syncLoop
通过 多路复用(Multiplexing) 监听多个事件通道,使用 select
语句等待任意一个通道的事件到达,然后分发给对应的处理逻辑。func (kl *Kubelet) syncLoop() {
for {
if !kl.syncLoopIteration(...) {
break
}
}
}
func (kl *Kubelet) syncLoopIteration(...) bool {
select {
case <-configCh: // 处理配置变更(如 Pod 的增删改)
case <-plegCh: // 处理容器状态变化事件
case <-syncCh: // 定时强制同步
case <-housekeepingCh: // 定期清理资源
case update := <-kl.livenessManager.Updates():
case update := <-kl.readinessManager.Updates():
case update := <-kl.startupManager.Updates():
case update := <-kl.containerManager.Updates():
}
return true
}
事件来源 | 触发条件 | 处理逻辑 |
---|---|---|
configCh |
API Server 或静态 Pod 的配置变更 | 处理pod的增删改查、重新调谐 |
plegCh |
PLEG 检测到容器状态变化(如崩溃、重启) | 定期 relist 环境中所有pod,对比变化后调用 HandlePodSyncs 重新同步受影响的 Pod,还负责清理终止的容器。 |
syncCh |
定时器触发(默认 1秒) | 强制同步所有标记为需要同步的 Pod。 |
housekeepingCh |
定时器触发(默认 2秒) | 调用 HandlePodCleanups 清理孤儿 Pod、残留的卷和网络资源。 |
liveness/readiness |
存活/就绪探针状态变更 | 更新容器状态,触发容器重启(存活探针失败)或服务端点更新(就绪探针变更)。 |
containerManager |
设备资源变更(如 GPU 分配) | 重新同步涉及设备资源的 Pod。 |
StatusManager
上报到 API Server。模块 | 协作方式 |
---|---|
PLEG | 通过 plegCh 提供容器状态变化事件,触发 Pod 同步。 |
PodWorker | 异步执行具体的 Pod 同步操作(如创建容器、挂载卷)。 |
StatusManager | 将 Pod 的最新状态上报到 API Server。 |
VolumeManager | 管理卷的挂载/卸载操作,确保 Pod 启动前卷已就绪。 |
ContainerRuntime | 调用容器运行时接口(CRI)执行容器生命周期操作。 |
metadata:
annotations:
kubernetes.io/config.source: file # 标识来源为本地文件
kubernetes.io/config.hash: > # 文件内容哈希值
kubernetes.io/config.mirror: > # 标识为镜像 Pod
podWorker
是 kubelet 中用于 管理单个 Pod 生命周期操作的核心工作单元。每个 Pod 对应一个独立的 podWorker
,负责执行该 Pod 的创建、更新、删除等同步操作,确保 Pod 的实际状态与期望状态一致。它是 kubelet 实现 Pod 异步化、并行化管理的核心机制。CreateContainer
、StartContainer
)。VolumeManager
协作挂载/卸载存储卷。StatusManager
协作上报 Pod 状态到 API Server。podUpdates
通道接收同步请求。syncLoop
分发的同步事件触发操作。SyncPod
、Terminating
)。syncLoop
接收事件(如 ADD
、UPDATE
、DELETE
)。VolumeManager
完成卷挂载。StatusManager
将最终状态上报到 API Server。操作顺序性
同步模式
模式 | 触发条件 | 行为特性 |
---|---|---|
增量同步 | Pod 配置发生部分变更(如环境变量更新) | 仅执行必要的变更操作(如重启容器)。 |
全量同步 | Pod 配置发生重大变更(如镜像版本变更) | 销毁旧容器并重新创建。 |
强制同步 | 定时触发或手动干预(如 kubectl replace ) |
忽略状态缓存,全量重新同步。 |
klog
输出错误详情(如容器启动失败原因)。Warning
类型事件供用户查看(如 FailedCreateContainer
)。--image-gc-high-threshold
):
85%
。当磁盘使用率超过此阈值时,触发镜像清理。--image-gc-low-threshold
):
80%
。清理镜像直到磁盘使用率降至此阈值以下。docker rmi
或 containerd 的 ctr images rm
)。+---------------------+
| 周期性检查磁盘使用率 |
+----------+----------+
|
v
+----------+----------+
| 使用率 > 高水位阈值? +--否--> 等待下一周期
+----------+----------+
|
是
v
+----------+----------+
| 列出所有未使用的镜像 |
+----------+----------+
|
v
+----------+----------+
| 按 LRU 排序镜像 |
+----------+----------+
|
v
+----------+----------+
| 依次删除镜像直到使用率 ≤ 低水位阈值 |
+---------------------+
参数 | 说明 | 默认值 |
---|---|---|
--image-gc-high-threshold |
触发镜像清理的磁盘使用率阈值(百分比)。 | 85 |
--image-gc-low-threshold |
清理后磁盘使用率的目标阈值(百分比)。 | 80 |
--minimum-image-ttl-duration |
镜像的最小存活时间,短于此时间的镜像即使未使用也不会被删除(例如 2h )。 |
0 (禁用) |
ListImages
和 RemoveImage
接口)。--image-gc-high-threshold=90
、--image-gc-low-threshold=85
。--image-gc-period
(如 15m
),减少对性能的影响。pause
镜像),确保它们被至少一个 Pod 引用。docker system prune
),需与 ImageGC 协调配置。以下是关于 kubelet 的 Container Garbage Collection(容器垃圾回收模块,ContainerGC) 的详细介绍:
Completed
或 Error
状态的容器)。Exited
)。+---------------------+
| 周期性扫描容器列表 |
+----------+----------+
|
v
+----------+----------+
| 筛选已终止或孤立容器 |
+----------+----------+
|
v
+----------+----------+
| 应用保留策略 |
| - 保留最近的N个容器 |
| - 保留时间超过阈值 |
+----------+----------+
|
v
+----------+----------+
| 调用容器运行时删除容器 |
+---------------------+
--serialize-image-pulls
参数配置是否串行拉取)。PullImage
方法。nginx:latest
),值为镜像的元数据(如大小、拉取时间、引用计数)。ListImages
:获取本地镜像列表。PullImage
:拉取远程镜像。ImageStatus
:检查镜像的详细信息。RemoveImage
:删除镜像(通常由 ImageGC 触发)。参数 | 说明 | 默认值 |
---|---|---|
--serialize-image-pulls |
是否串行拉取镜像(设为 false 允许并行拉取,提升效率)。 |
true (Kubernetes ≤1.17)false (Kubernetes ≥1.18) |
--image-pull-progress-deadline |
镜像拉取的超时时间(超过此时间未完成则标记为失败)。 | 1m |
--registry-qps |
访问镜像仓库的每秒查询次数(QPS)限制。 | 5 |
--registry-burst |
访问镜像仓库的突发请求数限制(Burst)。 | 10 |
certificates.k8s.io
API 提交 CSR。/var/lib/kubelet/pki
)。csrapprover
)批准 CSR。apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: kubelet-node1
spec:
request: -encoded-csr>
signerName: kubernetes.io/kube-apiserver-client-kubelet
usages:
- digital signature
- key encipherment
- client auth
kubectl apply -f kubelet-csr.yaml
system:nodes
组)。kubernetes.io/kube-apiserver-client-kubelet
)。csrapprover
控制器自动批准合法的 kubelet CSR。/var/lib/kubelet/pki/kubelet-client-current.pem
/var/lib/kubelet/pki/kubelet-client-current.pem
kubelet-client-current.pem
指向实际证书文件)。0600
,仅允许 kubelet 用户访问。client auth
,避免权限过度分配。参数 | 说明 | 默认值 |
---|---|---|
--rotate-certificates |
是否启用自动证书轮换。 | true |
--cert-dir |
证书存储目录。 | /var/lib/kubelet/pki |
--tls-cert-file |
kubelet 服务端证书文件路径(若 kubelet 作为服务器)。 | 空(客户端模式无需配置) |
--tls-private-key-file |
kubelet 服务端私钥文件路径。 | 空 |
--feature-gates=RotateKubeletServerCertificate |
启用服务端证书轮换(Kubernetes ≥1.8)。 | true (默认启用) |
certificate rotation error
。kubectl get csr
。journalctl -u kubelet | grep certificate
。openssl x509 -in /etc/kubernetes/pki/ca.crt -text
。700
,文件权限为 600
:chmod 700 /var/lib/kubelet/pki
chmod 600 /var/lib/kubelet/pki/kubelet-client-current.pem
Pending
状态。spec.signerName
和 spec.groups
是否符合自动批准策略。Running
、Failed
)与节点上实际运行的 Pod 状态一致,是 kubelet 与集群控制平面通信的关键组件。ResourceVersion
处理乐观锁冲突。Running
、Exited
)。v1.PodStatus
对象。UpdateStatus
方法提交状态变更。模块 | 协作方式 |
---|---|
PodWorker | 接收 Pod 操作结果(如容器启动成功/失败),触发状态更新。 |
ProbeManager | 获取容器探针(Liveness/Readiness)的结果,更新 Pod 的 Ready 条件。 |
ContainerRuntime | 获取容器实际状态(如 Running 、Exited )。 |
EvictionManager | 当 Pod 被驱逐时,更新 Pod 状态为 Failed 并添加 Evicted 条件。 |
VolumeManager | 当卷挂载失败时,更新 Pod 状态为 Pending 并记录错误信息。 |
/var/lib/kubelet/pods//volumes
)。emptyDir
、configMap
、secret
。persistentVolumeClaim
(PVC)、hostPath
。downwardAPI
、projected
。emptyDir
卷创建临时目录。configMap
/secret
卷生成配置文件。/var/lib/kubelet/pods//volumes/...
)。/data
)。umount
或 CSI 插件的 Unmount
接口)。VolumeManager 为每个卷维护一个状态机,包括以下状态:
模块 | 协作方式 |
---|---|
PodWorker | 在启动容器前等待 VolumeManager 完成卷挂载。 |
CSI 插件 | 调用 CSI 接口完成存储卷的挂载、卸载和扩容操作。 |
API Server | 同步 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)的状态。 |
EvictionManager | 当卷空间不足时触发 Pod 驱逐。 |
ProbeManager | 若卷挂载失败,可能触发容器健康检查失败。 |