通过 CLI 开始使用

本教程介绍了如何配置和测试要求提供证明的 Binary Authorization 政策。这类政策指定谁可以在 Google Kubernetes Engine (GKE) 上部署容器映像以及允许在 GKE 上部署哪些容器映像,从而保护基于容器的软件供应链。

在部署时,Binary Authorization 使用证明者来验证证明中的数字签名。证明是由签名者在持续集成 (CI) 流水线中创建的。

在本教程中,GKE 集群、证明和证明者均位于单个项目中。单项目配置最适合用于测试或试用该服务。如需查看更多实际示例,请参阅多项目配置

以下步骤介绍了您可以通过命令行执行的任务。如需使用 Google Cloud Console 执行这些步骤,请参阅通过控制台开始使用

目标

在本教程中,您将学习如何执行以下操作:

  • 创建启用了 Binary Authorization 的 Google Kubernetes Engine (GKE) 集群
  • 创建一个供 Binary Authorization Enforcer 用于验证证明中的签名的证明者
  • 配置要求提供证明的政策
  • 创建加密密钥对,用于对证明签名,并在稍后进行验证
  • 对容器映像摘要签名,同时创建签名
  • 使用签名创建证明
  • 通过将容器映像部署到 GKE 来测试政策

费用

本教程使用 Google Cloud 的以下收费组件:

  • Container Registry
  • GKE

请使用价格计算器根据您的预计使用情况来估算费用。Cloud Platform 新用户可能有资格免费试用

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 安装并初始化 Cloud SDK
  5. 安装 kubectl,以与 GKE 进行交互。

启用 Binary Authorization

设置默认项目

第一步是设置 gcloud 命令使用的默认 Google Cloud 项目:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

其中,PROJECT_ID 是您的项目的名称。

启用必需的 API

接下来,为 GKE、Container Analysis 和 Binary Authorization 启用 Google Cloud API:

gcloud services enable \
    container.googleapis.com \
    containeranalysis.googleapis.com \
    binaryauthorization.googleapis.com

创建启用了 Binary Authorization 的集群

创建集群

现在,您可以创建一个启用了 Binary Authorization 的 GKE 集群。这是您希望运行已部署的容器映像的集群。创建集群时,请将 --enable-binauthz 标志传递给 gcloud container clusters create 命令。

如需创建集群,请运行以下命令:

gcloud container clusters create \
    --enable-binauthz \
    --zone us-central1-a \
    test-cluster

在此处,您在 GKE 区域 us-central1-a 中创建了名为 test-cluster 的集群。

配置 kubectl

您还必须为 kubectl 安装更新本地 kubeconfig 文件。这可以提供访问 GKE 中的集群所需的凭据和端点信息。

如需更新本地 kubeconfig 文件,请运行以下命令:

gcloud container clusters get-credentials \
    --zone us-central1-a \
    test-cluster

查看默认政策

Binary Authorization 中的政策是一组规则,用于管理容器映像的部署。每个项目可以有一项政策。默认情况下,政策会配置为允许部署所有容器映像。

借助 Binary Authorization,您可以导出和导入 YAML 格式的政策文件。此格式反映了该服务存储的政策的内部结构。使用 gcloud 命令配置政策时,您可以修改此文件。

如需查看默认政策,请导出 YAML 格式的政策文件:

gcloud container binauthz policy export

默认情况下,该文件包含以下内容:

admissionWhitelistPatterns:
- namePattern: gcr.io/google_containers/*
- namePattern: gcr.io/google-containers/*
- namePattern: k8s.gcr.io/*
- namePattern: gke.gcr.io/*
- namePattern: gcr.io/stackdriver-agents/*
globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/${PROJECT_ID}/policy

在这里,默认规则在 defaultAdmissionRule 节点中定义。evaluationMode 指明该政策允许映像部署时的所有尝试。

如需详细了解政策的结构,请参阅 YAML 格式政策参考文档

创建证明者

证明者是 Binary Authorization Enforcer 用来在部署时决定是否允许 GKE 部署已签名的相应容器映像的验证机构。证明者包含公钥,通常由您的组织内负责软件供应链安全性的人员管理。

创建证明者需要您执行以下操作:

  • Container Analysis 中创建备注,以存储授权流程中使用的可信元数据
  • 在 Binary Authorization 中创建证明者本身,并将您创建的备注关联起来

在本教程中,您有一个名为 test-attestor 的证明者和一个名为 test-attestor-note 的 Container Analysis 备注。在实际使用场景中,您可以拥有任意数量的证明者,每个证明者代表参与容器映像授权过程的一方。

创建 Container Analysis 备注

  1. 设置变量,以存储证明者的名称和 Container Analysis 备注:

    ATTESTOR=test-attestor
    NOTE_ID=test-attestor-note
    
  2. /tmp/note_payload.json 中创建一个描述 Container Analysis 备注的 JSON 文件:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}",
      "attestation": {
        "hint": {
          "human_readable_name": "Attestor Note"
        }
      }
    }
    EOM
    
  3. 通过向 Container Analysis REST API 发送 HTTP 请求来创建备注:

    curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
        --data-binary @/tmp/note_payload.json  \
        "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    
  4. 验证备注是否已创建:

    curl \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
    

创建证明者

现在,您可以创建证明者:

  1. 在 Binary Authorization 中创建证明者:

    gcloud container binauthz attestors create ${ATTESTOR} \
    --attestation-authority-note=${NOTE_ID} \
    --attestation-authority-note-project=${PROJECT_ID}
    
  2. 验证证明者是否已创建:

    gcloud container binauthz attestors list
    

您创建的证明者在没有关联的 PKIX 密钥对(在下文中创建)的情况下尚无法使用。

生成密钥对

Binary Authorization 使用加密密钥来安全地验证签名者的身份。这样可以确保只能部署经过授权的容器映像。密钥对由私钥和公钥组成。签名者使用私钥对容器映像摘要签名,同时生成签名,然后签名会存储在证明中。公钥存储在证明者中。在部署时,Binary Authorization Enforcer 会使用证明者的公钥来验证证明中的签名,正确无误后才允许部署容器。

在本教程中,您需要为加密密钥使用公钥基础架构 (X.509) (PKIX) 格式。本教程使用推荐的椭圆曲线数字签名算法 (ECDSA) 来生成 PKIX 密钥对。您也可以使用 RSA 或 PGP 密钥进行签名。

如需详细了解如何对算法签名,请参阅密钥用途和算法

Cloud Key Management Service (Cloud KMS) 生成和存储的密钥符合 PKIX。如需详细了解如何使用 PKIX 密钥和 Cloud KMS,请参阅使用 CLI 创建证明者

如需生成 PKIX 密钥对,请按以下步骤操作:

  1. 创建私钥:

    PRIVATE_KEY_FILE="/tmp/ec_private.pem"
    openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
    
  2. 从私钥中提取公钥:

    PUBLIC_KEY_FILE="/tmp/ec_public.pem"
    openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
    
  3. 将 ECDSA 公钥添加到证明者。

    现在,将您导出的公钥添加到证明者中,供 Binary Authorization 用它来进行身份验证:

    gcloud --project="${PROJECT_ID}" \
        beta container binauthz attestors public-keys add \
        --attestor="${ATTESTOR}" \
        --pkix-public-key-file=${PUBLIC_KEY_FILE} \
        --pkix-public-key-algorithm=ecdsa-p256-sha256
    
  4. 保存公钥 ID。

    如需保存公钥 ID,您可以从上面的 public-keys add 输出中进行复制。如需在将证明者的公钥添加到证明者后查看其 ID,请使用 gcloud container binauthz attestors describe ${ATTESTOR}

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    

配置政策

现在,您可以配置政策了。在此步骤中,您将 YAML 格式政策文件导出到本地系统,并修改默认规则,使其要求您在前面指定的证明者提供证明。

如需配置政策,请按照以下步骤操作:

  1. 创建一个新的政策文件,它应该允许 Google 维护的系统映像、将 evaluationMode 设置为 REQUIRE_ATTESTATION,并添加一个名为 requireAttestationsBy 且引用您创建的证明者的节点:

    cat > /tmp/policy.yaml << EOM
        globalPolicyEvaluationMode: ENABLE
        defaultAdmissionRule:
          evaluationMode: REQUIRE_ATTESTATION
          enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
          requireAttestationsBy:
            - projects/${PROJECT_ID}/attestors/${ATTESTOR}
        name: projects/${PROJECT_ID}/policy
    EOM
    
  2. 将 YAML 格式政策文件导入 Binary Authorization:

    gcloud container binauthz policy import /tmp/policy.yaml
    

如需详细了解如何配置政策,请参阅使用 CLI 配置政策

测试政策

您可以通过尝试将示例容器映像部署到集群来测试前面配置的政策。该政策将阻止部署,因为尚未提供必需的证明。

在本教程中,您可以使用 Container Registry 内位于路径 gcr.io/google-samples/hello-app 中的示例映像。这是一个由 Google 创建的公共容器映像,其中包含一个 Hello, World! 示例应用。

首先,请尝试部署该映像:

kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080

现在,验证 Binary Authorization 是否会阻止部署:

kubectl get pods

该命令会输出以下消息,表明该映像未部署:

No resources found.

您可以进一步了解部署详情:

kubectl get event --template \
'{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'

这表明政策不允许进行该部署:

FailedCreate: Error creating: pods "hello-server-579859fb5b-hjvnr" is forbidden: image policy webhook backend denied one or more images: Denied by default admission rule. Denied by Attestation Authority. Image gcr.io/google-samples/hello-app:1.0 denied by projects/example-project/attestors/test-attestor: No attestations found

请务必删除该部署,以便继续执行下一步:

kubectl delete deployment hello-server

创建证明

证明是一种数字文档,由签名者创建,用于证明 GKE 可以部署关联的容器映像。创建证明的过程有时被称为“对映像签名”。签名者可以是个人,更为常见的是在构建容器映像时运行的自动化流程。签名是使用密钥对中的私钥创建的。在部署时,Binary Authorization Enforcer 会使用证明者的公钥来验证证明中的签名。

在本教程中,您的证明仅说明您已授权对映像进行部署。

如需创建证明,请按照下列步骤操作:

  1. 设置用于存储映像的注册表路径和摘要的变量:

    IMAGE_PATH="gcr.io/google-samples/hello-app"
    IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4"
    
  2. 生成证明载荷:

    gcloud container binauthz create-signature-payload \
    --artifact-url=${IMAGE_PATH}@${IMAGE_DIGEST} > /tmp/generated_payload.json
    

    载荷 JSON 文件包含以下内容:

    {
      "critical": {
        "identity": {
          "docker-reference": "gcr.io/google-samples/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea
    882eb722c3be4"
        },
        "type": "Google cloud binauthz container signature"
      }
    }
    
  3. 请使用 PKIX 私钥对载荷签名并输出签名文件:

    openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
    

    签名文件是您在前面创建的载荷 JSON 文件的数字签名版本。

  4. 创建证明:

    gcloud container binauthz attestations create \
        --artifact-url="${IMAGE_PATH}@${IMAGE_DIGEST}" \
        --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}"
    

    或者,如需创建证明并验证 (validate) 证明是否可以由提供的证明者进行验证,请运行以下命令:

    gcloud alpha container binauthz attestations create \
        --artifact-url="${IMAGE_PATH}@${IMAGE_DIGEST}" \
        --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
    

    其中,PUBLIC_KEY_ID 是您在上面的生成 PKIX 密钥对中找到的公钥 ID。

  5. 验证是否已创建证明:

    gcloud container binauthz attestations list \
        --attestor=$ATTESTOR --attestor-project=$PROJECT_ID
    

如需详细了解如何创建证明,请参阅创建证明

重新测试政策

同样,可通过将示例容器映像部署到集群来测试政策。这次,您必须使用摘要(而非 1.0latest 等标记)部署映像,因为 Binary Authorization 将使用映像路径和摘要来查找证明。在此,Binary Authorization 允许部署映像,因为已完成必需的证明。

如需部署映像,请运行以下命令:

kubectl run hello-server --image ${IMAGE_PATH}@${IMAGE_DIGEST} --port 8080

如需验证映像是否已部署,请运行以下命令:

kubectl get pods

该命令会输出类似于以下内容的消息,表示部署成功:

NAME                            READY     STATUS    RESTARTS   AGE
hello-server-579859fb5b-h2k8s   1/1       Running   0          1m

清理

为避免因本教程中使用的资源导致您的 Google Cloud Platform 帐号产生费用,请执行以下操作:

删除您在 GKE 中创建的集群:

gcloud container clusters delete \
    --zone=us-central1-a \
    test-cluster

后续步骤