跳到主要内容
约 5 分钟3 张卡

容器原理

Linux 容器是一组受隔离和资源约束的进程。本文负责 Namespace、cgroup 和分层文件系统。

1. 面试核心​

先记住这几条,再读正文
  • 容器与虚拟机。 Linux 容器共享宿主内核,虚拟机运行独立内核。卡 · 容器与虚拟机
  • 隔离与资源约束。 Namespace 隔离资源视图,cgroup 统计并约束资源用量。卡 · Namespace
  • 资源配额。 cgroup v2 的 cpu.max 限制 CPU 配额,memory.max 限制内存。
  • 文件系统。 OverlayFS 用可写上层和只读下层组成文件视图。
  • 权限控制。 capabilities 拆分特权,seccomp 过滤系统调用。卡 · 容器安全边界

2. 容器与虚拟机​

维度Linux 容器虚拟机
运行对象宿主内核调度的进程虚拟硬件上的客户操作系统
内核与宿主共享客户系统独立运行
启动工作创建隔离环境并启动程序启动客户内核和系统服务
资源开销进程和隔离机制的开销另有客户操作系统的开销
安全边界依赖共享内核和权限配置依赖虚拟化边界及其实现
系统兼容程序须兼容所用内核与架构客户系统须适配虚拟硬件

容器启动时间还包括镜像拉取和应用初始化。虚拟机也能通过快照缩短启动时间。因此,启动耗时应在相同工作负载下比较。

Linux 容器在 macOS 上运行时,需要 Linux 虚拟机。容器共享的是该虚拟机的内核。

3. Namespace​

Namespace 为进程提供独立的资源视图。

类型隔离对象
PID进程 ID 与可见进程范围
Network网络设备、路由、协议栈和端口
Mount挂载点
UTS主机名和 NIS 域名
IPCSystem V IPC 与 POSIX 消息队列
User用户、组 ID 和对应特权范围
Cgroup可见的 cgroup 根路径
Time单调时钟与启动时钟的偏移

Mount Namespace 隔离挂载视图。运行时还需设置根目录及具体挂载。Network Namespace 本身只提供网络隔离。veth、网桥或路由由网络配置建立。

ls -l /proc/<pid>/ns 可查看 Namespace 标识。nsenter -t <pid> -n ip addr 在目标网络视图内执行命令。docker exec 则通过运行时创建新的容器内进程。Linux 运行时可用 setns() 加入现有 Namespace。PID Namespace 的加入对后续创建的子进程生效。

容器可以显式共享部分 Namespace。例如 --network=host 使用宿主网络视图。

4. Cgroups​

cgroup 把进程组织成资源管理层级。本文的文件名以 cgroup v2 为准。

文件含义
cpu.max每个周期内可用的 CPU 时间
cpu.weight竞争 CPU 时的相对权重
cpuset.cpus允许使用的 CPU 集合
memory.max内存硬上限
memory.current当前内存用量
memory.events内存压力、OOM 与 OOM kill 事件计数
io.max指定块设备的带宽与 IOPS 上限
pids.max任务数量上限,线程也计入

cpu.max=50000 100000 表示每 100 ms 可用 50 ms。配额由组内任务共享,相当于半个 CPU 的时间。用完配额后,任务等待后续周期。宿主 CPU 空闲时也会发生这种限流。cpu.stat 的 nr_throttled 可用于确认。

内存达到 memory.max 后,内核尝试回收。回收无法满足分配时,会触发组内 OOM。确认 OOM 应结合 memory.events 与运行时状态。137 是 128+SIGKILL 的常见退出编码。手工强杀和停止超时也能产生该值。

v1 允许控制器使用不同层级。v2 使用统一层级,祖先的约束也作用于后代。v2 默认按进程分组,threaded 模式支持部分线程级控制。实际使用版本由宿主系统配置决定。

Docker 参数包括 --cpus=1.5、--memory=512m。任务数可通过 --pids-limit=100 约束。

5. 联合文件系统​

OverlayFS 将多层目录合并成一个视图。

  • lowerdir 提供只读下层。
  • upperdir 保存新增和修改后的文件。
  • merged 是应用看到的挂载视图。

读取时,上层同名对象覆盖下层对象。修改下层文件内容会触发 copy-up。文件复制到上层后,再接受修改。仅修改元数据时,行为还取决于 metacopy 配置。

删除下层文件会创建 whiteout,遮住原文件。下层镜像中的内容仍被保留。持久数据应使用卷,具体方式见 Docker 镜像与 Dockerfile。

6. 容器安全边界​

容器安全还依赖特权和系统调用约束。Namespace 只隔离各类资源视图。

capabilities 将 root 权限拆成独立能力。seccomp 按策略过滤系统调用。AppArmor、SELinux 进一步约束文件和资源访问。

非 root 用户可减少应用本身的权限。User Namespace 可将容器 UID 映射到宿主普通 UID。Docker rootless 还让守护进程以非 root 身份运行。两者的范围不同。

--privileged 会显著扩大容器权限。挂载 Docker socket 也会暴露守护进程控制能力。运行不可信代码时,还需评估独立虚拟机等隔离方案。

7 · 面试题卡片​

本页题目与参考回答

7.1 容器和虚拟机有什么本质区别?​

考察重点

  • 是否共享内核:容器是隔离的进程,虚拟机虚拟了硬件。
  • 由此推出启动速度、开销、隔离强度和可运行系统的差异。

相关内容:容器与虚拟机、Namespace、Cgroups。

参考回答

Linux 容器共享宿主内核,虚拟机有独立的客户内核。

容器通过 Namespace 隔离资源视图。cgroup 负责资源约束,运行时设置根文件系统。

容器省去客户内核及系统服务的开销。实际启动速度还取决于镜像和应用初始化。虚拟机增加了一层虚拟化安全边界。容器则依赖共享内核和权限策略。两者都需要结合具体实现评估隔离能力。

7.2 容器是怎样实现隔离和资源限制的?Namespace 和 Cgroups 分别解决什么问题?​

考察重点

  • 各类 Namespace 隔离的内容;Cgroups 的主要控制器。
  • 内存超限与 CPU 限流的表现;v1 与 v2 的区别;docker exec 的原理。

相关内容:Namespace、Cgroups、联合文件系统。

参考回答

Namespace 隔离资源视图,cgroup 约束资源用量。

PID、Network、Mount 分别管理进程、网络与挂载视图。docker exec 让运行时启动新的容器内进程。运行时可通过 setns() 加入已有 Namespace。

cgroup v2 的 cpu.max 按周期限制 CPU 时间。配额用尽会引发限流。memory.max 触发回收,回收失败后可触发 OOM。退出码 137 还需结合 OOM 事件确认。pids.max 约束任务数,包含线程。

v1 可以有多个控制器层级,v2 使用统一层级。父级的资源上限同样约束子级。

7.3 容器内使用非 root 用户后,还需要哪些安全限制?​

考察重点:用户映射、权限与系统调用边界。

相关内容:容器安全边界。

参考回答

还需要限制 capabilities、系统调用和宿主资源访问。

非 root 用户只降低进程的用户权限。seccomp 过滤系统调用,安全模块控制资源访问。User Namespace 提供 UID 映射。rootless 还降低守护进程权限。容器共享内核,因此仍需评估内核攻击面。

8. 参考资料​