kubelet 深度解析:节点上的 Pod 管家

kubelet 深度解析:节点上的 Pod 管家

1. kubelet 的核心职责

kubelet 是运行在每个 Worker Node 上的节点代理,是 Kubernetes 与容器运行时之间的桥梁:

1
2
3
4
5
6
7
8
9
10
11
kube-apiserver

│ Watch Pod 分配

kubelet

├── 通过 CRI 管理容器生命周期
├── 通过 CNI 配置 Pod 网络
├── 通过 CSI 挂载存储卷
├── 上报节点状态和 Pod 状态
└── 执行健康检查(Probe)

2. kubelet 架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────────────┐
│ kubelet │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ PodManager │ │ ProbeManager│ │ StatusManager │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │VolumeManager│ │ ImageGC │ │ ContainerGC │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PLEG(Pod Lifecycle Event Generator)│ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ CRI gRPC API │
│ │ │
└──────────────────────────┼──────────────────────────────┘

┌──────┴──────┐
│ containerd │
└─────────────┘

3. Pod 生命周期管理

3.1 Pod 创建流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. kubelet Watch 到新 Pod 分配到本节点

2. 准备 Pod 沙箱(Sandbox)
- 创建 pause 容器(infra container
- 配置网络(调用 CNI)

3. 拉取镜像(并行拉取所有容器镜像)

4. 启动 Init 容器(按顺序,前一个成功才启动下一个)

5. 启动业务容器(并行启动)

6. 执行 PostStart Hook(如果配置了)

7. 开始健康检查(startupProbe → livenessProbe + readinessProbe)

8. Pod 进入 Running 状态

3.2 Pod 终止流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kubectl delete pod / 驱逐 / 节点关闭

1. Pod 状态变为 Terminating
从 Service Endpoints 中移除(停止接收流量)

2. 执行 PreStop Hook(如果配置了)

3. 发送 SIGTERM 信号给容器主进程

4. 等待 terminationGracePeriodSeconds(默认 30s)

5. 超时后发送 SIGKILL 强制终止

6. 清理网络(调用 CNI DEL)
7. 清理存储卷
8. 删除 Pod 对象

3.3 优雅终止最佳实践

1
2
3
4
5
6
7
8
9
spec:
terminationGracePeriodSeconds: 60 # 给足够的优雅退出时间
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"] # 等待流量切走
# 应用代码需要处理 SIGTERM 信号

4. PLEG(Pod Lifecycle Event Generator)

PLEG 是 kubelet 的核心组件,负责感知容器状态变化

1
2
3
4
5
6
7
8
9
10
11
PLEG 每 1s 轮询一次容器运行时


对比上次状态,生成事件:
- ContainerStarted
- ContainerDied
- ContainerRemoved
- ContainerChanged


触发 Pod 同步(syncPod)

PLEG is not healthy

这是 kubelet 最常见的报错之一:

1
2
3
4
5
6
7
8
9
10
11
# 症状
PLEG is not healthy: pleg was last seen active 3m0s ago; threshold is 3m0s

# 原因
1. 容器运行时(containerd/docker)响应慢
2. 节点负载过高,kubelet 无法及时轮询
3. 大量容器同时启停

# 排查
journalctl -u kubelet -f
crictl ps # 检查容器运行时状态

5. CRI(Container Runtime Interface)

CRI 是 kubelet 与容器运行时之间的标准接口(gRPC):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
kubelet

│ gRPC

CRI Runtime(containerd / CRI-O)

├── RuntimeService(管理 Pod 和容器)
│ ├── RunPodSandbox
│ ├── StopPodSandbox
│ ├── CreateContainer
│ ├── StartContainer
│ ├── StopContainer
│ └── ExecSync

└── ImageService(管理镜像)
├── PullImage
├── ListImages
└── RemoveImage

containerd 架构

1
2
3
4
5
6
7
kubelet ──CRI gRPC──▶ containerd

containerd-shim

runc(OCI 运行时)

容器进程

常用 crictl 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看所有容器
crictl ps -a

# 查看所有 Pod 沙箱
crictl pods

# 查看容器日志
crictl logs <container-id>

# 进入容器
crictl exec -it <container-id> sh

# 查看镜像
crictl images

# 拉取镜像
crictl pull nginx:latest

# 查看容器详情
crictl inspect <container-id>

6. 健康检查(Probe)

6.1 三种 Probe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
spec:
containers:
- name: app
# 启动探针:容器启动期间使用,成功后切换到 liveness
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30 # 最多等待 30 × 10s = 5min
periodSeconds: 10

# 存活探针:失败则重启容器
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
timeoutSeconds: 5

# 就绪探针:失败则从 Service Endpoints 移除
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 3

6.2 Probe 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# HTTP GET
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Authorization
value: Bearer token

# TCP Socket
tcpSocket:
port: 3306

# Exec 命令
exec:
command:
- cat
- /tmp/healthy

# gRPC(1.24+)
grpc:
port: 9090
service: liveness

6.3 Probe 最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
# 区分 liveness 和 readiness 的检查逻辑
# liveness:检查进程是否存活(简单检查)
# readiness:检查是否能处理请求(包括依赖检查)

livenessProbe:
exec:
command: ["pgrep", "myapp"] # 只检查进程存在

readinessProbe:
httpGet:
path: /ready # 检查数据库连接、缓存预热等
port: 8080

7. 资源管理

7.1 资源请求与限制

1
2
3
4
5
6
7
resources:
requests:
cpu: "250m" # 0.25 核,调度依据
memory: "256Mi" # 调度依据
limits:
cpu: "1" # 超出则 CPU 节流(throttle)
memory: "512Mi" # 超出则 OOM Kill

7.2 QoS 等级

kubelet 根据资源配置将 Pod 分为三个 QoS 等级:

QoS 等级 条件 驱逐优先级
Guaranteed requests == limits(所有容器) 最后驱逐
Burstable 部分容器设置了 requests/limits 中间
BestEffort 没有设置任何 requests/limits 最先驱逐
1
2
3
4
5
6
7
8
# Guaranteed QoS
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "1"
memory: "1Gi"

7.3 节点资源预留

1
2
3
4
# kubelet 启动参数
--kube-reserved=cpu=200m,memory=500Mi,ephemeral-storage=1Gi
--system-reserved=cpu=200m,memory=500Mi
--eviction-hard=memory.available<100Mi,nodefs.available<10%
1
2
3
4
5
节点总资源
├── kube-reserved(K8s 组件预留)
├── system-reserved(OS 预留)
├── eviction-threshold(驱逐阈值)
└── Allocatable(可分配给 Pod)

7.4 驱逐机制

1
2
3
4
5
6
7
8
# 软驱逐(给 Pod 优雅退出时间)
--eviction-soft=memory.available<200Mi
--eviction-soft-grace-period=memory.available=1m30s

# 硬驱逐(立即驱逐)
--eviction-hard=memory.available<100Mi,nodefs.available<5%

# 驱逐顺序:BestEffort → Burstable → Guaranteed

8. 节点状态上报

kubelet 定期向 apiserver 上报节点状态:

1
2
3
4
5
# 节点状态更新频率
--node-status-update-frequency=10s # 默认 10s

# 节点心跳(Lease 对象)
--node-lease-duration-seconds=40 # 默认 40s

节点条件(Node Conditions)

1
2
3
4
5
6
7
kubectl describe node <node-name>
# Conditions:
# Type Status
# MemoryPressure False # 内存压力
# DiskPressure False # 磁盘压力
# PIDPressure False # PID 压力
# Ready True # 节点就绪

9. Static Pod

Static Pod 由 kubelet 直接管理,不经过 apiserver:

1
2
3
4
5
6
7
8
9
# Static Pod 目录(默认)
/etc/kubernetes/manifests/

# 控制平面组件就是 Static Pod
ls /etc/kubernetes/manifests/
# etcd.yaml
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml

Static Pod 的特点:

  • kubelet 直接读取 YAML 文件创建 Pod
  • apiserver 中会有对应的 Mirror Pod(只读)
  • 节点重启后自动恢复

10. 镜像垃圾回收

1
2
3
4
# 镜像 GC 配置
--image-gc-high-threshold=85 # 磁盘使用率超过 85% 触发 GC
--image-gc-low-threshold=80 # GC 到磁盘使用率降至 80%
--minimum-image-ttl-duration=2m # 镜像最少保留 2 分钟

11. 常见问题排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看 kubelet 日志
journalctl -u kubelet -f --since "10 minutes ago"

# 查看节点状态
kubectl describe node <node-name>

# 查看 Pod 事件
kubectl describe pod <pod-name>

# 检查容器运行时
systemctl status containerd
crictl info

# 检查 kubelet 配置
cat /var/lib/kubelet/config.yaml

# 检查节点资源
kubectl top node <node-name>

12. 总结

kubelet 是 Kubernetes 节点层面的核心组件:

  1. Pod 生命周期:从创建到终止的全程管理
  2. CRI 接口:与容器运行时解耦,支持 containerd/CRI-O
  3. 健康检查:三种 Probe 保障应用可用性
  4. 资源管理:QoS 等级、驱逐机制保障节点稳定
  5. 状态上报:实时向 apiserver 同步节点和 Pod 状态
  6. Static Pod:控制平面组件的自举机制

kubelet 深度解析:节点上的 Pod 管家
https://k8s.chucz.asia/kubelet深度解析/
作者
K8s Engineer
发布于
2026年1月11日
许可协议