在 Pod 中使用用户命名空间

特性状态:Kubernetes v1.30 [beta] (默认启用:false)

此页面展示如何为 Pod 配置用户命名空间。这允许你将容器内运行的用户与主机中的用户隔离开。

在容器中以 root 身份运行的进程可以在主机中以不同的(非 root)用户身份运行;换句话说,该进程在用户命名空间内具有完全的操作权限,但在命名空间外不具有操作权限。

你可以使用此特性来减少被入侵的容器对主机或同一节点中的其他 Pod 可能造成的损害。 有几个安全漏洞被评为 **高** 或 **严重**,当用户命名空间处于活动状态时,这些漏洞是不可利用的。 预计用户命名空间也将缓解未来的一些漏洞。

如果不使用用户命名空间,以 root 身份运行的容器在容器突破的情况下,将具有节点上的 root 权限。 如果向容器授予了某些功能,则这些功能在主机上也有效。 当使用用户命名空间时,这些情况都不成立。

准备开始

你必须拥有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具与你的集群通信。 建议在至少有两个不充当控制平面主机的节点上运行本教程。 如果你还没有集群,你可以使用 minikube 创建一个,或者你可以使用以下 Kubernetes 游乐场之一

你的 Kubernetes 服务器必须是 v1.25 或更高版本。 要检查版本,请输入 kubectl version

  • 节点操作系统需要是 Linux
  • 你需要在主机中执行命令
  • 你需要能够进入 Pod 中执行命令
  • 你需要启用 UserNamespacesSupport 特性门控

你正在使用的集群**必须**至少包含一个满足将用户命名空间与 Pod 一起使用的要求的节点。

如果你有混合节点,并且只有部分节点为 Pod 提供用户命名空间支持,则还需要确保用户命名空间 Pod 被调度到合适的节点。

运行使用用户命名空间的 Pod

通过将 .spechostUsers 字段设置为 false 来启用 Pod 的用户命名空间。 例如

apiVersion: v1
kind: Pod
metadata:
  name: userns
spec:
  hostUsers: false
  containers:
  - name: shell
    command: ["sleep", "infinity"]
    image: debian
  1. 在你的集群上创建 Pod

    kubectl apply -f https://k8s.io/examples/pods/user-namespaces-stateless.yaml
    
  2. 连接到容器并运行 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 网站指南

在提出添加额外第三方链接的更改之前,你应该阅读内容指南

上次修改时间为太平洋标准时间 2024 年 2 月 20 日上午 9:48:将更多特性状态短代码切换为数据驱动 (7b6866063f)