Containerd 元数据备份:四步搞定 meta.db 备份与 containerd 数据恢复
【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd
Containerd 是开源容器运行时,而 Containerd 元数据备份的对象只有一个文件:BoltDB 数据库meta.db,它保存了镜像、容器、快照等全部对象记录。一旦损坏或误删,整个节点上的容器生命周期管理都会失效。这篇文章讲清楚三件事:meta.db的备份边界、标准备份与 containerd 自动化备份的执行方式、以及 containerd 数据恢复时的恢复与修复路径。
meta.db 存了什么:先划清备份边界
元数据插件基于 bbolt 实现,事务接口见 core/metadata/bolt.go,数据库句柄与迁移逻辑在 core/metadata/db.go。Linux 下默认位置是:
/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db目录结构参考 docs/ops.md。数据库按版本/命名空间/对象分层(schema 定义在 core/metadata/buckets.go),当前 schema 为 v1,随版本提供 core/metadata/migrations.go 迁移。备份边界如下:
| 在 meta.db 里(需要备份) | 不在 meta.db 里(需要另行备份) |
|---|---|
| 镜像记录:名称、目标 digest、mediaType、标签 | 镜像层 blob 数据(io.containerd.content.v1.content/blobs) |
| 容器、sandbox 的 spec、runtime 配置、状态记录 | 快照文件系统数据(各 snapshotter 目录,如io.containerd.snapshotter.v1.overlayfs) |
| 快照引用关系:父子链、所属 snapshotter | 任务运行时状态:PID、挂载点(在/run/containerd状态目录,重启即失) |
| content 的 blob 索引与 ingest 引用(仅引用,不含内容) | 插件自身数据(如 overlayfs 的metadata.db) |
| 命名空间、namespace 级标签、leases | — |
结论:meta.db 是"索引 + 记录",不是"数据本体"。备份它只保证对象关系可恢复,层内容仍需从 root 目录其他位置获得。
执行一次标准 containerd meta.db 备份
整个流程四步,顺序不能变:
DB=/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db TS=$(date +%Y%m%d_%H%M%S) mkdir -p /backup # 1. 停服务:daemon 运行时持有 BoltDB 写锁,热拷贝会得到不一致的文件 systemctl stop containerd # 2. 复制文件:生成带时间戳的完整副本 cp "$DB" "/backup/meta_${TS}.db" # 3. bbolt 校验:确认副本结构完整、可打开(需先安装 bbolt 工具) bbolt check "/backup/meta_${TS}.db" # 4. 启服务:校验通过后再恢复业务 systemctl start containerd校验工具一次安装即可:go install go.etcd.io/bbolt/cmd/bbolt@latest。bbolt check无错误输出且退出码为 0 即通过;它只验证副本,不影响在线库。
让 containerd 自动化备份跑起来:脚本 + systemd 定时器
手动备份依赖人为触发,生产环境建议拆成两层:可重复执行的脚本,负责定时触发的 systemd 单元。
备份脚本
创建/usr/local/bin/containerd-meta-backup.sh,核心逻辑与上面四步一致,外加保留期清理(保留最近 30 天):
#!/bin/bash set -euo pipefail DB=/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db DIR=/backup/containerd TS=$(date +%Y%m%d_%H%M%S) mkdir -p "$DIR" systemctl stop containerd trap 'systemctl start containerd' EXIT # 异常退出也保证服务拉起 cp "$DB" "$DIR/meta_${TS}.db" bbolt check "$DIR/meta_${TS}.db" find "$DIR" -name 'meta_*.db' -mtime +30 -deletetrap是关键细节:哪怕bbolt check失败,daemon 也不会停在关闭状态。
systemd 定时器
/etc/systemd/system/containerd-backup.service:
[Unit] Description=Containerd meta.db backup [Service] Type=oneshot ExecStart=/usr/local/bin/containerd-meta-backup.sh/etc/systemd/system/containerd-backup.timer:
[Unit] Description=Timer for containerd meta.db backup [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target启用:systemctl daemon-reload && systemctl enable --now containerd-backup.timer。Persistent=true保证机器关机错过的周期开机后补跑。备份窗口只有秒级,选在业务低峰期触发即可。
containerd 数据恢复:meta.db 的恢复与修复
恢复前确认三件事,能避免"用坏备份覆盖好现场":
- 备份文件本身已通过
bbolt check; - 产生备份的 containerd 版本不高于当前版本(schema 迁移只向前兼容,高版本 meta.db 放不进低版本);
- 当前损坏的 meta.db 已先移走留证,而不是直接覆盖。
确认完成后,按备份的逆序执行(停止 daemon 的命令同备份第 1 步):
cp /backup/containerd/meta_20260901_030000.db \ /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db chown root:root /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db # 仅当 bbolt check 报告错误时执行修复: bbolt fix /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db systemctl start containerd启动后用只读命令验证记录是否可读:ctr namespaces ls和ctr -n default images ls。
⚠️ 避坑清单:上生产前核对这 5 条
- 不做热备份。BoltDB 单写者模型下,daemon 运行中直接
cpmeta.db 可能得到撕裂文件。停服务是必须步骤,代价只是秒级窗口。 - meta.db 不等于全部数据。完整恢复还要保留 root 目录下的 content blobs 与 snapshotter 目录,或依赖镜像可重新拉取这一前提。
- 定期演练恢复。每月在测试机实际恢复一次备份副本并验证
ctr输出;没演练过的备份等于没有。 - 副本带时间戳并异地存放。本地
/backup与主目录同盘时,磁盘故障会同时带走两者;至少保留一份异机或对象存储副本。 - 监控备份任务状态。对 oneshot 服务的
Result状态或脚本退出码做告警,备份静默失败是最常见的事故形态。
小结
Containerd 元数据备份就是"停服务、拷 meta.db、bbolt check、启服务"四步,恢复时先验副本再覆盖。把脚本和定时器部署上去,并每月演练一次恢复,meta.db就不再是单点。更多运维细节见官方文档 docs/ops.md 与 docs/。
【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考