第 15 章 管理安全性上下文约束
在 OpenShift Container Platform 中,您可以使用安全性上下文约束 (SCC) 来控制集群中 pod 的权限。
安装期间会创建默认 SCC,安装一些 Operator 或其他组件。作为集群管理员,您还可以使用 OpenShift CLI (oc
) 创建自己的 SCC。
不要修改默认 SCC。自定义默认 SCC 可能会导致在一些平台 Pod 部署或 OpenShift Container Platform 升级时出现问题。另外,默认 SCC 值会在一些集群升级过程中重置为默认值,这会丢弃对这些 SCC 的所有自定义。
根据需要创建并修改您自己的 SCC,而不是修改默认 SCC。有关详细步骤,请参阅创建安全性上下文约束。
15.1. 关于安全性上下文约束
与 RBAC 资源控制用户访问的方式类似,管理员可以使用安全性上下文约束 (SCC) 来控制 Pod 的权限。这些权限决定了 Pod 可以执行的操作以及它们可以访问的资源。您可以使用 SCC 定义 Pod 运行必须满足的一组条件,以便其能被系统接受。
通过安全性上下文约束,管理员可以控制:
-
pod 是否可以使用
allowPrivilegedContainer
标志运行特权容器 -
使用
allowPrivilegeEscalation
标记限制 pod - 容器可以请求的功能
- 将主机目录用作卷
- 容器的 SELinux 上下文
- 容器用户 ID
- 使用主机命名空间和网络
-
拥有 pod 卷的
FSGroup
的分配 - 允许的补充组的配置
- 容器是否需要对其 root 文件系统进行写访问权限
- 卷类型的使用
-
允许的
seccomp
配置集的配置
不要在 OpenShift Container Platform 中的任何命名空间上设置 openshift.io/run-level
标签。此标签供内部 OpenShift Container Platform 组件用来管理主要 API 组的启动,如 Kubernetes API 服务器和 OpenShift API 服务器。如果设置了 openshift.io/run-level
标签,则不会将 SCC 应用到该命名空间中的 pod,从而导致该命名空间中运行的任何工作负载都具有高度特权。
15.1.1. 默认安全性上下文约束
集群包含多个默认安全性上下文约束 (SCC),如下表所述。将 Operator 或其他组件安装到 OpenShift Container Platform 时,可能会安装额外的 SCC。
不要修改默认 SCC。自定义默认 SCC 可能会导致在一些平台 Pod 部署或 OpenShift Container Platform 升级时出现问题。另外,默认 SCC 值会在一些集群升级过程中重置为默认值,这会丢弃对这些 SCC 的所有自定义。
根据需要创建并修改您自己的 SCC,而不是修改默认 SCC。有关详细步骤,请参阅创建安全性上下文约束。
安全性上下文约束 | 描述 |
---|---|
|
提供 |
| 允许访问所有主机命名空间,但仍要求使用分配至命名空间的 UID 和 SELinux 上下文运行容器集。 警告 此 SCC 允许主机访问命名空间、文件系统和 PID。它应当仅由受信任的容器集使用。请谨慎授予。 |
|
提供 警告 此 SCC 允许主机文件系统作为任何 UID 访问,包括 UID 0。请谨慎授予。 |
| 允许使用主机网络和主机端口,但仍要求使用分配至命名空间的 UID 和 SELinux 上下文运行容器集。 警告
如果在 control plane 主机上运行额外的工作负载,在提供 |
|
与
|
| 用于 Prometheus 节点导出器。 警告 此 SCC 允许主机文件系统作为任何 UID 访问,包括 UID 0。请谨慎授予。 |
|
提供 |
|
与
|
| 允许访问所有特权和主机功能,并且能够以任何用户、任何组、任何 FSGroup 以及任何 SELinux 上下文运行。 警告 这是最宽松的 SCC,应仅用于集群管理。请谨慎授予。
注意
在 Pod 规格中设置 |
| 拒绝访问所有主机功能,并且要求使用 UID 运行容器集,以及分配至命名空间的 SELinux 上下文。
在从 OpenShift Container Platform 4.10 或更早版本升级的集群中,任何经过身份验证的用户都可以使用这个 SCC。只有明确授予了访问权限,否则新 OpenShift Container Platform 4.11 或更高版本的安装不再提供 |
|
与
这是一个新安装可以提供的最严格的 SCC,经过身份验证的用户会默认使用它。 注意
|
15.1.2. 安全性上下文约束设置
安全性上下文约束 (SCC) 由控制 Pod 可访问的安全功能的设置和策略组成。这些设置分为三个类别:
类别 | 描述 |
---|---|
由布尔值控制 |
此类型的字段默认为限制性最强的值。例如, |
由允许的集合控制 | 针对集合检查此类型的字段,以确保其值被允许。 |
由策略控制 | 具有生成某个值的策略的条目提供以下功能:
|
CRI-O 具有以下默认能力列表,允许用于 pod 的每个容器:
-
CHOWN
-
DAC_OVERRIDE
-
FSETID
-
FOWNER
-
SETGID
-
SETUID
-
SETPCAP
-
NET_BIND_SERVICE
-
KILL
容器使用此默认列表中的功能,但 Pod 清单作者可以通过请求额外功能或移除某些默认行为来修改列表。使用 allowedCapabilities
、defaultAddCapabilities
和 requiredDropCapabilities
参数来控制来自容器集的此类请求。通过这些参数,您可以指定可以请求哪些功能,哪些必须添加到每一个容器,哪些必须被每个容器禁止或丢弃。
您可以通过将 requiredDropCapabilities
参数设置为 ALL
来丢弃容器的所有功能。这是 restricted-v2
SCC 的作用。
15.1.3. 安全性上下文约束策略
RunAsUser
MustRunAs
- 需要配置runAsUser
。使用配置的runAsUser
作为默认值。针对配置的runAsUser
进行验证。MustRunAs
片断示例... runAsUser: type: MustRunAs uid: <id> ...
MustRunAsRange
- 如果不使用预分配值,则需要定义最小值和最大值。使用最小值作为默认值。针对整个允许范围进行验证。MustRunAsRange
代码片段示例... runAsUser: type: MustRunAsRange uidRangeMax: <maxvalue> uidRangeMin: <minvalue> ...
MustRunAsNonRoot
- 需要 Pod 提交为具有非零runAsUser
或具有镜像中定义的USER
指令。不提供默认值。MustRunAsNonRoot
片断示例... runAsUser: type: MustRunAsNonRoot ...
RunAsAny
- 不提供默认值。允许指定任何runAsUser
。RunAsAny
代码片段示例... runAsUser: type: RunAsAny ...
SELinuxContext
-
MustRunAs
- 如果不使用预分配的值,则需要配置seLinuxOptions
。使用seLinuxOptions
作为默认值。针对seLinuxOptions
进行验证。 -
RunAsAny
- 不提供默认值。允许指定任何seLinuxOptions
。
SupplementalGroups
-
MustRunAs
- 如果不使用预分配值,则需要至少指定一个范围。使用第一个范围内的最小值作为默认值。针对所有范围进行验证。 -
RunAsAny
- 不提供默认值。允许指定任何supplementalGroups
。
FSGroup
-
MustRunAs
- 如果不使用预分配值,则需要至少指定一个范围。使用第一个范围内的最小值作为默认值。针对第一个范围内的第一个 ID 进行验证。 -
RunAsAny
- 不提供默认值。允许指定任何fsGroup
ID。
15.1.4. 控制卷
通过设置 SCC 的 volumes
字段,控制特定卷类型的使用。
此字段的允许值与创建卷时定义的卷来源对应:
-
awsElasticBlockStore
-
azureDisk
-
azureFile
-
cephFS
-
cinder
-
configMap
-
csi
-
downwardAPI
-
emptyDir
-
fc
-
flexVolume
-
flocker
-
gcePersistentDisk
-
ephemeral
-
gitRepo
-
glusterfs
-
hostPath
-
iscsi
-
nfs
-
persistentVolumeClaim
-
photonPersistentDisk
-
portworxVolume
-
projected
-
quobyte
-
rbd
-
scaleIO
-
secret
-
storageos
-
vsphereVolume
- *(允许使用所有卷类型的一个特殊值)
-
none
(禁止使用所有卷类型的一个特殊值。仅为向后兼容而存在。)
为新 SCC 推荐的允许卷最小集合是 configMap
、downAPI
、emptyDir
、persistentVolumeClaim
、secret
和 projected
。
允许卷类型列表并不完整,因为每次发布新版 OpenShift Container Platform 时都会添加新的类型。
为向后兼容,使用 allowHostDirVolumePlugin
将覆盖 volumes
字段中的设置。例如,如果 allowHostDirVolumePlugin
设为 false,但在 volumes
字段中是允许,则将移除 volumes
中的 hostPath
值。
15.1.5. 准入控制
利用 SCC 的准入控制可以根据授予用户的能力来控制资源的创建。
就 SCC 而言,这意味着准入控制器可以检查上下文中提供的用户信息以检索一组合适的 SCC。这样做可确保 Pod 具有相应的授权,能够提出与其操作环境相关的请求或生成一组要应用到 Pod 的约束。
准入用于授权 Pod 的 SCC 集合由用户身份和用户所属的组来决定。另外,如果 Pod 指定了服务帐户,则允许的 SCC 集合包括服务帐户可访问的所有约束。
在创建工作负载资源(如部署)时,只有服务帐户用于查找 SCC,并在创建时接受 Pod。
准入使用以下方法来创建 Pod 的最终安全性上下文:
- 检索所有可用的 SCC。
- 为请求上未指定的安全性上下文设置生成字段值。
- 针对可用约束来验证最终设置。
如果找到了匹配的约束集合,则接受 Pod。如果请求不能与 SCC 匹配,则拒绝 Pod。
Pod 必须针对 SCC 验证每一个字段。以下示例中只有其中两个字段必须验证:
这些示例是在使用预分配值的策略上下文中。
FSGroup SCC 策略为 MustRunAs
如果 Pod 定义了 fsGroup
ID,该 ID 必须等于默认的 fsGroup
ID。否则,Pod 不会由该 SCC 验证,而会评估下一个 SCC。
如果 SecurityContextConstraints.fsGroup
字段的值为 RunAsAny
,并且 Pod 规格省略了 Pod.spec.securityContext.fsGroup
,则此字段被视为有效。注意在验证过程中,其他 SCC 设置可能会拒绝其他 Pod 字段,从而导致 Pod 失败。
SupplementalGroups
SCC 策略为 MustRunAs
如果 Pod 规格定义了一个或多个 supplementalGroups
ID,则 Pod 的 ID 必须等于命名空间的 openshift.io/sa.scc.supplemental-groups
注解中的某一个 ID。否则,Pod 不会由该 SCC 验证,而会评估下一个 SCC。
如果 SecurityContextConstraints.supplementalGroups
字段的值为 RunAsAny
,并且 Pod 规格省略了 Pod.spec.securityContext.supplementalGroups
,则此字段被视为有效。注意在验证过程中,其他 SCC 设置可能会拒绝其他 Pod 字段,从而导致 Pod 失败。
15.1.6. 安全性上下文约束优先级
安全性上下文约束 (SCC) 具有一个优先级字段,它会影响准入控制器尝试验证请求时的排序。
优先级值为 0
是最低优先级。nil 优先级被视为 0
或最低优先级。在排序时,优先级更高的 SCC 会被移到集合的前面。
确定了一组可用 SCC 后,SCC 会按照以下方式排序:
- 最高优先级 SCC 首先排序。
- 如果优先级相等,则 SCC 按照限制性最强到最弱排序。
- 如果优先级和限制性都相等,则 SCC 按照名称排序。
默认情况下,授权给集群管理员的 anyuid
SCC 在 SCC 集合中具有优先权。这允许集群管理员通过在 Pod 的 SecurityContext
中指定 RunAsUser
,以任何用户身份运行 Pod。