27.18.2. SCC、defaults 和 Allowed Ranges
SCC 会影响 pod 是否被授予默认用户 ID、fsGroup
ID、补充组 ID 和 SELinux 标签。它们也会影响 Pod 定义(或镜像中)提供的 ID 是否针对一系列允许 ID 进行验证。如果需要验证并失败,pod 也会失败。
SCC 定义策略,如 runAsUser
、supplementalGroups
和 fsGroup
。这些策略帮助决定 pod 是否被授权。设为 RunAsAny 的策略值实质上表示该 pod 能执行与该策略相关的内容。会为该策略跳过授权,且不会基于此策略生成 OpenShift Container Platform 默认授权。因此,生成的容器中的 ID 和 SELinux 标签基于容器默认值,而不是 OpenShift Container Platform 策略。
有关 RunAsAny 的快速摘要:
- 允许容器集定义(或镜像)中定义的任何 ID。
- 如果容器集定义(和镜像中)中没有 ID,则容器会分配 ID,这是 Docker 的 root (0)。
- 没有定义 SELinux 标签,因此 Docker 将分配唯一标签。
因此,应对 ID 相关策略的带有 RunAsAny 的 SCC 进行保护,以便普通开发人员无法访问 SCC。另一方面,SCC 策略设置为 MustRunAs 或 MustRunAsRange 触发器 ID 验证(用于 ID 相关的策略),并在 Pod 定义或镜像中未提供这些值时向容器提供默认值。
允许访问具有 RunAsAny FSGroup
策略的 SCC 也可以阻止用户访问其块设备。Pod 需要指定 fsGroup
才能接管其块设备。通常,这在 SCC FSGroup
策略被设置为 MustRunAs 时完成。如果用户的 Pod 分配有 RunAsAny FSGroup
策略的 SCC,则用户可能会面临 权限被拒绝 的错误,直到他们发现需要指定 fsGroup
本身。
SCC 可以定义允许的 ID(用户或组)的范围。如果需要进行范围检查(例如,使用 MustRunAs,且 SCC 中没有定义允许范围),则项目决定 ID 范围。因此,项目支持允许的 ID 范围。但是,与 SCC 不同,项目不定义策略,如 runAsUser
。
允许的范围不仅有用,因为它们为容器 ID 定义界限,而且因为该范围内的最小值成为问题 ID 的默认值。例如,如果 SCC ID 策略值是 MustRunAs,则 ID 范围的最小值为 100,并且容器集定义中没有该 ID,则将 100 作为此 ID 的默认值。
作为 pod 准入的一部分,会检查 Pod 可用的 SCC(大约在优先级顺序中,其次序为限制)来最好与 pod 请求匹配。将 SCC 的策略类型设置为 RunAsAny 的限制性较低,而 MustRunAs 类型则更严格的。所有这些策略都被评估。要查看哪些 SCC 分配给 pod,请使用 oc get pod
命令:
# oc get pod <pod_name> -o yaml ... metadata: annotations: openshift.io/scc: nfs-scc 1 name: nfs-pod1 2 namespace: default 3 ...
可能不会直接识别哪些 SCC 与 pod 匹配,因此上述命令对于了解 UID、补充组和 SELinux 在实时容器中重新标记非常有用。
任何策略设置为 RunAsAny 的 SCC 允许在容器集定义(和/或镜像)中定义该策略的特定值。当这应用到用户 ID (runAsUser
) 时,需要谨慎来限制对 SCC 的访问,以防止容器以 root 用户身份运行。
由于 Pod 通常与 受限 SCC 匹配,因此值得了解这一要求的安全性。受限 SCC 具有以下特征:
-
用户 ID 被限制,因为
runAsUser
策略被设置为 MustRunAsRange。这会强制用户 ID 验证。 -
因为 SCC 中没有定义允许的用户 ID 范围(请参阅 oc get -o yaml --export scc restricted' 以获取更多详情),项目的
openshift.io/sa.scc.uid-range
范围将用于范围检查和默认 ID(如果需要)。 -
当 Pod 定义中没有指定用户 ID 且匹配的 SCC 的
runAsUser
设置为 MustRunAsRange 时,会生成一个默认用户 ID。 -
需要 SELinux 标签(
seLinuxContext
设置为 MustRunAs),它使用项目的默认 MCS 标签。 -
fsGroup
ID 仅限于单个值,因为FSGroup
策略被设置为 MustRunAs,这表示要使用的值是指定第一个范围的最小值。 -
因为 SCC 中没有定义允许
fsGroup
ID 范围,因此项目的openshift.io/sa.scc.supplemental-groups
范围(或用于用户 ID 的相同范围)将用于验证和默认 ID(如果需要)。 -
当 pod 中没有指定
fsGroup
ID 且匹配的 SCC 的FSGroup
设为 MustRunAs 时,会生成一个默认的fsGroup
ID。 -
允许使用任意补充组 ID,因为不需要范围检查。这是将
supplementalGroups
策略设置为 RunAsAny 的结果。 - 由于 RunAsAny 对于上述两个组策略,因此不会为正在运行的 Pod 生成默认的补充组。因此,如果在 Pod 定义中(或镜像中没有定义任何组),则容器不会预定义任何补充组。
以下显示了 default 项目和自定义 SCC(my-custom-scc),它总结了 SCC 和项目的交互:
$ oc get project default -o yaml 1 ... metadata: annotations: 2 openshift.io/sa.scc.mcs: s0:c1,c0 3 openshift.io/sa.scc.supplemental-groups: 1000000000/10000 4 openshift.io/sa.scc.uid-range: 1000000000/10000 5 $ oc get scc my-custom-scc -o yaml ... fsGroup: type: MustRunAs 6 ranges: - min: 5000 max: 6000 runAsUser: type: MustRunAsRange 7 uidRangeMin: 1000100000 uidRangeMax: 1000100999 seLinuxContext: 8 type: MustRunAs SELinuxOptions: 9 user: <selinux-user-name> role: ... type: ... level: ... supplementalGroups: type: MustRunAs 10 ranges: - min: 5000 max: 6000
- 1
- default 是项目的名称。
- 2
- 仅当对应的 SCC 策略不是 RunAsAny 时,才会生成默认值。
- 3
- 在 Pod 定义或 SCC 中定义时,SELinux 默认。
- 4
- 允许的组 ID 范围。只有 SCC 策略是 RunAsAny 时才会进行 ID 验证。可以指定多个范围,用逗号分开。有关 支持的格式,请参阅以下。
- 5
- 与 <4> 相同,但适用于用户 ID。另外,只支持一个用户 ID。
- 6 10
- MustRunAs 强制实施组 ID 范围检查,提供容器的组默认值。根据此 SCC 定义,默认值为 5000(最小 ID 值)。如果 SCC 省略了范围,则默认值为 1000000000(从项目获得)。其他支持的类型 RunAsAny 不执行范围检查,因此允许任何组 ID,且不生成默认组。
- 7
- MustRunAsRange 强制实施用户 ID 范围检查并提供 UID 默认。根据此 SCC,默认的 UID 为 1000100000(最小值)。如果在 SCC 中省略了最小和最大范围,则默认用户 ID 为 1000000000(从项目派生出)。MustRunAsNonRoot 和 RunAsAny 是其他受支持的类型。可以定义允许 ID 的范围,使其包含目标存储所需的任何用户 ID。
- 8
- 当设置为 MustRunAs 时,会使用 SCC 的 SELinux 选项或项目中定义的 MCS 默认创建容器。类型为 RunAsAny 表示不需要 SELinux 上下文,如果 Pod 中未定义,则不会在容器中设置 SELinux 上下文。
- 9
- 此处可以定义 SELinux 用户名、角色名称、类型和标签。
允许的范围支持两种格式:
-
M/N
,其中M
是起始 ID,N
是 count,因此范围变为M
(包括)M+N-1
。 -
M-N
,其中M
再次是起始 ID,N
是结束的 ID。默认组 ID 是第一个范围内的起始 ID,本例中为1000000000
。如果 SCC 没有定义最小组 ID,则应用项目的默认 ID。