OCI Runtime Specification 介绍
1154 Words … ⏲ Reading Time: 5 Minutes, 14 Seconds
2024-02-17 22:43 +0800
在上次的 文章 OCI Image Specification 介绍 中我们介绍了 OCI Image Specification 定义的关于镜像如何实现的标准。这篇文章我们接着介绍一下 OCI Runtime Specification。
OCI Runtime Specification 的出发点和 Image Spec 基本一致,它通过制定容器执行的标准规范,使容器的行为和状态与具体的上层软件无关,实现容器的便携性和更好地自动化支持。
满足 OCI Runtime 的标准容器有五个基本的原则(runtime-spec/principles.md at main · opencontainers/runtime-spec):
- Standard Operations
- Content-agnostic
- Infra-agnostic
- Designed for automation
- Industrial-grade delivery
术语
为了尽可能准确地明确文章中使用术语的上下文,我们着重介绍一下 Runtime Spec 中涉及到的两个和其上下文较紧密相关的术语, 详细的列表大家可以参考 runtime-spec/glossary.md at main · opencontainers/runtime-spec
- Bundle: OCI Runtime Filesystem Bundle, 是符合 OCI Runtime Spec 定义规范的,用于创建容器的文件夹
- Runtime: OCI Runtime Spec 的具体实现,我们下文举例会用到的
runc
就术语 runtime, 其他例子见 runtime-spec/implementations.md at main · opencontainers/runtime-spec
Filesystem Bundle
如图所示,Runtime Bundle 包含两部分文件内容。
config.json
文件
Config 文件 是和容器运行相关的配置文件,必须放在 Bundle 根目录下。它包含的典型内容如环境变量信息、挂载(Mounts) 信息、容器进程(process
) 信息、和容器生命周期相关的 hooks 等。
Config 文件的生成来源主要有两种:
- 通过 Runtime 指令生成默认的 config.json 文件: 如
runc spec
, 通常用于开发、测试或是定制化配置的场景,生成默认配置后可以在其上进行修改来适配容器场景。 - 通过 OCI Image config 转化: 转化逻辑可以参考 image-spec/conversion.md at main · opencontainers/image-spec, 我们日常接触的其实主要是这种来源,它具有一致性和可复现,通常与容器生态系统进行了集成(如 Docker 实际上帮我们做了这层转化)。
rootfs
文件夹
rootfs 即容器的 filesystem, 工业使用场景中通过 Image Layers unpack 得到, rootfs
的路径和名称可以在 config.json
文件的 root.path
中进行指定。
Demo
Runtime Bundle 的文件结构相较于 Image Spec 要简单许多,我们不妨尝试按一下步骤动手尝试构建一个 Bundle 。
-
准备 Linux 环境(runc 只支持 Linux 环境执行)并进行
runc
准备, 见 runc -
通过 docker export 指令获得容器的 rootfs 并放置在指定文件夹, 这里以 busybox 镜像为例
$ mkdir rootfs $ docker export $(docker create busybox:latest) | tar -C rootfs -xvf -
-
创建默认的 config.json 文件
$ runc spec
Over, 最终文件结构如下
$ tree -L 2
.
├── config.json
└── rootfs
├── bin
├── dev
├── etc
├── home
├── lib
├── lib64 -> lib
├── proc
├── root
├── sys
├── tmp
├── usr
└── var
13 directories, 1 file
Lifecycle
除了文件结构 Bundle, OCI Runtime Spec 还定义了容器状态机及相关的 (Runtime 需要支持的) Operation 操作。
上图展示了容器的生命周期、对应触发指令及容器的响应行为,上图涉及的相关行为说明可以在 runtime-spec/runtime.md at main · opencontainers/runtime-spec 这里找到, 图上涉及的 Env 信息、Hooks 信息、用户制定的容器进程 process 都是在 config.json
文件中指定的。
我们可以在上文初始化好的 bundle 文件夹中创建容器并观察 Lifecycle:
-
执行
runc create <container-id>
, container-id 可以任意指定, 这里我们指定为 testid -
执行
runc list
观察状态, 这时我们容器的状态为 created$ runc list ID PID STATUS BUNDLE CREATED OWNER testid 7094 created .../busybox_fs 2024-02-17T13:20:13.231362865Z root
-
执行
runc start testid
后再执行runc list
, 会发现状态变为了stopped
(我们没有指定 process) -
可以通过
runc state testid
获得 runtime-spec/runtime.md at main · opencontainers/runtime-spec 描述的状态元数据信息, 如{ "ociVersion": "1.1.0+dev", "id": "testid", "pid": 0, "status": "stopped", "bundle": "...", "rootfs": "...", "created": "2024-02-17T14:19:51.642906094Z", "owner": "" }