4.16. 为 OpenShift Pipelines 提供链安全使用 Tekton 链


重要

Tekton 链只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

Tekton Chains 是一个 Kubernetes 自定义资源定义(CRD)控制器。您可以使用它来管理使用 Red Hat OpenShift Pipelines 创建的任务和管道的供应链安全。

默认情况下,Tekton Chains 会观察 OpenShift Container Platform 集群中的所有任务运行执行。当任务运行完成时,Tekton Chains 会获取任务运行的快照。然后,它会将快照转换为一个或多个标准有效负载格式,最后签署并存储所有工件。

要捕获有关任务运行的信息,Tekton Chains 使用 ResultPipelineResource 对象。当对象不可用时,Tekton 会链 OCI 镜像的 URL 和合格摘要。

注意

PipelineResource 对象已弃用,并将在以后的发行版本中删除 ; 对于手动使用,建议使用 Results 对象。

4.16.1. 主要特性

  • 您可以使用加密密钥类型和服务(如 cosign )为任务运行、任务运行结果和 OCI registry 镜像签名。
  • 您可以使用"测试"格式,如 in-toto
  • 您可以使用 OCI 存储库作为存储后端安全存储签名和签名工件。

4.16.2. 使用 Red Hat OpenShift Pipelines Operator 安装 Tekton 链

集群管理员可以使用 TektonChain 自定义资源(CR)来安装和管理 Tekton 链。

注意

Tekton Chains 是 Red Hat OpenShift Pipelines 的一个可选组件。目前,您无法使用 TektonConfig CR 安装它。

先决条件

  • 确保在集群中的 openshift-pipelines 命名空间中安装了 Red Hat OpenShift Pipelines Operator。

流程

  1. 为 OpenShift Container Platform 集群创建 TektonChain CR。

    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonChain
    metadata:
      name: chain
    spec:
      targetNamespace: openshift-pipelines
  2. 应用 TektonChain CR。

    $ oc apply -f TektonChain.yaml 1
    1
    使用 TektonChain CR 的文件名替换。
  3. 检查安装的状态。

    $ oc get tektonchains.operator.tekton.dev

4.16.3. 配置 Tekton 链

Tekton Chains 在 openshift-pipelines 命名空间中使用名为 chains-configConfigMap 对象进行配置。

要配置 Tekton 链,请使用以下示例:

示例:配置 Tekton 链

$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}' 1

1
在 JSON 有效负载中使用支持的键值对组合。

4.16.3.1. Tekton Chains 配置支持的键

集群管理员可以使用各种支持的键和值来配置任务运行、OCI 镜像和存储的规格。

4.16.3.1.1. 任务运行支持的键
表 4.13. 链配置:任务运行支持的密钥
支持的键描述支持的值默认值

artifacts.taskrun.format

存储任务运行有效负载的格式。

tekton, in-toto

tekton

artifacts.taskrun.storage

任务运行签名的存储后端。您可以将多个后端指定为用逗号分开的列表,如 “tekton,oci”。要禁用此工件,请提供一个空字符串 ""

tekton, oci

tekton

artifacts.taskrun.signer

签名后端为任务运行有效负载进行签名。

x509

x509

4.16.3.1.2. OCI 支持的密钥
表 4.14. 链配置: OCI 支持的密钥
支持的键描述支持的值默认值

artifacts.oci.format

存储 OCI 有效负载的格式。

simplesigning

simplesigning

artifacts.oci.storage

OCI 签名的存储后端。您可以将多个后端指定为用逗号分开的列表,如 “oci,tekton”。要禁用 OCI 工件,请提供空字符串 ""

tekton, oci

oci

artifacts.oci.signer

签名后端以签署 OCI 有效负载。

x509,cosign

x509

4.16.3.1.3. 支持的存储密钥
表 4.15. 链配置:存储支持的密钥
支持的键描述支持的值默认值

artifacts.oci.repository

用于存储 OCI 签名的 OCI 存储库。

目前,链仅支持内部 OpenShift OCI registry;不支持 Quay 等其他流行选项。

 

4.16.4. 在 Tekton Chains 中签名 secret

集群管理员可以生成密钥对,并使用 Tekton 链来使用 Kubernetes secret 为工件签名。要使 Tekton 链正常工作,加密的密钥和密码必须作为 openshift-pipelines 命名空间中的 signing-secrets Kubernetes secret 的一部分存在。

目前,Tekton 链支持 x509cosign 签名方案。

注意

只使用一个受支持的签名方案。

4.16.4.1. 使用 x509 进行签名

要将 x509 签名方案与 Tekton Chains 搭配使用,请将 ed25519ecdsa 类型的 x509.pem 私钥存储在 signing-secrets Kubernetes secret 中。确保密钥保存为未加密的 PKCS8 PEM 文件(BEGIN PRIVATE KEY)。

4.16.4.2. 使用 cosign 进行签名

使用 Tekton 链的 cosign 签名方案:

  1. 安装 cosign
  2. 生成 cosign.keycosign.pub 密钥对。

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    Cosign 提示您输入密码,并创建一个 Kubernetes secret。

  3. 将加密的 cosign.key 私钥和 cosign.password 解密密码存储在 signing-secrets Kubernetes secret 中。确保私钥存储为 ENCRYPTED COSIGN PRIVATE KEY 类型的加密 PEM 文件。

4.16.4.3. 签名故障排除

如果签名 secret 已填充,您可能会遇到以下错误:

Error from server (AlreadyExists): secrets "signing-secrets" already exists

要解决这个问题:

  1. 删除 secret:

    $ oc delete secret signing-secrets -n openshift-pipelines
  2. 重新创建密钥对并使用您首选的签名方案将其存储在 secret 中。

4.16.5. 对 OCI registry 进行身份验证

在将签名推送到 OCI Registry 之前,集群管理员必须配置 Tekton 链,以便与 registry 进行身份验证。Tekton Chains 控制器使用与任务运行相同的服务帐户。要设置具有所需凭证(push)到 OCI registry 的服务帐户,请执行以下步骤:

流程

  1. 设置 Kubernetes 服务帐户的命名空间和名称。

    $ export NAMESPACE=<namespace> 1
    $ export SERVICE_ACCOUNT_NAME=<service_account> 2
    1
    与服务帐户关联的命名空间。
    2
    服务帐户的名称。
  2. 创建 Kubernetes secret。

    $ oc create secret registry-credentials \
      --from-file=.dockerconfigjson \ 1
      --type=kubernetes.io/dockerconfigjson \
      -n $NAMESPACE
    1
    使用 Docker 配置文件的路径替换。默认路径为 ~/.docker/config.json
  3. 授予服务帐户对 secret 的访问权限。

    $ oc patch serviceaccount $SERVICE_ACCOUNT_NAME \
      -p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACE

    如果对 Red Hat OpenShift Pipelines 分配到所有任务的默认 pipeline 服务帐户进行补丁,Red Hat OpenShift Pipelines Operator 将覆盖服务帐户。作为最佳实践,您可以执行以下步骤:

    1. 创建单独的服务帐户,以分配给用户的任务运行。

      $ oc create serviceaccount <service_account_name>
    2. 通过设置任务运行模板中的 serviceaccountname 字段的值,将服务帐户关联到运行任务。

      apiVersion: tekton.dev/v1beta1
      kind: TaskRun
      metadata:
      name: build-push-task-run-2
      spec:
      serviceAccountName: build-bot 1
      taskRef:
        name: build-push
      ...
      1
      使用新创建的服务帐户的名称替换。

4.16.5.1. 创建和验证任务运行签名而无需任何其他身份验证

要验证使用 Tekton 链与任何其他身份验证一起运行的任务的签名,请执行以下任务:

  • 创建加密的 x509 密钥对,并将它保存为 Kubernetes secret。
  • 配置 Tekton Chains 后端存储。
  • 创建任务运行,为它签名并将签名和有效负载存储为任务运行自身时的注解。
  • 从已签名任务运行中检索签名和有效负载。
  • 验证任务运行的签名。

先决条件

确保在集群中安装了以下内容:

  • Red Hat OpenShift Pipelines Operator
  • Tekton Chains
  • Cosign

流程

  1. 创建加密的 x509 密钥对,并将它保存为 Kubernetes secret:

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    提示时提供密码。Cosign 将生成的私钥存储为 openshift-pipelines 命名空间中的 signing-secrets Kubernetes secret 的一部分。

  2. 在 Tekton Chains 配置中,禁用 OCI 存储,并将任务运行存储和格式设置为 tekton

    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}'
  3. 重启 Tekton Chains 控制器,以确保应用了修改后的配置。

    $ oc delete po -n openshift-pipelines -l app=tekton-chains-controller
  4. 创建任务运行。

    $ oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml 1
    taskrun.tekton.dev/build-push-run-output-image-qbjvh created
    1
    使用指向您的任务运行的 URI 或文件路径替换。
  5. 检查步骤的状态,并等待 till 进程完成。

    $ tkn tr describe --last
    [...truncated output...]
    NAME                            STATUS
    ∙ create-dir-builtimage-9467f   Completed
    ∙ git-source-sourcerepo-p2sk8   Completed
    ∙ build-and-push                Completed
    ∙ echo                          Completed
    ∙ image-digest-exporter-xlkn7   Completed
  6. 从存储为 base64 编码注解的对象检索签名和有效负载:

    $ export TASKRUN_UID=$(tkn tr describe --last -o  jsonpath='{.metadata.uid}')
    $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-taskrun-$TASKRUN_UID}" > signature
    $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/payload-taskrun-$TASKRUN_UID}" | base64 -d > payload
  7. 验证签名。

    $ cosign verify-blob --key k8s://openshift-pipelines/signing-secrets --signature ./signature ./payload
    Verified OK

4.16.6. 使用 Tekton 链来签名和验证镜像并证明

集群管理员可以通过执行以下任务来使用 Tekton 链来签名和验证镜像和验证镜像:

  • 创建加密的 x509 密钥对,并将它保存为 Kubernetes secret。
  • 为 OCI registry 设置身份验证,以在测试过程中存储镜像、镜像签名和签名的镜像。
  • 配置 Tekton 链以生成和签署认可。
  • 在任务运行中,使用 Kaniko 创建镜像。
  • 验证已签名的镜像及已签名证明。

先决条件

确保在集群中安装了以下内容:

  • Red Hat OpenShift Pipelines Operator
  • Tekton Chains
  • Cosign
  • Rekor
  • jq

流程

  1. 创建加密的 x509 密钥对,并将它保存为 Kubernetes secret:

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    提示时提供密码。Cosign 将生成的私钥作为 openshift-pipelines 命名空间中的 signing-secrets Kubernetes secret 的一部分存储在 openshift-pipelines 命名空间中,并将公钥写入 cosign.pub 本地文件。

  2. 为镜像 registry 配置身份验证。

    1. 要将 Tekton Chains 控制器配置为将签名推送到 OCI registry,请使用与任务运行服务帐户关联的凭证。如需更多信息,请参阅"授权到 OCI registry"部分。
    2. 要为构建并推送到 registry 的 Kaniko 任务配置身份验证,请创建一个包含所需凭证的 docker config.json 文件的 Kubernetes secret。

      $ oc create secret generic <docker_config_secret_name> \ 1
        --from-file <path_to_config.json> 2
      1
      使用 docker config secret 的名称替换。
      2
      使用 docker config.json 文件的路径替换。
  3. 通过在 chains-config 对象中设置 artifacts.taskrun.formatartifacts.taskrun.storagetransparency.enabled 参数来配置 Tekton 链 :

    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.format": "in-toto"}}'
    
    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.storage": "oci"}}'
    
    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"transparency.enabled": "true"}}'
  4. 启动 Kaniko 任务。

    1. 将 Kaniko 任务应用到集群。

      $ oc apply -f examples/kaniko/kaniko.yaml 1
      1
      使用 Kaniko 任务的 URI 或文件路径替换。
    2. 设置适当的环境变量。

      $ export REGISTRY=<url_of_registry> 1
      
      $ export DOCKERCONFIG_SECRET_NAME=<name_of_the_secret_in_docker_config_json> 2
      1
      使用您要推送镜像的 registry 的 URL 替换。
      2
      使用 docker config.json 文件中的 secret 名称替换。
    3. 启动 Kaniko 任务。

      $ tkn task start --param IMAGE=$REGISTRY/kaniko-chains --use-param-defaults --workspace name=source,emptyDir="" --workspace name=dockerconfig,secret=$DOCKERCONFIG_SECRET_NAME kaniko-chains

      观察此任务的日志,直到所有步骤都完成。身份验证成功后,最终镜像将推送到 $REGISTRY/kaniko-chains

  5. 等待一分钟,以允许 Tekton 链生成证据并对其进行签名,然后在任务运行时检查 chains.tekton.dev/signed=true 注解的可用性。

    $ oc get tr <task_run_name> \ 1
    -o json | jq -r .metadata.annotations
    
    {
      "chains.tekton.dev/signed": "true",
      ...
    }
    1
    使用任务运行的名称替换。
  6. 验证镜像和 attestation。

    $ cosign verify --key cosign.pub $REGISTRY/kaniko-chains
    
    $ cosign verify-attestation --key cosign.pub $REGISTRY/kaniko-chains
  7. 在 Rekor 中找到镜像的验证情况。

    1. 获取 $REGISTRY/kaniko-chains 镜像摘要。您可以搜索任务运行或拉取镜像以提取摘要。
    2. 搜索 Rekor 以查找与镜像 sha256 摘要匹配的所有条目。

      $ rekor-cli search --sha <image_digest> 1
      
      <uuid_1> 2
      <uuid_2> 3
      ...
      1
      使用镜像的 sha256 摘要替换。
      2
      第一个匹配通用唯一标识符(UUID)。
      3
      第二个匹配 UUID。

      搜索结果显示匹配条目的 UUID。其中其中一个 UUID 包含 attestation。

    3. 检查 attestation。

      $ rekor-cli get --uuid <uuid> --format json | jq -r .Attestation | base64 --decode | jq

4.16.7. 其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.