作者: Rodrigo Campos Catelin(微软)、Giuseppe Scrivano(红帽)、Sascha Grunert(红帽)
Kubernetes v1.25 引入了仅对无状态 Pod 的用户命名空间的支持。在 1.27 中进行了一些设计更改后,Kubernetes 1.28 取消了该限制。
这个功能的美妙之处在于:
- 采用起来很简单(你只需要在 pod 规范中设置一个 bool 即可)
- 对于大多数应用程序不需要任何更改
- 通过大幅增强容器的隔离并减少评级为“高”和“危”的 CVE 来提高安全性。
这篇文章解释了用户命名空间的基础知识,还展示了:
- 最近的 Kubernetes v1.28 版本中的更改
- 评级为“高”的漏洞的演示,该漏洞无法通过用户命名空间利用
- 使用此功能的运行时要求
- 您可以在未来版本中期待有关用户命名空间的内容。
什么是用户命名空间?
用户命名空间是一项 Linux 功能,它将容器的用户和组标识符(UID 和 GID)与主机上的用户和组标识符隔离。容器中的标识符可以映射到主机上的标识符,其中用于不同容器的主机 UID/GID 不会重叠。更重要的是,标识符可以映射到主机上的非特权非重叠 UID 和 GID。这基本上意味着两件事:
-
由于不同容器的 UID 和 GID 映射到主机上不同的 UID 和 GID,因此即使容器逃出了容器边界,也很难相互攻击。例如,如果容器 A 在主机上使用与容器 B 不同的 UID 和 GID 运行,则它可以对容器 B 的文件和进程执行的操作受到限制:只能读/写文件允许其他人执行的操作,因为它永远不会执行其他操作。所有者或组的权限(主机上的 UID/GID 保证对于不同的容器是不同的)。
-
由于 UID 和 GID 映射到主机上的非特权用户,如果容器逃逸了容器边界,即使它在容器内以 root 身份运行,它在主机上也没有特权。这极大地保护了它可以读/写哪些主机文件、可以向哪个进程发送信号等。
此外,授予的功能仅在用户命名空间内有效,而在主机上无效。
在不使用用户命名空间的情况下,以 root 身份运行的容器在容器突破的情况下具有节点上的 root 权限。如果某些功能被授予容器,那么这些功能在主机上也有效。当使用用户命名空间时,这一切都不是真的(当然,模错误)
K8s 1.28变化
如前所述,从 1.28 开始,Kubernetes 支持具有有状态 Pod 的用户命名空间。这意味着具有用户命名空间的 Pod 可以使用任何类型的卷,它们不再像以前那样仅限于某些卷类型。
激活此功能的功能门已重命名,不再是, UserNamespacesStatelessPodsSupport但从 1.28 开始您应该使用 UserNamespacesSupport。进行了许多更改,并且对节点主机的要求也发生了变化。因此,在 Kubernetes 1.28 中,功能标志被重命名以反映这一点。