符合 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 加固实践。当某个 namespace 被标记为此标准时,在该 namespace 中创建的所有 Pod 都必须满足严格的安全要求。
本指南说明如何配置 Tekton Pipelines 以满足 restricted 安全标准,确保 Tasks 中的所有容器都可以在受限的 namespace 中成功运行。
使用场景
- 在带有
pod-security.kubernetes.io/enforce=restricted标签的 namespace 中运行Tekton Pipelines - 满足组织的安全合规要求
- 提升 CI/CD 流水线的安全态势
- 在高度受监管的环境中运行工作负载
前提条件
- 已通过
TektonPipeline或TektonConfigCR 安装Tekton Pipelines - 你有权限修改
TektonPipeline或TektonConfig资源 - 你可以创建或编辑
Task定义 - 对于自定义镜像,你可以修改
Containerfiles并重新构建镜像
了解 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:
应用该配置:
注意: 此配置更改会立即生效,无需重启
Tektoncontroller。此更改之后创建的新TaskRuns和PipelineRuns会自动为 init 容器应用所需的安全上下文。
2. 为自定义 Task 定义添加安全上下文
对于自定义 Tasks(不是平台提供的内置 Tasks),你需要显式为每个 step 添加安全上下文。
带有安全上下文的 Task 示例:
重要: 此步骤适用于自定义
Tasks。平台提供的内置Tasks(buildah除外,见“故障排除”部分)与这些安全约束兼容,但它们的Task定义不包含显式的securityContext配置,因为它们的设计目标是在多种安全上下文下工作,而不仅仅是 restricted 模式。
3. 配置容器镜像使用非 root 用户
容器镜像必须配置为以非 root 用户运行。必须使用数字 UID 来指定用户,而不是用户名。
在你的 Containerfile 中,添加一个非 root 用户并将其设为默认用户。以下是一个基于 Alpine 的镜像示例:
注意:
adduser命令的语法会因基础镜像而异。有关其他基础镜像的示例,请参见下面引用的文档。
验证镜像配置:
有关调整 Containerfiles 的详细指南,请参见 调整用于构建兼容 Task 的自定义镜像的 Containerfile。
操作结果
完成上述步骤后:
- Init 容器:
Tekton创建的 init 容器将自动符合restricted标准 - 自定义 Tasks:你的自定义
Tasksteps 将具有所需的安全上下文 - 容器镜像:镜像将以非 root 用户身份运行,并具有最小权限
你可以通过在受限的 namespace 中创建 TaskRun 来验证合规性:
成功的 TaskRun 会显示 SUCCEEDED 为 True,REASON 为 Succeeded,表示所有容器都在所需的安全约束下成功运行。
使用策略强制执行工具
如果你希望采用更自动化的方法,可以使用类似 Kyverno 的策略强制执行工具,自动为所有容器注入所需的安全上下文。通过创建一个 Kyverno Policy(使用 apiVersion: kyverno.io/v1 和 kind: Policy),你可以自动 mutate Pods,为其添加必要的安全上下文配置。
更多信息请参见 场景 4:指定 Namespace 安全上下文强制执行。
这种方式无需为每个 Task 手动配置安全上下文,从而简化合规管理。
有关为此目的配置 Kyverno 策略的详细指南,请参见:
故障排除
内置 Tasks 与 Restricted 标准
在平台提供的内置 Tasks 中,只有 buildah Task 无法在 restricted 标准下运行。这是因为 buildah 构建容器镜像时需要提升权限。
buildah Task 需要以下安全上下文:
解决方案:
- 在单独的 namespace 中使用
buildahTask,并将其设置为baseline模式,而不是restricted模式(例如,pod-security.kubernetes.io/enforce=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。 -
在
TasksecurityContext中指定用户: -
在
TaskRun的podTemplate中指定用户:
注意:
podTemplate.securityContext设置的是 Pod 级别的安全上下文,除非在容器级别被覆盖,否则会被所有容器继承。
当你无法修改容器镜像时,选项 2 和 3 会很有用。
TaskRun 因“Forbidden: cannot set securityContext.capabilities”而失败
当安全上下文尝试在删除所有 capabilities 的同时添加 capabilities 时,就会发生此错误。
解决方案: 确保你的 Task 不添加任何 capabilities。仅像示例中那样删除 capabilities。
Init 容器在权限错误下失败
如果在设置 set-security-context: true 后 init 容器因权限错误而失败,请验证以下内容:
- namespace 具有适当的安全策略
Tekton使用的容器镜像已配置为以非 root 身份运行Tekton安装版本是最新的