【kubernetes v1.21】(kubelet 1)Kubelet 核心架构与启动流程

Kubelet 核心架构与启动流程超深度分析

基于 Kubernetes 源码解析,覆盖 cmd/kubelet、pkg/kubelet 核心代码路径


一、模块定位

1.1 Kubelet 业务职责

Kubelet 是 Kubernetes 集群中运行在每个 Node 上的核心代理(Node Agent),它是将"声明式 API 世界"映射到"容器运行时现实"的关键桥梁。其核心职责可归纳为:

职责域 具体内容
Pod 生命周期管理 接收 PodSpec,驱动容器创建/启动/停止/删除,实现期望状态收敛
节点状态上报 周期性向 API Server 报告 Node Status(Capacity、Allocatable、Conditions、Addresses、Images)
容器健康探测 执行 Liveness、Readiness、Startup 三种探针,根据结果决策重启/流量/状态
资源驱逐(Eviction) 监控节点资源压力(Memory、Disk、PID),按策略驱逐低优先级 Pod
卷管理(Volume) 协调 Volume Attach/Mount/Unmount/Detach,确保 Pod 存储就绪
镜像垃圾回收 按磁盘使用率阈值回收未使用镜像,保障节点磁盘空间
容器垃圾回收 清理已终止容器,防止磁盘泄漏
Cgroup 资源管理 按 QoS 等级创建/维护 Cgroup 层级,实施资源限制
静态 Pod 管理 监控本地文件/HTTP URL 上的 PodSpec,自动创建 Mirror Pod
证书轮转 支持客户端/服务端证书自动轮转,保障集群安全通信
节点优雅关闭 监听系统关机信号,按策略优雅终止 Pod
设备管理 通过 Device Plugin 框架管理 GPU/FPGA/RDMA 等扩展资源
动态配置 从 API Server 动态获取并应用 Kubelet 配置变更

1.2 在 Kubernetes 架构中的位置

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    Control Plane                             │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
│  │ API Server│ │ Scheduler│ │Ctrl Mgr  │ │  Cloud Ctrl    │ │
│  └────┬──────┘ └──────────┘ └──────────┘ └────────────────┘ │
│       │ Watch/REST                                           │
└───────┼──────────────────────────────────────────────────────┘
        │
        ▼
┌───────────────────────────────────────────────────────────────┐
│                     Node                                      │
│  ┌──────────────────────────────────────────────────────────┐ │
│  │                     Kubelet                              │ │
│  │  ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────────┐  │ │
│  │  │PodConfig│ │SyncLoop  │ │PLEG     │ │StatusManager │  │ │
│  │  └─────────┘ └──────────┘ └─────────┘ └──────────────┘  │ │
│  │  ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────────┐  │ │
│  │  │VolumeMgr│ │Eviction  │ │Prober   │ │ContainerMgr  │  │ │
│  │  └─────────┘ └──────────┘ └─────────┘ └──────────────┘  │ │
│  │         │                                                 │ │
│  │         ▼ CRI                                             │ │
│  │  ┌──────────────────────────────────────────────────────┐│ │
│  │  │              Container Runtime                       ││ │
│  │  │  (dockershim / containerd / CRI-O / ...)            ││ │
│  │  └──────────────────────────────────────────────────────┘│ │
│  └──────────────────────────────────────────────────────────┘ │
│  ┌────────┐ ┌──────────┐ ┌──────────────────────┐           │
│  │ kubelet│ │  kube-   │ │  Linux Kernel        │           │
│  │  proxy │ │  proxy   │ │  (cgroup/net/iptables)│           │
│  └────────┘ └──────────┘ └──────────────────────┘           │
└───────────────────────────────────────────────────────────────┘

Kubelet 处于控制面与数据面的交汇点------它既是控制面的"执行者"(接收调度结果、执行 Pod 创建/删除),也是数据面的"观察者"(采集节点状态、容器状态、资源指标)。


二、模块整体结构

2.1 Kubelet Struct 字段详解

Kubelet 结构体是整个 Kubelet 的核心实体,位于 pkg/kubelet/kubelet.go,拥有超过 80 个字段,按功能域分类如下:

go 复制代码
type Kubelet struct {
    // ====== 身份与基础配置 ======
    kubeletConfiguration kubeletconfiginternal.KubeletConfiguration  // 运行时配置(可动态更新)
    hostname             string                // 检测到或被覆盖的主机名
    hostnameOverridden   bool                  // 主机名是否被覆盖
    nodeName             types.NodeName        // 节点名(可能由云提供商确定)
    rootDirectory        string                // 根目录(默认 /var/lib/kubelet)
    nodeIPs              []net.IP              // 节点 IP(支持双栈)
    providerID           string                // 外部数据库中的节点唯一标识

    // ====== 客户端连接 ======
    kubeClient           clientset.Interface   // 与 API Server 通信的主客户端
    heartbeatClient      clientset.Interface   // 专用于心跳的客户端(独立限流)
    onRepeatedHeartbeatFailure func()          // 心跳持续失败回调(关闭所有连接)

    // ====== Pod 管理 ======
    podManager           kubepod.Manager       // Pod 真实来源的统一门面(API+Static+Mirror)
    podWorkers           PodWorkers            // Per-Pod 异步同步工作器
    workQueue            queue.WorkQueue       // 触发 Pod Worker 的工作队列
    podCache             kubecontainer.Cache   // Pod 运行时状态缓存
    podKiller            PodKiller             // 处理需要被杀死的 Pod

    // ====== 状态管理 ======
    statusManager        status.Manager        // Pod 状态与 API Server 同步
    reasonCache          *ReasonCache          // 容器创建失败原因缓存
    lastContainerStartedTime *timeCache        // 每Pod最后一次容器启动时间

    // ====== 容器运行时 ======
    containerRuntime     kubecontainer.Runtime        // 容器运行时抽象接口
    containerRuntimeName string                       // 运行时名称(docker/remote)
    runtimeService       internalapi.RuntimeService   // CRI RuntimeService 客户端
    runtimeCache         kubecontainer.RuntimeCache   // 运行时状态缓存
    streamingRuntime     kubecontainer.StreamingRuntime // 流式操作接口(exec/attach/port-forward)
    runner               kubecontainer.CommandRunner  // 命令执行器
    containerLogManager  logs.ContainerLogManager     // 容器日志管理器
    dockerLegacyService  legacy.DockerLegacyService   // Docker 遗留服务

    // ====== 运行时状态 ======
    runtimeState         *runtimeState         // 运行时健康状态(网络/存储/运行时错误)
    oneTimeInitializer   sync.Once             // 运行时依赖模块的一次性初始化

    // ====== 探针 ======
    probeManager         prober.Manager        // 探针管理器(Liveness/Readiness/Startup)
    livenessManager      proberesults.Manager  // Liveness 探针结果
    readinessManager     proberesults.Manager  // Readiness 探针结果
    startupManager       proberesults.Manager  // Startup 探针结果

    // ====== 垃圾回收 ======
    containerGC          kubecontainer.GC      // 容器 GC
    imageManager         images.ImageGCManager // 镜像 GC
    containerDeletor     *podContainerDeletor  // Pod 内容器删除器

    // ====== 资源管理 ======
    containerManager     cm.ContainerManager   // Cgroup/设备/拓扑管理器
    cgroupsPerQOS        bool                  // 是否启用 QoS Cgroup 层级
    cgroupRoot           string                // Cgroup 根路径
    evictionManager      eviction.Manager      // 驱逐管理器

    // ====== 卷与存储 ======
    volumePluginMgr      *volume.VolumePluginMgr  // 卷插件管理器
    volumeManager        volumemanager.VolumeManager // 卷 Attach/Mount 协调器
    mounter              mount.Interface         // 文件系统挂载接口
    hostutil             hostutil.HostUtils      // 宿主文件系统工具
    subpather            subpath.Interface       // 子路径处理

    // ====== 网络 ======
    dnsConfigurer        *dns.Configurer       // DNS 解析配置器
    makeIPTablesUtilChains bool                 // 是否创建 iptables 工具链
    iptablesMasqueradeBit int                   // SNAT 标记位
    iptablesDropBit      int                    // DROP 标记位

    // ====== 云提供商 ======
    cloud                cloudprovider.Interface        // 云提供商接口
    cloudResourceSyncManager cloudresource.SyncManager  // 云资源同步管理器
    externalCloudProvider bool                         // 是否使用外部云控制器

    // ====== 节点注册与状态 ======
    registerNode         bool                  // 是否自动注册节点
    registerWithTaints   []api.Taint           // 注册时添加的 Taint
    registrationCompleted bool                  // 注册是否完成
    nodeStatusUpdateFrequency time.Duration    // 节点状态更新频率
    nodeStatusReportFrequency  time.Duration   // 节点状态上报频率(启用 Lease 时)
    lastStatusReportTime time.Time             // 最后上报时间
    nodeLeaseController  lease.Controller      // 节点 Lease 控制器
    nodeRef              *v1.ObjectReference   // 节点对象引用(用于事件)
    nodeLabels           map[string]string     // 注册时的节点标签
    nodeLister           corelisters.NodeLister    // 节点列表器
    nodeHasSynced        cache.InformerSynced       // 节点 Informer 同步状态
    daemonEndpoints      *v1.NodeDaemonEndpoints    // Daemon 端口信息
    nodeStatusMaxImages  int32                      // 节点状态中最大镜像数

    // ====== 服务发现 ======
    serviceLister        serviceLister         // Service 列表器
    serviceHasSynced     cache.InformerSynced  // Service 同步状态
    masterServiceNamespace string              // Master Service 命名空间

    // ====== 配置与密钥 ======
    secretManager        secret.Manager        // Secret 管理器
    configMapManager     configmap.Manager     // ConfigMap 管理器

    // ====== 准入与生命周期钩子 ======
    admitHandlers        lifecycle.PodAdmitHandlers    // Pod 准入处理器链
    softAdmitHandlers    lifecycle.PodAdmitHandlers    // 软准入处理器链(准入后、运行前)
    PodSyncLoopHandlers  lifecycle.PodSyncLoopHandlers // SyncLoop 同步钩子
    PodSyncHandlers      lifecycle.PodSyncHandlers     // Sync 同步钩子

    // ====== 其他关键模块 ======
    cadvisor             cadvisor.Interface        // cAdvisor 接口
    StatsProvider        *stats.Provider           // 统计数据提供者
    resourceAnalyzer     serverstats.ResourceAnalyzer // 资源分析器
    oomWatcher           oomwatcher.Watcher         // OOM 事件监听器
    pluginManager        pluginmanager.PluginManager // 插件管理器(CSI/DevicePlugin)
    runtimeClassManager  *runtimeclass.Manager      // RuntimeClass 管理器
    serverCertificateManager certificate.Manager    // 服务端证书管理器
    appArmorValidator    apparmor.Validator          // AppArmor 验证器
    shutdownManager      *nodeshutdown.Manager       // 节点关闭管理器

    // ====== 同步控制 ======
    sourcesReady         config.SourcesReady     // 配置源就绪状态
    resyncInterval       time.Duration           // 周期性全量同步间隔
    syncLoopMonitor      atomic.Value            // 同步循环监控时间戳
    backOff              *flowcontrol.Backoff     // 容器重启退避
    maxPods              int                      // 最大 Pod 数
    podsPerCore          int                      // 每核心 Pod 数

    // ====== 杂项 ======
    os                   kubecontainer.OSInterface // 系统调用抽象
    clock                clock.Clock              // 时钟(可测试)
    logServer            http.Handler             // 日志 HTTP Handler
    recorder             record.EventRecorder     // 事件记录器
    streamingConnectionIdleTimeout time.Duration   // 流式连接空闲超时
    experimentalHostUserNamespaceDefaulting bool   // 实验性 Host 用户命名空间
    keepTerminatedPodVolumes bool                  // 保持已终止 Pod 卷挂载(调试用)
}

2.2 核心接口定义

SyncHandler 接口

SyncHandler 是 Kubelet 实现的核心接口,定义了 SyncLoop 回调方法:

go 复制代码
type SyncHandler interface {
    HandlePodAdditions(pods []*v1.Pod)    // Pod 新增
    HandlePodUpdates(pods []*v1.Pod)      // Pod 更新
    HandlePodRemoves(pods []*v1.Pod)      // Pod 移除
    HandlePodReconcile(pods []*v1.Pod)    // Pod 状态调和
    HandlePodSyncs(pods []*v1.Pod)        // Pod 同步触发
    HandlePodCleanups() error             // Pod 清理
}

Kubelet 自身实现了该接口,在 syncLoopIteration 中通过 select 多路复用分发事件。

Bootstrap 接口

Bootstrap 接口定义了 Kubelet 的引导协议:

go 复制代码
type Bootstrap interface {
    GetConfiguration() kubeletconfiginternal.KubeletConfiguration
    BirthCry()
    StartGarbageCollection()
    ListenAndServe(kubeCfg, tlsOptions, auth)
    ListenAndServeReadOnly(address, port)
    ListenAndServePodResources()
    Run(updates <-chan kubetypes.PodUpdate)
    RunOnce(updates <-chan kubetypes.PodUpdate) ([]RunPodResult, error)
}
PodWorkers 接口
go 复制代码
type PodWorkers interface {
    UpdatePod(options *UpdatePodOptions)                        // 更新 Pod
    ForgetNonExistingPodWorkers(desiredPods map[types.UID]sets.Empty) // 清理不存在的 Pod Worker
    ForgetWorker(uid types.UID)                                  // 遗忘特定 Pod Worker
}

2.3 依赖注入 Dependencies

Dependencies 是 Kubelet 的运行时依赖注入容器,由 UnsecuredDependencies 或调用方构建:

go 复制代码
type Dependencies struct {
    Options []Option                          // 函数式选项

    Auth                    server.AuthInterface          // 认证/授权接口
    CAdvisorInterface       cadvisor.Interface            // cAdvisor 接口
    Cloud                   cloudprovider.Interface       // 云提供商
    ContainerManager        cm.ContainerManager           // 容器管理器
    DockerOptions           *DockerOptions                // Docker 特定配置
    EventClient             v1core.EventsGetter           // 事件客户端
    HeartbeatClient         clientset.Interface           // 心跳客户端
    OnHeartbeatFailure      func()                        // 心跳失败回调
    KubeClient              clientset.Interface           // API Server 客户端
    Mounter                 mount.Interface               // 挂载器
    HostUtil                hostutil.HostUtils            // 宿主工具
    OOMAdjuster             *oom.OOMAdjuster              // OOM 调整器
    OSInterface             kubecontainer.OSInterface     // OS 抽象
    PodConfig               *config.PodConfig             // Pod 配置多路复用器
    Recorder                record.EventRecorder          // 事件记录器
    Subpather               subpath.Interface             // 子路径
    VolumePlugins           []volume.VolumePlugin         // 卷插件列表
    DynamicPluginProber     volume.DynamicPluginProber    // 动态插件探测器
    TLSOptions              *server.TLSOptions            // TLS 配置
    KubeletConfigController *kubeletconfig.Controller     // 动态配置控制器
    RemoteRuntimeService    internalapi.RuntimeService    // CRI Runtime 服务
    RemoteImageService      internalapi.ImageManagerService // CRI Image 服务
    dockerLegacyService     legacy.DockerLegacyService    // Docker 遗留服务
    useLegacyCadvisorStats bool                           // 是否使用遗留 cAdvisor 统计
}

2.4 核心方法清单

方法 所属 功能
NewKubeletCommand() app 创建 Cobra 命令入口
Run() app 启动 Kubelet 的顶层函数
run() app Run 的实际实现
RunKubelet() app 创建并启动 Kubelet 实例
createAndInitKubelet() app 调用 NewMainKubelet 并初始化
startKubelet() app 启动 Kubelet 的 goroutine
NewMainKubelet() kubelet 构造 Kubelet 对象及其所有子模块
Run() Kubelet Kubelet 主运行循环
initializeModules() Kubelet 初始化不依赖运行时的模块
initializeRuntimeDependentModules() Kubelet 初始化依赖运行时的模块
syncLoop() Kubelet 主同步循环(永不返回)
syncLoopIteration() Kubelet 单次同步迭代
syncPod() Kubelet 单 Pod 同步事务脚本
HandlePodAdditions() Kubelet 处理 Pod 新增
HandlePodUpdates() Kubelet 处理 Pod 更新
HandlePodRemoves() Kubelet 处理 Pod 移除
HandlePodReconcile() Kubelet 处理 Pod 调和
HandlePodSyncs() Kubelet 处理 Pod 同步
HandlePodCleanups() Kubelet 处理 Pod 清理
canAdmitPod() Kubelet Pod 准入检查
canRunPod() Kubelet Pod 运行性检查
dispatchWork() Kubelet 分发 Pod 到 Worker
deletePod() Kubelet 删除 Pod
updateRuntimeUp() Kubelet 更新运行时状态
syncNodeStatus() Kubelet 同步节点状态到 API Server

2.5 调用关系总图

#mermaid-svg-2VvvArcuwNTVviYy{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2VvvArcuwNTVviYy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2VvvArcuwNTVviYy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2VvvArcuwNTVviYy .error-icon{fill:#552222;}#mermaid-svg-2VvvArcuwNTVviYy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2VvvArcuwNTVviYy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2VvvArcuwNTVviYy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2VvvArcuwNTVviYy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2VvvArcuwNTVviYy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2VvvArcuwNTVviYy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2VvvArcuwNTVviYy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2VvvArcuwNTVviYy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2VvvArcuwNTVviYy .marker.cross{stroke:#333333;}#mermaid-svg-2VvvArcuwNTVviYy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2VvvArcuwNTVviYy p{margin:0;}#mermaid-svg-2VvvArcuwNTVviYy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2VvvArcuwNTVviYy .cluster-label text{fill:#333;}#mermaid-svg-2VvvArcuwNTVviYy .cluster-label span{color:#333;}#mermaid-svg-2VvvArcuwNTVviYy .cluster-label span p{background-color:transparent;}#mermaid-svg-2VvvArcuwNTVviYy .label text,#mermaid-svg-2VvvArcuwNTVviYy span{fill:#333;color:#333;}#mermaid-svg-2VvvArcuwNTVviYy .node rect,#mermaid-svg-2VvvArcuwNTVviYy .node circle,#mermaid-svg-2VvvArcuwNTVviYy .node ellipse,#mermaid-svg-2VvvArcuwNTVviYy .node polygon,#mermaid-svg-2VvvArcuwNTVviYy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2VvvArcuwNTVviYy .rough-node .label text,#mermaid-svg-2VvvArcuwNTVviYy .node .label text,#mermaid-svg-2VvvArcuwNTVviYy .image-shape .label,#mermaid-svg-2VvvArcuwNTVviYy .icon-shape .label{text-anchor:middle;}#mermaid-svg-2VvvArcuwNTVviYy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2VvvArcuwNTVviYy .rough-node .label,#mermaid-svg-2VvvArcuwNTVviYy .node .label,#mermaid-svg-2VvvArcuwNTVviYy .image-shape .label,#mermaid-svg-2VvvArcuwNTVviYy .icon-shape .label{text-align:center;}#mermaid-svg-2VvvArcuwNTVviYy .node.clickable{cursor:pointer;}#mermaid-svg-2VvvArcuwNTVviYy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2VvvArcuwNTVviYy .arrowheadPath{fill:#333333;}#mermaid-svg-2VvvArcuwNTVviYy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2VvvArcuwNTVviYy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2VvvArcuwNTVviYy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2VvvArcuwNTVviYy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2VvvArcuwNTVviYy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2VvvArcuwNTVviYy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2VvvArcuwNTVviYy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2VvvArcuwNTVviYy .cluster text{fill:#333;}#mermaid-svg-2VvvArcuwNTVviYy .cluster span{color:#333;}#mermaid-svg-2VvvArcuwNTVviYy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2VvvArcuwNTVviYy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2VvvArcuwNTVviYy rect.text{fill:none;stroke-width:0;}#mermaid-svg-2VvvArcuwNTVviYy .icon-shape,#mermaid-svg-2VvvArcuwNTVviYy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2VvvArcuwNTVviYy .icon-shape p,#mermaid-svg-2VvvArcuwNTVviYy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2VvvArcuwNTVviYy .icon-shape .label rect,#mermaid-svg-2VvvArcuwNTVviYy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2VvvArcuwNTVviYy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2VvvArcuwNTVviYy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2VvvArcuwNTVviYy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} pkg/kubelet
cmd/kubelet
main()
NewKubeletCommand()
Run() (cobra)
app.Run()
app.run()
RunKubelet()
createAndInitKubelet()
startKubelet()
NewMainKubelet()
k.BirthCry()
k.StartGarbageCollection()
k.Run()
k.initializeModules()
k.initializeRuntimeDependentModules()
k.syncLoop()
k.syncLoopIteration()
k.syncPod()
k.HandlePodAdditions()
k.HandlePodUpdates()
k.HandlePodRemoves()
k.HandlePodReconcile()
k.HandlePodSyncs()
k.HandlePodCleanups()

2.6 数据流

#mermaid-svg-wX72ZgC8yxfhSaGf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wX72ZgC8yxfhSaGf .error-icon{fill:#552222;}#mermaid-svg-wX72ZgC8yxfhSaGf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wX72ZgC8yxfhSaGf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wX72ZgC8yxfhSaGf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wX72ZgC8yxfhSaGf .marker.cross{stroke:#333333;}#mermaid-svg-wX72ZgC8yxfhSaGf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wX72ZgC8yxfhSaGf p{margin:0;}#mermaid-svg-wX72ZgC8yxfhSaGf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf .cluster-label text{fill:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf .cluster-label span{color:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf .cluster-label span p{background-color:transparent;}#mermaid-svg-wX72ZgC8yxfhSaGf .label text,#mermaid-svg-wX72ZgC8yxfhSaGf span{fill:#333;color:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf .node rect,#mermaid-svg-wX72ZgC8yxfhSaGf .node circle,#mermaid-svg-wX72ZgC8yxfhSaGf .node ellipse,#mermaid-svg-wX72ZgC8yxfhSaGf .node polygon,#mermaid-svg-wX72ZgC8yxfhSaGf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wX72ZgC8yxfhSaGf .rough-node .label text,#mermaid-svg-wX72ZgC8yxfhSaGf .node .label text,#mermaid-svg-wX72ZgC8yxfhSaGf .image-shape .label,#mermaid-svg-wX72ZgC8yxfhSaGf .icon-shape .label{text-anchor:middle;}#mermaid-svg-wX72ZgC8yxfhSaGf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wX72ZgC8yxfhSaGf .rough-node .label,#mermaid-svg-wX72ZgC8yxfhSaGf .node .label,#mermaid-svg-wX72ZgC8yxfhSaGf .image-shape .label,#mermaid-svg-wX72ZgC8yxfhSaGf .icon-shape .label{text-align:center;}#mermaid-svg-wX72ZgC8yxfhSaGf .node.clickable{cursor:pointer;}#mermaid-svg-wX72ZgC8yxfhSaGf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wX72ZgC8yxfhSaGf .arrowheadPath{fill:#333333;}#mermaid-svg-wX72ZgC8yxfhSaGf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wX72ZgC8yxfhSaGf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wX72ZgC8yxfhSaGf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wX72ZgC8yxfhSaGf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wX72ZgC8yxfhSaGf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wX72ZgC8yxfhSaGf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wX72ZgC8yxfhSaGf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wX72ZgC8yxfhSaGf .cluster text{fill:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf .cluster span{color:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wX72ZgC8yxfhSaGf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wX72ZgC8yxfhSaGf rect.text{fill:none;stroke-width:0;}#mermaid-svg-wX72ZgC8yxfhSaGf .icon-shape,#mermaid-svg-wX72ZgC8yxfhSaGf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wX72ZgC8yxfhSaGf .icon-shape p,#mermaid-svg-wX72ZgC8yxfhSaGf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wX72ZgC8yxfhSaGf .icon-shape .label rect,#mermaid-svg-wX72ZgC8yxfhSaGf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wX72ZgC8yxfhSaGf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wX72ZgC8yxfhSaGf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wX72ZgC8yxfhSaGf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Container Runtime
PodWorkers
SyncLoop
PodConfig
配置源
File Source

(Static Pod)
HTTP Source

(URL Manifest)
APIServer Source

(Watch/List)
config.Mux
podStorage
updates chan
syncLoopIteration
SyncHandler
Pod Worker 1
Pod Worker 2
Pod Worker N
CRI RuntimeService
CRI ImageService


三、核心业务逻辑深度解析

3.1 启动完整流程:main() → Run → NewMainKubelet → Run

3.1.1 入口:main()
go 复制代码
// cmd/kubelet/kubelet.go
func main() {
    rand.Seed(time.Now().UnixNano())         // 初始化随机种子
    command := app.NewKubeletCommand()        // 创建 Cobra 命令
    logs.InitLogs()                          // 初始化日志
    defer logs.FlushLogs()                   // 确保日志刷盘
    if err := command.Execute(); err != nil {
        os.Exit(1)
    }
}
3.1.2 NewKubeletCommand()
go 复制代码
func NewKubeletCommand() *cobra.Command {
    kubeletFlags := options.NewKubeletFlags()            // 初始化 Flag 对象
    kubeletConfig, err := options.NewKubeletConfiguration() // 初始化配置对象

    cmd := &cobra.Command{
        Use:   "kubelet",
        DisableFlagParsing: true,   // 禁用 Cobra 解析,手动处理以实现 Flag 优先级
        Run: func(cmd *cobra.Command, args []string) {
            // 1. 手动解析 Flag
            cleanFlagSet.Parse(args)

            // 2. 设置 Feature Gates
            utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates)

            // 3. 验证 KubeletFlags
            options.ValidateKubeletFlags(kubeletFlags)

            // 4. 加载配置文件(如果指定了 --config)
            if configFile := kubeletFlags.KubeletConfigFile; len(configFile) > 0 {
                kubeletConfig = loadConfigFile(configFile)
                // 4.1 重新应用 Flag 优先级
                kubeletConfigFlagPrecedence(kubeletConfig, args)
                // 4.2 更新 Feature Gates
                utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates)
            }

            // 5. 验证 KubeletConfiguration
            kubeletconfigvalidation.ValidateKubeletConfiguration(kubeletConfig)

            // 6. 动态配置初始化(如果启用)
            if dynamicConfigDir := kubeletFlags.DynamicConfigDir.Value(); len(dynamicConfigDir) > 0 {
                dynamicKubeletConfig, kubeletConfigController = BootstrapKubeletConfigController(...)
                if dynamicKubeletConfig != nil {
                    kubeletConfig = dynamicKubeletConfig
                }
            }

            // 7. 构建 KubeletServer
            kubeletServer := &options.KubeletServer{
                KubeletFlags:         *kubeletFlags,
                KubeletConfiguration: *kubeletConfig,
            }

            // 8. 构建默认 Dependencies
            kubeletDeps = UnsecuredDependencies(kubeletServer, utilfeature.DefaultFeatureGate)

            // 9. 设置信号上下文
            ctx := genericapiserver.SetupSignalContext()

            // 10. 执行 Run
            Run(ctx, kubeletServer, kubeletDeps, utilfeature.DefaultFeatureGate)
        },
    }
    // 注册 Flag
    kubeletFlags.AddFlags(cleanFlagSet)
    options.AddKubeletConfigFlags(cleanFlagSet, kubeletConfig)
    return cmd
}

关键设计点------Flag 优先级 :Kubelet 禁用了 Cobra 的自动 Flag 解析,改为手动处理。这是因为需要实现严格的优先级规则:命令行 Flag > 配置文件 > 默认值kubeletConfigFlagPrecedence 函数通过重新解析 Flag 覆盖配置文件中的值,确保向后兼容。

3.1.3 Run() → run()
go 复制代码
func Run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Dependencies, ...) error {
    // 初始化日志格式
    logOption.Apply()
    klog.InfoS("Kubelet version", "kubeletVersion", version.Get())
    // OS 特定初始化
    initForOS(s.KubeletFlags.WindowsService, s.KubeletFlags.WindowsPriorityClass)
    // 委托给 run()
    run(ctx, s, kubeDeps, featureGate)
}

run() 是真正的启动逻辑,执行顺序如下:

复制代码
1.  设置 Feature Gates
2.  验证 KubeletServer
3.  获取文件锁(flock.Acquire)
4.  注册 /configz 端点
5.  判断 standalone 模式
6.  初始化 Dependencies(如果为 nil)
7.  初始化云提供商
8.  获取 hostname → nodeName
9.  构建 KubeClient / EventClient / HeartbeatClient
10. 构建 Auth 认证器
11. 计算 cgroupRoots
12. 初始化 cAdvisor
13. 设置 EventRecorder
14. 初始化 ContainerManager
15. 应用 OOM Score 调整
16. PreInitRuntimeService(初始化 CRI 运行时)
17. RunKubelet
18. 启动动态配置同步(如果启用)
19. 启动 Healthz Server
20. 通知 systemd READY=1
21. 阻塞等待信号
3.1.4 启动完整流程图

#mermaid-svg-H0E1VfiZHkxPJVbT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H0E1VfiZHkxPJVbT .error-icon{fill:#552222;}#mermaid-svg-H0E1VfiZHkxPJVbT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H0E1VfiZHkxPJVbT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H0E1VfiZHkxPJVbT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H0E1VfiZHkxPJVbT .marker.cross{stroke:#333333;}#mermaid-svg-H0E1VfiZHkxPJVbT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H0E1VfiZHkxPJVbT p{margin:0;}#mermaid-svg-H0E1VfiZHkxPJVbT .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT .cluster-label text{fill:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT .cluster-label span{color:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT .cluster-label span p{background-color:transparent;}#mermaid-svg-H0E1VfiZHkxPJVbT .label text,#mermaid-svg-H0E1VfiZHkxPJVbT span{fill:#333;color:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT .node rect,#mermaid-svg-H0E1VfiZHkxPJVbT .node circle,#mermaid-svg-H0E1VfiZHkxPJVbT .node ellipse,#mermaid-svg-H0E1VfiZHkxPJVbT .node polygon,#mermaid-svg-H0E1VfiZHkxPJVbT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H0E1VfiZHkxPJVbT .rough-node .label text,#mermaid-svg-H0E1VfiZHkxPJVbT .node .label text,#mermaid-svg-H0E1VfiZHkxPJVbT .image-shape .label,#mermaid-svg-H0E1VfiZHkxPJVbT .icon-shape .label{text-anchor:middle;}#mermaid-svg-H0E1VfiZHkxPJVbT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H0E1VfiZHkxPJVbT .rough-node .label,#mermaid-svg-H0E1VfiZHkxPJVbT .node .label,#mermaid-svg-H0E1VfiZHkxPJVbT .image-shape .label,#mermaid-svg-H0E1VfiZHkxPJVbT .icon-shape .label{text-align:center;}#mermaid-svg-H0E1VfiZHkxPJVbT .node.clickable{cursor:pointer;}#mermaid-svg-H0E1VfiZHkxPJVbT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H0E1VfiZHkxPJVbT .arrowheadPath{fill:#333333;}#mermaid-svg-H0E1VfiZHkxPJVbT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H0E1VfiZHkxPJVbT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H0E1VfiZHkxPJVbT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H0E1VfiZHkxPJVbT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H0E1VfiZHkxPJVbT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H0E1VfiZHkxPJVbT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H0E1VfiZHkxPJVbT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H0E1VfiZHkxPJVbT .cluster text{fill:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT .cluster span{color:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H0E1VfiZHkxPJVbT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H0E1VfiZHkxPJVbT rect.text{fill:none;stroke-width:0;}#mermaid-svg-H0E1VfiZHkxPJVbT .icon-shape,#mermaid-svg-H0E1VfiZHkxPJVbT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H0E1VfiZHkxPJVbT .icon-shape p,#mermaid-svg-H0E1VfiZHkxPJVbT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H0E1VfiZHkxPJVbT .icon-shape .label rect,#mermaid-svg-H0E1VfiZHkxPJVbT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H0E1VfiZHkxPJVbT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H0E1VfiZHkxPJVbT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H0E1VfiZHkxPJVbT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是





startKubelet()
rand.Seed()
NewKubeletCommand()
command.Execute()
解析命令行 Flags
设置 Feature Gates
验证 KubeletFlags
是否指定 --config?
loadConfigFile()
跳过
kubeletConfigFlagPrecedence()

Flag 覆盖配置文件
更新 Feature Gates
ValidateKubeletConfiguration()
DynamicConfigDir

是否指定?
BootstrapKubeletConfigController()
跳过
构建 KubeletServer
UnsecuredDependencies()
SetupSignalContext()
Run()
初始化日志
initForOS()
run()
设置 Feature Gates
ValidateKubeletServer()
Acquire File Lock
initConfigz()
standalone模式?
buildKubeletClientConfig()

→ KubeClient

→ EventClient

→ HeartbeatClient
所有 Client = nil
BuildAuth()
cAdvisor.New()
makeEventRecorder()
cm.NewContainerManager()
OOMAdjuster.ApplyOOMScoreAdj()
PreInitRuntimeService()
RunKubelet()
createAndInitKubelet()
go k.Run()
阻塞等待信号
NewMainKubelet()
k.BirthCry()
k.StartGarbageCollection()

3.2 NewMainKubelet() ------ 子模块构建全解析

NewMainKubelet 是 Kubelet 最复杂的构造函数,创建 30+ 个子模块。以下是关键步骤:

go 复制代码
func NewMainKubelet(kubeCfg, kubeDeps, crOptions, containerRuntime, hostname, ...) (*Kubelet, error) {
    // ===== 1. 参数校验 =====
    if rootDirectory == "" { return nil, fmt.Errorf(...) }
    if kubeCfg.SyncFrequency.Duration <= 0 { return nil, fmt.Errorf(...) }
    // iptables bit 范围检查

    // ===== 2. 创建 Informer =====
    if kubeDeps.KubeClient != nil {
        kubeInformers := informers.NewSharedInformerFactoryWithOptions(kubeDeps.KubeClient, 0, ...)
        nodeLister = kubeInformers.Core().V1().Nodes().Lister()
        nodeHasSynced = kubeInformers.Core().V1().Nodes().Informer().HasSynced
        kubeInformers.Start(wait.NeverStop)
    } else {
        // standalone 模式:使用空 Indexer
        nodeIndexer := cache.NewIndexer(...)
        nodeHasSynced = func() bool { return true }
    }

    // ===== 3. 创建 PodConfig =====
    if kubeDeps.PodConfig == nil {
        kubeDeps.PodConfig = makePodSourceConfig(kubeCfg, kubeDeps, nodeName, nodeHasSynced)
    }

    // ===== 4. 解析驱逐配置 =====
    thresholds := eviction.ParseThresholdConfig(...)
    evictionConfig := eviction.Config{...}

    // ===== 5. 创建 Service Informer =====
    if kubeDeps.KubeClient != nil {
        kubeInformers := informers.NewSharedInformerFactory(kubeDeps.KubeClient, 0)
        serviceLister = kubeInformers.Core().V1().Services().Lister()
    }

    // ===== 6. 构造 Kubelet 对象 =====
    klet := &Kubelet{
        hostname:           hostname,
        nodeName:           nodeName,
        kubeClient:         kubeDeps.KubeClient,
        podManager:         nil, // 后面设置
        statusManager:      nil, // 后面设置
        // ... 40+ 字段初始化
    }

    // ===== 7. Secret/ConfigMap Manager =====
    switch kubeCfg.ConfigMapAndSecretChangeDetectionStrategy {
    case WatchChangeDetectionStrategy:
        secretManager = secret.NewWatchingSecretManager(...)
        configMapManager = configmap.NewWatchingConfigMapManager(...)
    case TTLCacheChangeDetectionStrategy:
        secretManager = secret.NewCachingSecretManager(...)
        configMapManager = configmap.NewCachingConfigMapManager(...)
    case GetChangeDetectionStrategy:
        secretManager = secret.NewSimpleSecretManager(...)
        configMapManager = configmap.NewSimpleConfigMapManager(...)
    }

    // ===== 8. MachineInfo =====
    machineInfo := klet.cadvisor.MachineInfo()

    // ===== 9. 探针管理器 =====
    klet.livenessManager = proberesults.NewManager()
    klet.readinessManager = proberesults.NewManager()
    klet.startupManager = proberesults.NewManager()

    // ===== 10. PodManager =====
    mirrorPodClient := kubepod.NewBasicMirrorClient(klet.kubeClient, string(nodeName), nodeLister)
    klet.podManager = kubepod.NewBasicPodManager(mirrorPodClient, secretManager, configMapManager)

    // ===== 11. StatusManager =====
    klet.statusManager = status.NewManager(klet.kubeClient, klet.podManager, klet)

    // ===== 12. 容器运行时 =====
    runtime := kuberuntime.NewKubeGenericRuntimeManager(
        kubecontainer.FilterEventRecorder(kubeDeps.Recorder),
        klet.livenessManager, klet.readinessManager, klet.startupManager,
        seccompProfileRoot, machineInfo, klet, kubeDeps.OSInterface,
        klet, httpClient, imageBackOff,
        kubeCfg.SerializeImagePulls, kubeCfg.RegistryPullQPS, kubeCfg.RegistryBurst,
        imageCredentialProviderConfigFile, imageCredentialProviderBinDir,
        kubeCfg.CPUCFSQuota, kubeCfg.CPUCFSQuotaPeriod,
        kubeDeps.RemoteRuntimeService, kubeDeps.RemoteImageService,
        kubeDeps.ContainerManager.InternalContainerLifecycle(),
        kubeDeps.dockerLegacyService, klet.containerLogManager, klet.runtimeClassManager,
    )
    klet.containerRuntime = runtime

    // ===== 13. PLEG =====
    klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{})

    // ===== 14. 运行时状态 =====
    klet.runtimeState = newRuntimeState(maxWaitForContainerRuntime)
    klet.runtimeState.addHealthCheck("PLEG", klet.pleg.Healthy)

    // ===== 15. 容器 GC / 镜像 GC =====
    containerGC := kubecontainer.NewContainerGC(...)
    imageManager := images.NewImageGCManager(...)

    // ===== 16. 探针管理器 =====
    klet.probeManager = prober.NewManager(
        klet.statusManager, klet.livenessManager, klet.readinessManager, klet.startupManager,
        klet.runner, kubeDeps.Recorder)

    // ===== 17. 卷插件 & 卷管理器 =====
    klet.volumePluginMgr = NewInitializedVolumePluginMgr(klet, secretManager, configMapManager, ...)
    klet.volumeManager = volumemanager.NewVolumeManager(...)

    // ===== 18. Pod Workers =====
    klet.workQueue = queue.NewBasicWorkQueue(klet.clock)
    klet.podWorkers = newPodWorkers(klet.syncPod, kubeDeps.Recorder, klet.workQueue, klet.resyncInterval, backOffPeriod, klet.podCache)

    // ===== 19. 驱逐管理器 =====
    evictionManager, evictionAdmitHandler := eviction.NewManager(...)
    klet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)

    // ===== 20. 准入处理器链 =====
    klet.admitHandlers.AddPodAdmitHandler(sysctlsWhitelist)
    klet.AddPodSyncLoopHandler(activeDeadlineHandler)
    klet.AddPodSyncHandler(activeDeadlineHandler)
    klet.admitHandlers.AddPodAdmitHandler(klet.containerManager.GetAllocateResourcesPodAdmitHandler())
    criticalPodAdmissionHandler := preemption.NewCriticalPodAdmissionHandler(...)
    klet.admitHandlers.AddPodAdmitHandler(lifecycle.NewPredicateAdmitHandler(...))
    // 软准入
    klet.softAdmitHandlers.AddPodAdmitHandler(lifecycle.NewAppArmorAdmitHandler(...))
    klet.softAdmitHandlers.AddPodAdmitHandler(lifecycle.NewNoNewPrivsAdmitHandler(...))
    klet.softAdmitHandlers.AddPodAdmitHandler(lifecycle.NewProcMountAdmitHandler(...))

    // ===== 21. Lease Controller =====
    klet.nodeLeaseController = lease.NewController(...)

    // ===== 22. 节点关闭管理器 =====
    shutdownManager, shutdownAdmitHandler := nodeshutdown.NewManager(...)
    klet.admitHandlers.AddPodAdmitHandler(shutdownAdmitHandler)

    // ===== 23. 设置节点状态函数 =====
    klet.setNodeStatusFuncs = klet.defaultNodeStatusFuncs()

    return klet, nil
}

3.3 依赖注入构建图

#mermaid-svg-8exn2HEe9jCI33QA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8exn2HEe9jCI33QA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8exn2HEe9jCI33QA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8exn2HEe9jCI33QA .error-icon{fill:#552222;}#mermaid-svg-8exn2HEe9jCI33QA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8exn2HEe9jCI33QA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8exn2HEe9jCI33QA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8exn2HEe9jCI33QA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8exn2HEe9jCI33QA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8exn2HEe9jCI33QA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8exn2HEe9jCI33QA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8exn2HEe9jCI33QA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8exn2HEe9jCI33QA .marker.cross{stroke:#333333;}#mermaid-svg-8exn2HEe9jCI33QA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8exn2HEe9jCI33QA p{margin:0;}#mermaid-svg-8exn2HEe9jCI33QA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8exn2HEe9jCI33QA .cluster-label text{fill:#333;}#mermaid-svg-8exn2HEe9jCI33QA .cluster-label span{color:#333;}#mermaid-svg-8exn2HEe9jCI33QA .cluster-label span p{background-color:transparent;}#mermaid-svg-8exn2HEe9jCI33QA .label text,#mermaid-svg-8exn2HEe9jCI33QA span{fill:#333;color:#333;}#mermaid-svg-8exn2HEe9jCI33QA .node rect,#mermaid-svg-8exn2HEe9jCI33QA .node circle,#mermaid-svg-8exn2HEe9jCI33QA .node ellipse,#mermaid-svg-8exn2HEe9jCI33QA .node polygon,#mermaid-svg-8exn2HEe9jCI33QA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8exn2HEe9jCI33QA .rough-node .label text,#mermaid-svg-8exn2HEe9jCI33QA .node .label text,#mermaid-svg-8exn2HEe9jCI33QA .image-shape .label,#mermaid-svg-8exn2HEe9jCI33QA .icon-shape .label{text-anchor:middle;}#mermaid-svg-8exn2HEe9jCI33QA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8exn2HEe9jCI33QA .rough-node .label,#mermaid-svg-8exn2HEe9jCI33QA .node .label,#mermaid-svg-8exn2HEe9jCI33QA .image-shape .label,#mermaid-svg-8exn2HEe9jCI33QA .icon-shape .label{text-align:center;}#mermaid-svg-8exn2HEe9jCI33QA .node.clickable{cursor:pointer;}#mermaid-svg-8exn2HEe9jCI33QA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8exn2HEe9jCI33QA .arrowheadPath{fill:#333333;}#mermaid-svg-8exn2HEe9jCI33QA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8exn2HEe9jCI33QA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8exn2HEe9jCI33QA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8exn2HEe9jCI33QA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8exn2HEe9jCI33QA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8exn2HEe9jCI33QA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8exn2HEe9jCI33QA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8exn2HEe9jCI33QA .cluster text{fill:#333;}#mermaid-svg-8exn2HEe9jCI33QA .cluster span{color:#333;}#mermaid-svg-8exn2HEe9jCI33QA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8exn2HEe9jCI33QA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8exn2HEe9jCI33QA rect.text{fill:none;stroke-width:0;}#mermaid-svg-8exn2HEe9jCI33QA .icon-shape,#mermaid-svg-8exn2HEe9jCI33QA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8exn2HEe9jCI33QA .icon-shape p,#mermaid-svg-8exn2HEe9jCI33QA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8exn2HEe9jCI33QA .icon-shape .label rect,#mermaid-svg-8exn2HEe9jCI33QA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8exn2HEe9jCI33QA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8exn2HEe9jCI33QA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8exn2HEe9jCI33QA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} NewMainKubelet 中构建
run() 中补充构建
UnsecuredDependencies 构建
InitializeTLS()
mount.New()
subpath.New()
hostutil.NewHostUtil()
ProbeVolumePlugins()
GetDynamicPluginProber()
oom.NewOOMAdjuster()
kubecontainer.RealOS{}
cloudprovider.InitCloudProvider()
buildKubeletClientConfig()

→ KubeClient

→ EventClient

→ HeartbeatClient
BuildAuth()
cadvisor.New()
makeEventRecorder()
cm.NewContainerManager()
SharedInformerFactory
makePodSourceConfig()
SecretManager
ConfigMapManager
PodManager
StatusManager
KubeGenericRuntimeManager
GenericPLEG
ContainerGC
ImageGCManager
ProbeManager
VolumeManager
WorkQueue
PodWorkers
EvictionManager
NodeLeaseController
ShutdownManager
Dependencies
Dependencies 补充
Kubelet

3.4 Kubelet.Run() ------ 主运行循环

go 复制代码
func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
    // 1. 设置日志服务器
    if kl.logServer == nil {
        kl.logServer = http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/")))
    }

    // 2. 启动云资源同步管理器
    if kl.cloudResourceSyncManager != nil {
        go kl.cloudResourceSyncManager.Run(wait.NeverStop)
    }

    // 3. 初始化不依赖运行时的模块
    if err := kl.initializeModules(); err != nil {
        os.Exit(1)
    }

    // 4. 启动卷管理器
    go kl.volumeManager.Run(kl.sourcesReady, wait.NeverStop)

    // 5. 节点状态同步(如果有 KubeClient)
    if kl.kubeClient != nil {
        go wait.Until(kl.syncNodeStatus, kl.nodeStatusUpdateFrequency, wait.NeverStop)
        go kl.fastStatusUpdateOnce()           // 加速首次状态更新
        go kl.nodeLeaseController.Run(wait.NeverStop)  // 启动 Lease 续约
    }

    // 6. 运行时状态更新
    go wait.Until(kl.updateRuntimeUp, 5*time.Second, wait.NeverStop)

    // 7. iptables 规则
    if kl.makeIPTablesUtilChains { kl.initNetworkUtil() }

    // 8. Pod Killer
    go wait.Until(kl.podKiller.PerformPodKillingWork, 1*time.Second, wait.NeverStop)

    // 9. StatusManager
    kl.statusManager.Start()

    // 10. RuntimeClass Manager
    if kl.runtimeClassManager != nil { kl.runtimeClassManager.Start(wait.NeverStop) }

    // 11. PLEG
    kl.pleg.Start()

    // 12. 进入主同步循环(永不返回)
    kl.syncLoop(updates, kl)
}

3.5 initializeModules() ------ 运行时无关模块初始化

go 复制代码
func (kl *Kubelet) initializeModules() error {
    // 1. 注册 Prometheus 指标
    metrics.Register(
        collectors.NewVolumeStatsCollector(kl),
        collectors.NewLogMetricsCollector(kl.StatsProvider.ListPodStats),
    )
    metrics.SetNodeName(kl.nodeName)
    servermetrics.Register()

    // 2. 创建文件系统目录
    kl.setupDataDirs()  // /var/lib/kubelet, /var/lib/kubelet/pods, /var/lib/kubelet/plugins, ...

    // 3. 创建容器日志目录
    os.MkdirAll(ContainerLogsDir, 0755)  // /var/log/containers

    // 4. 启动镜像管理器
    kl.imageManager.Start()

    // 5. 启动证书管理器
    if kl.serverCertificateManager != nil {
        kl.serverCertificateManager.Start()
    }

    // 6. 启动 OOM Watcher
    kl.oomWatcher.Start(kl.nodeRef)

    // 7. 启动资源分析器
    kl.resourceAnalyzer.Start()

    return nil
}

3.6 initializeRuntimeDependentModules() ------ 运行时依赖模块

通过 sync.Once 保证只执行一次,在 updateRuntimeUp() 检测到运行时就绪后触发:

go 复制代码
func (kl *Kubelet) initializeRuntimeDependentModules() {
    // 1. 启动 cAdvisor
    kl.cadvisor.Start()  // 失败则 os.Exit(1)

    // 2. 触发一次按需统计收集(为 ephemeral storage 容量信息)
    kl.StatsProvider.GetCgroupStats("/", true)

    // 3. 启动 ContainerManager(必须在 cAdvisor 之后,因为需要文件系统容量信息)
    node := kl.getNodeAnyWay()
    kl.containerManager.Start(node, kl.GetActivePods, kl.sourcesReady, kl.statusManager, kl.runtimeService)

    // 4. 启动 Eviction Manager(必须在 cAdvisor 之后,因为需要知道 imagefs)
    kl.evictionManager.Start(kl.StatsProvider, kl.GetActivePods, kl.podResourcesAreReclaimed, evictionMonitoringPeriod)

    // 5. 启动容器日志管理器
    kl.containerLogManager.Start()

    // 6. 注册 CSI/DevicePlugin Handler 并启动 PluginManager
    kl.pluginManager.AddHandler(pluginwatcherapi.CSIPlugin, plugincache.PluginHandler(csi.PluginHandler))
    kl.pluginManager.AddHandler(pluginwatcherapi.DevicePlugin, kl.containerManager.GetPluginRegistrationHandler())
    go kl.pluginManager.Run(kl.sourcesReady, wait.NeverStop)

    // 7. 启动节点关闭管理器
    kl.shutdownManager.Start()
}

3.7 Kubelet 核心类图

#mermaid-svg-yGMnDBw88gur3NDH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yGMnDBw88gur3NDH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yGMnDBw88gur3NDH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yGMnDBw88gur3NDH .error-icon{fill:#552222;}#mermaid-svg-yGMnDBw88gur3NDH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yGMnDBw88gur3NDH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yGMnDBw88gur3NDH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yGMnDBw88gur3NDH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yGMnDBw88gur3NDH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yGMnDBw88gur3NDH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yGMnDBw88gur3NDH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yGMnDBw88gur3NDH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yGMnDBw88gur3NDH .marker.cross{stroke:#333333;}#mermaid-svg-yGMnDBw88gur3NDH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yGMnDBw88gur3NDH p{margin:0;}#mermaid-svg-yGMnDBw88gur3NDH g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-yGMnDBw88gur3NDH g.classGroup text .title{font-weight:bolder;}#mermaid-svg-yGMnDBw88gur3NDH .cluster-label text{fill:#333;}#mermaid-svg-yGMnDBw88gur3NDH .cluster-label span{color:#333;}#mermaid-svg-yGMnDBw88gur3NDH .cluster-label span p{background-color:transparent;}#mermaid-svg-yGMnDBw88gur3NDH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yGMnDBw88gur3NDH .cluster text{fill:#333;}#mermaid-svg-yGMnDBw88gur3NDH .cluster span{color:#333;}#mermaid-svg-yGMnDBw88gur3NDH .nodeLabel,#mermaid-svg-yGMnDBw88gur3NDH .edgeLabel{color:#131300;}#mermaid-svg-yGMnDBw88gur3NDH .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-yGMnDBw88gur3NDH .label text{fill:#131300;}#mermaid-svg-yGMnDBw88gur3NDH .labelBkg{background:#ECECFF;}#mermaid-svg-yGMnDBw88gur3NDH .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-yGMnDBw88gur3NDH .classTitle{font-weight:bolder;}#mermaid-svg-yGMnDBw88gur3NDH .node rect,#mermaid-svg-yGMnDBw88gur3NDH .node circle,#mermaid-svg-yGMnDBw88gur3NDH .node ellipse,#mermaid-svg-yGMnDBw88gur3NDH .node polygon,#mermaid-svg-yGMnDBw88gur3NDH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yGMnDBw88gur3NDH .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH g.clickable{cursor:pointer;}#mermaid-svg-yGMnDBw88gur3NDH g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-yGMnDBw88gur3NDH g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-yGMnDBw88gur3NDH .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-yGMnDBw88gur3NDH .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-yGMnDBw88gur3NDH .dashed-line{stroke-dasharray:3;}#mermaid-svg-yGMnDBw88gur3NDH .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-yGMnDBw88gur3NDH #compositionStart,#mermaid-svg-yGMnDBw88gur3NDH .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #compositionEnd,#mermaid-svg-yGMnDBw88gur3NDH .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #dependencyStart,#mermaid-svg-yGMnDBw88gur3NDH .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #dependencyStart,#mermaid-svg-yGMnDBw88gur3NDH .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #extensionStart,#mermaid-svg-yGMnDBw88gur3NDH .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #extensionEnd,#mermaid-svg-yGMnDBw88gur3NDH .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #aggregationStart,#mermaid-svg-yGMnDBw88gur3NDH .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #aggregationEnd,#mermaid-svg-yGMnDBw88gur3NDH .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #lollipopStart,#mermaid-svg-yGMnDBw88gur3NDH .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH #lollipopEnd,#mermaid-svg-yGMnDBw88gur3NDH .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-yGMnDBw88gur3NDH .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-yGMnDBw88gur3NDH .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yGMnDBw88gur3NDH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yGMnDBw88gur3NDH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yGMnDBw88gur3NDH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} implements
implements
uses
constructed from
Kubelet
-kubeletConfiguration KubeletConfiguration
-hostname string
-nodeName types.NodeName
-podManager kubepod.Manager
-podWorkers PodWorkers
-statusManager status.Manager
-containerRuntime kubecontainer.Runtime
-volumeManager volumemanager.VolumeManager
-evictionManager eviction.Manager
-probeManager prober.Manager
-pleg pleg.PodLifecycleEventGenerator
-containerManager cm.ContainerManager
-imageManager images.ImageGCManager
-containerGC kubecontainer.GC
-runtimeState runtimeState
+Run(updates)
+syncLoop(updates, handler)
+syncLoopIteration(configCh, handler, syncCh, housekeepingCh, plegCh)
+syncPod(options) : error
+HandlePodAdditions(pods)
+HandlePodUpdates(pods)
+HandlePodRemoves(pods)
+HandlePodReconcile(pods)
+HandlePodSyncs(pods)
+HandlePodCleanups() : error
+canAdmitPod(pods, pod)(bool, string, string)
+canRunPod(pod) : PodAdmitResult
+dispatchWork(pod, syncType, mirrorPod, start)
+deletePod(pod) : error
+initializeModules() : error
+initializeRuntimeDependentModules()
+updateRuntimeUp()
+StartGarbageCollection()
+BirthCry()
<<interface>>
SyncHandler
+HandlePodAdditions(pods)
+HandlePodUpdates(pods)
+HandlePodRemoves(pods)
+HandlePodReconcile(pods)
+HandlePodSyncs(pods)
+HandlePodCleanups() : error
<<interface>>
Bootstrap
+GetConfiguration() : KubeletConfiguration
+BirthCry()
+StartGarbageCollection()
+ListenAndServe(...)
+Run(updates)
+RunOnce(updates)
<<interface>>
PodWorkers
+UpdatePod(options)
+ForgetNonExistingPodWorkers(desiredPods)
+ForgetWorker(uid)
Dependencies
+Auth server.AuthInterface
+CAdvisorInterface cadvisor.Interface
+Cloud cloudprovider.Interface
+ContainerManager cm.ContainerManager
+KubeClient clientset.Interface
+HeartbeatClient clientset.Interface
+EventClient v1core.EventsGetter
+PodConfig config.PodConfig
+Recorder record.EventRecorder
+VolumePlugins \[\]volume.VolumePlugin
+RemoteRuntimeService internalapi.RuntimeService
+RemoteImageService internalapi.ImageManagerService

3.8 SyncPod 完整逻辑深度解析

syncPod 是 Kubelet 最核心的事务脚本,处理单个 Pod 的状态收敛。以下逐行解析:

go 复制代码
func (kl *Kubelet) syncPod(o syncPodOptions) error {
    pod := o.pod
    mirrorPod := o.mirrorPod
    podStatus := o.podStatus
    updateType := o.updateType

    // ========== 步骤 1:Kill 请求处理 ==========
    if updateType == kubetypes.SyncPodKill {
        killPodOptions := o.killPodOptions
        apiPodStatus := killPodOptions.PodStatusFunc(pod, podStatus)
        kl.statusManager.SetPodStatus(pod, apiPodStatus)
        err := kl.killPod(pod, nil, podStatus, killPodOptions.PodTerminationGracePeriodSecondsOverride)
        return err
    }

    // ========== 步骤 2:优雅终止中检查 ==========
    podFullName := kubecontainer.GetPodFullName(pod)
    if kl.podKiller.IsPodPendingTerminationByPodName(podFullName) {
        return fmt.Errorf("pod %q is pending termination", podFullName)
    }

    // ========== 步骤 3:记录首次可见时间 ==========
    var firstSeenTime time.Time
    if firstSeenTimeStr, ok := pod.Annotations[kubetypes.ConfigFirstSeenAnnotationKey]; ok {
        firstSeenTime = kubetypes.ConvertToTimestamp(firstSeenTimeStr).Get()
    }

    // ========== 步骤 4:记录 Pod Worker 启动延迟 ==========
    if updateType == kubetypes.SyncPodCreate {
        if !firstSeenTime.IsZero() {
            metrics.PodWorkerStartDuration.Observe(metrics.SinceInSeconds(firstSeenTime))
        }
    }

    // ========== 步骤 5:生成 API Pod Status ==========
    apiPodStatus := kl.generateAPIPodStatus(pod, podStatus)
    // 处理 host network 场景下的 Pod IP
    podStatus.IPs = make([]string, 0, len(apiPodStatus.PodIPs))
    for _, ipInfo := range apiPodStatus.PodIPs {
        podStatus.IPs = append(podStatus.IPs, ipInfo.IP)
    }

    // ========== 步骤 6:记录 Pod 启动延迟 ==========
    existingStatus, ok := kl.statusManager.GetPodStatus(pod.UID)
    if !ok || existingStatus.Phase == v1.PodPending && apiPodStatus.Phase == v1.PodRunning && !firstSeenTime.IsZero() {
        metrics.PodStartDuration.Observe(metrics.SinceInSeconds(firstSeenTime))
    }

    // ========== 步骤 7:准入检查 ==========
    runnable := kl.canRunPod(pod)
    if !runnable.Admit {
        apiPodStatus.Reason = runnable.Reason
        apiPodStatus.Message = runnable.Message
        // 设置所有 Waiting 容器原因为 "Blocked"
        for _, cs := range apiPodStatus.InitContainerStatuses {
            if cs.State.Waiting != nil { cs.State.Waiting.Reason = "Blocked" }
        }
        for _, cs := range apiPodStatus.ContainerStatuses {
            if cs.State.Waiting != nil { cs.State.Waiting.Reason = "Blocked" }
        }
    }

    // ========== 步骤 8:更新 Status Manager ==========
    kl.statusManager.SetPodStatus(pod, apiPodStatus)

    // ========== 步骤 9:不可运行则 Kill ==========
    if !runnable.Admit || pod.DeletionTimestamp != nil || apiPodStatus.Phase == v1.PodFailed {
        err := kl.killPod(pod, nil, podStatus, nil)
        return syncErr
    }

    // ========== 步骤 10:网络就绪检查 ==========
    if err := kl.runtimeState.networkErrors(); err != nil && !kubecontainer.IsHostNetworkPod(pod) {
        kl.recorder.Eventf(pod, v1.EventTypeWarning, events.NetworkNotReady, ...)
        return fmt.Errorf("%s: %v", NetworkNotReadyErrorMsg, err)
    }

    // ========== 步骤 11:Cgroup 管理 ==========
    pcm := kl.containerManager.NewPodContainerManager()
    if !kl.podIsTerminated(pod) {
        firstSync := true
        for _, containerStatus := range apiPodStatus.ContainerStatuses {
            if containerStatus.State.Running != nil { firstSync = false; break }
        }
        podKilled := false
        if !pcm.Exists(pod) && !firstSync {
            kl.killPod(pod, nil, podStatus, nil)  // QoS Cgroup 不存在且非首次同步→重建
            podKilled = true
        }
        if !(podKilled && pod.Spec.RestartPolicy == v1.RestartPolicyNever) {
            kl.containerManager.UpdateQOSCgroups()
            pcm.EnsureExists(pod)  // 确保 Pod Cgroup 存在
        }
    }

    // ========== 步骤 12:静态 Pod Mirror Pod 管理 ==========
    if kubetypes.IsStaticPod(pod) {
        if mirrorPod != nil {
            if mirrorPod.DeletionTimestamp != nil || !kl.podManager.IsMirrorPodOf(mirrorPod, pod) {
                kl.podManager.DeleteMirrorPod(podFullName, &mirrorPod.ObjectMeta.UID)
            }
        }
        if mirrorPod == nil || deleted {
            node, err := kl.GetNode()
            if err == nil || node.DeletionTimestamp == nil {
                kl.podManager.CreateMirrorPod(pod)  // 创建 Mirror Pod
            }
        }
    }

    // ========== 步骤 13:创建 Pod 数据目录 ==========
    kl.makePodDataDirs(pod)

    // ========== 步骤 14:等待卷 Attach/Mount ==========
    if !kl.podIsTerminated(pod) {
        kl.volumeManager.WaitForAttachAndMount(pod)
    }

    // ========== 步骤 15:获取 Image Pull Secrets ==========
    pullSecrets := kl.getPullSecretsForPod(pod)

    // ========== 步骤 16:调用容器运行时 SyncPod ==========
    result := kl.containerRuntime.SyncPod(pod, podStatus, pullSecrets, kl.backOff)
    kl.reasonCache.Update(pod.UID, result)
    if err := result.Error(); err != nil {
        // 仅在非 CrashLoopBackOff/ErrImagePullBackOff 时返回错误
        for _, r := range result.SyncResults {
            if r.Error != kubecontainer.ErrCrashLoopBackOff && r.Error != images.ErrImagePullBackOff {
                return err
            }
        }
        return nil
    }

    return nil
}

3.9 SyncPod 完整流程图

#mermaid-svg-GEu5Z4nXsrOqwq9s{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GEu5Z4nXsrOqwq9s .error-icon{fill:#552222;}#mermaid-svg-GEu5Z4nXsrOqwq9s .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GEu5Z4nXsrOqwq9s .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .marker.cross{stroke:#333333;}#mermaid-svg-GEu5Z4nXsrOqwq9s svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GEu5Z4nXsrOqwq9s p{margin:0;}#mermaid-svg-GEu5Z4nXsrOqwq9s .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .cluster-label text{fill:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .cluster-label span{color:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .cluster-label span p{background-color:transparent;}#mermaid-svg-GEu5Z4nXsrOqwq9s .label text,#mermaid-svg-GEu5Z4nXsrOqwq9s span{fill:#333;color:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .node rect,#mermaid-svg-GEu5Z4nXsrOqwq9s .node circle,#mermaid-svg-GEu5Z4nXsrOqwq9s .node ellipse,#mermaid-svg-GEu5Z4nXsrOqwq9s .node polygon,#mermaid-svg-GEu5Z4nXsrOqwq9s .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .rough-node .label text,#mermaid-svg-GEu5Z4nXsrOqwq9s .node .label text,#mermaid-svg-GEu5Z4nXsrOqwq9s .image-shape .label,#mermaid-svg-GEu5Z4nXsrOqwq9s .icon-shape .label{text-anchor:middle;}#mermaid-svg-GEu5Z4nXsrOqwq9s .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .rough-node .label,#mermaid-svg-GEu5Z4nXsrOqwq9s .node .label,#mermaid-svg-GEu5Z4nXsrOqwq9s .image-shape .label,#mermaid-svg-GEu5Z4nXsrOqwq9s .icon-shape .label{text-align:center;}#mermaid-svg-GEu5Z4nXsrOqwq9s .node.clickable{cursor:pointer;}#mermaid-svg-GEu5Z4nXsrOqwq9s .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .arrowheadPath{fill:#333333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GEu5Z4nXsrOqwq9s .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GEu5Z4nXsrOqwq9s .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GEu5Z4nXsrOqwq9s .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GEu5Z4nXsrOqwq9s .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .cluster text{fill:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s .cluster span{color:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GEu5Z4nXsrOqwq9s .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GEu5Z4nXsrOqwq9s rect.text{fill:none;stroke-width:0;}#mermaid-svg-GEu5Z4nXsrOqwq9s .icon-shape,#mermaid-svg-GEu5Z4nXsrOqwq9s .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GEu5Z4nXsrOqwq9s .icon-shape p,#mermaid-svg-GEu5Z4nXsrOqwq9s .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GEu5Z4nXsrOqwq9s .icon-shape .label rect,#mermaid-svg-GEu5Z4nXsrOqwq9s .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GEu5Z4nXsrOqwq9s .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GEu5Z4nXsrOqwq9s .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GEu5Z4nXsrOqwq9s :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SyncPodKill
其他










否 & 非HostNetwork
是 或 HostNetwork
否 & 非首次
是 或 首次







是 & 仅BackOff
是 & 其他错误
syncPod 入口
updateType?
killPod()

设置 Pod Status → Kill
返回
Pod 正在

优雅终止?
返回: pending termination
获取 firstSeenTime

(annotations)
updateType

== Create?
记录 PodWorkerStart

延迟指标
跳过
generateAPIPodStatus()
设置 podStatus.IPs
Phase 变化

Pending→Running?
记录 PodStart

延迟指标
跳过
canRunPod()
Admit?
设置 Reason=Blocked

更新 Status
statusManager.

SetPodStatus()
不可运行/

DeletionTimestamp/

Phase=Failed?
killPod()
网络就绪?
返回错误
返回 NetworkNotReady
Cgroup 管理
Pod Cgroup

存在?
killPod() 重建
EnsureExists()

UpdateQOSCgroups()
静态 Pod?
makePodDataDirs()
Mirror Pod

存在且匹配?
创建 Mirror Pod
Pod 已终止?
WaitForAttachAndMount()
getPullSecretsForPod()
containerRuntime.

SyncPod()
reasonCache.Update()
SyncResult

有错误?
返回 nil
返回 nil

忽略 BackOff 错误
返回错误

3.10 syncLoop ------ 主同步循环

syncLoop 是 Kubelet 的心跳,永不返回。它从多个事件源接收更新,驱动 Pod 状态收敛。

go 复制代码
func (kl *Kubelet) syncLoop(updates <-chan kubetypes.PodUpdate, handler SyncHandler) {
    klog.InfoS("Starting kubelet main sync loop")

    syncTicker := time.NewTicker(time.Second)          // 1 秒同步检查
    housekeepingTicker := time.NewTicker(housekeepingPeriod) // 2 秒清理检查
    plegCh := kl.pleg.Watch()                           // PLEG 事件通道

    // 初始退避参数
    const (base = 100*time.Millisecond; max = 5*time.Second; factor = 2)
    duration := base

    // 检查 resolv.conf 限制
    if kl.dnsConfigurer != nil && kl.dnsConfigurer.ResolverConfig != "" {
        kl.dnsConfigurer.CheckLimitsForResolvConf()
    }

    for {
        // 运行时错误检查 → 指数退避
        if err := kl.runtimeState.runtimeErrors(); err != nil {
            time.Sleep(duration)
            duration = time.Duration(math.Min(float64(max), factor*float64(duration)))
            continue
        }
        duration = base  // 成功则重置退避

        kl.syncLoopMonitor.Store(kl.clock.Now())
        if !kl.syncLoopIteration(updates, handler, syncTicker.C, housekeepingTicker.C, plegCh) {
            break  // updates channel 关闭时退出
        }
        kl.syncLoopMonitor.Store(kl.clock.Now())
    }
}

3.11 syncLoopIteration ------ 单次迭代事件分发

go 复制代码
func (kl *Kubelet) syncLoopIteration(configCh, handler, syncCh, housekeepingCh, plegCh) bool {
    select {
    // ====== 事件 1:配置源更新 ======
    case u, open := <-configCh:
        if !open { return false }  // 通道关闭 → 退出
        switch u.Op {
        case kubetypes.ADD:     handler.HandlePodAdditions(u.Pods)
        case kubetypes.UPDATE:  handler.HandlePodUpdates(u.Pods)
        case kubetypes.REMOVE:  handler.HandlePodRemoves(u.Pods)
        case kubetypes.RECONCILE: handler.HandlePodReconcile(u.Pods)
        case kubetypes.DELETE:  handler.HandlePodUpdates(u.Pods)  // DELETE 当 UPDATE 处理
        case kubetypes.SET:     klog.ErrorS(nil, "Kubelet does not support snapshot update")
        }
        kl.sourcesReady.AddSource(u.Source)

    // ====== 事件 2:PLEG 事件 ======
    case e := <-plegCh:
        if e.Type == pleg.ContainerStarted {
            kl.lastContainerStartedTime.Add(e.ID, time.Now())
        }
        if isSyncPodWorthy(e) {
            if pod, ok := kl.podManager.GetPodByUID(e.ID); ok {
                handler.HandlePodSyncs([]*v1.Pod{pod})
            }
        }
        if e.Type == pleg.ContainerDied {
            kl.cleanUpContainersInPod(e.ID, containerID)
        }

    // ====== 事件 3:定时同步 ======
    case <-syncCh:
        podsToSync := kl.getPodsToSync()
        if len(podsToSync) > 0 {
            handler.HandlePodSyncs(podsToSync)
        }

    // ====== 事件 4:Liveness 探针失败 ======
    case update := <-kl.livenessManager.Updates():
        if update.Result == proberesults.Failure {
            handleProbeSync(kl, update, handler, "liveness", "unhealthy")
        }

    // ====== 事件 5:Readiness 探针更新 ======
    case update := <-kl.readinessManager.Updates():
        ready := update.Result == proberesults.Success
        kl.statusManager.SetContainerReadiness(update.PodUID, update.ContainerID, ready)
        handleProbeSync(kl, update, handler, "readiness", ...)

    // ====== 事件 6:Startup 探针更新 ======
    case update := <-kl.startupManager.Updates():
        started := update.Result == proberesults.Success
        kl.statusManager.SetContainerStartup(update.PodUID, update.ContainerID, started)
        handleProbeSync(kl, update, handler, "startup", ...)

    // ====== 事件 7:Housekeeping ======
    case <-housekeepingCh:
        if kl.sourcesReady.AllReady() {
            handler.HandlePodCleanups()
        }
    }
    return true
}

重要细节 :Go 的 select 在多个 case 同时就绪时,会伪随机选择一个执行。这意味着事件处理没有严格的优先级------PLEG 事件可能与 config 更新竞争。

3.12 Pod 同步主循环图

#mermaid-svg-iMbewZAtdbGgLYSi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iMbewZAtdbGgLYSi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iMbewZAtdbGgLYSi .error-icon{fill:#552222;}#mermaid-svg-iMbewZAtdbGgLYSi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iMbewZAtdbGgLYSi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iMbewZAtdbGgLYSi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iMbewZAtdbGgLYSi .marker.cross{stroke:#333333;}#mermaid-svg-iMbewZAtdbGgLYSi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iMbewZAtdbGgLYSi p{margin:0;}#mermaid-svg-iMbewZAtdbGgLYSi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-iMbewZAtdbGgLYSi .cluster-label text{fill:#333;}#mermaid-svg-iMbewZAtdbGgLYSi .cluster-label span{color:#333;}#mermaid-svg-iMbewZAtdbGgLYSi .cluster-label span p{background-color:transparent;}#mermaid-svg-iMbewZAtdbGgLYSi .label text,#mermaid-svg-iMbewZAtdbGgLYSi span{fill:#333;color:#333;}#mermaid-svg-iMbewZAtdbGgLYSi .node rect,#mermaid-svg-iMbewZAtdbGgLYSi .node circle,#mermaid-svg-iMbewZAtdbGgLYSi .node ellipse,#mermaid-svg-iMbewZAtdbGgLYSi .node polygon,#mermaid-svg-iMbewZAtdbGgLYSi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iMbewZAtdbGgLYSi .rough-node .label text,#mermaid-svg-iMbewZAtdbGgLYSi .node .label text,#mermaid-svg-iMbewZAtdbGgLYSi .image-shape .label,#mermaid-svg-iMbewZAtdbGgLYSi .icon-shape .label{text-anchor:middle;}#mermaid-svg-iMbewZAtdbGgLYSi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iMbewZAtdbGgLYSi .rough-node .label,#mermaid-svg-iMbewZAtdbGgLYSi .node .label,#mermaid-svg-iMbewZAtdbGgLYSi .image-shape .label,#mermaid-svg-iMbewZAtdbGgLYSi .icon-shape .label{text-align:center;}#mermaid-svg-iMbewZAtdbGgLYSi .node.clickable{cursor:pointer;}#mermaid-svg-iMbewZAtdbGgLYSi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iMbewZAtdbGgLYSi .arrowheadPath{fill:#333333;}#mermaid-svg-iMbewZAtdbGgLYSi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iMbewZAtdbGgLYSi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iMbewZAtdbGgLYSi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iMbewZAtdbGgLYSi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iMbewZAtdbGgLYSi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iMbewZAtdbGgLYSi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iMbewZAtdbGgLYSi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iMbewZAtdbGgLYSi .cluster text{fill:#333;}#mermaid-svg-iMbewZAtdbGgLYSi .cluster span{color:#333;}#mermaid-svg-iMbewZAtdbGgLYSi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iMbewZAtdbGgLYSi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iMbewZAtdbGgLYSi rect.text{fill:none;stroke-width:0;}#mermaid-svg-iMbewZAtdbGgLYSi .icon-shape,#mermaid-svg-iMbewZAtdbGgLYSi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iMbewZAtdbGgLYSi .icon-shape p,#mermaid-svg-iMbewZAtdbGgLYSi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iMbewZAtdbGgLYSi .icon-shape .label rect,#mermaid-svg-iMbewZAtdbGgLYSi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iMbewZAtdbGgLYSi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iMbewZAtdbGgLYSi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iMbewZAtdbGgLYSi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

syncLoop (永不返回)
runtimeState

有错误?
指数退避

100ms→5s
select 多路复用
configCh

配置源更新
plegCh

PLEG 事件
syncCh

定时同步

(1s)
livenessManager.Updates()

Liveness 探针
readinessManager.Updates()

Readiness 探针
startupManager.Updates()

Startup 探针
housekeepingCh

清理检查

(2s)
HandlePodAdditions
HandlePodUpdates
HandlePodRemoves
HandlePodReconcile
HandlePodUpdates

(DELETE→UPDATE)
ContainerStarted

记录时间
isSyncPodWorthy?

→ HandlePodSyncs
ContainerDied

→ cleanUpContainersInPod
getPodsToSync()

→ HandlePodSyncs
Failure?

→ HandlePodSyncs
SetContainerReadiness

→ HandlePodSyncs
SetContainerStartup

→ HandlePodSyncs
HandlePodCleanups()
dispatchWork()

→ podWorkers.UpdatePod()
Per-Pod Worker

managePodLoop()
syncPod()
containerRuntime.SyncPod()
清理逻辑

→ 删除孤儿 Pod

→ 清理终止 Pod

→ 清理孤立卷

3.13 接口层次图

#mermaid-svg-mJd0iAJ6jL0skS4t{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mJd0iAJ6jL0skS4t .error-icon{fill:#552222;}#mermaid-svg-mJd0iAJ6jL0skS4t .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mJd0iAJ6jL0skS4t .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mJd0iAJ6jL0skS4t .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mJd0iAJ6jL0skS4t .marker.cross{stroke:#333333;}#mermaid-svg-mJd0iAJ6jL0skS4t svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mJd0iAJ6jL0skS4t p{margin:0;}#mermaid-svg-mJd0iAJ6jL0skS4t .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t .cluster-label text{fill:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t .cluster-label span{color:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t .cluster-label span p{background-color:transparent;}#mermaid-svg-mJd0iAJ6jL0skS4t .label text,#mermaid-svg-mJd0iAJ6jL0skS4t span{fill:#333;color:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t .node rect,#mermaid-svg-mJd0iAJ6jL0skS4t .node circle,#mermaid-svg-mJd0iAJ6jL0skS4t .node ellipse,#mermaid-svg-mJd0iAJ6jL0skS4t .node polygon,#mermaid-svg-mJd0iAJ6jL0skS4t .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mJd0iAJ6jL0skS4t .rough-node .label text,#mermaid-svg-mJd0iAJ6jL0skS4t .node .label text,#mermaid-svg-mJd0iAJ6jL0skS4t .image-shape .label,#mermaid-svg-mJd0iAJ6jL0skS4t .icon-shape .label{text-anchor:middle;}#mermaid-svg-mJd0iAJ6jL0skS4t .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mJd0iAJ6jL0skS4t .rough-node .label,#mermaid-svg-mJd0iAJ6jL0skS4t .node .label,#mermaid-svg-mJd0iAJ6jL0skS4t .image-shape .label,#mermaid-svg-mJd0iAJ6jL0skS4t .icon-shape .label{text-align:center;}#mermaid-svg-mJd0iAJ6jL0skS4t .node.clickable{cursor:pointer;}#mermaid-svg-mJd0iAJ6jL0skS4t .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mJd0iAJ6jL0skS4t .arrowheadPath{fill:#333333;}#mermaid-svg-mJd0iAJ6jL0skS4t .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mJd0iAJ6jL0skS4t .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mJd0iAJ6jL0skS4t .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mJd0iAJ6jL0skS4t .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mJd0iAJ6jL0skS4t .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mJd0iAJ6jL0skS4t .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mJd0iAJ6jL0skS4t .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mJd0iAJ6jL0skS4t .cluster text{fill:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t .cluster span{color:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mJd0iAJ6jL0skS4t .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mJd0iAJ6jL0skS4t rect.text{fill:none;stroke-width:0;}#mermaid-svg-mJd0iAJ6jL0skS4t .icon-shape,#mermaid-svg-mJd0iAJ6jL0skS4t .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mJd0iAJ6jL0skS4t .icon-shape p,#mermaid-svg-mJd0iAJ6jL0skS4t .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mJd0iAJ6jL0skS4t .icon-shape .label rect,#mermaid-svg-mJd0iAJ6jL0skS4t .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mJd0iAJ6jL0skS4t .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mJd0iAJ6jL0skS4t .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mJd0iAJ6jL0skS4t :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 管理器层
运行时层
核心层
应用层
命令层
implements
implements
cobra.Command

(NewKubeletCommand)
app.Run()
app.run()
RunKubelet()
Bootstrap 接口
SyncHandler 接口
PodWorkers 接口
kubecontainer.Runtime 接口
KubeGenericRuntimeManager
RemoteRuntimeService

(CRI)
RemoteImageService

(CRI)
kubepod.Manager
status.Manager
volumemanager.VolumeManager
eviction.Manager
prober.Manager
cm.ContainerManager
images.ImageGCManager
kubecontainer.GC
pleg.PodLifecycleEventGenerator
Kubelet


四、Pod 状态机与生命周期管理

4.1 Pod 状态机转换图

#mermaid-svg-3ci8202c6V799Rnm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3ci8202c6V799Rnm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3ci8202c6V799Rnm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3ci8202c6V799Rnm .error-icon{fill:#552222;}#mermaid-svg-3ci8202c6V799Rnm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3ci8202c6V799Rnm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3ci8202c6V799Rnm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3ci8202c6V799Rnm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3ci8202c6V799Rnm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3ci8202c6V799Rnm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3ci8202c6V799Rnm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3ci8202c6V799Rnm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3ci8202c6V799Rnm .marker.cross{stroke:#333333;}#mermaid-svg-3ci8202c6V799Rnm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3ci8202c6V799Rnm p{margin:0;}#mermaid-svg-3ci8202c6V799Rnm defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-3ci8202c6V799Rnm g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-3ci8202c6V799Rnm g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-3ci8202c6V799Rnm g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-3ci8202c6V799Rnm g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-3ci8202c6V799Rnm g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-3ci8202c6V799Rnm .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-3ci8202c6V799Rnm .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-3ci8202c6V799Rnm .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-3ci8202c6V799Rnm .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-3ci8202c6V799Rnm .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-3ci8202c6V799Rnm .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-3ci8202c6V799Rnm .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-3ci8202c6V799Rnm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3ci8202c6V799Rnm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3ci8202c6V799Rnm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3ci8202c6V799Rnm .edgeLabel .label text{fill:#333;}#mermaid-svg-3ci8202c6V799Rnm .label div .edgeLabel{color:#333;}#mermaid-svg-3ci8202c6V799Rnm .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-3ci8202c6V799Rnm .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-3ci8202c6V799Rnm .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-3ci8202c6V799Rnm .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-3ci8202c6V799Rnm .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-3ci8202c6V799Rnm .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3ci8202c6V799Rnm .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3ci8202c6V799Rnm #statediagram-barbEnd{fill:#333333;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3ci8202c6V799Rnm .cluster-label,#mermaid-svg-3ci8202c6V799Rnm .nodeLabel{color:#131300;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-3ci8202c6V799Rnm .note-edge{stroke-dasharray:5;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-note text{fill:black;}#mermaid-svg-3ci8202c6V799Rnm .statediagram-note .nodeLabel{color:black;}#mermaid-svg-3ci8202c6V799Rnm .statediagram .edgeLabel{color:red;}#mermaid-svg-3ci8202c6V799Rnm #dependencyStart,#mermaid-svg-3ci8202c6V799Rnm #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-3ci8202c6V799Rnm .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3ci8202c6V799Rnm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} API Server 创建 Pod
等待调度/卷挂载/镜像拉取
所有容器启动成功
准入拒绝/不可运行
Init 容器失败(restartPolicy=Never)
容器重启/探针通过
所有容器正常退出(restartPolicy=Never/OnFailure)
非零退出码(restartPolicy=Never)
Liveness 探针持续失败(restartPolicy=Never)
驱逐/节点关闭
Pending
Running
Failed
Succeeded
Kubelet 侧状态转换:

  1. ADD → dispatchWork(SyncPodCreate)

  2. syncPod → generateAPIPodStatus

  3. canAdmitPod → Admit/Reject

  4. containerRuntime.SyncPod
    运行中状态维持:

  5. PLEG 周期性检测容器变化

  6. 探针持续检查健康状态

  7. SyncLoop 定期全量同步

4.2 Pod 配置操作类型

go 复制代码
const (
    SET      PodOperation = iota  // 全量设置(初始化时)
    ADD                           // 新增 Pod
    DELETE                        // 优雅删除
    REMOVE                        // 直接移除
    UPDATE                        // 更新
    RECONCILE                     // 状态调和
)

4.3 SyncPodType 类型

go 复制代码
const (
    SyncPodSync   SyncPodType = iota  // 周期性同步
    SyncPodUpdate                      // 配置源更新
    SyncPodCreate                      // 首次创建
    SyncPodKill                        // 内部触发 Kill(驱逐)
)

4.4 Pod 生命周期事件处理图

ProbeManager PLEG StatusManager ContainerRuntime PodWorker SyncLoop PodConfig API Server ProbeManager PLEG StatusManager ContainerRuntime PodWorker SyncLoop PodConfig API Server #mermaid-svg-pq5Ek96tujDz4EA2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pq5Ek96tujDz4EA2 .error-icon{fill:#552222;}#mermaid-svg-pq5Ek96tujDz4EA2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pq5Ek96tujDz4EA2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pq5Ek96tujDz4EA2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pq5Ek96tujDz4EA2 .marker.cross{stroke:#333333;}#mermaid-svg-pq5Ek96tujDz4EA2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pq5Ek96tujDz4EA2 p{margin:0;}#mermaid-svg-pq5Ek96tujDz4EA2 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-pq5Ek96tujDz4EA2 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-pq5Ek96tujDz4EA2 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-pq5Ek96tujDz4EA2 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-pq5Ek96tujDz4EA2 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-pq5Ek96tujDz4EA2 .sequenceNumber{fill:white;}#mermaid-svg-pq5Ek96tujDz4EA2 #sequencenumber{fill:#333;}#mermaid-svg-pq5Ek96tujDz4EA2 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-pq5Ek96tujDz4EA2 .messageText{fill:#333;stroke:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-pq5Ek96tujDz4EA2 .labelText,#mermaid-svg-pq5Ek96tujDz4EA2 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .loopText,#mermaid-svg-pq5Ek96tujDz4EA2 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-pq5Ek96tujDz4EA2 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-pq5Ek96tujDz4EA2 .noteText,#mermaid-svg-pq5Ek96tujDz4EA2 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-pq5Ek96tujDz4EA2 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-pq5Ek96tujDz4EA2 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-pq5Ek96tujDz4EA2 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-pq5Ek96tujDz4EA2 .actorPopupMenu{position:absolute;}#mermaid-svg-pq5Ek96tujDz4EA2 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-pq5Ek96tujDz4EA2 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-pq5Ek96tujDz4EA2 .actor-man circle,#mermaid-svg-pq5Ek96tujDz4EA2 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-pq5Ek96tujDz4EA2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} altADDUPDATEDELETEREMOVE Watch 事件 (Pod ADD/UPDATE/DELETE)updates chan → PodUpdate{Op, Pods, Source}syncLoopIteration() selectHandlePodAdditions(pods)podManager.AddPod(pod)canAdmitPod() 准入检查dispatchWork(SyncPodCreate)HandlePodUpdates(pods)podManager.UpdatePod(pod)dispatchWork(SyncPodUpdate)HandlePodUpdates(pods) 当UPDATE处理dispatchWork(SyncPodUpdate)HandlePodRemoves(pods)podManager.DeletePod(pod)deletePod(pod) → podKiller.KillPod()managePodLoop()syncPod() → containerRuntime.SyncPod()SetPodStatus()Patch Pod Status周期性 relist (1s)plegCh → ContainerStarted/ContainerDiedHandlePodSyncs()执行 Liveness/Readiness/StartuplivenessManager.Updates()HandlePodSyncs()SetContainerReadiness/SetContainerStartup

4.5 Pod 准入处理器链

Pod 准入由一系列 PodAdmitHandler 串行执行,任一 Handler 拒绝则 Pod 不被运行:
#mermaid-svg-yCrBMxwBBuV0gX0e{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yCrBMxwBBuV0gX0e .error-icon{fill:#552222;}#mermaid-svg-yCrBMxwBBuV0gX0e .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yCrBMxwBBuV0gX0e .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yCrBMxwBBuV0gX0e .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yCrBMxwBBuV0gX0e .marker.cross{stroke:#333333;}#mermaid-svg-yCrBMxwBBuV0gX0e svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yCrBMxwBBuV0gX0e p{margin:0;}#mermaid-svg-yCrBMxwBBuV0gX0e .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e .cluster-label text{fill:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e .cluster-label span{color:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e .cluster-label span p{background-color:transparent;}#mermaid-svg-yCrBMxwBBuV0gX0e .label text,#mermaid-svg-yCrBMxwBBuV0gX0e span{fill:#333;color:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e .node rect,#mermaid-svg-yCrBMxwBBuV0gX0e .node circle,#mermaid-svg-yCrBMxwBBuV0gX0e .node ellipse,#mermaid-svg-yCrBMxwBBuV0gX0e .node polygon,#mermaid-svg-yCrBMxwBBuV0gX0e .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yCrBMxwBBuV0gX0e .rough-node .label text,#mermaid-svg-yCrBMxwBBuV0gX0e .node .label text,#mermaid-svg-yCrBMxwBBuV0gX0e .image-shape .label,#mermaid-svg-yCrBMxwBBuV0gX0e .icon-shape .label{text-anchor:middle;}#mermaid-svg-yCrBMxwBBuV0gX0e .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yCrBMxwBBuV0gX0e .rough-node .label,#mermaid-svg-yCrBMxwBBuV0gX0e .node .label,#mermaid-svg-yCrBMxwBBuV0gX0e .image-shape .label,#mermaid-svg-yCrBMxwBBuV0gX0e .icon-shape .label{text-align:center;}#mermaid-svg-yCrBMxwBBuV0gX0e .node.clickable{cursor:pointer;}#mermaid-svg-yCrBMxwBBuV0gX0e .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yCrBMxwBBuV0gX0e .arrowheadPath{fill:#333333;}#mermaid-svg-yCrBMxwBBuV0gX0e .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yCrBMxwBBuV0gX0e .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yCrBMxwBBuV0gX0e .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yCrBMxwBBuV0gX0e .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yCrBMxwBBuV0gX0e .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yCrBMxwBBuV0gX0e .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yCrBMxwBBuV0gX0e .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yCrBMxwBBuV0gX0e .cluster text{fill:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e .cluster span{color:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yCrBMxwBBuV0gX0e .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yCrBMxwBBuV0gX0e rect.text{fill:none;stroke-width:0;}#mermaid-svg-yCrBMxwBBuV0gX0e .icon-shape,#mermaid-svg-yCrBMxwBBuV0gX0e .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yCrBMxwBBuV0gX0e .icon-shape p,#mermaid-svg-yCrBMxwBBuV0gX0e .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yCrBMxwBBuV0gX0e .icon-shape .label rect,#mermaid-svg-yCrBMxwBBuV0gX0e .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yCrBMxwBBuV0gX0e .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yCrBMxwBBuV0gX0e .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yCrBMxwBBuV0gX0e :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Admit
Admit
Reject
Reject
Reject
Pod
Eviction AdmitHandler

(资源压力检查)
Sysctl Whitelist

(安全Sysctl检查)
CPU/Memory/Topology

AllocateResourcesAdmitHandler

(资源分配准入)
PredicateAdmitHandler

(节点条件/优先级抢占)
AppArmor AdmitHandler
NoNewPrivs AdmitHandler
ProcMount AdmitHandler
Pod 可以运行
Pod 被阻塞

Reason=Blocked


相关推荐
用户987409238871 小时前
超算中心 高性能计算 htc命令module use的作用
架构
AI科技星2 小时前
基于**v=c(空间光速螺旋运动)唯一第一性原理**重新完整求导证明
人工智能·线性代数·算法·机器学习·架构·概率论·学习方法
__log2 小时前
如何优雅地“借鉴”任何网站的设计系统
人工智能·架构·知识图谱
宇明一不急2 小时前
k8s HPA storageclass configmap
云原生·容器·kubernetes
她的男孩3 小时前
从自然语言到数据大屏:Forge Report Studio 的 AI 生成链路
人工智能·后端·架构
她的男孩3 小时前
大屏动态数据接入:从静态 Mock 到真实业务 API
后端·架构
吴佳浩3 小时前
Vibe Coding 时代,研发经理为何越来越值钱?
算法·架构
canonical_entropy4 小时前
为什么 Attractor Guided Engineering 不能被降级为 AI Agent Skill
架构·agent·ai编程
Upsy-Daisy4 小时前
IOTA 学习笔记(四):当前 IOTA 架构总览
笔记·学习·架构