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


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

默认情况下,容器在主机系统的 root 用户命名空间中运行。当容器需要仅在该用户命名空间中可用的功能时,在主机用户命名空间中运行容器很有用。但是,这会引入一些安全问题,如容器逃逸问题(container breakout)- 容器中的一个进程会逃逸到主机中,这个进程将可以访问或修改主机上的文件。

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

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

重要

对 Linux 用户命名空间的支持只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

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

2.14.1. 配置 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 功能集无法撤消,并会阻止次版本更新。此功能集允许您在测试集群中启用这些技术预览功能,您可以在测试集群中完全测试它们。不要在生产环境集群中启用此功能。

    保存更改后,会创建新的机器配置,然后更新机器配置池,并在应用更改时在每个节点上调度。

  • 您在 worker 节点上启用了 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 规格中指定的值匹配。Linux 用户命名空间的范围必须小于 65,535。默认为 1000000000/10000
    2
    编辑默认 UID,使其与您在 pod 规格中指定的值匹配。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. 为该节点启动一个 debug 会话:

      $ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9

      示例命令

      $ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9

    2. /host 设置为 debug 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,它与您在容器集规格中设置的不同。
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.