为 Pod 配置用户名字空间
Kubernetes v1.25 [alpha]
本页展示如何为无状态 Pod 配置用户名字空间。可以将容器内的用户与主机上的用户隔离开来。
在容器中以 root 用户运行的进程可以以不同的(非 root)用户在宿主机上运行;换句话说, 进程在用户名字空间内部拥有执行操作的全部特权,但在用户名字空间外部并没有执行操作的特权。
你可以使用这个特性来减少有害的容器对同一宿主机上其他容器的影响。 有些安全脆弱性问题被评为 HIGH or CRITICAL,但当用户名字空间被启用时, 它们是无法被利用的。相信用户名字空间也能减轻一些未来的漏洞的影响。
在不使用用户名字空间的情况下,对于以 root 用户运行的容器而言,发生容器逃逸时, 容器将拥有在宿主机上的 root 特权。如果容器被赋予了某些权限,则这些权限在宿主机上同样有效。 当使用用户名字空间时这些都不可能发生。
准备开始
你必须拥有一个 Kubernetes 的集群,同时你必须配置 kubectl 命令行工具与你的集群通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 v1.25. 要获知版本信息,请输入kubectl version
.
- 节点上的操作系统必须为 Linux
- 你需要在宿主机上执行命令
- 你需要能够通过 exec 操作进入 Pod
- 你需要启用
UserNamespacesSupport
特性门控。
在用户名字空间原来仅支持无状态的 Pod 时,启用用户名字空间的特性门控先前被命名为 UserNamespacesStatelessPodsSupport
。
只有 Kubernetes v1.25 到 v1.27 才能识别 UserNamespacesStatelessPodsSupport
。
你所使用的集群必须包括至少一个符合 要求 的节点,以便为 Pod 配置用户名字空间。
如果你有混合节点,并且只有部分节点支持为 Pod 配置用户名字空间, 你还需要确保配置了用户名字空间的 Pod 被调度到合适的节点。
- CRI-O: v1.25 支持用户名字空间。
请注意 如果你的容器运行时环境不支持用户名字空间,那么 Pod 规约中的 hostUsers
字段将被静默忽略,
并且系统会在没有用户名字空间的环境中创建 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 0 4294967295
然后,在主机中打开一个 Shell 并运行相同的命令。
输出一定是不同的。这意味着主机和 Pod 使用不同的用户名字空间。当未启用用户名字空间时, 宿主机和 Pod 使用相同的用户名字空间。
如果你在用户名字空间中运行 kubelet,则需要将在 Pod 中运行命令的输出与在主机中运行的输出进行比较:
readlink /proc/$pid/ns/user
user:[4026534732]
使用 kubelet 的进程号代替 $pid
本页面中的条目引用了第三方产品或项目,这些产品(项目)提供了 Kubernetes 所需的功能。Kubernetes 项目的开发人员不对这些第三方产品(项目)负责。请参阅CNCF 网站指南了解更多细节。
在提交更改建议,向本页添加新的第三方链接之前,你应该先阅读内容指南。