$ oc edit featuregate cluster
Linux 用户命名空间允许管理员隔离容器用户和组标识符 (UID 和 GID),以便容器在用户命名空间中的权限集与在其运行的主机系统上的权限集不同。这允许容器在用户命名空间内运行具有完全权限的进程,但这些进程对于主机上的操作可能是非特权的。
默认情况下,容器在主机系统的 root 用户命名空间中运行。在主机用户命名空间中运行容器在容器需要仅在该用户命名空间中可用的功能时非常有用。但是,它会引入安全问题,例如容器突破的可能性,其中容器内的进程突破到主机,该进程可以访问或修改主机或其他容器上的文件。
在单独的用户命名空间中运行容器可以减轻容器突破以及受损容器可能对其他 Pod 和节点本身造成的其他一些漏洞。
您可以通过在 pod 规范中将hostUsers
参数设置为false
来配置 Linux 用户命名空间的使用,如下所示。
对 Linux 用户命名空间的支持仅是技术预览功能。技术预览功能不受 Red Hat 生产服务级别协议 (SLA) 的支持,并且可能功能不完整。Red Hat 不建议在生产环境中使用它们。这些功能提供对即将推出的产品功能的早期访问,使客户能够在开发过程中测试功能并提供反馈。 有关 Red Hat 技术预览功能的支持范围的更多信息,请参阅技术预览功能支持范围。 |
您通过编辑名为cluster
的FeatureGate
CR 来为您的集群启用所需的技术预览功能
$ oc edit featuregate cluster
FeatureGate
CR 示例apiVersion: config.openshift.io/v1
kind: FeatureGate
metadata:
name: cluster
spec:
featureSet: TechPreviewNoUpgrade (1)
1 | 启用所需的UserNamespacesSupport 和ProcMountType 功能。 |
在您的集群上启用 |
保存更改后,将创建新的机器配置,更新机器配置池,并在应用更改期间禁用每个节点上的调度。
您已在工作节点上启用了 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 | 指定要部署的容器运行时。 |
通过运行以下命令来编辑部署 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 范围。 |
通过创建一个配置为使用restricted
配置文件并且hostUsers
参数设置为false
的 pod 来启用 Linux 用户命名空间的使用。
创建一个类似于以下内容的 YAML 文件
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 。 |
通过运行以下命令来创建 pod
$ oc create -f <file_name>.yaml
检查您创建的 Pod 容器中使用的 Pod 用户和组 ID。此 Pod 位于 Linux 用户命名空间内。
启动与您 Pod 中容器的 shell 会话
$ oc rsh -c <container_name> pod/<pod_name>
$ oc rsh -c userns-container_name pod/userns-pod
显示容器内使用的用户和组 ID
sh-5.1$ id
uid=1000(1000) gid=1000(1000) groups=1000(1000)
显示容器用户命名空间中使用的用户 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 规范中设置的相同。 |
检查在创建 Pod 的节点上使用的 Pod 用户 ID。该节点位于 Linux 用户命名空间之外。此用户 ID 应与容器中使用的 UID 不同。
启动该节点的调试会话
$ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
$ oc debug node/ci-ln-z5vppzb-72292-8zp2b-worker-c-q8sh9
将/host
设置为调试 shell 中的根目录
sh-5.1# chroot /host
显示节点用户命名空间中使用的用户 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 规范中设置的不同。 |