×

关于 Pod 安全准入

OpenShift Container Platform 包含 Kubernetes Pod 安全准入。不符合全局或命名空间级别定义的 Pod 安全准入的 Pod 不会被准入到集群中,也无法运行。

在全局范围内,强制执行 `privileged` 配置文件,并使用 `restricted` 配置文件发出警告和审核。

您还可以配置命名空间级别的 Pod 安全准入设置。

不要在默认项目中运行工作负载或共享对默认项目的访问权限。默认项目保留用于运行核心集群组件。

以下默认项目被认为是高度特权的:defaultkube-publickube-systemopenshiftopenshift-infraopenshift-node,以及其他具有openshift.io/run-level标签设置为01的系统创建的项目。依赖于准入插件的功能(例如 Pod 安全准入、安全上下文约束、集群资源配额和镜像引用解析)在高度特权的项目中不起作用。

Pod 安全准入模式

您可以为命名空间配置以下 Pod 安全准入模式

表 1. Pod 安全准入模式
模式 标签 描述

强制执行

pod-security.kubernetes.io/enforce

如果 Pod 不符合设定的配置文件,则拒绝 Pod 准入

审计

pod-security.kubernetes.io/audit

如果 Pod 不符合设定的配置文件,则记录审计事件

警告

pod-security.kubernetes.io/warn

如果 Pod 不符合设定的配置文件,则显示警告

Pod 安全准入配置文件

您可以将每种 Pod 安全准入模式设置为以下配置文件之一

表 2. Pod 安全准入配置文件
配置文件 描述

privileged(特权)

限制最少的策略;允许已知的权限提升

baseline(基线)

限制最小的策略;防止已知的权限提升

restricted(受限)

限制最严格的策略;遵循当前的 Pod 加固最佳实践

特权命名空间

以下系统命名空间始终设置为privileged Pod 安全准入配置文件

  • default

  • kube-public

  • kube-system

您无法更改这些特权命名空间的 Pod 安全配置文件。

Pod 安全准入和安全上下文约束

Pod 安全准入标准和安全上下文约束由两个独立的控制器协调和强制执行。这两个控制器使用以下流程独立地强制执行安全策略:

  1. 安全上下文约束控制器可以根据 Pod 分配的 SCC 更改某些安全上下文字段。例如,如果 seccomp 配置文件为空或未设置,并且 Pod 分配的 SCC 强制seccompProfiles字段为runtime/default,则控制器会将默认类型设置为RuntimeDefault

  2. 安全上下文约束控制器根据匹配的 SCC 验证 Pod 的安全上下文。

  3. Pod 安全准入控制器根据分配给命名空间的 Pod 安全标准验证 Pod 的安全上下文。

关于 Pod 安全准入同步

除了全局 Pod 安全准入控制配置外,控制器还会根据给定命名空间中服务帐户的 SCC 权限,将 Pod 安全准入控制warnaudit标签应用于命名空间。

控制器检查ServiceAccount对象的权限以在每个命名空间中使用安全上下文约束。安全上下文约束 (SCC) 基于其字段值映射到 Pod 安全配置文件;控制器使用这些转换后的配置文件。Pod 安全准入warnaudit标签设置为命名空间中特权级别最高的 Pod 安全配置文件,以防止在创建 Pod 时显示警告和记录审计事件。

命名空间标签基于对命名空间本地服务帐户权限的考虑。

直接应用 Pod 可能会使用运行 Pod 的用户的 SCC 权限。但是,在自动标记期间不会考虑用户权限。

Pod 安全准入同步命名空间排除

大多数系统创建的命名空间都永久禁用了 Pod 安全准入同步。用户创建的以openshift-*为前缀的命名空间也最初禁用了同步,但您以后可以为其启用同步。

如果在标签同步的命名空间上手动修改 Pod 安全准入标签(pod-security.kubernetes.io/<mode>),使其与自动标记的值不同,则该标签的同步将被禁用。

如有必要,您可以使用以下方法之一重新启用同步:

  • 从命名空间中删除已修改的 Pod 安全准入标签

  • security.openshift.io/scc.podSecurityLabelSync标签设置为true

    如果您通过添加此标签强制同步,则任何已修改的 Pod 安全准入标签都将被覆盖。

永久禁用的命名空间

作为集群有效负载一部分定义的命名空间永久禁用了 Pod 安全准入同步。以下命名空间永久禁用:

  • default

  • kube-node-lease

  • kube-system

  • kube-public

  • openshift

  • 所有以openshift-为前缀的系统创建的命名空间,openshift-operators除外

最初禁用的命名空间

默认情况下,所有以openshift-为前缀的命名空间最初都禁用了 Pod 安全准入同步。您可以为用户创建的openshift-*命名空间和openshift-operators命名空间启用同步。

您无法为任何系统创建的openshift-*命名空间启用同步,openshift-operators除外。

如果在用户创建的openshift-*命名空间中安装了 Operator,则在命名空间中创建集群服务版本 (CSV) 后,将自动启用同步。同步的标签来自命名空间中服务帐户的权限。

控制 Pod 安全准入同步

您可以为大多数命名空间启用或禁用自动 Pod 安全准入同步。

您无法在某些系统创建的命名空间上启用 Pod 安全准入同步。有关更多信息,请参见“Pod 安全准入同步命名空间排除”。

步骤
  • 对于要配置的每个命名空间,请为security.openshift.io/scc.podSecurityLabelSync标签设置一个值。

    • 要禁用命名空间中的 Pod 安全准入标签同步,请将security.openshift.io/scc.podSecurityLabelSync标签的值设置为false

      运行以下命令:

      $ oc label namespace <namespace> security.openshift.io/scc.podSecurityLabelSync=false
    • 要启用命名空间中的 Pod 安全准入标签同步,请将security.openshift.io/scc.podSecurityLabelSync标签的值设置为true

      运行以下命令:

      $ oc label namespace <namespace> security.openshift.io/scc.podSecurityLabelSync=true

    如果此标签已在命名空间中设置,请使用--overwrite标志覆盖该值。

为命名空间配置 Pod 安全准入

您可以在命名空间级别配置 Pod 安全准入设置。对于命名空间上的每种 Pod 安全准入模式,您可以设置要使用的 Pod 安全准入配置文件。

步骤
  • 对于要在命名空间上设置的每种 Pod 安全准入模式,请运行以下命令:

    $ oc label namespace <namespace> \                (1)
        pod-security.kubernetes.io/<mode>=<profile> \ (2)
        --overwrite
    1 <namespace>设置为要配置的命名空间。
    2 <mode>设置为enforcewarnaudit。将<profile>设置为restrictedbaselineprivileged

关于 Pod 安全准入警报

当 Kubernetes API 服务器报告 Pod 安全准入控制器的审计级别存在 Pod 拒绝时,会触发PodSecurityViolation警报。此警报持续一天。

查看 Kubernetes API 服务器审计日志以调查已触发的警报。例如,如果全局强制执行设置为restricted Pod 安全级别,则工作负载很可能无法准入。

有关识别 Pod 安全准入违规审计事件的帮助,请参阅 Kubernetes 文档中的审计注释

识别 Pod 安全性违规

PodSecurityViolation 警报不会提供有关哪些工作负载导致 Pod 安全性违规的详细信息。您可以通过查看 Kubernetes API 服务器审计日志来识别受影响的工作负载。此过程使用must-gather工具收集审计日志,然后搜索pod-security.kubernetes.io/audit-violations注释。

先决条件
  • 您已安装jq

  • 您可以以具有cluster-admin角色的用户身份访问集群。

步骤
  1. 要收集审计日志,请输入以下命令:

    $ oc adm must-gather -- /usr/bin/gather_audit_logs
  2. 要输出受影响的工作负载详细信息,请输入以下命令:

    $ zgrep -h pod-security.kubernetes.io/audit-violations must-gather.local.<archive_id>/<image_digest_id>/audit_logs/kube-apiserver/*log.gz \
      | jq -r 'select((.annotations["pod-security.kubernetes.io/audit-violations"] != null) and (.objectRef.resource=="pods")) | .objectRef.namespace + " " + .objectRef.name' \
      | sort | uniq -c

    <archive_id><image_digest_id>替换为实际路径名称。

    示例输出:
    1 test-namespace my-pod