符合 Pod Security Restricted 标准
目录
功能概述使用场景前提条件了解 Restricted 标准步骤1. 配置 Tekton 为 init 容器添加安全上下文选项 A:通过 TektonPipeline 配置选项 B:通过 TektonConfig 配置2. 为自定义 Task 定义添加安全上下文3. 配置容器镜像使用非 root 用户操作结果使用策略强制执行工具故障排查内置 Tasks 与 Restricted 标准TaskRun 因容器用户错误而失败TaskRun 因 "Forbidden: cannot set securityContext.capabilities" 而失败Init 容器在权限错误下失败了解更多功能概述
pod-security.kubernetes.io/enforce=restricted 标准是最严格的 Pod Security Standard,用于强制执行当前 pod 加固最佳实践。当某个命名空间标记为此标准时,在该命名空间中创建的所有 pod 都必须符合严格的安全要求。
本指南说明如何配置 Tekton Pipelines 以满足 restricted 安全标准,确保 Tasks 中的所有容器都能在受限命名空间中成功运行。
使用场景
- 在带有
pod-security.kubernetes.io/enforce=restricted标记的命名空间中运行Tekton Pipelines - 满足组织的安全合规要求
- 提升 CI/CD 流水线的安全性
- 在高度受监管的环境中运行工作负载
前提条件
- 已通过
TektonPipeline或TektonConfigCR 安装Tekton Pipelines - 你有权限修改
TektonPipeline或TektonConfig资源 - 你可以创建或编辑
Task定义 - 对于自定义镜像,你有权限修改
Containerfile并重新构建镜像
了解 Restricted 标准
pod-security.kubernetes.io/enforce=restricted 标准要求 Pod 中的三种容器都满足以下安全上下文要求:
- 普通容器 (
containers) - Init 容器 (
initContainers) - Ephemeral 容器 (
ephemeralContainers)
每个容器都必须具有以下安全上下文配置:
配置说明:
步骤
1. 配置 Tekton 为 init 容器添加安全上下文
Tekton 会为其管理的每个 Pod 创建 init 容器。要符合 restricted 标准,你需要启用 Tekton,使其自动为这些 init 容器添加所需的安全上下文。
选项 A:通过 TektonPipeline 配置
如果你通过 TektonPipeline CR 直接管理 Tekton:
应用该配置:
选项 B:通过 TektonConfig 配置
如果你通过 TektonConfig CR 管理 Tekton:
应用该配置:
注意: 此配置更改会立即生效,无需重启
Tekton控制器。在此更改之后创建的新TaskRun和PipelineRun会自动将所需的安全上下文应用到 init 容器。
2. 为自定义 Task 定义添加安全上下文
对于自定义 Task(而不是平台提供的内置 Task),你需要显式地为每个 step 添加安全上下文。
带有安全上下文的 Task 示例:
重要: 此步骤适用于自定义
Task。平台提供的内置Task(buildah除外,见故障排查部分)与这些安全限制兼容,但其Task定义中不包含显式的securityContext配置,因为它们旨在适配多种安全上下文,而不仅仅是 restricted 模式。
3. 配置容器镜像使用非 root 用户
容器镜像必须配置为以非 root 用户运行。必须使用数字 UID 指定用户,而不是用户名。
在你的 Containerfile 中,添加一个非 root 用户并将其设为默认用户。以下是基于 Alpine 的镜像示例:
注意:
adduser命令语法因基础镜像而异。有关其他基础镜像的示例,请参见下面引用的文档。
验证镜像配置:
有关如何调整 Containerfile 的详细说明,请参阅 为构建兼容 Task 的自定义镜像调整 Containerfile。
操作结果
完成上述步骤后:
- Init 容器:
Tekton创建的 init 容器将自动符合restricted标准 - 自定义 Task:你的自定义
Task步骤将具有所需的安全上下文 - 容器镜像:镜像将以非 root 用户身份运行,并且权限最小化
你可以通过在受限命名空间中创建一个 TaskRun 来验证合规性:
成功的 TaskRun 会显示 SUCCEEDED 为 True,REASON 为 Succeeded,这表明所有容器都已在所需的安全限制下成功运行。
使用策略强制执行工具
为了实现更自动化的方法,你可以使用类似 Kyverno 的策略强制执行工具,自动为所有容器注入所需的安全上下文。通过创建一个 Kyverno Policy(使用 apiVersion: kyverno.io/v1 和 kind: Policy),你可以自动变更 Pods,为其添加必要的安全上下文配置。
更多信息请参阅 场景 4:指定命名空间的安全上下文强制执行。
这种基于 Kyverno 的方法不会使内置的 buildah Task 兼容 restricted 标准。有关 buildah 的限制,请参阅下面的 内置 Tasks 与 Restricted 标准。
这种方法消除了为每个 Task 手动配置安全上下文的需要,从而简化了合规管理。
有关为此目的配置 Kyverno 策略的详细说明,请参阅:
故障排查
内置 Tasks 与 Restricted 标准
在平台提供的内置 Tasks 中,只有 buildah Task 不能在 restricted 标准下运行。这是因为 buildah 需要提升权限来构建容器镜像。
即使使用 Kyverno 自动为 Pods 注入所需的 restricted 安全上下文,这一限制仍然适用。Kyverno 可以添加 restricted 标准所需的字段,但无法使内置的 buildah Task 兼容 restricted,因为 buildah 需要该标准所禁止的权限。
buildah Task 需要以下安全上下文:
解决方案:
-
在单独的命名空间中使用
buildahTask,并将模式设置为baseline而不是restricted。要允许
buildah工作负载运行,将pod-security.kubernetes.io/enforce更改为baseline是必需步骤。warn和audit标签不会阻止准入。重新标记命名空间后,在该命名空间中创建一个使用
buildahTask的新TaskRun或PipelineRun。当 registry 凭据、Containerfile和 workspace 配置正确时,buildahTask可以在baseline标准下正常运行。 -
探索其他可能具有不同安全要求的容器镜像构建方法。
TaskRun 因容器用户错误而失败
你可能会遇到以下错误之一:
- "container has runAsNonRoot and image will run as root" - 容器镜像在
Containerfile中没有USER指令(默认为 root),或显式设置为USER 0或USER root - "container has runAsNonRoot and image has non-numeric user" - 容器镜像使用了符号用户名(例如
USER appuser),而不是数字 UID
解决方案:
-
按照步骤 3 的说明,使用数字非 root 用户 ID 重新构建镜像。例如,使用
USER 65532,而不是USER appuser或USER root。 -
在
Task的securityContext中指定用户: -
在
TaskRun的podTemplate中指定用户:
注意:
podTemplate.securityContext设置的是 Pod 级别的安全上下文,除非在容器级别被覆盖,否则会被所有容器继承。
当你无法修改容器镜像时,选项 2 和 3 会很有用。
TaskRun 因 "Forbidden: cannot set securityContext.capabilities" 而失败
当安全上下文尝试在删除所有 capabilities 的同时添加 capabilities 时,就会出现此错误。
解决方案: 确保你的 Task 不添加任何 capabilities。仅按示例所示删除 capabilities。
Init 容器在权限错误下失败
如果在设置 set-security-context: true 后 init 容器仍因权限错误而失败,请验证以下内容:
- 命名空间具有适当的安全策略
Tekton使用的容器镜像已配置为以非 root 身份运行Tekton安装已更新到最新版本