跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何在Docker中利用Checkpoint实现容器运行状态的动态保存与离线迁移

Docker checkpoint功能默认不可用,需同时满足三个前提:安装CRIU≥3.15、Docker daemon启用experimental模式、/etc/docker/daemon.json中设"experimental":true;缺一即报错或静默禁用。 Checkpoint 功能在 Docker 中默认不可用 Docker 原生不支持
docker checkpoint
,必须依赖底层 runc 和 CRIU,并手动启用实验性功能。如果你执行
docker checkpoint create
报错 “command not found” 或 “feature disabled”,不是命令写错了,而是 Docker daemon 根本没开启 checkpoint 支持。 关键前置条件有三个:
criu
已安装且版本 ≥ 3.15(推荐 3.17+),Docker 启动时加了
--experimental
,且
/etc/docker/daemon.json
中明确设
"experimental": true
。缺一不可。 常见坑:
criu
安装后未加入
$PATH
,Docker 启动时找不到二进制,但不会报错,只静默禁用 checkpoint 修改
daemon.json
后忘记
sudo systemctl restart docker
,配置不生效 容器启动时用了
--privileged
或挂载了
/dev
、
/proc
等敏感路径,CRIU 拒绝 checkpoint(提示
dump failed: exited with error
) 创建 checkpoint 必须满足容器运行约束 不是所有容器都能被 checkpoint。CRIU 要求进程处于“可冻结”状态:不能有用户态线程、不能使用某些内核特性(如 AF_UNIX abstract socket、memfd_create)、不能有打开的 inotify 实例等。最稳妥的做法是用极简镜像启动测试容器,例如:
docker run -d --name chktest --security-opt seccomp=unconfined alpine:latest sleep 3600
注意点: 必须去掉
--restart
策略,否则 checkpoint 后恢复可能触发自动重启,干扰状态一致性 避免挂载宿主机
/sys
、
/run
或使用
tmpfs
,这些会引入不可序列化的内核对象 如果容器内主进程是 shell(如
sh -c "while true; do ..."
),CRIU 可能因信号处理异常失败,建议用单进程模型(如直接跑
sleep
或
nginx -g "daemon off;"
) checkpoint 目录权限和路径必须由 Docker 管理 Docker 不允许指定任意路径保存 checkpoint,必须用
docker checkpoint create --checkpoint-dir
指向一个已存在的、Docker daemon 有读写权限的目录,且该目录不能是符号链接或 NFS 挂载点——CRIU 需要稳定的 inode 和本地文件系统语义。 Docker Sandbox 创建并管理 Docker 沙箱虚拟机环境以安全执行代理。适用于运行不受信任代码、探索包或隔离代理工作负载。支持 Claude、Codex、Copilot、Gemini 和 Kiro 代理,并提供网络代理控制。 下载 典型安全做法: 创建专用目录:
sudo mkdir -p /var/lib/docker/checkpoints
确保属主为
root:root
,权限
700
执行:
docker checkpoint create --checkpoint-dir /var/lib/docker/checkpoints chktest chk1
若提示
permission denied on checkpoint dir
,大概率是 SELinux 启用中,需临时设为 permissive:
sudo setenforce 0
(生产环境应配对应策略而非关闭)。 restore 时容器 ID 和网络状态不会自动还原 checkpoint 只保存进程内存、寄存器、打开文件描述符、TCP 连接状态等,不保存容器元数据(如 IP 地址、端口映射、卷挂载点)。执行
docker start --checkpoint chk1 chktest
会复用原容器配置,但若原容器已被
rm
,则必须用
docker run --rm --name chktest --checkpoint chk1 ...
重建,且需严格匹配原始
docker run
参数(包括
-v
、
--net
、
--ip
等),否则 restore 失败或行为异常。 特别注意: restore 前必须确保目标宿主机安装了完全一致的
criu
版本,否则可能因 ABI 不兼容导致段错误 跨机器迁移时,CPU 微架构差异(如从 Intel 迁到 AMD)虽通常可行,但若容器用了 AVX-512 指令,restore 会崩溃,CRIU 日志里会出现
Illegal instruction
checkpoint 文件夹(如
/var/lib/docker/checkpoints/chktest/chk1
)包含几十个二进制和元信息文件,迁移时必须整目录拷贝,不能只传其中几个 真正麻烦的从来不是命令怎么敲,而是确认 CRIU 能否干净地冻结那个特定进程——它对内核版本、glibc、甚至 Go runtime 的 GC 行为都敏感。调试时优先看
/var/log/syslog
或
journalctl -u docker | grep criu
,而不是只盯着 Docker CLI 的返回码。

相关文章