Google Cloud 控制台使用入门 (GKE)


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

在部署时,Binary Authorization 使用证明者来验证证明中的数字签名。证明是由签名者在构建流程中创建的。

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

以下步骤介绍了您可以通过 Google Cloud 控制台执行的相关任务,以及您可以使用 gcloud 命令执行的一些任务。如需使用 gcloud 执行这些步骤,请参阅 Google Cloud CLI 使用入门

目标

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

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

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

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

准备工作

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

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 Container Registry, Artifact Analysis and Binary Authorization API。

    启用 API

  5. 安装 Google Cloud CLI。
  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  8. 确保您的 Google Cloud 项目已启用结算功能

  9. 启用 Container Registry, Artifact Analysis and Binary Authorization API。

    启用 API

  10. 安装 Google Cloud CLI。
  11. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  12. 安装 kubectl

设置默认项目

为方便执行下面的命令,请将您的 Google Cloud 项目 ID 存储在某个环境变量中,如下所示:

PROJECT_ID=PROJECT_ID

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

如果未选择默认项目,请立即设置:

gcloud config set project ${PROJECT_ID}

创建启用了 Binary Authorization 的集群

创建集群

现在,您可以创建一个启用了 Binary Authorization 的 GKE 集群。在此处,您在 GKE 区域 us-central1-a 中创建了名为 test-cluster 的集群。

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

  1. 访问 Google Cloud 控制台中的 GKE 菜单。

    转到 GKE

  2. 点击创建集群

  3. 名称字段中输入 test-cluster

  4. 位置类型选项中选择区域

  5. 区域下拉列表中选择 us-central1-a

  6. 点击可用性、网络、安全性及其他功能

  7. 安全性部分,选择启用 Binary Authorization

  8. 选择仅强制执行

  9. 点击创建

配置 kubectl

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

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

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

查看默认政策

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

如需查看默认政策,请按照以下步骤操作:

  1. 转到 Google Cloud 控制台中的 Binary Authorization 页面。

    转到 Binary Authorization

  2. 点击修改政策

  3. 项目默认规则中,会显示允许所有映像选项。

  4. 点击保存政策

创建证明者

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

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

  • 在 Binary Authorization 中创建证明者本身
  • Artifact Analysis 中自动生成关联的证明者备注,以存储在授权过程中使用的可信证明元数据

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

生成密钥对

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}
    

创建证明者

现在,您可以在 Binary Authorization 中创建证明者本身,并关联您创建的公钥。

如需创建证明者,请执行以下操作:

  1. 返回 Google Cloud 控制台中的 Binary Authorization 页面。

    返回 Binary Authorization

  2. 证明者标签页中,点击创建

    显示默认规则的“政策”标签页的屏幕截图

  3. 如下所示填写各个字段:

    1. 证明者名称字段中输入 test-attestor

    2. 确认已选中自动创建 Artifact Analysis 备注

    3. 点击添加 PKIX 公钥

    4. 在文本编辑器中打开 /tmp/ec_public.pem。这是您在上一步中创建的公钥文件。将文件内容复制到公钥资料文本框中。

    5. 点击签名算法下拉列表中的 Elliptic Curve P-256 - SHA256 Digest

    6. 点击完成

  4. 点击创建以创建证明者。

  5. 存储公钥 ID。

    如需在将证明者的公钥添加到证明者后查看其 ID,请使用 gcloud container binauthz attestors describe ${ATTESTOR_NAME}。如需创建环境变量来存储公钥 ID,请执行以下命令:

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

配置政策

现在,您可以配置政策了:

  1. 返回 Google Cloud 控制台中的“Binary Authorization”页面。

  2. 政策标签页中,点击修改政策

  3. 选择只允许已被以下所有证明者批准的映像

  4. 点击添加证明者

  5. 点击根据项目和证明者名称添加

  6. 项目名称字段中输入 PROJECT_ID

  7. 证明者名称字段中输入 test-attestor

  8. 点击添加 1 个证明者

  9. 点击保存政策

如需了解详情,请参阅使用控制台配置政策

测试政策

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

在本教程中,您可以使用 Container Registry 和 Artifact Registry 中的示例映像。Container Registry 中的映像位于路径 gcr.io/google-samples/hello-app:1.0。Artifact Registry 中的映像位于路径 us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0。两个路径都包含由 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 POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by ATTESTOR_NAME: No attestations found

在此输出中:

  • POD_NAME:Pod 的名称。
  • IMAGE_NAME:映像的名称。
  • ATTESTOR_NAME:证明者的名称。

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

kubectl delete deployment hello-server

创建证明

证明是一种数字文档,由签名者创建,用于证明 GKE 可以部署关联的容器映像。创建证明的过程有时被称为“对映像签名”。

在本教程中,您将为 Container Registry 和 Artifact Registry 中的示例映像创建证明。

如需创建证明,请执行以下操作:

  1. 设置用于存储映像的注册表路径和摘要以及证明者名称的变量:

    Container Registry

    IMAGE_PATH="gcr.io/google-samples/hello-app"
    IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4"
    ATTESTOR="test-attestor"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    

    Artifact Registry

    IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app"
    IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
    ATTESTOR="test-attestor"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    
  2. 生成证明载荷:

    Container Registry

    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"
    }
    }
    

    Artifact Registry

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

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

    {
    "critical": {
      "identity": {
        "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app"
      },
      "image": {
        "docker-manifest-digest": "sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
      },
      "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 \
        --project="${PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
    

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

    validate 标志用于检查证明是否可由您在政策中配置的证明者进行验证。

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

    gcloud container binauthz attestations list \
        --attestor=$ATTESTOR_NAME --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

如需删除 Pod,请执行以下命令:

kubectl delete pod hello-server

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

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

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

后续步骤