Kubernetes v1.36 [稳定](默认启用)本页介绍如何为 Pod 配置用户命名空间。这允许你将容器内运行的用户与主机上的用户隔离开来。
在容器中以 root 用户运行的进程可以在主机上以不同的(非 root)用户身份运行;换句话说,该进程在用户命名空间内拥有完全的特权,但在命名空间之外的操作则是无特权的。
你可以使用此特性来减少受损容器可能对主机或同一节点上的其他 Pod 造成的损害。有若干个安全漏洞被评为高危或严重,在启用用户命名空间时无法被利用。预计用户命名空间也将缓解未来的一些漏洞。
如果不使用用户命名空间,以 root 身份运行的容器在发生容器逃逸时,会在节点上拥有 root 特权。并且如果容器被授予了某些能力(capability),这些能力在主机上也是有效的。而当使用用户命名空间时,这些情况都不会发生。
你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群通信。建议在至少有两个节点的集群上运行本教程,且这些节点不能作为控制平面主机。如果你还没有集群,可以通过 minikube 创建一个,或者使用以下 Kubernetes 演练场之一。
你的 Kubernetes 服务器版本必须为 v1.25 或更高。要检查版本,请输入 kubectl version。
你使用的集群必须包含至少一个符合使用 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/user
kubectl 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。