新闻详情

新闻详情

首页 / 资讯中心 / 详情

go-criu:在 containerd 中以 Go 原生方式驱动 CRIU 实现容器检查点与恢复

发布时间:2026/9/13 20:00:51来源:尧图网络
go-criu:在 containerd 中以 Go 原生方式驱动 CRIU 实现容器检查点与恢复
go-criu在 containerd 中以 Go 原生方式驱动 CRIU 实现容器检查点与恢复【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd本文以 containerd 仓库 vendored 的 go-criu v7 文档为主线讲解如何在 Go 程序中通过 CRIU RPC 完成进程转储dump、恢复restore与版本/特性检查并结合 containerd 的 CRI 检查点实现剖析其在真实容器运行时中的落地方式。读完本文你将掌握 go-criu 的 API 用法、底层 RPC 通信机制以及它如何支撑 containerd 的容器 Checkpoint/Restore 能力。go-criu 是什么go-criu 是为 CRIUCheckpoint/Restore In Userspace用户态检查点/恢复工具提供的 Go 语言绑定。CRIU 能在不中断运行的情况下冻结一个进程及其进程树、命名空间、网络连接等把完整运行状态写入磁盘镜像文件随后在相同或另一台机器上恢复执行是 Linux 容器实时迁移、应用快照等技术的基础组件。go-criu 的代码源自 CRIU 仓库中的 Go 版 PHaul进程 HA 实时迁移实现。为了让其他 Go 项目更方便地引入CRIU 官方把 Go 绑定独立成库并迁移到本仓库checkpoint-restore/go-criu。在 containerd 中该库被 vendored 在 vendor/github.com/checkpoint-restore/go-criu/v7 下为 CRI 的容器检查点功能提供核心支撑。go-criu 的核心价值在于使用者无需自行搭建 CRIU RPC 连接基础设施即可从 Go 中直接调用 CRIU 的 RPC 接口完成 dump、restore、预转储、page server 启动、版本与特性查询等操作。快速上手从 Go 调用 CRIUgo-criu 的用法非常轻量只需两步创建Criu对象然后调用其方法。获取 CRIU 版本下面这段来自官方 README 的示例会打印 CRIU 的版本号import ( log github.com/checkpoint-restore/go-criu/v7 ) func main() { c : criu.MakeCriu() version, err : c.GetCriuVersion() if err ! nil { log.Fatalln(err) } log.Println(version) }MakeCriu()返回一个*Criu对象其实现位于 main.go默认swrkPath为criu即从系统PATH中查找 CRIU 二进制。若 CRIU 安装在非标准位置可用SetCriuPath(path string)指定路径。GetCriuVersion()会执行VERSIONRPC 调用并按Major * 10000 Minor * 100 SubLevel的规则把版本号编码为整数返回main.go。若检测到 CRIU 是 git 开发版返回了gitid还会把 minor 进位 1这一逻辑与 runc 的做法保持一致。检查最低版本有时并不关心具体版本号只想知道当前 CRIU 是否满足某个最低要求c : criu.MakeCriu() result, err : c.IsCriuAtLeast(31100)IsCriuAtLeast(version int)内部调用GetCriuVersion()后与传入值比较main.go常用于启动前的能力校验。例如 go-criu 的utils包定义了两种最低版本常量utils/criu.goMinCriuVersionPodman 31100Podman 使用 go-criu 所需的最低 CRIU 版本3.11PodCriuVersion 31600容器进出 Pod共享 PID 命名空间场景下的检查点/恢复所需最低版本3.16。版本与特性检查的源码佐证IsCriuAtLeast依赖的版本号计算在 main.go 中完成依次累加 major、minor、sublevel遇到 git 版则version - (version % 100); version 100。这意味着传入比较的整数必须是同一编码规则例如31100表示 3.11、31600表示 3.16。除了版本号go-criu 还提供基于 libcriu 的特性检查能力。有些 CRIU 特性不取决于 CRIU 版本而取决于内核特性或 CPU 架构——比如内存追踪memory tracking可能在内核中关闭或 aarch64 等架构不支持。FeatureCheck(features *rpc.CriuFeatures)会发起FEATURE_CHECKRPC将待检查的特性字段置为 true 后传入CRIU 会在当前 CRIU/内核/架构组合下逐一核实可用特性返回时保持 true缺失特性被置为 falsefeatures.go。核心操作Dump、Restore 与预转储go-criu 为最常见的 CRIU 操作提供了同名方法全部定义在 main.go方法对应 RPC 类型作用Dump(opts, nfy)DUMP转储一个进程main.goRestore(opts, nfy)RESTORE从镜像恢复进程main.goPreDump(opts, nfy)PRE_DUMP预转储内存页预拷贝供迭代式迁移使用main.goStartPageServer(opts)PAGE_SERVER启动 page servermain.goStartPageServerChld(opts)PAGE_SERVER_CHLD启动 page server 并返回其 PID 与端口main.goGetCriuVersion()VERSION查询 CRIU 版本FeatureCheck(features)FEATURE_CHECK查询 CRIU/内核/架构特性这些方法的第二个参数nfy Notify用于接收 CRIU 生命周期事件。Notify接口定义在 notify.go共 9 个回调type Notify interface { PreDump() error PostDump() error PreRestore() error PostRestore(pid int32) error NetworkLock() error NetworkUnlock() error SetupNamespaces(pid int32) error PostSetupNamespaces() error PostResume() error }如果调用方不关心这些事件可以直接传NoNotify{}——它是接口的空实现所有方法都返回nilnotify.go。底层 RPC 通信机制go-criu 通过UNIX socketpair CRIUswrk子进程实现 RPCmain.goPrepare()调用syscall.Socketpair(AF_LOCAL, SOCK_SEQPACKET, 0)创建一对面向连接的本地 socket以criu swrk fd方式启动 CRIU 子进程把服务端 socket fd 传给 CRIU后续所有请求经sendAndRecv在 socket 上以 protobuf 序列化传输main.go请求/响应的消息结构定义在 rpc/rpc.proto操作完成后Cleanup()关闭 socket 并等待子进程退出main.go。doSwrkWithRespmain.go是核心循环发送请求后读取响应若响应类型为NOTIFY且传入了Notify则按notify.GetScript()的取值pre-dump、post-dump、pre-restore、post-restore、network-lock、network-unlock、setup-namespaces、post-setup-namespaces、post-resume分发到对应回调并回发NotifySuccess: true告知 CRIU 继续直到收到与请求类型一致的最终响应才返回。注意传入了Notify时go-criu 会自动把opts.NotifyScripts置为 true让 CRIU 以通知脚本模式工作。从源码结构看Prepare/Cleanup是惰性触发的首次发起 RPC 时若swrkCmd nil会自动Prepare()并在请求完成后 deferCleanup()调用方通常无需显式管理子进程生命周期。containerd 中的实际应用CRI 容器检查点go-criu 在 containerd 中最重要的落地场景是 CRI 服务的容器检查点CheckpointContainer功能实现在 internal/cri/server/container_checkpoint_linux.go。启动时的 CRIU 能力校验doCheckCriu()container_checkpoint_linux.go在每次检查点操作前执行一次由sync.Once保护client : criu.MakeCriu() client.SetCriuPath(path) version, err : client.GetCriuVersion() if err ! nil { return fmt.Errorf(failed to retrieve criu version: %w, err) } if version utils.PodCriuVersion { return fmt.Errorf(checkpoint/restore requires at least CRIU %d, current version is %d, utils.PodCriuVersion, version) }这里正是 README 中MakeCriu()SetCriuPath()GetCriuVersion()三步曲的生产级用法containerd 先通过resolveCriuPathcontainer_checkpoint_linux.go在 shim 配置路径或系统PATH中定位criu二进制再用utils.PodCriuVersion3.16做最低版本校验——该常量即来自 go-criu 的 utils/criu.go。检查点流程中的 go-criu 调用链CheckpointContainercontainer_checkpoint_linux.go的完整流程为校验 CRIU 可用且容器处于CONTAINER_RUNNING状态生成容器元数据config、status 等 JSON通过task.Checkpoint(ctx, withCheckpointOpts(...))调用底层 containerd Task 接口最终触发 CRIU 的DumpRPCwithCheckpointOptscontainer_checkpoint_linux.go为 runc v2 shim 设置CheckpointOptionsopts.Exit !leaveRunningKubernetes Forensic Container Checkpointing KEP 场景下leaveRunning true容器不停止并指定 CRIU 工作目录WorkPath把 CRIU 转储数据MediaTypeContainerd1Checkpoint、可写层 diffMediaTypeImageLayerGzip、容器 specMediaTypeContainerd1CheckpointConfig三个 blob 从检查点镜像中解出连同container.log、dump.log、stats-dump等一起打包成检查点归档 tar。也就是说go-criu 的Dump由 shim 层间接调用CRI 服务侧主要用到的是版本查询与路径配置能力而 go-criu 的Restore则服务于恢复流程containerd 客户端client/container_checkpoint_opts.go、client/container_restore_opts.go等文件中暴露对应的 Task 选项。独立的 CRIU 可用性检测工具仓库还附带一个独立小工具 contrib/checkpoint/checkcriu.go它直接调用 go-criuutils包的CheckForCriu(PodCriuVersion)来检测系统是否具备 pod 场景下容器检查点所需的 CRIU≥3.16若缺失则 panic。可用作 CI 或部署前的能力探测。版本关系与发布策略go-criu 的版本策略与 CRIU 版本存在对应关系。首个 go-criu 版本为 3.11对应 CRIU 3.11最初计划与 CRIU 保持同版本号但因 go-criu 被其他项目以 Go module 方式引入遵循语义化版本Semantic Versioning更合理因此自 4.0.0 起独立演进。README 中的版本对照表如下go-criu 大版本最新发布版对应 CRIU 版本v77.2.03.19v77.0.03.18v66.3.03.17v55.3.03.16v55.0.03.15v44.1.03.14containerd 当前 vendored 的是go-criu v7导入路径github.com/checkpoint-restore/go-criu/v7并与checkpointctl等配套库一起支撑 CRI 的检查点/恢复特性。CRITGo 原生的 CRIU 镜像文件解析go-criu 仓库还包含crit包用于在 Go 中解码、编码和操作 CRIU 镜像文件并提供一个与原始 CRIT Python 工具类似的 CLI。该包是分析、改写转储镜像的入口例如在恢复前对镜像做定制修改其用法文档见 CRITGo library。由于 containerd 的检查点归档是以 OCI 镜像形式分发docs/cri/architecture.md 描述了 CRI 架构crit可与容器镜像工具链配合使用属于进阶能力。参与贡献与许可go-criu 的贡献规范README 中 How to contribute 一节要点如下修复类 PR 可以不开 issue但需在 PR 中附带 issue 同等信息如复现步骤新特性 PR 应说明目标用例大 PR 应拆分为可独立评审的小 PR所有 PR 应包含注释良好的代码改动、测试用例理想情况下在改动前应失败、文档改动commit 应逻辑成组每个 commit 实现单一想法且 PR 分支在每个 commit 上都能通过测试修复 issue 的 PR 应在 commit message 中写Closes #XXXX以便自动关闭 issue贡献者须遵守 Developer Certificate of Origin 1.1在每条 commit message 中添加包含姓名与邮箱的Signed-off-by行。许可方面除文件头另有说明外go-criu 全部代码以 Apache 2.0 许可发布作者保留其代码的版权无版权转让作者与贡献者列表可从 git 提交历史及部分文件头获取。vendor 目录中同时保留了 LICENSE 与 MAINTAINERS 文件。小结go-criu 为 Go 生态提供了一条通往 CRIU 能力的低门槛通道API 简单MakeCriu()后即可调用Dump/Restore/PreDump/GetCriuVersion/IsCriuAtLeast/FeatureCheck无需手写 RPC 基础设施底层可靠基于 socketpair protobuf 的 RPC 通道main.go支持完整的 Notify 事件回调生命周期生产验证containerd 的 CRI 检查点/恢复能力正是建立在其之上container_checkpoint_linux.go版本校验、shim 路径解析与检查点归档流程均可直接参考生态配套utils提供最低版本常量crit提供镜像文件级操作能力v7 与 CRIU 3.18/3.19 对应。若要在自己的 Go 项目中接入容器检查点能力建议从IsCriuAtLeast(utils.PodCriuVersion)起步做能力探测再以Dump/RestoreNoNotify完成最小可用闭环最后按需实现Notify接口接入网络锁、命名空间等高级事件处理。【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

VMware Workstation安装Ubuntu虚拟机:从零开始到VMware Tools配置实战 2026/9/13 20:42:56

VMware Workstation安装Ubuntu虚拟机:从零开始到VMware Tools配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
SSD主控DDR初始化的7类硬性数据结构与排错实战 2026/9/13 20:42:56

SSD主控DDR初始化的7类硬性数据结构与排错实战

1. 这不是“填空题”,而是主控固件启动时的生死时速你拆过SSD吗?不是指换块盘,是真把PCB板子翻过来,用示波器探针点在主控芯片的DDR信号线上——那种在上电复位后几十微秒内就疯狂读写、像被按了快进键的波形。很多人以为SSD固件启…

阅读更多 →
Metabase 模块化嵌入主题配色键全解析:MetabaseEmbeddingColorKeyV2 类型与保护色机制 2026/9/13 20:42:56

Metabase 模块化嵌入主题配色键全解析:MetabaseEmbeddingColorKeyV2 类型与保护色机制

Metabase 模块化嵌入主题配色键全解析:MetabaseEmbeddingColorKeyV2 类型与保护色机制 【免费下载链接】metabase The easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart: 项目地址: htt…

阅读更多 →
FunASR 官方 checkpoint 原生 vLLM 验证实战指南:Fun-ASR-Nano 固定 revision 的服务化复现与边界 2026/9/13 20:42:56

FunASR 官方 checkpoint 原生 vLLM 验证实战指南:Fun-ASR-Nano 固定 revision 的服务化复现与边界

FunASR 官方 checkpoint 原生 vLLM 验证实战指南:Fun-ASR-Nano 固定 revision 的服务化复现与边界 【免费下载链接】FunASR Open-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, an…

阅读更多 →
Rowboat 视频通话模式(Video Mode / Calls)深度解析:多模态帧管线、推按说话语音回路与 LLM 提示面 2026/9/13 20:42:56

Rowboat 视频通话模式(Video Mode / Calls)深度解析:多模态帧管线、推按说话语音回路与 LLM 提示面

Rowboat 视频通话模式(Video Mode / Calls)深度解析:多模态帧管线、推按说话语音回路与 LLM 提示面 【免费下载链接】rowboat Open-source AI coworker, with memory 项目地址: https://gitcode.com/GitHub_Trending/rowb/rowboat 导读…

阅读更多 →
无人机飞控二次开发:树莓派外挂与MAVLink分层实践指南 2026/9/13 20:39:55

无人机飞控二次开发:树莓派外挂与MAVLink分层实践指南

1. 别急着编译px4——先搞清“二次开发”到底在开发什么 很多人一听说“飞控二次开发”,第一反应就是clone px4或ardupilot仓库,打开vscode,对着一堆C文件发呆。我见过太多人花两周配好环境、编译成功、烧录进飞控板,结果连LED灯怎…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞