快照、commit、diff 与 export
定义
工作负载的文件系统除了运行期读写之外,还支持四类产品操作。它们经常被放在同一组 CLI 下,但语义不可互换。
| 操作 | 输入 | 输出 | 目的 |
|---|---|---|---|
| snapshot | 一个已停止(或按契约可静默)的 box | 版本化、可恢复的文件系统检查点 | 以后把该 box 恢复到这一时刻 |
| commit | 一个 box 的当前根文件系统 | 新的镜像 | 把实例变成可再次 run 的镜像 |
| diff | 一个 box 与其启动基线 | 文件增删改列表 | 审查运行期改动了什么 |
| export | 一个 box 的根文件系统 | tar 等归档 | 把当前根拷贝到宿主,而不创建镜像元数据 |
此外还有内存级的 snapshot-fork,属于运行中的 MicroVM,不是本页的文件系统检查点。
问题背景
容器可写层默认是易失的。开发与运维仍然需要三种能力:看清改动、把改动变成新镜像、在不创建镜像的情况下留下可回滚点。若只用
cp
往宿主拷文件,则丢失元数据与可复现的恢复路径。把这四类操作做成一等命令,是为了让「文件系统历史」进入产品状态,而不是散落在临时目录。
机制说明
snapshot:检查点
a3s-box snapshot create data-app --name checkpoint-1
把干净的文件系统世代克隆到完整性受检的
bundle,并在恢复时给出私有可写克隆。Box 在 macOS 上的当前实现针对干净的
raw ext4 世代,创建、恢复与删除不要求宿主挂载客户机磁盘,恢复后的 box
也不依赖快照存储继续存在。快照 freezer
会持久化「运行时变更是否已应用」,以免崩溃恢复重放已经完成的 thaw。
commit:实例镜像化
commit
读取当前根(含可写层与已应用的修改),写出新的镜像配置与层。此后应通过新镜像启动,而不是假设旧
box 会永远活着。commit
不会自动代替卷:数据库若只写在卷里,未包含进根的数据不会进入新镜像。
diff:相对基线的变化
diff 需要一条基线。Box 在工作负载启动前捕获 guest 可见的 Linux 元数据,并由宿主原子发布;之后的启动不再重扫整个 rootfs。比较的是「现在」与「那条基线」,不是与 registry 里的原镜像做层哈希对比。日志脏磁盘在恢复完成前会被拒绝参与维护操作。
export:归档
export
把当前根打包给宿主。它不注册为镜像,因此没有标签与配置对象。适合取证或迁移到不理解
Box 快照格式的工具。macOS 上,干净停止的 box 通过一次性、无网络的维护
MicroVM 提供 diff / export /
commit:维护 init 从临时目录根启动,只读附加用户磁盘,以
ro,noload 挂载,只暴露归档、心跳与关机控制。
在 Box 中的位置
- 核心类型:
src/core/src/snapshot.rs、rootfs_baseline.rs。 - 运行时:
src/runtime/src/snapshot/、local_execution/snapshot.rs。 - CLI:
snapshot.rs、commit/、diff.rs、export.rs。 - 客户机基线:
src/guest/init/src/diff_baseline.rs。 - 设计:
docs/guest-native-rootfs-design.md、docs/cow-snapshot-fork-design.md。
验证命令
a3s-box volume create data |
/tmp/only-in-writable.txt 应出现在 diff 中;卷
data 的内容则属于卷,不因 snapshot 名称而自动并入镜像。
相关与易混
- 相关:rootfs、卷与挂载、镜像与层、Warm pool 与 snapshot-fork
- 易混:
snapshot恢复的是文件系统世代,不是 Kubernetes VolumeSnapshot。commit产生镜像,不产生可回滚的命名检查点。save/load作用于镜像归档,作用于仓库对象,而不是正在运行的根。