namespace 与 cgroup
定义
namespace(命名空间)与 cgroup(control group,控制组)是 Linux 内核提供的两组正交机制。namespace 决定进程能够看见哪些内核对象;cgroup 决定进程能够消耗多少资源。共享内核容器的隔离能力,主要来自这两套机制的组合,而不是来自第二份内核。
问题背景
同一台机器上运行多个互不信任或互不影响的程序时,需要同时回答两个问题。
第一,程序 A 是否应当看见程序 B 的进程列表、网络接口或文件系统挂载。若完全共享,则保密性与可复现性都无法保证。第二,程序 A 是否可以占满 CPU 或耗尽内存。若没有上限,则一台机器上的局部故障会变成整机故障。
早期 Unix 主要通过用户身份(UID)与权限位做隔离,粒度粗,也无法给出独立的网络栈或独立的 PID 空间。Linux 在内核中增加 namespace 与 cgroup 之后,才可能在不启动虚拟机的前提下,为进程构造近似「独立机器」的运行环境。
机制说明
namespace:改变可见性
可以把 namespace 理解成「给进程换一副眼镜」。内核对象仍然只有一份,但不同 namespace 中的进程看到不同的子集或不同的编号。
常见类型如下。不必一次记住全部名称,先记住每一类隔离的是什么对象。
| 类型 | 隔离对象 | 直观效果 |
|---|---|---|
| Mount | 挂载表 | 容器可以拥有自己的 /,宿主根目录不必被改写 |
| PID | 进程号空间 | 容器内入口进程可以是 PID 1,却不是宿主的 PID 1 |
| Network | 网络栈 | 独立的网卡、路由表、端口与防火墙规则 |
| UTS | 主机名与 NIS 域名 | 容器可以有自己的 hostname |
| IPC | System V IPC 与 POSIX 消息队列 | 进程间通信对象不与宿主或其他容器共享 |
| User | 用户与组 ID 的映射 | 容器内的 root 可以映射为宿主上的普通用户 |
| Cgroup | cgroup 目录树的视图 | 限制进程看见的控制组层级 |
「隔离可见性」不等于「再造一份内核」。容器调用
open、socket、clone
时,执行这些系统调用的仍然是宿主内核。因此,内核漏洞利用一旦成功,攻击面是整台宿主,而不是单个容器。
cgroup:改变配额
cgroup 把进程放进层级化的组,并对组设置控制器。常见控制器包括:
cpu:限制可用的 CPU 时间比例或带宽;memory:限制匿名内存与文件缓存,超限时触发回收或 OOM;pids:限制可创建的进程数,防止 fork 炸弹;io:限制块设备读写带宽。
没有 cgroup,namespace
只能做到「看不见别人」,做不到「用不完整机」。生产环境中的
--cpus、--memory 一类参数,最终都要落到 cgroup
配置。
二者如何组成一个容器
一个最小容器启动过程可以抽象为:
- 创建一组新的 namespace;
- 将该进程移入事先建好的 cgroup;
- 在新的 mount namespace 中把 rootfs
准备为
/; - 在该环境中执行入口程序。
此后在同一容器中 exec 出的进程,默认继承同一组 namespace
与 cgroup,因此看到同一套文件系统与网络,并共享同一份配额。
在 Box 中的位置
- Box 的共享内核路径(
--isolation sandbox)把 namespace 与 cgroup 的创建交给 A3S OCI Runtime。Box 在产品层记录 CPU、内存等意图,并在实时更新时通过持久化的运行时代际下发,见src/runtime/src/local_execution/中的资源更新路径。 - CLI 的
a3s-box container-update以及 SDK 的update_resources对应「先持久化资源意图,再要求运行时应用到确切 cgroup」的契约,而不是直接改写宿主/sys/fs/cgroup。 - MicroVM 路径上,客户机内部仍使用 Linux 的 namespace 与 cgroup;但宿主与工作负载之间的主边界是硬件虚拟化,而不是宿主 namespace。二者不可互相替代。
验证命令
在 Sandbox 中查看当前进程所属的 cgroup,并与宿主对比:
a3s-box run --rm --isolation sandbox --cpus 1 --memory 256m alpine:3.20 -- \ |
若主机已准备 OCI Runtime,输出中的 cgroup 路径与内存总量应反映容器配额,而不是整机容量。
相关与易混
- 相关:容器、隔离级别对比、Sandbox(共享内核)
- 易混:namespace 不提供加密或防侧信道能力;cgroup
不隔离内核漏洞。把「看见独立的
/」理解成「拥有独立操作系统」,是最常见的误读。