符合 Pod Security Restricted Standard
目录
功能概述使用场景前提条件理解 Restricted Standard步骤1. 配置 Tekton 为 init 容器添加安全上下文选项 A:通过 TektonPipeline 配置选项 B:通过 TektonConfig 配置2. 为自定义 Task 定义添加安全上下文3. 配置容器镜像使用非 root 用户结果使用策略强制执行工具故障排查内置 Task 与 Restricted StandardTaskRun 因容器用户错误而失败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定义 - 对于自定义镜像,你可以修改
Containerfiles并重新构建镜像
理解 Restricted Standard
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控制器。在此更改之后创建的新TaskRuns和PipelineRuns会自动将所需的安全上下文应用到 init 容器。
2. 为自定义 Task 定义添加安全上下文
对于自定义 Tasks(不是平台提供的内置 Tasks),你需要显式地为每个 step 添加安全上下文。
带有安全上下文的 Task 示例:
重要: 此步骤适用于自定义
Tasks。平台提供的内置Tasks(buildah除外,见故障排查部分)与这些安全限制兼容,但它们的Task定义不包含显式的securityContext配置,因为它们的设计目标是适配多种安全上下文,而不仅仅是 restricted 模式。
3. 配置容器镜像使用非 root 用户
容器镜像必须配置为以非 root 用户运行。必须使用数字 UID 指定用户,而不是用户名。
在你的 Containerfile 中,添加一个非 root 用户并将其设置为默认用户。以下是基于 Alpine 的镜像示例:
说明:
adduser命令的语法会因基础镜像不同而有所差异。有关其他基础镜像的示例,请参见下面引用的文档。
验证镜像配置:
有关调整 catalog Task 镜像的详细指导,请参见 Task 镜像兼容性。
结果
完成上述步骤后:
- Init 容器:
Tekton创建的 init 容器将自动符合restricted标准 - 自定义 Tasks:你的自定义
Taskstep 将具有所需的安全上下文 - 容器镜像:镜像将以非 root 用户身份运行,并且权限最小化
你可以通过在受限命名空间中创建 TaskRun 来验证合规性:
成功的 TaskRun 会显示 SUCCEEDED 为 True,REASON 为 Succeeded,表示所有容器都已在所需的安全限制下成功运行。
使用策略强制执行工具
如果你希望采用更自动化的方式,可以使用诸如 Kyverno 之类的策略强制执行工具,自动将所需的安全上下文注入到所有容器中。通过创建一个 Kyverno Policy(使用 apiVersion: kyverno.io/v1 和 kind: Policy),你可以自动变更 Pods,为其添加必要的安全上下文配置。
有关更多信息,请参见 场景 4:指定命名空间安全上下文强制执行。
这种基于 Kyverno 的方式并不能使内置的 buildah Task 与 restricted 标准兼容。关于 buildah 的限制,请参见下方的 内置 Task 与 Restricted Standard。
这种方式消除了为每个 Task 手动配置安全上下文的需要,从而简化了合规管理。
有关为此目的配置 Kyverno 策略的详细指导,请参见:
故障排查
内置 Task 与 Restricted Standard
在平台提供的内置 Tasks 中,只有 buildah Task 不能在 restricted 标准下运行。这是因为 buildah 在构建容器镜像时需要提升后的权限。
即使使用 Kyverno 自动将所需的 restricted 安全上下文注入到 Pods 中,这一限制仍然存在。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和 workspaces 配置正确时,buildahTask可以在baseline标准下正常运行。可选: 如果命名空间必须为
buildah使用baseline模式,但你仍希望防止同一命名空间中的其他 Pods 请求更宽泛的权限,可以启用 Tekton Pipelines 的ValidatingAdmissionPolicy保护措施。此保护措施不会使内置buildahTask与restricted模式兼容。它适用于所有标记为buildah.alauda.io/enabled=true的命名空间中的 Pods:它只允许buildah所需的SETFCAP已添加 capability,并拒绝特权容器、宿主机命名空间、hostPath 卷以及除SETFCAP之外的已添加 capabilities。编辑
TektonConfig资源以启用该策略:在
spec.pipeline.params下添加或更新以下条目。如果params已经包含其他条目,请保留它们,只添加或更新enable-validating-admission-policy。等待
TektonConfig就绪:验证策略资源已安装:
这两个命令都应返回一个名为
pipelines-restricted的资源。验证该保护措施会拒绝请求超出
buildah例外范围的工作负载。下面的 server-side dry run 不会创建Pod,但仍会经过准入流程。它应该被拒绝,因为NET_BIND_SERVICE在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中指定用户: -
在
TaskRunpodTemplate中指定用户:
说明:
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安装是否为最新版本