Kubelet

Kubernetes Kubelet 代码结构 #

仓库地址: cmdpkg


整体代码布局 #

kubernetes/
├── cmd/kubelet/                           # 入口:二进制启动命令
│   ├── kubelet.go                         # main() 入口
│   └── app/                               # 应用初始化、配置解析
│       ├── server.go                      # Kubelet 启动核心(NewKubeletCommand → Run)
│       ├── auth.go                        # HTTP API 认证授权
│       ├── plugins.go                     # CSI/CNI/DeviceManager 插件注册
│       ├── init_others.go                 # 非 Windows 平台初始化
│       ├── init_windows.go                # Windows 平台初始化
│       ├── server_linux.go                # Linux 特定启动逻辑
│       ├── server_others.go               # 非 Linux 平台启动逻辑
│       ├── server_windows.go              # Windows 特定启动逻辑
│       └── options/                       # 命令行选项解析
│
└── pkg/kubelet/                           # 核心实现
    │
    ├── kubelet.go                         # Kubelet 主结构体 + Run() + SyncPod()
    ├── kubelet_pods.go                    # Pod 管理(创建/更新/删除)
    ├── kubelet_volumes.go                 # 卷挂载/卸载
    ├── kubelet_node_status.go             # 节点状态上报
    ├── kubelet_network.go                 # 网络设置
    ├── kubelet_getters.go                 # 各类 Getter 方法
    ├── kubelet_resources.go               # 资源管理
    ├── pod_workers.go                     # Pod Worker(每 Pod 一个 goroutine)
    ├── pod_container_deletor.go           # 容器清理
    ├── active_deadline.go                 # ActiveDeadlineSeconds 处理
    ├── reason_cache.go                    # 容器终止原因缓存
    ├── runtime.go                         # 容器运行时接口
    │
    ├── apis/                              # KubeletConfiguration API 定义
    ├── cadvisor/                          # cAdvisor 集成(容器资源监控)
    ├── certificate/                       # 证书轮转管理
    ├── checkpointmanager/                 # 检查点管理(持久化状态)
    ├── client/                            # kubeclient 创建
    ├── clustertrustbundle/                # 集群信任包分发
    ├── cm/                                # 容器管理器(cgroup/QoS/设备)
    │   ├── container_manager.go           # ContainerManager 接口
    │   ├── container_manager_linux.go     # Linux 实现
    │   ├── cgroup_v1_manager_linux.go     # cgroup v1 管理器
    │   ├── cgroup_v2_manager_linux.go     # cgroup v2 管理器
    │   ├── cpumanager/                    # CPU 管理器(静态分配/亲和性)
    │   ├── devicemanager/                 # 设备管理器(GPU/RDMA 等)
    │   ├── memorymanager/                 # 内存管理器(NUMA 绑定)
    │   ├── topologymanager/               # 拓扑管理器(CPU/设备 NUMA 协调)
    │   ├── qos/                           # QoS 等级管理
    │   ├── dra/                           # Dynamic Resource Allocation
    │   └── admission/                     # 容器级准入控制
    │
    ├── config/                            # Pod 配置源(API Server/File/HTTP)
    ├── configmap/                         # ConfigMap 挂载管理
    ├── container/                         # 容器运行时抽象接口
    ├── envvars/                           # 环境变量注入
    ├── events/                            # Event 记录器
    ├── eviction/                          # 驱逐管理器(压力回收)
    ├── images/                            # 镜像管理(拉取/GC)
    ├── kuberuntime/                       # CRI 容器运行时实现
    │   ├── kuberuntime_manager.go         # kubeRuntimeManager 主结构体
    │   ├── kuberuntime_container.go       # 容器生命周期(创建/启动/停止)
    │   ├── kuberuntime_sandbox.go         # Pod Sandbox 管理
    │   ├── kuberuntime_gc.go              # 容器/Sandbox 垃圾回收
    │   ├── kuberuntime_image.go           # 镜像拉取/删除
    │   ├── kuberuntime_logs.go            # 容器日志管理
    │   └── security_context.go            # 安全上下文设置
    │
    ├── kubeletconfig/                     # Kubelet 动态配置管理
    ├── lifecycle/                         # Pod 生命周期事件(Admit/Sync)
    ├── logs/                              # 日志轮转管理
    ├── metrics/                           # Prometheus 指标
    ├── network/                           # CNI 网络插件管理
    ├── nodeshutdown/                      # 节点关机/重启处理
    ├── nodestatus/                        # 节点状态维护
    ├── oom/                               # OOM 事件监控
    ├── pleg/                              # Pod 生命周期事件生成器
    │   ├── pleg.go                        # PLEG 接口定义
    │   ├── generic.go                     # Generic PLEG(轮询模式)
    │   └── evented.go                     # Evented PLEG(事件驱动模式)
    │
    ├── pluginmanager/                     # 插件管理器(CSI/Device Plugin)
    ├── pod/                               # Pod 操作工具
    ├── podcertificate/                    # Pod 证书管理
    ├── preemption/                        # 节点级抢占
    ├── prober/                            # 探针管理器(Liveness/Readiness/Startup)
    ├── qos/                               # QoS 工具函数
    ├── runtimeclass/                      # RuntimeClass 支持
    ├── secret/                            # Secret 挂载管理
    ├── server/                            # Kubelet HTTP API Server
    ├── stats/                             # 统计信息收集
    ├── status/                            # Pod 状态管理器
    ├── sysctl/                            # Sysctl 应用
    ├── token/                             # ServiceAccount Token 管理
    ├── types/                             # 类型定义(PodStatus/运行时状态)
    ├── userns/                            # 用户命名空间映射
    ├── util/                              # 工具函数
    ├── volumemanager/                     # 卷管理器
    │   ├── volume_manager.go              # VolumeManager 主结构体
    │   ├── cache/                         # 卷状态缓存
    │   ├── populator/                     # 期望/实际状态同步
    │   ├── reconciler/                    # 卷挂载/卸载协调器
    │   └── volumehealth/                  # 卷健康检查
    ├── watchdog/                          # 看门狗
    └── winstats/                          # Windows 统计信息

核心文件解析 #

1. cmd/kubelet/kubelet.go — 入口 #

func main() {
    command := app.NewKubeletCommand()
    code := cli.Run(command)
    os.Exit(code)
}

核心逻辑:与 Scheduler/Controller Manager 一样,main() 极其简单,通过 cobra Command 启动。


2. cmd/kubelet/app/server.go — 启动核心 #

这是 Kubelet 最重要的启动文件,负责:

  • 解析命令行参数和配置文件
  • 构建 KubeletServer 配置
  • 创建并运行 Kubelet 实例
func NewKubeletCommand() *cobra.Command {
    cleanFlagSet := pflag.NewFlagSet(...)
    kubeletFlags := options.NewKubeletFlags()
    kubeletConfig := kubeletconfig.KubeletConfiguration{}

    cmd := &cobra.Command{
        Use: "kubelet",
        Run: func(cmd *cobra.Command, args []string) {
            // 1. 加载配置文件(--config)
            // 2. 校验配置
            // 3. 构建依赖(kubeclient, CRI, CNI 等)
            // 4. 运行 Kubelet
            Run(ctx, kubeletServer, kubeletDeps, ...)
        },
    }
    return cmd
}

启动流程:

main()
  └── NewKubeletCommand()
        └── Run()
              ├── UnsecuredDependencies()     // 构建基础依赖(不含认证)
              ├── SecureDependencies()        // 添加 TLS/认证依赖
              └── RunKubelet()
                    ├── createAndInitKubelet()
                    │     ├── NewMainKubelet()  // 创建 Kubelet 实例
                    │     └── k.Run()           // 启动主循环
                    └── startKubelet()
                          ├── k.Run()           // 核心循环
                          └── server.ListenAndServe()  // HTTP API

3. pkg/kubelet/kubelet.go — Kubelet 主结构体 #

这是 Kubelet 最核心的文件,定义了 Kubelet 结构体和所有主循环逻辑:

type Kubelet struct {
    // --- 核心依赖 ---
    kubeClient       clientset.Interface        // API Server 客户端
    heartbeatClient  clientset.Interface        // 心跳上报专用客户端
    podClient        clientset.Interface        // Pod 操作客户端
    containerManager cm.ContainerManager        // 容器管理器(cgroup)
    containerRuntime kubecontainer.Runtime      // 容器运行时(CRI)
    podWorkers       PodWorkers                 // Pod Worker 池
    pleg             pleg.PodLifecycleEventGenerator  // PLEG
    podCache         kubecontainer.Cache        // Pod 状态缓存

    // --- 子系统 ---
    volumeManager    volumemanager.VolumeManager   // 卷管理器
    probeManager     prober.Manager                // 探针管理器
    evictionManager  eviction.Manager              // 驱逐管理器
    imageManager     images.ImageManager           // 镜像管理器
    statusManager    status.Manager                // Pod 状态管理器
    podAddscribers   []PodAddSubscriber            // Pod 添加订阅者

    // --- Informer ---
    podLister        corelisters.PodLister
    nodeLister       corelisters.NodeLister

    // --- 配置 ---
    kubeletConfiguration kubeletconfig.KubeletConfiguration
    recorder         record.EventRecorder          // 事件记录器
    clock            clock.Clock
    nodeName         string
}

Run() — 主启动方法 #

func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
    // 1. 启动 Cloud Provider 同步
    kl.cloudResourceSyncManager.Run(wait.NeverStop)

    // 2. 启动 VolumeManager
    go kl.volumeManager.Run(kl.sourcesReady, wait.NeverStop, wait.NeverStop)

    // 3. 启动容器运行时(CRI)
    kl.containerRuntime.Start()

    // 4. 启动 PLEG(Pod 生命周期事件生成器)
    kl.pleg.Start()

    // 5. 启动 Pod Workers
    kl.podWorkers.Start()

    // 6. 启动探针管理器
    kl.probeManager.Start()

    // 7. 启动驱逐管理器
    kl.evictionManager.Start(kl)

    // 8. 启动节点状态上报循环
    go kl.nodeStatusManager.Run(wait.NeverStop)

    // 9. 启动状态管理器
    kl.statusManager.Start()

    // 10. 启动主 Pod 同步循环
    go wait.Until(kl.syncLoop, 0, wait.NeverStop)
}

4. pkg/kubelet/pod_workers.go — Pod Worker #

每个 Pod 对应一个独立的 worker goroutine,负责该 Pod 的全部生命周期管理:

type PodWorkers struct {
    podUpdates map[types.UID]chan podWork  // 每 Pod 一个 channel
    cache      *podCache
    client     Client                        // 创建/更新 Pod 状态
    runtime    kubecontainer.Runtime         // CRI 运行时
}

// UpdatePod 处理 Pod 的更新事件
func (p *podWorkers) UpdatePod(options UpdatePodOptions) {
    uid := options.Pod.UID
    ch, exists := p.podUpdates[uid]
    if !exists {
        // 首次见到该 Pod → 创建 worker goroutine
        ch = make(chan podWork, 1)
        p.podUpdates[uid] = ch
        go p.podWorkerLoop(uid, ch)        // 每个 Pod 一个 goroutine
    }
    ch <- podWork{UpdateType: options.UpdateType, Pod: options.Pod}
}

// podWorkerLoop 每 Pod 的主循环
func (p *podWorkers) podWorkerLoop(uid types.UID, ch <-chan podWork) {
    for work := range ch {
        p.syncPodFn(work.Pod)              // 调用 Kubelet.syncPod()
    }
}

5. pkg/kubelet/kubelet.gosyncPod() — Pod 同步核心 #

syncPod() 是 Kubelet 处理单个 Pod 的核心方法:

func (kl *Kubelet) syncPod(ctx context.Context, updateType kubetypes.SyncPodType,
    pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) error {
    // 1. 判断 Pod 是否需要终止(被删除/驱逐)
    if err := kl.canRunPod(pod); err != nil {
        kl.rejectPod(pod, reason, message)
        return err
    }

    // 2. 网络插件设置(CNI)
    if !kl.podIsTerminated(pod) {
        kl.networkPlugin.SetUpPod(pod.Namespace, pod.Name, ...)
    }

    // 3. 创建/更新 Pod Sandbox(CRI)
    podSandboxID, err := kl.containerRuntime.EnsureSandbox(pod)

    // 4. 挂载卷
    kl.volumeManager.WaitForAttachAndMount(pod)

    // 5. 拉取镜像
    kl.containerRuntime.EnsureImageExists(pod, container)

    // 6. 创建/启动容器
    for _, container := range pod.Spec.Containers {
        kl.containerRuntime.CreateContainer(pod, container, podSandboxID)
        kl.containerRuntime.StartContainer(containerID)
    }

    // 7. 启动探针
    kl.probeManager.AddPod(pod)
}

Kubelet 主循环(syncLoop) #

syncLoop 是 Kubelet 的心脏,不断协调多个事件源并驱动 Pod 同步:

┌──────────────────────────────────────────────────────────────────────────┐
│                        Kubelet syncLoop                                   │
│                                                                          │
│  ┌──────────────────┐  ┌──────────────┐  ┌───────────────────┐          │
│  │ Pod 配置源        │  │ PLEG 事件    │  │ 定时同步 (Housekeeping) │      │
│  │ (API Server)     │  │ (容器状态变化) │  │ (每 10s)           │          │
│  └────────┬─────────┘  └──────┬───────┘  └─────────┬─────────┘          │
│           │                   │                     │                    │
│           ▼                   ▼                     ▼                    │
│  ┌──────────────────────────────────────────────────────────┐           │
│  │                    syncLoopIteration()                    │           │
│  │                    (事件合并 + 去重)                        │           │
│  └──────────────────────────┬───────────────────────────────┘           │
│                             │                                            │
│                             ▼                                            │
│  ┌──────────────────────────────────────────────────────────┐           │
│  │                    dispatchWork()                         │           │
│  │                    ┌─ 更新类型判断 ─┐                      │           │
│  │                    │ SyncPodCreate  │                      │           │
│  │                    │ SyncPodUpdate  │                      │           │
│  │                    │ SyncPodKill    │                      │           │
│  │                    └───────┬────────┘                      │           │
│  └────────────────────────────┼──────────────────────────────┘           │
│                               ▼                                          │
│  ┌──────────────────────────────────────────────────────────┐           │
│  │              podWorkers.UpdatePod()                       │           │
│  │              ┌─── 每 Pod 一个 channel ───┐                 │           │
│  │              │  podWorkerLoop (goroutine) │                 │           │
│  │              │       └── syncPod()        │                 │           │
│  │              │            └── CRI 调用    │                 │           │
│  │              └────────────────────────────┘                 │           │
│  └──────────────────────────────────────────────────────────┘           │
└──────────────────────────────────────────────────────────────────────────┘

PLEG — Pod 生命周期事件生成器 #

PLEG 负责检测容器运行时中 Pod 状态的变化,并生成事件通知 Kubelet 进行同步。

两种 PLEG 模式 #

模式文件机制优势劣势
Generic PLEGgeneric.go定时轮询 CRI 获取容器状态兼容性好,适用于所有运行时CPU 开销大,延迟较高(~10s)
Evented PLEGevented.go通过 CRI GetContainerEvents 流式订阅低延迟,低 CPU 开销需要运行时支持(containerd 1.7+)

Generic PLEG 工作流 #

// pkg/kubelet/pleg/generic.go
type GenericPLEG struct {
    runtime    kubecontainer.Runtime
    channel    chan *PodLifecycleEvent   // 事件输出 channel
    podCache   kubecontainer.Cache
    relistPeriod time.Duration            // 轮询间隔(默认 1s)
}

func (g *GenericPLEG) Start() {
    go wait.Until(g.relist, g.relistPeriod, wait.NeverStop)
}

func (g *GenericPLEG) relist() {
    // 1. 从 CRI 获取所有 Pod 的当前状态
    pods, err := g.runtime.GetPods(true)

    // 2. 与缓存中的旧状态对比
    for _, pod := range pods {
        oldStatus := g.podCache.Get(pod.ID)
        newStatus := currentStatus(pod)

        // 3. 检测变化并生成事件
        if oldStatus.Phase != newStatus.Phase {
            g.channel <- &PodLifecycleEvent{
                ID: pod.ID,
                Type: ContainerStarted, // 或 ContainerDied
            }
        }
    }

    // 4. 更新缓存
    g.podCache.Set(pod.ID, newStatus)
}
PLEG 工作流:

  CRI Runtime                Generic PLEG              syncLoop
      │                          │                         │
      │   GetPods() (每 1s)      │                         │
      │ ←────────────────────────│                         │
      │ ──────────────────────→  │                         │
      │                          │ 对比新旧状态              │
      │                          │ 生成 PodLifecycleEvent   │
      │                          │ ──────────────────────→ │
      │                          │                         │ dispatchWork()

容器运行时(CRI) #

Kubelet 通过 CRI(Container Runtime Interface)与容器运行时通信,实现在 kuberuntime/ 目录下:

CRI 架构 #

┌─────────────────────────────────────────────────────┐
│                     Kubelet                          │
│                                                      │
│  ┌──────────────┐    ┌──────────────────────────┐   │
│  │  syncPod()   │───→│  kubeRuntimeManager      │   │
│  │              │    │  (kuberuntime_manager.go) │   │
│  └──────────────┘    └───────────┬──────────────┘   │
│                                  │                   │
│                    ┌─────────────┼─────────────┐    │
│                    │             │             │    │
│              ┌─────▼───┐  ┌─────▼───┐  ┌─────▼───┐  │
│              │Sandbox   │  │Container │  │ Image   │  │
│              │Manager   │  │Manager   │  │ Manager │  │
│              │(sandbox) │  │(container)│  │(image)  │  │
│              └─────┬───┘  └─────┬───┘  └─────┬───┘  │
│                    │            │            │       │
└────────────────────┼────────────┼────────────┼───────┘
                     │    gRPC    │            │
                     ▼            ▼            ▼
              ┌──────────────────────────────────────┐
              │     Container Runtime (CRI shim)      │
              │  ┌──────────┐ ┌────────┐ ┌─────────┐ │
              │  │containerd│ │cri-dockerd│ │CRI-O  │ │
              │  └──────────┘ └────────┘ └─────────┘ │
              └──────────────────────────────────────┘

CRI 两大服务 #

服务gRPC 方法对应文件职责
RuntimeServiceRunPodSandboxkuberuntime_sandbox.go创建/停止 Pod Sandbox(网络命名空间)
CreateContainerkuberuntime_container.go创建容器
StartContainer同上启动容器
StopContainer同上停止容器
RemoveContainer同上删除容器
ListContainers同上列出容器
ContainerStatus同上容器状态
ImageServicePullImagekuberuntime_image.go拉取镜像
ListImages同上列出镜像
RemoveImage同上删除镜像

Pod 创建的 CRI 调用序列 #

syncPod()
  │
  ├── 1. RuntimeService.RunPodSandbox()      → 创建 Pod Sandbox(网络/IPC/UTS 命名空间)
  │       └── 返回 sandboxID
  │
  ├── 2. VolumeManager.WaitForAttachAndMount()  → 等待卷挂载完成
  │
  ├── 3. ImageService.PullImage()            → 拉取容器镜像
  │       └── 返回 imageRef
  │
  ├── 4. RuntimeService.CreateContainer()    → 创建容器(传入 sandboxID, imageRef, 配置)
  │       └── 返回 containerID
  │
  ├── 5. RuntimeService.StartContainer()     → 启动容器
  │
  └── 6. 启动探针(probeManager.AddPod)       → Liveness/Readiness/Startup 探针

容器管理器(Container Manager) #

容器管理器位于 cm/,负责节点级资源管理:

┌─────────────────────────────────────────────────────────────┐
│                  ContainerManager                            │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐  │
│  │ CPUManager   │  │ MemoryManager│  │ DeviceManager     │  │
│  │ (cpumanager) │  │(memorymanager)│  │(devicemanager)   │  │
│  │              │  │              │  │                    │  │
│  │ • static 策略│  │ • NUMA 绑定  │  │ • GPU/RDMA 设备   │  │
│  │ • 独占 CPU   │  │ • 大页管理   │  │ • Device Plugin   │  │
│  └──────┬───────┘  └──────┬───────┘  └────────┬───────────┘  │
│         │                 │                   │              │
│         └─────────────────┼───────────────────┘              │
│                           │                                  │
│                  ┌────────▼─────────┐                        │
│                  │ TopologyManager  │ ← 协调 CPU/设备 NUMA    │
│                  │(topologymanager) │   亲和性分配             │
│                  └──────────────────┘                        │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐  │
│  │ CgroupManager│  │ QoSManager   │  │ InternalContainer │  │
│  │ v1 / v2      │  │ (qos)        │  │ Lifecycle          │  │
│  │              │  │              │  │ (容器级生命周期)      │  │
│  │ • 资源限制   │  │ • Guaranteed │  │ • OOM 分数调整     │  │
│  │ • 命名空间   │  │ • Burstable  │  │ • cgroup 创建      │  │
│  └──────────────┘  └──────────────┘  └──────────────────┘  │
└─────────────────────────────────────────────────────────────┘

QoS 与 cgroup 层级 #

/kubepods (QoS 根 cgroup)
├── /kubepods/pod<UID>/           → Burstable Pod
│   └── <containerID>/
├── /kubepods/burstable/          → Burstable Pod 集合
│   └── pod<UID>/
│       └── <containerID>/
└── /kubepods/besteffort/         → BestEffort Pod 集合
    └── pod<UID>/
        └── <containerID>/

卷管理器(Volume Manager) #

卷管理器位于 volumemanager/,负责 Pod 卷的挂载和卸载:

┌──────────────────────────────────────────────────────────────┐
│                    VolumeManager                               │
│                                                               │
│  ┌─────────────────┐     ┌───────────────────────────────┐   │
│  │ 期望状态          │     │ 实际状态                       │   │
│  │ (来自 Pod Spec)  │     │ (来自 Node 本地)              │   │
│  └────────┬────────┘     └──────────────┬────────────────┘   │
│           │                             │                     │
│           ▼                             ▼                     │
│  ┌────────────────────────────────────────────────────────┐  │
│  │              Populator(填充器)                         │  │
│  │              对比期望 vs 实际,生成 PendingOperations     │  │
│  └────────────────────────┬───────────────────────────────┘  │
│                           │                                    │
│                           ▼                                    │
│  ┌────────────────────────────────────────────────────────┐  │
│  │              Reconciler(协调器)                        │  │
│  │                                                        │  │
│  │  • AttachVolume    → CSI/云驱动挂载远程卷               │  │
│  │  • MountDevice     → 挂载块设备                         │  │
│  │  • SetUp           → 格式化 + 挂载到 Pod 目录           │  │
│  │  • UnmountVolume   → 卸载                              │  │
│  │  • DetachVolume    → 分离远程卷                         │  │
│  └────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────┘

探针管理器(Prober Manager) #

探针管理器位于 prober/,负责 Liveness/Readiness/Startup 探针:

// prober/manager.go
type manager struct {
    // 探针执行器
    livenessProbe  prober.Prober     // HTTP/TCP/Exec 探针执行
    readinessProbe prober.Prober
    startupProbe   prober.Prober

    // 探针结果
    liveness  results.Manager        // 存储结果 + 通知 listener
    readiness results.Manager
    startup   results.Manager

    workers map[probeKey]*worker     // 每容器每探针一个 worker
}

// AddPod 为 Pod 中的每个容器注册探针
func (m *manager) AddPod(pod *v1.Pod) {
    for _, container := range pod.Spec.Containers {
        if container.LivenessProbe != nil {
            key := probeKey{podUID: pod.UID, containerName: container.Name}
            m.workers[key] = newWorker(m.livenessProbe, pod, container)
        }
        // ReadinessProbe / StartupProbe 同理
    }
}

三种探针对比 #

探针作用失败后果文件
Liveness检测容器是否存活重启容器prober/prober.go
Readiness检测容器是否就绪从 Service Endpoints 移除同上
Startup检测容器是否已启动禁用 Liveness/Readiness 直到成功同上
探针执行流程:

  worker.doProbe()
    │
    ├── 容器是否还在运行?
    │     └── 否 → 标记为 Unknown
    │
    ├── HTTP 探针 → HTTP GET :path
    │     └── 200-399 → Success
    │     └── 其他 → Failure
    │
    ├── TCP 探针 → TCP 连接
    │     └── 连通 → Success
    │     └── 超时 → Failure
    │
    ├── Exec 探针 → 容器内执行命令
    │     └── exit 0 → Success
    │     └── exit ≠ 0 → Failure
    │
    └── 结果 → results.Manager → 通知 listener
          ├── Liveness 失败 → kubelet.killContainer() + 重建
          ├── Readiness 失败 → statusManager 更新 Pod Conditions
          └── Startup 成功 → 激活 Liveness/Readiness 探针

驱逐管理器(Eviction Manager) #

驱逐管理器位于 eviction/,在节点资源紧张时主动回收:

节点资源压力检测

  ┌─────────────────┐    超过 Soft Threshold    ┌──────────────────┐
  │ Memory Pressure │ ──────────────────────→  │  Eviction Manager │
  │ Disk Pressure   │    超过 Hard Threshold    │                   │
  │ PID Pressure    │ ──────────────────────→  │  1. 评估所有 Pod   │
  └─────────────────┘                          │  2. 按 QoS 排序    │
                                               │     BestEffort 优先│
                                               │  3. 驱逐选中的 Pod  │
                                               └────────┬──────────┘
                                                        │
                                                        ▼
                                               ┌──────────────────┐
                                               │  KillPod()       │
                                               │  → 删除容器       │
                                               │  → 更新 Pod 状态  │
                                               └──────────────────┘

驱逐信号与阈值 #

信号描述Soft ThresholdHard Threshold
memory.available可用内存100Mi100Mi
nodefs.available节点根分区可用10%5%
nodefs.inodesFree节点 inode 可用5%5%
imagefs.available镜像存储可用15%5%
pid.available可用 PID1000

驱逐优先级 #

驱逐排序(优先级从高到低驱逐):

  1. BestEffort Pod(最优先驱逐)
  2. Burstable Pod 中超过资源请求用量的 Pod
  3. Guaranteed Pod(几乎不会被驱逐)

  同等级内:
  → 优先驱逐使用量超出请求量最多的 Pod

节点状态上报 #

Kubelet 定期向 API Server 上报节点状态,核心逻辑在 kubelet_node_status.go

// 默认每 10s 上报一次
func (kl *Kubelet) registerNode() error {
    // 1. 初始注册 Node
    node := &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: kl.nodeName}}
    node.Status = kl.generateNodeStatus()
    _, err := kl.kubeClient.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{})
}

// 心跳上报(Lease 方式,默认 10s)
func (kl *Kubelet) updateNodeStatus() error {
    // 1. 获取当前节点状态(资源使用、条件、地址等)
    node, _ := kl.kubeClient.CoreV1().Nodes().Get(ctx, kl.nodeName, ...)

    // 2. 更新 Conditions
    //    - Ready(节点是否正常)
    //    - MemoryPressure(内存压力)
    //    - DiskPressure(磁盘压力)
    //    - PIDPressure(PID 压力)
    //    - NetworkUnavailable(网络不可用)

    // 3. 更报容量和分配量
    node.Status.Capacity = kl.containerManager.GetNodeAllocatable()
    node.Status.Allocatable = kl.containerManager.GetNodeAllocatable()

    // 4. 通过 Lease 快速心跳
    kl.leaseManager.Update(ctx, node)
}
心跳机制(两种):

  ┌─────────────────┐         ┌──────────────┐
  │   Kubelet        │         │  API Server   │
  │                  │         │               │
  │  Node Status     │── 10s → │  Node 对象更新 │ ← 完整状态
  │  (更新 Conditions) │        │               │
  │                  │         │               │
  │  Node Lease      │── 10s → │  Lease 对象   │ ← 轻量心跳
  │  (仅 renewTime)  │         │  (coordination.k8s.io/lease)
  └─────────────────┘         └──────────────┘

  节点失联判定:
  ├── Lease 超过 40s 未更新 → 栀 node.kubernetes.io/unreachable
  └── Controller Manager 标记 NotReady + 驱逐 Pod(--pod-eviction-timeout)

Kubelet HTTP API #

Kubelet 在 10250 端口提供 HTTP/HTTPS API,实现在 server/

端点方法认证功能
/podsGET列出本节点所有 Pod
/runningpodsGET列出运行中的 Pod
/run/<ns>/<pod>/<container>POST在容器内执行命令
/exec/<ns>/<pod>/<container>GET/POST容器 exec(WebSocket)
/attach/<ns>/<pod>/<container>GET/POST容器 attach
/portForward/<ns>/<pod>GET/POST端口转发
/containerLogs/<ns>/<pod>/<container>GET获取容器日志
/stats/summaryGET资源使用统计(cAdvisor)
/metricsGETPrometheus 指标
/healthzGET健康检查
/pods/statusPUT更新 Pod 状态(kube-proxy)

Kubelet 组件协作全景 #

                         ┌──────────────┐
                         │  API Server  │
                         └──────┬───────┘
                                │ Watch (Pod/Node)
                    ┌───────────┼───────────┐
                    ▼           │           ▼
          ┌──────────────┐      │    ┌──────────────┐
          │ Pod 配置源    │      │    │  节点状态上报  │
          │ (config/)    │      │    │ (node_status) │
          └──────┬───────┘      │    └──────────────┘
                 │              │
                 ▼              │
    ┌────────────────────────────┴───────────────────────────┐
    │                    Kubelet syncLoop                      │
    │                                                         │
    │  ┌─────────┐  ┌─────────┐  ┌──────────┐  ┌──────────┐ │
    │  │ config  │  │  pleg   │  │ syncLoop │  │ housekeep│ │
    │  │  源     │  │  事件   │  │   迭代   │  │  定时    │ │
    │  └────┬────┘  └────┬────┘  └────┬─────┘  └────┬─────┘ │
    │       └─────────────┴───────────┴─────────────┘       │
    │                          │                              │
    │                    dispatchWork()                       │
    │                          │                              │
    │              ┌───────────▼───────────┐                  │
    │              │    podWorkers          │                  │
    │              │  ┌─ Pod A (goroutine) │                  │
    │              │  ├─ Pod B (goroutine) │                  │
    │              │  └─ Pod C (goroutine) │                  │
    │              └───────────┬───────────┘                  │
    └──────────────────────────┼──────────────────────────────┘
                               │ syncPod()
                    ┌──────────┼──────────────────────────┐
                    ▼          ▼                           ▼
          ┌──────────────┐  ┌──────────────┐    ┌──────────────┐
          │ VolumeManager│  │   CRI        │    │ ProbeManager │
          │ (挂载/卸载卷)  │  │ (创建/启动   │    │ (存活/就绪   │
          │              │  │  容器)       │    │  探针)       │
          └──────────────┘  └──────┬───────┘    └──────┬───────┘
                                   │                   │
                          ┌────────┴────────┐         │
                          ▼                 ▼         │
                 ┌──────────────┐  ┌──────────────┐   │
                 │ContainerMgr  │  │   Status     │◄──┘
                 │ (cgroup/CPU  │  │  Manager     │
                 │  /设备/内存)  │  │ (上报 Pod    │
                 └──────────────┘  │  状态到 API)  │
                                   └──────────────┘

关键设计模式 #

1. 声明式 Reconcile 循环 #

// syncLoop 每次迭代都对比期望状态和实际状态
func (kl *Kubelet) syncLoopIteration(...) {
    // 从多个 channel 读取事件
    select {
    case update := <-kl.podConfig.Updates():
        // Pod 配置变更 → dispatchWork
    case e := <-kl.pleg.Watch():
        // PLEG 检测到容器状态变化 → dispatchWork
    case <-housekeeping:
        // 定时清理
    }
}

// 不管事件来源如何,最终都走 syncPod()
// syncPod 从缓存读取最新状态而非依赖事件数据

2. 每 Pod 独立 Worker 隔离 #

// 每 Pod 独立 goroutine,避免慢 Pod 阻塞其他 Pod
// Pod A 的 syncPod 耗时 30s 不会阻塞 Pod B 的处理
go p.podWorkerLoop(uidA, chA)   // Pod A worker
go p.podWorkerLoop(uidB, chB)   // Pod B worker
go p.podWorkerLoop(uidC, chC)   // Pod C worker

3. PLEG 事件驱动(避免盲轮询) #

// Generic PLEG:用 relist 轮询代替每容器单独轮询
// 通过对比新旧状态,仅在变化时生成事件
// syncLoop 收到事件后 dispatchWork,避免不必要的同步

4. 多级缓存与最终一致性 #

  API Server (etcd)
       │
       ▼ Watch
  Pod Informer (本地缓存)          ← podLister
       │
       ▼ syncLoop
  Pod Status Cache (kubecontainer.Cache)  ← PLEG 维护
       │
       ▼ CRI
  Container Runtime (真实容器状态)

学习路径建议 #

第一步:理解整体架构
  ├── Kubelet 是什么(节点 Agent,非集群级组件)
  ├── syncLoop 主循环(事件驱动 + Reconcile)
  └── Pod 从 API Server 到容器的完整链路

第二步:从入口追踪
  ├── cmd/kubelet/kubelet.go → main()
  ├── app/server.go → Run() → RunKubelet()
  ├── kubelet.go → NewMainKubelet() → Run()
  └── 关注 Run() 中启动的各个子系统

第三步:精读 Pod 生命周期
  ├── kubelet.go → syncPod()(核心方法)
  ├── pod_workers.go → UpdatePod() + podWorkerLoop()
  ├── kuberuntime_manager.go → 创建 Sandbox + 容器
  └── 追踪 CRI 调用链:RunPodSandbox → PullImage → CreateContainer → StartContainer

第四步:理解状态感知
  ├── pleg/generic.go → relist() 轮询机制
  ├── pleg/evented.go → 事件驱动 PLEG(新特性)
  ├── prober/manager.go → 探针管理
  └── status/manager.go → 状态上报 API Server

第五步:深入子系统
  ├── cm/ → cgroup v1/v2、CPU/内存/设备管理
  ├── volumemanager/ → 卷 Attach/Mount/Unmount
  ├── eviction/ → 资源压力驱逐策略
  └── network/ → CNI 插件调用

第六步:扩展实践
  ├── 编写 CRI shim(实现 RuntimeService + ImageService)
  ├── 编写 CNI 插件(实现 CmdAdd/CmdDel)
  ├── 编写 Device Plugin(gRPC 设备分配)
  └── 阅读 Kubelet 性能优化提案(PLEG → Evented PLEG)

Reference #

kubelet 源码入口

pkg/kubelet 核心实现

CRI 容器运行时实现

PLEG 源码

容器管理器源码

卷管理器源码

Kubelet 官方文档

CRI 规范

Evented PLEG KEP

Kubelet 架构文档

探针配置文档