将用户命名空间与 Pod 一起使用
Kubernetes v1.33 [beta](默认启用)本页展示如何为 Pod 配置用户命名空间。这允许您将容器内运行的用户与主机上的用户隔离。
在容器中以 root 用户运行的进程可以在主机上以不同的(非 root)用户运行;换句话说,该进程在用户命名空间内拥有完全权限,但在命名空间外则没有权限。
您可以使用此功能来减少受损容器对主机或其他位于同一节点上的 Pod 造成的损害。存在一些评级为 HIGH 或 CRITICAL 的安全漏洞,在启用用户命名空间时无法利用。预计用户命名空间也将缓解未来的一些漏洞。
如果不使用用户命名空间,容器以 root 身份运行时,在发生容器逃逸的情况下,将拥有节点上的 root 权限。如果授予容器某些能力,这些能力在主机上也是有效的。当使用用户命名空间时,以上情况都不成立。
开始之前
您需要一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议在至少具有两个非控制平面主机的集群上运行本教程。如果您还没有集群,可以使用 minikube 创建一个,或者可以使用以下 Kubernetes 游乐场
您的 Kubernetes 服务器必须是 v1.25 或更高版本。要检查版本,请输入 kubectl version。
- 节点操作系统需要是 Linux
- 您需要在主机中执行命令
- 您需要能够进入 Pod
- 您需要启用
UserNamespacesSupport特性门控
说明
启用用户命名空间的特性门控先前名为UserNamespacesStatelessPodsSupport,当时仅支持无状态 Pod。仅 Kubernetes v1.25 到 v1.27 识别 UserNamespacesStatelessPodsSupport。您使用的集群必须包含至少一个满足 Pod 使用用户命名空间的要求的节点。
如果您有混合节点,并且只有一些节点提供 Pod 的用户命名空间支持,您还需要确保用户命名空间 Pod 被 调度到合适的节点。
运行使用用户命名空间的 Pod
通过将 .spec 的 hostUsers 字段设置为 false 来启用 Pod 的用户命名空间。例如
apiVersion: v1
kind: Pod
metadata:
name: userns
spec:
hostUsers: false
containers:
- name: shell
command: ["sleep", "infinity"]
image: debian
在您的集群上创建 Pod
kubectl apply -f https://k8s.io/examples/pods/user-namespaces-stateless.yaml进入 Pod 并运行
readlink /proc/self/ns/userkubectl exec -ti userns -- bash
运行此命令
readlink /proc/self/ns/user
输出类似于
user:[4026531837]
同时运行
cat /proc/self/uid_map
输出类似于
0 833617920 65536
然后在主机中打开 shell 并运行相同的命令。
readlink 命令显示进程正在运行的用户命名空间。在主机上运行时和在容器内部运行时,它应该不同。
容器内 uid_map 文件的最后一个数字必须是 65536,在主机上必须是一个更大的数字。
如果您在用户命名空间内运行 kubelet,则需要比较在 Pod 中运行命令的输出与在主机中运行命令的输出。
readlink /proc/$pid/ns/user
将 $pid 替换为 kubelet PID。
此页面上的项目引用了 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅 CNCF 网站指南。
在提出添加额外的第三方链接的更改之前,您应该阅读 内容指南。