Skip to content

kubelet 节点代理深度解析

kubelet 职责

kubelet 是运行在每个 Worker Node 上的节点代理,负责:

  • 向 API Server 注册节点
  • 监听分配到本节点的 Pod,驱动容器运行时创建/删除容器
  • 上报节点和 Pod 的状态
  • 执行健康检查(liveness/readiness/startup probe)
  • 管理节点资源(CPU/Memory/GPU)
API Server
    │ Watch Pod(spec.nodeName = 本节点)

  kubelet
    ├── CRI(容器运行时)→ containerd / CRI-O
    ├── CNI(网络插件)→ Calico / Cilium
    └── CSI(存储插件)→ 挂载 Volume

Pod 生命周期管理

API Server 下发 Pod


kubelet 接收 Pod Spec

    ├── 1. 准备 Volume(调用 CSI)
    ├── 2. 拉取镜像(通过 CRI)
    ├── 3. 创建 Pause 容器(网络命名空间)
    ├── 4. 调用 CNI 配置网络
    ├── 5. 启动 Init 容器(按顺序)
    ├── 6. 启动业务容器
    └── 7. 执行 postStart Hook

健康检查

yaml
spec:
  containers:
  - name: app
    # 存活探针:失败则重启容器
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 30  # 启动后等待 30s 再探测
      periodSeconds: 10        # 每 10s 探测一次
      failureThreshold: 3      # 连续失败 3 次则重启

    # 就绪探针:失败则从 Service 摘除
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
      successThreshold: 1

    # 启动探针:保护慢启动容器
    startupProbe:
      httpGet:
        path: /healthz
        port: 8080
      failureThreshold: 30     # 最多等待 30 * 10s = 5min
      periodSeconds: 10

资源管理

QoS 等级

kubelet 根据资源请求/限制将 Pod 分为三个 QoS 等级:

yaml
# Guaranteed(最高优先级,不会被驱逐)
resources:
  requests:
    cpu: "1"
    memory: "1Gi"
  limits:
    cpu: "1"      # requests == limits
    memory: "1Gi"

# Burstable(中等优先级)
resources:
  requests:
    cpu: "0.5"
    memory: "512Mi"
  limits:
    cpu: "2"
    memory: "2Gi"

# BestEffort(最低优先级,内存不足时首先被驱逐)
# 不设置 requests 和 limits

节点资源预留

bash
# kubelet 启动参数
--kube-reserved=cpu=200m,memory=500Mi    # 为 K8s 组件预留
--system-reserved=cpu=200m,memory=500Mi  # 为系统进程预留
--eviction-hard=memory.available<500Mi,nodefs.available<10%

CRI 接口

kubelet 通过 CRI(Container Runtime Interface)与容器运行时交互:

kubelet
    │ gRPC

CRI Runtime(containerd / CRI-O)


OCI Runtime(runc / kata-containers / gVisor)
go
// CRI 核心接口
type RuntimeService interface {
    RunPodSandbox(config *PodSandboxConfig) (string, error)
    StopPodSandbox(podSandboxID string) error
    RemovePodSandbox(podSandboxID string) error
    CreateContainer(podSandboxID string, config *ContainerConfig) (string, error)
    StartContainer(containerID string) error
    StopContainer(containerID string, timeout int64) error
    ExecSync(containerID string, cmd []string, timeout time.Duration) ([]byte, []byte, error)
}

节点状态上报

bash
# 查看节点详细状态
kubectl describe node node1

# 节点条件(Conditions)
# Ready:节点是否健康
# MemoryPressure:内存是否紧张
# DiskPressure:磁盘是否紧张
# PIDPressure:PID 是否紧张
# NetworkUnavailable:网络是否可用

静态 Pod

kubelet 可以直接管理静态 Pod(不经过 API Server),Control Plane 组件通常以静态 Pod 方式运行:

bash
# 静态 Pod 目录(默认)
ls /etc/kubernetes/manifests/
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml
# etcd.yaml

关键配置

yaml
# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd          # 与容器运行时保持一致
maxPods: 110                   # 节点最大 Pod 数
podPidsLimit: 4096             # Pod 最大 PID 数
evictionHard:
  memory.available: "500Mi"
  nodefs.available: "10%"
  imagefs.available: "15%"
containerLogMaxSize: "100Mi"
containerLogMaxFiles: 5

监控指标

kubelet_running_pods                    # 运行中的 Pod 数
kubelet_pod_start_duration_seconds      # Pod 启动耗时
kubelet_cgroup_manager_duration_seconds # cgroup 操作耗时
volume_manager_total_volumes            # 挂载的 Volume 数
kubelet_node_config_error               # 节点配置错误

本站内容由 褚成志 整理编写,仅供学习参考