2.17. 在 Linux 用户命名空间中运行 pod


Linux 用户命名空间允许管理员隔离容器用户和组标识符 (UID 和 GID),以便容器可以在用户命名空间中拥有与它运行的主机系统不同的权限集。这允许容器在用户命名空间中以完全特权运行容器,但对主机上的操作可以以非特权运行这些进程。

默认情况下,容器在主机用户命名空间中运行。当容器需要只在主机命名空间中可用的功能时,在主机用户命名空间中运行容器很有用。但是,在主机命名空间中运行的 pod 增加了安全性问题,如容器中断的可能性,另一个容器内的进程会破坏到主机上的进程,或者修改主机上的文件。

在独立用户命名空间中运行容器可以缓解容器逃逸的问题,以及其他可能会被破坏的容器对其他 pod 和节点本身造成影响的安全漏洞。

2.17.1. 配置 Linux 用户命名空间支持

您可以通过在 pod spec 中将 hostUsers 参数设置为 false 来配置 Linux 用户命名空间,以及一些其他配置,如以下步骤所示。

在用户命名空间中运行工作负载时,可以安全地为安全上下文约束(SCC)字段配置 RunAsAny,如 fsGrouprunAsGrouprunAsUser、runAsUser 和 supplementalGroups,因为容器外部的 UID 或 GID 与其中的不同,这些字段表示。

为获得额外的安全性,您可以使用 restricted-v3nested-container SCC,这专门为 Linux 用户命名空间中的工作负载设计。SCC 中的 userNamespaceLevel: RequirePodLevel 字段要求工作负载在用户命名空间中运行。如需有关 SCC 的更多信息,请参阅"管理安全性上下文约束"。

要要求特定的 SCC 用于工作负载,您可以使用 oc adm policy add-scc-to-useroc adm policy add-scc-to-group 命令将 SCC 添加到特定的用户或组。如需更多信息,请参阅"OpenShift CLI 管理员命令参考"。

另外,您还可以选择使用 pod 规格中的 procMount 参数将 pod 中的 /proc 文件系统配置为未 屏蔽。将 /proc 设置为未 屏蔽 的,这通常被视为安全,绕过容器运行时的默认掩码行为,并且仅与 hostUsers 设为 false 的 SCC 一起使用。

流程

  1. 运行以下命令,编辑部署 pod 的 OpenShift Container Platform 命名空间的默认用户 ID (UID) 和组 ID (GID) 范围:

    $ oc edit ns/<namespace_name>
    Copy to Clipboard Toggle word wrap

    命名空间示例

    apiVersion: v1
    kind: Namespace
    metadata:
      annotations:
        openshift.io/description: ""
        openshift.io/display-name: ""
        openshift.io/requester: system:admin
        openshift.io/sa.scc.mcs: s0:c27,c24
        openshift.io/sa.scc.supplemental-groups: 1000/10000 
    1
    
        openshift.io/sa.scc.uid-range: 1000/10000 
    2
    
    # ...
      name: userns
    # ...
    Copy to Clipboard Toggle word wrap

    1
    指定 pod 规格中需要的默认 GID。Linux 用户命名空间的范围必须是 65535 或较低。默认为 1000000000/10000
    2
    指定 pod 规格中需要的默认 UID。Linux 用户命名空间的范围必须是 65535 或较低。默认为 1000000000/10000
    注意

    范围 1000/10000 代表以 ID 1000 开始的 10,000 个值,因此它指定了从 1000 到 10,999 的 ID 范围。

  2. 通过创建配置为使用适当的 SCC 运行的工作负载来启用 Linux 用户命名空间,并将 hostUsers 参数设置为 false

    1. 创建一个类似以下示例的 YAML 文件:

      pod 规格示例

      apiVersion: v1
      kind: Pod
      metadata:
        namespace: userns
        name: userns-pod
      # ...
      spec:
      #...
        template:
          metadata:
            labels:
              app: name
            annotations:
              openshift.io/required-scc: "restricted-v3" 
      1
      
          spec:
            hostUsers: false 
      2
      
            containers:
            - name: userns-container
              image: registry.access.redhat.com/ubi9
              command: ["sleep", "1000"]
              securityContext:
                capabilities: 
      3
      
                  drop: ["ALL"]
                allowPrivilegeEscalation: false
                runAsNonRoot: true 
      4
      
                procMount: Unmasked 
      5
      
                runAsUser: 1000 
      6
      
                runAsGroup: 1000 
      7
      
      # ...
      Copy to Clipboard Toggle word wrap

      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。这必须属于您在 命名空间 对象中设置的范围。
    2. 运行以下命令来创建对象:

      $ oc create -f <file_name>.yaml
      Copy to Clipboard Toggle word wrap

验证

  1. 检查您创建的 pod 中容器使用的用户和组 ID。pod 位于 Linux 用户命名空间中。

    1. 使用您的 pod 中的容器启动一个 shell 会话:

      $ oc rsh -c <container_name> pod/<pod_name>
      Copy to Clipboard Toggle word wrap

      示例命令

      $ oc rsh -c userns-container_name pod/userns-pod
      Copy to Clipboard Toggle word wrap

    2. 显示在容器内使用的用户和组 ID:

      sh-5.1$ id
      Copy to Clipboard Toggle word wrap

      输出示例

      uid=1000(1000) gid=1000(1000) groups=1000(1000) 
      1
      Copy to Clipboard Toggle word wrap

      1
      容器的 UID 和组应当与您在 pod 规格中设置的相同。
    3. 显示容器用户命名空间中使用的用户 ID:

      sh-5.1$ lsns -t user
      Copy to Clipboard Toggle word wrap

      输出示例

              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 Toggle word wrap

      1
      进程的 UID 应与您在 pod 规格中设置相同。
  2. 检查节点使用的 UID。节点位于 Linux 用户命名空间之外。此用户 ID 应该与容器中使用的 UID 不同。

    1. 为该节点启动一个 debug 会话:

      $ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
      Copy to Clipboard Toggle word wrap

      示例命令

      $ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
      Copy to Clipboard Toggle word wrap

    2. /host 设置为 debug shell 中的根目录:

      sh-5.1# chroot /host
      Copy to Clipboard Toggle word wrap
    3. 显示节点使用的 UID:

      sh-5.1#  lsns -t user
      Copy to Clipboard Toggle word wrap

      示例命令

              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 Toggle word wrap

      1
      UID 应该与您在 pod 规格中设置的内容不同。
    4. 使用以下命令退出 debug 会话:

      sh-5.1#  exit
      Copy to Clipboard Toggle word wrap
      sh-5.1#  exit
      Copy to Clipboard Toggle word wrap
  3. 检查 /proc 文件系统是否作为未 屏蔽 挂载到容器中,如以下命令输出中的读/写权限(rw)表示:

    $ oc exec <pod_name> -- mount | grep /proc
    Copy to Clipboard Toggle word wrap

    输出示例

    proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
    Copy to Clipboard Toggle word wrap

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat