2. 容器运行时基础:OCI运行时规范、runc与crun、容器与宿主机内核的关系
容器运行时是容器生命周期管理的核心执行层,负责从镜像解包到进程隔离运行的全过程。在生产发布流水线中,运行时选择直接决定容器的启动速度、资源开销和安全隔离强度。本章从OCI规范出发,对比主流运行时实现,并深入剖析容器与宿主机内核的共享关系。
2.1 OCI运行时规范
Open Container Initiative(OCI)是Linux基金会下的开放标准组织,定义了容器格式和运行时的两份规范:
| 规范名称 | 版本 | 核心内容 | 典型实现 |
|---|---|---|---|
| OCI Image Spec | v1.1 | 镜像层结构、manifest、config JSON、索引格式 | containerd、podman、buildah |
| OCI Runtime Spec | v1.0 | 容器状态机、config.json、生命周期钩子、挂载、命名空间 | runc、crun、youki |
Runtime Spec 定义了容器运行时的最小行为契约:
- 状态机:容器状态在
creating→created→running→stopped之间流转。 - config.json:描述容器根文件系统、挂载点、进程参数、命名空间、cgroups、capabilities、seccomp 等。
- 生命周期钩子:
prestart、poststart、poststop,用于在关键节点注入自定义操作。
发布窗口防护要点:在流水线准入阶段,应校验 config.json 中的
readonlyPaths、maskedPaths、noNewPrivileges 字段,防止容器逃逸。
2.2 runc 与 crun 对比
runc 和 crun 是当前最主流的 OCI 运行时实现,两者在架构和性能上存在显著差异:
| 对比维度 | runc | crun |
|---|---|---|
| 开发语言 | Go | C |
| 启动延迟 | 较高(Go runtime 启动 + GC) | 极低(无 GC,直接系统调用) |
| 内存占用 | 每个容器约 2–5 MB | 每个容器约 0.5–1 MB |
| cgroup v2 支持 | 完整 | 完整(原生支持) |
| seccomp 性能 | 中等 | 高(C 级 BPF 编译) |
| 适用场景 | 通用、兼容性优先 | 高密度、低延迟、边缘计算 |
选型建议:在发布流水线中,若单节点容器密度超过 50 个或启动延迟要求低于 100ms,优先选用 crun;若依赖 containerd 默认集成且对兼容性要求高,可继续使用 runc。
2.3 容器与宿主机内核的关系
容器并非“轻量级虚拟机”,所有容器共享宿主机内核。这一共享模型是容器高性能的基础,也是安全风险的根源。
2.3.1 共享内核模型
- 系统调用直通:容器内进程直接通过宿主机内核进行系统调用,无虚拟化层开销。
- 内核对象共享:文件系统缓存、网络协议栈、进程调度、内存管理均由宿主机内核统一管理。
- 隔离依赖命名空间:PID、Mount、Network、UTS、IPC、User、Cgroup 等命名空间提供逻辑隔离,但内核漏洞可导致逃逸。
2.3.2 内核攻击面
| 攻击向量 | 风险描述 | 防护手段 |
|---|---|---|
| 内核漏洞(CVE) | 如 Dirty Pipe、OverlayFS 逃逸 | 及时打补丁、使用安全容器(Kata Containers) |
| 系统调用滥用 | 容器内执行危险 syscall | seccomp 白名单、AppArmor/SELinux |
| 资源耗尽 | fork bomb、内存泄漏影响宿主机 | cgroups 限制 pids.max、memory.limit |
| 命名空间逃逸 | 通过 --privileged 或挂载宿主机目录 |
禁止特权容器、只读根文件系统 |
发布窗口防护红线:在流水线准入阶段,必须检查容器是否以
privileged 模式运行、是否挂载宿主机 /proc//sys、是否禁用 seccomp。任何违反策略的镜像应被阻断上线。
2.4 容器运行时架构总览
下图展示了从高层容器管理工具到底层 OCI 运行时的完整调用链,以及容器与宿主机内核的共享关系:
2.5 发布窗口防护中的运行时检查清单
在流水线准入阶段,应针对容器运行时执行以下验证:
- 运行时版本检查:确认 runc/crun 版本已修复已知 CVE(如 CVE-2024-21626)。
- config.json 安全审计:检查
readonlyPaths、maskedPaths、noNewPrivileges、capabilities白名单。 - seccomp 策略验证:确保容器未使用
unconfinedseccomp 配置。 - 特权模式阻断:禁止
privileged: true容器通过准入。 - 挂载点审计:禁止挂载宿主机
/proc、/sys、/dev等敏感路径。 - cgroup 限制校验:确保
pids.max、memory.limit已设置合理上限。
最佳实践:在 CI/CD 流水线中集成
crictl inspect 或 runc state 命令,自动提取运行时配置并与安全基线比对,不符合策略的镜像直接阻断上线。