这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。
作者: Rodrigo Campos Catelin (Microsoft), Giuseppe Scrivano (Red Hat), Sascha Grunert (Red Hat)
译者: Xin Li (DaoCloud)
Kubernetes v1.25 引入用户命名空间(User Namespace)特性,仅支持无状态(Stateless)Pod。 Kubernetes 1.28 在 1.27 的基础上中进行了一些改进后,取消了这一限制。
此特性的精妙之处在于:
这篇文章介绍了用户命名空间的基础知识,并展示了:
用户命名空间是 Linux 的一项特性,它将容器的用户和组标识符(UID 和 GID)与宿主机上的标识符隔离开来。 容器中的标识符可以映射到宿主机上的标识符,其中用于不同容器的主机 UID/GID 从不重叠。 更重要的是,标识符可以映射到宿主机上的非特权、非重叠的 UID 和 GID。这基本上意味着两件事:
此外,所授予的权能(Capability)仅在用户命名空间内有效,而在宿主机上无效。
在不使用用户命名空间的情况下,以 root 身份运行的容器在发生逃逸的情况下会获得节点上的 root 权限。如果某些权能被授予容器,那么这些权能在主机上也有效。 当使用用户命名空间时,这些情况都会被避免(当然,除非存在漏洞 🙂)。
正如之前提到的,从 1.28 版本开始,Kubernetes 支持有状态的 Pod 的用户命名空间。 这意味着具有用户命名空间的 Pod 可以使用任何类型的卷,不再仅限于以前的部分卷类型。
从 1.28 版本开始,用于激活此特性的特性门控已被重命名,不再是 UserNamespacesStatelessPodsSupport,
而应该使用 UserNamespacesSupport。此特性经历了许多更改,
对节点主机的要求也发生了变化。因此,Kubernetes 1.28 版本将该特性标志重命名以反映这一变化。
Rodrigo 创建了一个利用 CVE 2022-0492 的演示, 用以展现如何在没有用户命名空间的情况下利用该漏洞。 他还展示了在容器使用了此特性的 Pod 中无法利用此漏洞的情况。
此漏洞被评为高危,允许一个没有特殊特权的容器读/写宿主机上的任何路径,并在宿主机上以 root 身份启动进程。
如今,容器中的大多数应用程序都以 root 身份运行,或者以半可预测的非 root 用户身份运行(用户 ID 65534 是一个比较流行的选择)。 当你运行某个 Pod,而其中带有使用用户名命名空间(userns)的容器时,Kubernetes 以非特权用户身份运行这些容器,无需在你的应用程序中进行任何更改。
这意味着两个以用户 65534 身份运行的容器实际上会被映射到宿主机上的不同用户, 从而限制了它们在发生逃逸的情况下能够对彼此执行的操作,如果它们以 root 身份运行, 宿主机上的特权也会降低到非特权用户的权限。
要使用此功能,对 Linux 内核版本以及容器运行时有一定要求。
在 Linux上,你需要 Linux 6.3 或更高版本。这是因为该特性依赖于一个名为 idmap mounts 的内核特性,而 Linux 6.3 中合并了针对 tmpfs 使用 idmap mounts 的支持
如果你使用 CRI-O 与 crun,这一特性在 CRI-O 1.28.1 和 crun 1.9 或更高版本中受支持。 如果你使用 CRI-O 与 runc,目前仍不受支持。
containerd 对此的支持目前设定的目标是 containerd 2.0;不管你是否与 crun 或 runc 一起使用,或许都不重要。
请注意,containerd 1.7 添加了对用户命名空间的实验性支持,正如在 Kubernetes 1.25 和 1.26 中实现的那样。1.27 版本中进行的重新设计不受 containerd 1.7 支持, 因此它在用户命名空间支持方面仅适用于 Kubernetes 1.25 和 1.26。
containerd 1.7 存在的一个限制是,在 Pod 启动期间需要更改容器镜像中每个文件和目录的所有权。 这意味着它具有存储开销,并且可能会显著影响容器启动延迟。containerd 2.0 可能会包括一个实现,可以消除增加的启动延迟和存储开销。如果计划在生产中使用 containerd 1.7 与用户命名空间,请考虑这一点。
这些 Containerd 限制均不适用于 [CRI-O 1.28][CRIO 版本]。
展望 Kubernetes 1.29,计划是与 SIG Auth 合作,将用户命名空间集成到 Pod 安全标准(PSS)和 Pod 安全准入中。
目前的计划是在使用用户命名空间时放宽 Pod 安全标准(PSS)策略中的检查。这意味着如果使用用户命名空间,那么字段
spec[.*].securityContext、runAsUser、runAsNonRoot、allowPrivilegeEscalation和capabilities
将不会触发违规,此行为可能会通过使用 API Server 特性门控来控制,比如 UserNamespacesPodSecurityStandards 或其他类似的。
你可以通过以下方式与 SIG Node 联系:
你还可以直接联系我们: