×

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

默认情况下,容器在主机系统的 root 用户命名空间中运行。在主机用户命名空间中运行容器在容器需要仅在该用户命名空间中可用的功能时非常有用。但是,它会引入安全问题,例如容器突破的可能性,其中容器内的进程突破到主机,该进程可以访问或修改主机或其他容器上的文件。

在单独的用户命名空间中运行容器可以减轻容器突破以及受损容器可能对其他 Pod 和节点本身造成的其他一些漏洞。

您可以通过在 pod 规范中将hostUsers参数设置为false来配置 Linux 用户命名空间的使用,如下所示。

对 Linux 用户命名空间的支持仅是技术预览功能。技术预览功能不受 Red Hat 生产服务级别协议 (SLA) 的支持,并且可能功能不完整。Red Hat 不建议在生产环境中使用它们。这些功能提供对即将推出的产品功能的早期访问,使客户能够在开发过程中测试功能并提供反馈。

有关 Red Hat 技术预览功能的支持范围的更多信息,请参阅技术预览功能支持范围

配置 Linux 用户命名空间支持

先决条件
  • 您通过编辑名为clusterFeatureGate CR 来为您的集群启用所需的技术预览功能

    $ oc edit featuregate cluster
    FeatureGate CR 示例
    apiVersion: config.openshift.io/v1
    kind: FeatureGate
    metadata:
      name: cluster
    spec:
      featureSet: TechPreviewNoUpgrade (1)
    1 启用所需的UserNamespacesSupportProcMountType功能。

    在您的集群上启用TechPreviewNoUpgrade功能集是不可撤销的,并且会阻止次要版本更新。此功能集允许您在测试集群上启用这些技术预览功能,您可以在其中对其进行全面测试。请勿在生产集群上启用此功能集。

    保存更改后,将创建新的机器配置,更新机器配置池,并在应用更改期间禁用每个节点上的调度。

  • 您已在工作节点上启用了 crun 容器运行时。目前,crun 是唯一支持用户命名空间的已发布 OCI 运行时。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: ContainerRuntimeConfig
    metadata:
     name: enable-crun-worker
    spec:
     machineConfigPoolSelector:
       matchLabels:
         pools.operator.machineconfiguration.openshift.io/worker: "" (1)
     containerRuntimeConfig:
       defaultRuntime: crun (2)
    1 指定机器配置池标签。
    2 指定要部署的容器运行时。
步骤
  1. 通过运行以下命令来编辑部署 pod 的 OpenShift Container Platform 命名空间的默认用户 ID (UID) 和组 ID (GID) 范围

    $ oc edit ns/<namespace_name>
    示例命名空间
    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
    # ...
    1 编辑默认 GID 以匹配您在 pod 规范中指定的 value。Linux 用户命名空间的范围必须小于 65,535。默认为1000000000/10000
    2 编辑默认 UID 以匹配您在 pod 规范中指定的 value。Linux 用户命名空间的范围必须小于 65,535。默认为1000000000/10000

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

  2. 通过创建一个配置为使用restricted配置文件并且hostUsers参数设置为false的 pod 来启用 Linux 用户命名空间的使用。

    1. 创建一个类似于以下内容的 YAML 文件

      示例 pod 规范
      apiVersion: v1
      kind: Pod
      metadata:
        name: userns-pod
      
      # ...
      
      spec:
        containers:
        - name: userns-container
          image: registry.access.redhat.com/ubi9
          command: ["sleep", "1000"]
          securityContext:
            capabilities:
              drop: ["ALL"]
            allowPrivilegeEscalation: false (1)
            runAsNonRoot: true (2)
            seccompProfile:
              type: RuntimeDefault
            runAsUser: 1000 (3)
            runAsGroup: 1000 (4)
        hostUsers: false (5)
      
      # ...
      1 指定 pod 不能请求权限升级。这是restricted-v2安全上下文约束 (SCC) 所必需的。
      2 指定容器将与任何 UID(非 0)的用户一起运行。
      3 指定容器运行的用户 UID。
      4 指定容器运行的主要 GID。
      5 请求在用户命名空间中运行 pod。如果为true,则 pod 在主机用户命名空间中运行。如果为false,则 pod 在为 pod 创建的新用户命名空间中运行。默认为true
    2. 通过运行以下命令来创建 pod

      $ oc create -f <file_name>.yaml
验证
  1. 检查您创建的 Pod 容器中使用的 Pod 用户和组 ID。此 Pod 位于 Linux 用户命名空间内。

    1. 启动与您 Pod 中容器的 shell 会话

      $ oc rsh -c <container_name> pod/<pod_name>
      示例命令
      $ oc rsh -c userns-container_name pod/userns-pod
    2. 显示容器内使用的用户和组 ID

      sh-5.1$ id
      示例输出
      uid=1000(1000) gid=1000(1000) groups=1000(1000)
    3. 显示容器用户命名空间中使用的用户 ID

      sh-5.1$ lsns -t user
      示例输出
              NS TYPE  NPROCS PID USER COMMAND
      4026532447 user       3   1 1000 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000 (1)
      
      1 进程的 UID 为1000,与您在 Pod 规范中设置的相同。
  2. 检查在创建 Pod 的节点上使用的 Pod 用户 ID。该节点位于 Linux 用户命名空间之外。此用户 ID 应与容器中使用的 UID 不同。

    1. 启动该节点的调试会话

      $ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
      示例命令
      $ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
    2. /host设置为调试 shell 中的根目录

      sh-5.1# chroot /host
    3. 显示节点用户命名空间中使用的用户 ID

      sh-5.1#  lsns -t user
      示例命令
              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)
      
      1 进程的 UID 为2908816384,与您在 Pod 规范中设置的不同。