基础镜像与 SBOM 验证
如果我们只想允许特定类型的基础镜像被部署, 可以在获取到相关信息后,将这些信息保存到镜像 attestation 中。
在 漏洞扫描与验证 中,cosign-vuln 格式的 attestation 已经包含了基础镜像信息。
但这里我们将采用另一种方法,使用 syft 为镜像生成 SBOM。
SBOM 信息同样包含基础镜像信息。
在 ACP (Alauda Container Platform) 中,你可以在 Tekton Pipeline 中使用 trivy 或 syft task 为镜像生成 SBOM。
这里我们使用 syft task 生成 SBOM。
目录
功能概述使用场景前提条件流程概览分步说明步骤 1-3:基础设置步骤 4:创建示例 Pipeline步骤 5:运行示例 Pipeline步骤 6:等待 PipelineRun 完成签名步骤 7:从 PipelineRun 获取镜像步骤 8:(可选)获取 SBOM attestation步骤 9:验证基础镜像信息步骤 9.1:创建 Kyverno policy 以验证基础镜像信息步骤 9.2:验证 policy步骤 10:清理资源预期结果参考资料功能概述
此方法使用类似 syft 的工具为镜像生成 SBOM,然后使用 Kyverno 验证该 SBOM:
- 使用
syftTekton Task 为镜像生成 SBOM 并附加到镜像。 - 配置 Kyverno 规则以验证 SBOM。
- 使用该镜像创建 Pod,以验证 SBOM。
使用场景
以下场景需要参考本文档中的指导:
- 在 Kubernetes 集群中使用 Kyverno 实现基础镜像验证
- 强制安全策略,只允许特定基础镜像被部署
- 在 CI/CD 流水线中设置自动化 SBOM 生成与验证
- 确保生产环境中的基础镜像符合合规要求
- 通过验证容器镜像的基础镜像信息,实施供应链安全控制
前提条件
- 已安装 Tekton Pipelines、Tekton Chains 和 Kyverno 的 Kubernetes 集群
- 已启用镜像推送的 registry
- 已安装并配置好可访问集群的
kubectlCLI - 已安装
cosignCLI 工具 - 已安装
jqCLI 工具
流程概览
分步说明
步骤 1-3:基础设置
这些步骤与 快速开始:Signed Provenance 指南相同。请按照该指南中的说明完成以下内容:
- 步骤 1:生成签名密钥
- 步骤 2:设置认证
- 步骤 3:配置 Tekton Chains
- 获取签名 secret
- 重要:这里仅为方便起见,因此使用 Chains 的全局签名证书。实际使用中,你可以使用单独的证书来签署镜像漏洞信息。
- 将该 secret 导入到 pipeline 执行所在的 namespace 中。
步骤 4:创建示例 Pipeline
这是一个 Pipeline 资源,用于构建镜像并生成 SBOM。
本教程通过在 pipeline 中内联生成 Containerfile 和 git-clone task 输出,演示了一个简化的工作流。
在生产环境中,你通常会:
- 使用
git-clonetask 从你的仓库获取源代码 - 使用源代码中已有的 Containerfile 构建镜像
- 这种方式可以确保正确的版本控制,并保持代码与 pipeline 配置之间的分离
YAML 字段说明
- 与 步骤 4:创建示例 Pipeline 中的内容基本一致,但新增了以下内容:
workspaces:signkey:用于镜像签名的私钥和密码所在的 workspace。
tasks:syft-sbom:用于为镜像生成 SBOM 并上传 attestation 的 task。 :::
保存为名为 chains-demo-5.yaml 的 yaml 文件,并使用以下命令应用:
步骤 5:运行示例 Pipeline
这是一个 PipelineRun 资源,用于运行该 pipeline。
:::details {title="YAML 字段说明"}
- 与 步骤 5:运行示例 Pipeline 中的内容大体一致。下面仅介绍差异部分。
workspacessignkey:签名密钥的 secret 名称。secret.secretName:上一步 获取签名 secret 中准备的签名 secret。但你需要在与 pipeline run 相同的 namespace 中创建一个新的 secret。 :::
保存为名为 chains-demo-5.pipelinerun.yaml 的 yaml 文件,并使用以下命令应用:
等待 PipelineRun 完成。
步骤 6:等待 PipelineRun 完成签名
等待 PipelineRun 出现 chains.tekton.dev/signed: "true" 注解。
一旦 PipelineRun 具有 chains.tekton.dev/signed: "true" 注解,就表示镜像已签名。
步骤 7:从 PipelineRun 获取镜像
此镜像将用于验证 SBOM。
步骤 8:(可选)获取 SBOM attestation
如果你对 SBOM attestation 的内容感兴趣,可以继续阅读以下内容。
关于 cyclonedx SBOM attestation 的更多细节,请参考 cyclonedx SBOM attestation
根据 获取签名公钥 小节获取签名公钥。
输出将类似如下内容,其中包含镜像的组件信息。
:::details {title="cyclonedx SBOM attestation"}
:::details {title="字段说明"}
predicateType:predicate 的类型。predicate:components:镜像的组件。bom-ref:组件的 BOM 引用。licenses:组件的许可证。license:组件的许可证。name:许可证名称。id:许可证 ID。
name:组件名称。type:组件类型。version:组件版本。
metadata:镜像的元数据。timestamp:镜像时间戳。tools:components:工具的组件。author:工具作者。name:工具名称。type:工具类型。version:工具版本。 :::
步骤 9:验证基础镜像信息
步骤 9.1:创建 Kyverno policy 以验证基础镜像信息
此步骤需要集群管理员权限。
关于 Kyverno ClusterPolicy 的更多信息,请参考 Kyverno ClusterPolicy
policy 如下:
:::details {title="YAML 字段说明"}
- 该 policy 与 镜像签名验证 中的 policy 基本一致
spec.rules[0].verifyImages[].attestations[0].conditionstype:cyclonedx SBOM attestation 的类型为https://cyclonedx.org/bomattestors:与上文相同。conditions:需要验证的条件。any:只要满足任一条件即可。key: "{{ components[?type=='operating-system'] | [?name=='ubuntu' && (version=='22.04' || version=='24.04')] | length(@) }}":操作系统必须是 Ubuntu 22.04 或 24.04。key: "{{ components[?type=='operating-system'] | [?name=='alpine' && (version=='3.18' || version=='3.20')] | length(@) }}":操作系统必须是 Alpine 3.18 或 3.20。 :::
将该 policy 保存为名为 kyverno.verify-base-image.yaml 的 yaml 文件,并使用以下命令应用:
步骤 9.2:验证 policy
在定义该 policy 的 policy namespace 中,创建一个 Pod 来验证该 policy。
使用构建好的镜像创建一个 Pod。
如果你的基础镜像是 Ubuntu 22.04 或 24.04,Pod 将会成功创建。
将 ClusterPolicy 中的条件修改为仅允许 Alpine 3.18 或 3.20。
然后创建一个 Pod 来验证该 policy。
将收到如下输出:
步骤 10:清理资源
删除前面步骤中创建的 Pod。
删除该 policy。
预期结果
完成本指南后:
- 你已经完成了 Tekton Chains 用于 SBOM 生成以及 Kyverno 用于基础镜像验证的可用配置
- 容器镜像会在其 attestation 中自动包含 SBOM 信息
- 只有基础镜像符合要求的镜像才能在指定 namespace 中部署
- 基础镜像不符合要求的镜像会被 Kyverno policy 自动阻止
- 你已经通过验证容器镜像的基础镜像信息,实现了基础的供应链安全控制
本指南为在 CI/CD 流水线中实施供应链安全提供了基础。在生产环境中,你应当:
- 配置适当的 namespace 隔离和访问控制
- 为签名密钥实施安全的密钥管理
- 建立针对 policy 违规的监控与告警
- 定期轮换签名密钥并更新安全 policy