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日
许可协议