OCI 标准与 bundle
定义
OCI(Open Container Initiative)是一组开放规范,把 Docker 早期实践中的镜像格式与运行时接口标准化。与本百科直接相关的有三份契约:
- Image Spec:镜像清单、配置与层如何编码;
- Distribution Spec:registry 如何用 HTTP 分发这些对象;
- Runtime Spec:如何用一份目录描述「待启动的容器」,以及运行时应实现哪些生命周期操作。
bundle 是 Runtime Spec
中的交接物:一个目录,至少包含
config.json(进程、挂载、命名空间、资源限制等)和
rootfs/(根文件系统)。底层运行时只消费 bundle,不负责理解
Dockerfile,也不负责访问 registry。
问题背景
若镜像格式与启动接口由单一厂商定义,则构建工具、仓库、编排器与运行时无法独立演进。OCI
把「什么是镜像」和「如何启动一个容器」从产品中抽出来,使
runc、containerd、CRI-O 以及 A3S OCI Runtime 可以在同一份
bundle 语义上互换底层实现,而不要求上层改用另一套镜像格式。
机制说明
镜像规范与运行时规范的分工
构建与分发阶段处理的是镜像:可存储、可签名、可在仓库之间复制。启动阶段处理的是bundle:已经落在本机、针对这一次运行填好了挂载与进程参数的目录。
二者之间需要一次转换。产品运行时(在 A3S 中是 Box)负责:
- 拉取并校验镜像;
- 将层展开或组装为 rootfs;
- 把用户请求(命令、环境、卷、资源、隔离)写成
config.json; - 原子地发布 bundle。
底层运行时负责:校验
config.json、创建隔离、启动进程或虚拟机、记录退出状态、按身份清理。
为什么 Box 与 OCI Runtime 要拆开
ROADMAP.md 将职责写成单向依赖:Box 拥有 Docker
式用户体验与产品资源;OCI Runtime 拥有进程与隔离边界。Box 不得导入
Runtime 的驱动内部类型;Runtime 不得导入 Box 的产品类型。公共交接面是
a3s-oci-sdk 与准备好的 bundle。
这一拆分的直接后果是:在 Sandbox 路径上,Box 看起来仍像
Docker,但真正创建 namespace 的代码不在 Box 仓库里。阅读
src/runtime/src/local_execution/oci_backend.rs 时,看到的是
SDK 调用与身份围栏,而不是 clone 系统调用本身。
runc 在图中的位置
runc 是最常见的 OCI Runtime Spec 实现,也是 Docker /
containerd 默认的底层执行器。A3S OCI Runtime 占据同一抽象位置:吃
bundle,产出确切的进程或 VM 状态。它额外提供代际、操作日志、native 与
utility-VM 驱动,以及给 Box 使用的类型化 SDK。它不是 Docker
守护进程,也不提供 Compose。
在 Box 中的位置
- 工作区依赖将
a3s-oci-sdk固定在0.3.1,见src/Cargo.toml。 - 创建期路由由
OciMigrationPolicy决定。Linux 上新的 Sandbox 记录默认走SandboxViaOci,见 ExecutionManager、Backend 与 Router。 - bundle 编译与所有者启动集中在
src/runtime/src/local_execution/oci_production.rs、oci_owner.rs以及src/runtime/src/sandbox/。
验证命令
a3s-box info |
在已安装固定 a3s-oci / a3s-oci-agent 的
Linux 主机上,info 应报告 OCI
相关能力(例如符号链接支持)。随后:
a3s-box run --rm --isolation sandbox alpine:3.20 -- /bin/true |
该命令的成功表示 Box 已能把镜像转换为 Runtime 可接受的 bundle,并由长期 OCI 所有者执行。