文档目录架构 · 18 篇

隔离与资源模型

说明工作负载的身份与凭据、命名空间与挂载视图、cgroup 资源约束,以及客户机与宿主两层强制执行的隔离边界。

译自microsoft/nvx · doc/design/4.3-isolation-and-resource-model.md。技术细节以英文原文为准。

架构文档 > 4. 客户机运行时架构

4.3.1 身份与凭据

工作负载以宿主选定的、在初次启动时固定的非 root 数字 UID 和 GID 运行。客户机代理要求在工作负载根中存在完全匹配的用户与主组,并在启动工作负载之前拒绝不可用的身份。当启动配置要求时,它们会改为为镜像所缺少的、由宿主选定的身份创建账号,并把使用该 UID 但主组不同、或没有可用家目录的镜像账号替换掉。这让宿主能够以自身用户的 ID 运行工作负载。

在工作负载启动之前,客户机代理清除附加组和每一个能力集合,并启用 no_new_privs。由于所有能力都被清除,工作负载无法执行端口 I/O,因此只有客户机代理才能请求一次捕获或确认一次恢复修复。

4.3.2 命名空间与挂载

在分层沙箱根中,工作负载获得私有的 mount、PID 和 UTS 命名空间。它的入口辅助程序使每一个挂载都变为私有,并提供:

  • 私有的 /proc 和只读的 /sys。
  • 受限的 /dev、devpts 和共享内存。
  • 工作负载根,通过 chroot 进入。
  • 只有宿主所声明的实时共享。
  • 工作负载的机器 ID,以只读方式从一个运行时文件绑定,以便客户机代理能在暂存盘冻结期间刷新它。
  • 客户机时间状态,以只读方式绑定。

客户机代理绝不从 initramfs 切换出去,因此它们保留自己的根,并留在工作负载的命名空间之外,在那里它们可以监管并拆除工作负载。控制设备绝不会暴露在工作负载的命名空间之内。

无块托管根没有这样的隔离。每次执行都运行在客户机的 initramfs 根中,不使用 chroot,与客户机代理处于相同的 mount、PID 和 UTS 命名空间中,因此它会看到客户机自身的 /proc、/sys 和 /dev,以及绑定到该根中的宿主映射。它的凭据和它的执行 cgroup约束着它,但它没有私有的挂载、进程、主机名或设备视图。

4.3.3 cgroup 与资源

在分层沙箱根中,客户机代理与工作负载占据同级的 cgroup。工作负载会被放入其 cgroup,但在放行之前一直挡在一道屏障之后。客户机代理的 cgroup 带有 16 MiB 的默认内存保护,这是一份软预留,能在工作负载内存压力下保护监管者免于被回收,但不保证它存活。工作负载 cgroup 带有可选的内存与进程数限制,并且是捕获冻结、终止和后代进程清理的单元。

在无块托管根中,每次执行在工作负载运行之前加入一个专用的 cgroup,用于终止与后代进程计数。这条路径不配置同级的客户机代理 cgroup,不配置 16 MiB 的内存保护,也不配置分层根的可选内存与进程数限制。

4.3.4 强制执行层

隔离有两层强制执行:

  • 客户机策略构建工作负载的凭据、挂载、能力与 cgroup,并且在分层沙箱根中构建它的命名空间。
  • 宿主设备独立地强制执行块可变性、网络策略和宿主文件系统访问。

客户机无法通过重新挂载文件系统、更改路由、创建链接或发出不同的设备请求来放宽宿主策略。