在 Pod 中使用用户命名空间
Kubernetes v1.30 [beta]
本页展示了如何为 Pod 配置用户命名空间。这允许您将容器内部运行的用户与主机中的用户隔离。
在容器中以 root 身份运行的进程可以在主机中以不同的(非 root)用户身份运行;换句话说,该进程对用户命名空间内的操作具有完全权限,但对命名空间之外的操作没有权限。
您可以使用此功能来减少被入侵的容器对主机或同一节点上的其他 Pod 造成的损害。有 几个安全漏洞 被评为 **高** 或 **严重**,当启用用户命名空间时,这些漏洞无法利用。预计用户命名空间也将缓解一些未来的漏洞。
如果不使用用户命名空间,则以 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
为 Pod 启用用户命名空间,将 .spec
的 hostUsers
字段设置为 false
。例如
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
附加到容器并运行
readlink /proc/self/ns/user
kubectl attach -it 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 网站指南。
在建议添加额外第三方链接的更改之前,您应该阅读 内容指南。