Kubernetes Kubelet CheckpointManager:Kubelet 子模块通用检查点框架的设计、演进与源码解析

发布时间:2026/10/15 20:43:11
Kubernetes Kubelet CheckpointManager:Kubelet 子模块通用检查点框架的设计、演进与源码解析 测试云原生质量保障【免费下载链接】originConformance test suite for OpenShift项目地址https://gitcode.com/gh_mirrors/or/origin点击查看免费下载导读本文以 vendor/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/README.md 为核心系统讲解 Kubernetes Kubelet 中 CheckpointManager 这一通用检查点checkpoint框架它是什么、为什么 Sig-Node 社区强烈建议非必要不新增 checkpointing、框架提供了哪些统一 API 与底层存储实现以及devicemanager、cpumanager、memorymanager、dra、allocation等 Kubelet 子模块如何基于它实现状态持久化与版本迁移。读完本文你将掌握 CheckpointManager 的接口设计、文件存储的原子写入机制、校验和checksum完整性校验原理以及各子模块的集成实践与版本兼容策略。说明本文所讨论的代码与文档均位于当前仓库的 vendored Kubernetes 源码目录vendor/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/即 Kubernetes 上游 kubelet 的实现快照。一、设计背景为什么尽量避免 checkpointing1.1 Sig-Node 社区的共识该 README 的开篇就是一个明确的DISCLAIMER免责声明Sig-Node 社区经过在生产环境中与一些难以排查的 bug 反复斗争后达成了普遍共识作为最佳实践应避免引入任何新的 checkpointing 支持这些难以调试的问题正是由 checkpointing 机制本身引起的任何对 checkpointed 数据结构checkpointed data structure的变更都会被视作不兼容变更因此组件如果要保证能够读取旧格式 checkpoint 文件必须自行添加相应的兼容处理。换句话说checkpointing 是一种把状态落到磁盘、并在 kubelet 重启后恢复的机制它把进程内状态暴露给了文件系统随之而来的是文件损坏、格式演进、磁盘故障、并发读写等一整套运维与兼容性负担。社区的态度是能不用就不用如果实在需要也必须走统一框架。1.2 既然要检查点就用统一 API在仍然需要 checkpointing的前提下checkpointmanager目录为 Kubelet 各子模块提供了公共的 APICheckpoint接口与CheckpointManager接口统一的框架实现文件存储 互斥锁 校验和验证。所有子模块使用同一套 API这保证了 Kubelet 层面的一致性consistency避免每个模块各自实现一套写文件 校验的逻辑。目前该框架被devicemanager、pods、cpumanager、memorymanager、dra、allocation等子模块使用用于在每个子模块级别实现检查点。二、核心接口Checkpoint 与 CheckpointManager框架的入口文件是 checkpoint_manager.go其中定义了两个关键接口。2.1 Checkpoint 接口检查点数据的契约// Checkpoint provides the process checkpoint data type Checkpoint interface { MarshalCheckpoint() ([]byte, error) UnmarshalCheckpoint(blob []byte) error VerifyChecksum() error }见 checkpoint_manager.go任何要被持久化的检查点数据都必须实现三个方法方法职责MarshalCheckpoint() ([]byte, error)将检查点数据序列化为字节流通常是 JSON并在序列化前计算并写入校验和UnmarshalCheckpoint(blob []byte) error从字节流反序列化恢复检查点数据VerifyChecksum() error校验当前数据的校验和是否匹配不匹配时返回CorruptCheckpointError2.2 CheckpointManager 接口管理检查点的四个操作// CheckpointManager provides the interface to manage checkpoint type CheckpointManager interface { // CreateCheckpoint persists checkpoint in CheckpointStore. checkpointKey is the key for utilstore to locate checkpoint. // For file backed utilstore, checkpointKey is the file name to write the checkpoint data. CreateCheckpoint(checkpointKey string, checkpoint Checkpoint) error // GetCheckpoint retrieves checkpoint from CheckpointStore. GetCheckpoint(checkpointKey string, checkpoint Checkpoint) error // WARNING: RemoveCheckpoint will not return error if checkpoint does not exist. RemoveCheckpoint(checkpointKey string) error // ListCheckpoints returns the list of existing checkpoints. ListCheckpoints() ([]string, error) }见 checkpoint_manager.go这里有几个值得注意的语义约定checkpointKey即存储键对于文件后端file backed utilstorecheckpointKey就是写入检查点数据的文件名RemoveCheckpoint是幂等的即使检查点不存在也不会返回错误接口注释中明确用WARNING标注所有操作都基于一个抽象存储层utilstore.Store目前 Kubelet 实际使用的是其文件实现FileStore。2.3 工厂函数与实现结构// NewCheckpointManager returns a new instance of a checkpoint manager func NewCheckpointManager(checkpointDir string) (CheckpointManager, error) { fstore, err : utilstore.NewFileStore(checkpointDir, utilfs.DefaultFs{}) if err ! nil { return nil, err } return impl{path: checkpointDir, store: fstore}, nil }见 checkpoint_manager.go创建管理器只需传入一个目录路径checkpointDir内部通过utilstore.NewFileStore构建文件存储并返回impl实现。impl结构体包含三个字段type impl struct { path string store utilstore.Store mutex sync.Mutex }见 checkpoint_manager.go其中sync.Mutex保证了对同一管理器的并发访问安全——CreateCheckpoint、GetCheckpoint、RemoveCheckpoint、ListCheckpoints四个方法都会先加锁再操作存储见 checkpoint_manager.go。2.4 读写流程与错误语义写入流程CreateCheckpoint先调用checkpoint.MarshalCheckpoint()得到序列化后的字节流这一步通常同时计算好校验和再调用store.Write(checkpointKey, blob)落盘。读取流程GetCheckpoint从存储读取字节流若键不存在utilstore.ErrKeyNotFound转换为errors.ErrCheckpointNotFound返回随后依次执行UnmarshalCheckpoint(blob)与VerifyChecksum()任何一步失败都会返回错误。也就是说读取时的校验和验证是框架层面的强制动作。三、底层存储FileStore 的原子写入与键约束3.1 Store 抽象接口存储层定义在 store.gotype Store interface { Write(key string, data []byte) error Read(key string) ([]byte, error) Delete(key string) error List() ([]string, error) }其中Read在键不存在时必须返回ErrKeyNotFoundDelete在键不存在时不得返回错误——这两条契约恰好与CheckpointManager的错误语义一一对应。3.2 键的格式与长度约束存储层对 key即检查点文件名有严格约束见 store.gokey 只能包含字母数字字符以及-、_、.必须以字母数字字符开头和结尾最大长度为250 个字符。keyMaxLength 250 keyCharFmt string [A-Za-z0-9] keyExtCharFmt string [-A-Za-z0-9_.]ValidateKey会在每次写入/读取/删除前执行校验见 store.go不合法即返回invalid key错误。这意味着子模块在命名检查点文件如cpu_manager_state时必须遵守该规则。3.3 原子写入临时文件 rename文件实现位于 filestore.go其写入采用经典的原子替换策略writeFile见 filestore.go在目标文件所在目录创建一个以.为前缀的临时文件tmpPrefix .写入数据调用Sync()将数据落盘fsync关闭临时文件Rename临时文件到最终路径实现一次性替换。任何一步出错都会关闭并清理临时文件。这种先写临时文件再 rename的方式避免了直接覆写目标文件可能导致的半写状态是检查点数据安全的重要保障。List()在枚举目录时会跳过以.开头的临时文件防止残留临时文件被误认为是检查点见 filestore.go。四、数据完整性FNV-32a 校验和与损坏检测4.1 checksum 工具包校验和的计算封装在 checksum/checksum.gotype Checksum uint64 func New(data interface{}) Checksum { return Checksum(getChecksum(data)) } func getChecksum(data interface{}) uint64 { hash : fnv.New32a() hashutil.DeepHashObject(hash, data) return uint64(hash.Sum32()) }算法核心是FNV-32a 哈希DeepHashObject深度序列化对数据结构做深度遍历后计算 32 位哈希。Verify方法对比存储的校验和与重新计算的值不一致时返回CorruptCheckpointErrorfunc (cs Checksum) Verify(data interface{}) error { actualCS : New(data) if cs ! actualCS { return errors.CorruptCheckpointError{ActualCS: uint64(actualCS), ExpectedCS: uint64(cs)} } return nil }见 checksum/checksum.go4.2 错误类型定义错误定义在 errors/errors.gotype CorruptCheckpointError struct { ActualCS, ExpectedCS uint64 } var ErrCheckpointNotFound fmt.Errorf(checkpoint is not found)CorruptCheckpointError校验和不匹配携带实际值ActualCS与期望值ExpectedCS并实现了Is方法支持errors.Is(err, CorruptCheckpointError{})模式匹配方便调用方判断检查点损坏这一具体场景ErrCheckpointNotFound检查点不存在子模块据此决定是直接初始化一个空状态并落盘还是报错退出。五、各子模块的集成实践源码级证据README 指出该框架服务于devicemanager、pods、cpumanager、memorymanager、dra、allocation等子模块。逐一核对当前仓库代码可以确认其中五个模块的实际调用点5.1 CPU ManagercpumanagerCPU Manager 的状态持久化是最典型的应用。在 state_checkpoint.go 中checkpointManager, err : checkpointmanager.NewCheckpointManager(stateDir) ... if err : stateCheckpoint.restoreState(); err ! nil { return nil, fmt.Errorf(could not restore state from checkpoint: %v, please drain this node and delete the CPU manager checkpoint file %q before restarting Kubelet, err, filepath.Join(stateDir, checkpointName)) }值得注意的实战要点恢复失败即拒绝启动如果从检查点恢复状态失败kubelet 会直接报错并提示用户排空该节点drain this node并删除 CPU manager 检查点文件后再重启 Kubelet检查点数据版本化CPUManagerCheckpointv3 格式包含policyName、defaultCpuSet、entries容器级 CPU 分配、podEntriesPod 级分配与checksum字段见 checkpoint.go自动迁移旧格式restoreState内部通过loadAndMigrateCheckpointV3/loadAndMigrateCheckpointV2链式回退实现 v1 → v2 → v3 的逐级迁移见 state_checkpoint.go这正是 README 中组件应自行保证读取旧格式检查点的向后兼容的落地实现校验和参与格式兼容v2 格式在计算校验和时会把结构体名从CPUManagerCheckpointV2替换为旧的CPUManagerCheckpoint以兼容不识别新结构体名的旧版 kubelet见 checkpoint.go。5.2 Memory ManagermemorymanagerMemory Manager 与 CPU Manager 结构高度对称。在 state_checkpoint.go 中同样通过checkpointmanager.NewCheckpointManager(stateDir)初始化并在恢复失败时提示删除 memory manager 检查点文件。检查点结构MemoryManagerCheckpoint保存policyName、machineStateNUMA 节点状态、entries容器内存分配、podEntries与校验和见 checkpoint.go同样实现了 v1 → v2 的格式迁移见 state_checkpoint.go。5.3 Device ManagerdevicemanagerDevice Manager 在 manager.go 中初始化检查点管理器其检查点目录来自 device plugin 的 socket 路径manager.checkpointdir, _ filepath.Split(server.SocketPath())检查点文件名为kubeletDeviceManagerCheckpoint。检查点数据DeviceManagerCheckpoint保存 pod 到设备的分配关系PodDevicesEntryPodUID、ContainerName、ResourceName、按 NUMA 分组的 DeviceIDs、AllocResp以及已注册设备列表见 checkpoint/checkpoint.go。写入时调用CreateCheckpoint读取时调用GetCheckpoint见 manager.go。5.4 DRAdraDRADynamic Resource Allocation模块封装了一个更上层的Checkpointer见 dra/state/checkpointer.gotype Checkpointer interface { GetOrCreate() (*Checkpoint, error) Store(*Checkpoint) error }其GetOrCreate在检查点不存在时ErrCheckpointNotFound自动创建空状态并落盘见 checkpointer.go。值得注意的是DRA 的检查点数据结构带有标准的 API 元信息CheckpointAPIGroup checkpoint.dra.kubelet.k8s.io CheckpointKind DRACheckpoint CheckpointAPIVersion CheckpointAPIGroup /v1见 dra/state/checkpoint.go其校验和采用的是CRC32crc32.ChecksumIEEE而非 FNV-32a见 dra/state/checkpoint.go说明框架只强制Checkpoint接口契约具体哈希算法由各模块自行选择。5.5 Pod 资源分配管理allocationallocation模块2025 年从 status manager 中拆分出的 pod 资源分配管理同样基于该框架。其NewStateCheckpoint在恢复失败时同样给出drain 节点并删除检查点文件的提示见 state_checkpoint.go。该模块还有一个值得借鉴的写优化storeState在落盘前对比新计算出的校验和与上次写入的校验和若没有变化则直接跳过重写减少不必要的磁盘 I/O见 state_checkpoint.go。六、演进历史Kubelet 中的 checkpointing 时间线README 提供了 Kubelet 各模块 checkpointing 支持的历史时间线整理如下PackageFirst checkpointing support merged on对应 PRStatuskubelet/dockershim2017-02-03PR #39903CRI Dockershim CheckpointRemoved已移除devicemanager2017-09-06PR #51744Deviceplugin checkpointIn use使用中kubelet/pod2017-11-22PR #50984基础 bootstrap-checkpoint 支持In use使用中cpumanager2017-10-27PR #54408Add file backed state to cpu managerIn use使用中memorymanager2021-02-09PR #95479Memory managerIn use使用中dra2023-03-12PR #115912DRA Manager 检查点机制In use使用中dra2024-07-24PR #126303DRA 检查点重构In use使用中allocation2025-02-28PR #130254将 pod 资源分配管理移出 status managerIn use使用中特别说明Dockershim 自 Kubernetes 1.24 起已从 Kubernetes 项目中移除相应地dockershim 的检查点支持也随之删除——这也是历史表中唯一标注为 Removed 的条目。从时间线可以清楚看到检查点支持整体呈现多模块复用同一框架的趋势且新模块memorymanager、dra、allocation均在框架成熟后接入。七、实战建议与注意事项结合 README 的警示与源码实现在使用或扩展 CheckpointManager 时应注意先问真的需要吗Sig-Node 社区的立场非常明确——能避免就避免。新增 checkpointing 意味着引入磁盘状态、格式兼容与故障排查负担且任何数据结构变更都会被认定为不兼容变更。必须使用时走统一框架实现Checkpoint接口MarshalCheckpoint/UnmarshalCheckpoint/VerifyChecksum并通过NewCheckpointManager(checkpointDir)获取管理器保证与既有模块一致。遵守 key 命名规范检查点文件名只能使用[A-Za-z0-9-_.]字符、以字母数字开头结尾且不超过 250 字符。处理好检查点不存在与检查点损坏两种错误ErrCheckpointNotFound通常意味着首次启动应初始化空状态并落盘CorruptCheckpointError则可能意味着磁盘损坏或写入中断需要决定是回退旧格式如 CPU/Memory Manager 的版本迁移链还是让 kubelet 拒绝启动并提示排空节点、删除检查点文件。恢复失败的处理CPU Manager、Memory Manager、allocation 的实践是恢复失败即拒绝启动并给出明确的恢复步骤drain 节点 删除检查点文件。这是为了避免在错误的状态基础上继续调度资源。写入安全底层FileStore已通过临时文件 fsync rename保证原子性各模块无需自行处理写中断导致的半写文件但仍应定期关注目录下是否存在以.开头的残留临时文件。版本迁移若检查点格式发生变化参考 CPU Manager 的 v1→v2→v3 迁移模式优先加载最新版本失败后逐级回退到旧版本并做内存内迁移迁移成功后按最新格式重写同时保证新旧 kubelet 都能正确校验如结构体名替换技巧。八、总结Kubelet CheckpointManager 是一个小而精的通用持久化框架以两个 Go 接口Checkpoint、CheckpointManager界定契约以文件存储FileStore 互斥锁 校验和FNV-32a/CRC32提供可靠落盘与完整性验证被 CPU/Memory/Device/DRA/Allocation 等资源管理模块广泛复用。它的存在让各子模块的状态持久化行为保持一致同时也承载了社区对 checkpointing 的审慎态度——这是一种允许但不鼓励、必须则统一的设计哲学。理解这个框架对于排查 kubelet 重启后的状态恢复问题、评估是否新增检查点以及实现检查点格式的向后兼容迁移都具有直接的实战指导意义。赞分享测试云原生质量保障【免费下载链接】originConformance test suite for OpenShift项目地址https://gitcode.com/gh_mirrors/or/origin点击查看免费下载相关推荐Dopamine JAX 版强化学习框架全解读架构设计、模块组织与预训练检查点使用Dopamine JAX 版强化学习框架全解读架构设计、模块组织与预训练检查点使用 本篇技术指南以仓库中 dopamine/jax/README.md htt机器学习深度学习Wan_2.2_ComfyUI_Repackaged LoRA使用指南LightX2V 4步加速与Relight重打光实战Wan_2.2_ComfyUI_Repackaged LoRA使用指南LightX2V 4步加速与Relight重打光实战 Wan_2.2_ComfyUI_R大模型媒体生成视频人工智能终极Lucky Lillia Bot架构解析模块化设计与多协议支持的完整指南终极Lucky Lillia Bot架构解析模块化设计与多协议支持的完整指南 Lucky Lillia Bot是一款功能强大的聊天机器人框架支持OneBot即时通讯后端上一篇RDP Wrapper Library打破Windows远程桌面连接限制的完整指南下一篇QMCDecode3步解锁QQ音乐加密格式让音乐文件重获自由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询