2.17. 在 Linux 用户命名空间中运行 pod
Linux 用户命名空间允许管理员隔离容器用户和组标识符 (UID 和 GID),以便容器可以在用户命名空间中拥有与它运行的主机系统不同的权限集。这允许容器在用户命名空间中以完全特权运行容器,但对主机上的操作可以以非特权运行这些进程。
默认情况下,容器在主机用户命名空间中运行。当容器需要只在主机命名空间中可用的功能时,在主机用户命名空间中运行容器很有用。但是,在主机命名空间中运行的 pod 增加了安全性问题,如容器中断的可能性,另一个容器内的进程会破坏到主机上的进程,或者修改主机上的文件。
在独立用户命名空间中运行容器可以缓解容器逃逸的问题,以及其他可能会被破坏的容器对其他 pod 和节点本身造成影响的安全漏洞。
2.17.1. 配置 Linux 用户命名空间支持 复制链接链接已复制到粘贴板!
您可以通过在 pod spec 中将 hostUsers
参数设置为 false
来配置 Linux 用户命名空间,以及一些其他配置,如以下步骤所示。
在用户命名空间中运行工作负载时,可以安全地为安全上下文约束(SCC)字段配置 RunAsAny
,如 fsGroup
、runAsGroup
、runAsUser
、runAsUser 和 supplementalGroups
,因为容器外部的 UID 或 GID 与其中的不同,这些字段表示。
为获得额外的安全性,您可以使用 restricted-v3
或 nested-container
SCC,这专门为 Linux 用户命名空间中的工作负载设计。SCC 中的 userNamespaceLevel: RequirePodLevel
字段要求工作负载在用户命名空间中运行。如需有关 SCC 的更多信息,请参阅"管理安全性上下文约束"。
要要求特定的 SCC 用于工作负载,您可以使用 oc adm policy add-scc-to-user
或 oc adm policy add-scc-to-group
命令将 SCC 添加到特定的用户或组。如需更多信息,请参阅"OpenShift CLI 管理员命令参考"。
另外,您还可以选择使用 pod 规格中的 procMount
参数将 pod 中的 /proc
文件系统配置为未 屏蔽
。将 /proc
设置为未 屏蔽
的,这通常被视为安全,绕过容器运行时的默认掩码行为,并且仅与 hostUsers
设为 false
的 SCC 一起使用。
流程
运行以下命令,编辑部署 pod 的 OpenShift Container Platform 命名空间的默认用户 ID (UID) 和组 ID (GID) 范围:
oc edit ns/<namespace_name>
$ oc edit ns/<namespace_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命名空间示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意范围 1000/10000 代表以 ID 1000 开始的 10,000 个值,因此它指定了从 1000 到 10,999 的 ID 范围。
通过创建配置为使用适当的 SCC 运行的工作负载来启用 Linux 用户命名空间,并将
hostUsers
参数设置为false
。创建一个类似以下示例的 YAML 文件:
pod 规格示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 指定要用于此工作负载的 SCC。
- 2
- 指定 pod 是否在用户命名空间中运行。如果为
false
,则 pod 在为 pod 创建的新用户命名空间中运行。如果为true
,则 pod 在主机用户命名空间中运行。默认值是true
。 - 3
capabilities
允许特权操作,而不提供完整的 root 访问权限。从技术上讲,在用户命名空间内设置功能比设置它们更安全,因为能力的范围受用户命名空间的限制,通常被视为安全。但是,为任何不受信任的工作负载提供CAP_SYS_ADMIN
等 pod 功能可能会增加容器化进程可访问的潜在内核面区域,并可以发现利用这个漏洞。因此,在 pod 安全准入中的基准
级别允许用户命名空间中的功能。- 4
- 指定容器内的进程使用 0 以外的任何 UID 的用户运行。
- 5
- 可选:指定用于容器的 proc 挂载类型。
unmasked
值可确保容器的/proc
文件系统被容器进程以读写模式挂载。默认值为Default
。 - 6
- 指定在容器内运行的进程的用户 ID。这必须属于您在
命名空间
对象中设置的范围。 - 7
- 指定在容器内运行的进程的组 ID。这必须属于您在
命名空间
对象中设置的范围。
运行以下命令来创建对象:
oc create -f <file_name>.yaml
$ oc create -f <file_name>.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
检查您创建的 pod 中容器使用的用户和组 ID。pod 位于 Linux 用户命名空间中。
使用您的 pod 中的容器启动一个 shell 会话:
oc rsh -c <container_name> pod/<pod_name>
$ oc rsh -c <container_name> pod/<pod_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例命令
oc rsh -c userns-container_name pod/userns-pod
$ oc rsh -c userns-container_name pod/userns-pod
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示在容器内使用的用户和组 ID:
id
sh-5.1$ id
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
uid=1000(1000) gid=1000(1000) groups=1000(1000)
uid=1000(1000) gid=1000(1000) groups=1000(1000)
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 容器的 UID 和组应当与您在 pod 规格中设置的相同。
显示容器用户命名空间中使用的用户 ID:
lsns -t user
sh-5.1$ lsns -t user
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
NS TYPE NPROCS PID USER COMMAND 4026532447 user 3 1 1000 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
NS TYPE NPROCS PID USER COMMAND 4026532447 user 3 1 1000 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 进程的 UID 应与您在 pod 规格中设置相同。
检查节点使用的 UID。节点位于 Linux 用户命名空间之外。此用户 ID 应该与容器中使用的 UID 不同。
为该节点启动一个 debug 会话:
oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
$ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例命令
oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
$ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将
/host
设置为 debug shell 中的根目录:chroot /host
sh-5.1# chroot /host
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示节点使用的 UID:
lsns -t user
sh-5.1# lsns -t user
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 示例命令
NS TYPE NPROCS PID USER COMMAND 4026531837 user 233 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 28 4026532447 user 1 4767 2908816384 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
NS TYPE NPROCS PID USER COMMAND 4026531837 user 233 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 28 4026532447 user 1 4767 2908816384 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- UID 应该与您在 pod 规格中设置的内容不同。
使用以下命令退出 debug 会话:
exit
sh-5.1# exit
Copy to Clipboard Copied! Toggle word wrap Toggle overflow exit
sh-5.1# exit
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
检查
/proc
文件系统是否作为未屏蔽
挂载到容器中,如以下命令输出中的读/写权限(rw
)表示:oc exec <pod_name> -- mount | grep /proc
$ oc exec <pod_name> -- mount | grep /proc
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
Copy to Clipboard Copied! Toggle word wrap Toggle overflow