实验设置说明和要求
保护您的账号和进度。请务必在无痕浏览器窗口中,使用实验凭证运行此实验。

使用 Binary Authorization 控制部署

实验 35 分钟 universal_currency_alt 5 个点数 show_chart 中级
info 此实验可能会提供 AI 工具来支持您学习。
此内容尚未针对移动设备进行优化。
为获得最佳体验,请在桌面设备上访问通过电子邮件发送的链接。

GSP1183

Google Cloud 自学实验

概览

Binary Authorization 是一种部署时安全控制措施,可确保在 Google Kubernetes Engine (GKE) 或 Cloud Run 上仅部署可信的容器映像。借助 Binary Authorization,您可以要求在开发过程中由可信授权方对映像进行签名,然后在部署时强制执行签名验证。通过强制执行验证,您可以确保仅将经过验证的映像集成到构建和发布流程中,从而对容器环境实施更严格的控制。

下图显示了 Binary Authorization/Cloud Build 设置中的组件:

Cloud Build/Binary Authorization 证明流水线。Cloud Build 流水线,用于创建 Binary Authorization 证明。

此流水线的具体步骤如下:

  1. 首先,系统将用于构建容器映像的代码推送到源代码库,例如 Cloud Source Repositories
  2. 持续集成 (CI) 工具 Cloud Build 构建并测试容器。
  3. 构建流程将容器映像推送到 Container Registry 或其他存储已构建映像的注册表。
  4. Cloud Key Management Service加密密钥对进行密钥管理,并为容器映像签名。然后,生成的签名将存储在新创建的证明中。
  5. 在部署时,证明者使用密钥对中的公钥来验证证明。Binary Authorization 强制执行政策,要求必须具有已签名的证明才能部署容器映像。

在本实验中,您将学习如何使用各种工具和技术来保护已部署的制品。本实验重点关注已完成创建、但尚未部署到任何特定环境的制品(容器)。

学习内容

  • 映像签名
  • 准入控制政策
  • 为扫描的映像签名
  • 授权已签名的映像
  • 屏蔽未签名的映像

设置和要求

点击“开始实验”按钮前的注意事项

请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。

此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。我们会为您提供新的临时凭证,让您可以在实验规定的时间内用来登录和访问 Google Cloud。

为完成此实验,您需要:

  • 能够使用标准的网络浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
  • 有充足时间完成实验 - 请注意,实验开始后无法暂停。
注意:如果您已有自己的个人 Google Cloud 账号或项目,请不要在此实验中使用,以避免您的账号产生额外的费用。

如何开始实验并登录 Google Cloud 控制台

  1. 点击开始实验按钮。如果该实验需要付费,系统会打开一个弹出式窗口供您选择付款方式。左侧是实验详细信息面板,其中包含以下各项:

    • 打开 Google Cloud 控制台按钮
    • 剩余时间
    • 进行该实验时必须使用的临时凭证
    • 帮助您逐步完成本实验所需的其他信息(如果需要)
  2. 点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。

    该实验会启动资源并打开另一个标签页,显示登录页面。

    提示:将这些标签页安排在不同的窗口中,并排显示。

    注意:如果您看见选择账号对话框,请点击使用其他账号
  3. 如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。

    {{{user_0.username | "<用户名>"}}}

    您也可以在实验详细信息面板中找到用户名

  4. 点击下一步

  5. 复制下面的密码,然后将其粘贴到欢迎对话框中。

    {{{user_0.password | "<密码>"}}}

    您也可以在实验详细信息面板中找到密码

  6. 点击下一步

    重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭证。 注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
  7. 继续在后续页面中点击以完成相应操作:

    • 接受条款及条件。
    • 由于这是临时账号,请勿添加账号恢复选项或双重验证。
    • 请勿注册免费试用。

片刻之后,系统会在此标签页中打开 Google Cloud 控制台。

注意:如需查看列有 Google Cloud 产品和服务的菜单,请点击左上角的导航菜单“导航菜单”图标

激活 Cloud Shell

Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。

  1. 点击 Google Cloud 控制台顶部的激活 Cloud Shell “激活 Cloud Shell”图标

如果您连接成功,即表示您已通过身份验证,且项目 ID 会被设为您的 Project_ID 。输出内容中有一行说明了此会话的 Project_ID

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

gcloud 是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。

  1. (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
  1. 点击授权

输出:

ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (可选)您可以通过此命令列出项目 ID:
gcloud config list project

输出:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} 注意:如需查看在 Google Cloud 中使用 gcloud 的完整文档,请参阅 gcloud CLI 概览指南

环境设置

在 Cloud Shell 中,为您的项目设置项目 ID 和项目编号。将这两者保存为 PROJECT_IDPROJECT_NUMBER 变量。

export PROJECT_ID=$(gcloud config get-value project) export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \ --format='value(projectNumber)')

启用服务

启用所有必要的服务:

gcloud services enable \ cloudkms.googleapis.com \ cloudbuild.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ artifactregistry.googleapis.com \ containerscanning.googleapis.com \ ondemandscanning.googleapis.com \ binaryauthorization.googleapis.com

任务 1. 创建 Artifact Registry 仓库

在本实验中,您将使用 Artifact Registry 来存储和扫描映像。

  1. 使用以下命令创建仓库:
gcloud artifacts repositories create artifact-scanning-repo \ --repository-format=docker \ --location={{{ project_0.default_region | "REGION" }}} \ --description="Docker repository"
  1. 将 Docker 配置为使用您的 gcloud 凭证访问 Artifact Registry:
gcloud auth configure-docker {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev
  1. 创建并切换到工作目录:
mkdir vuln-scan && cd vuln-scan
  1. 接下来定义一个示例映像。创建一个名为 Dockerfile 的文件,其中包含以下内容:
cat > ./Dockerfile << EOF FROM python:3.8-alpine # App WORKDIR /app COPY . ./ RUN pip3 install Flask==2.1.0 RUN pip3 install gunicorn==20.1.0 RUN pip3 install Werkzeug==2.2.2 CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app EOF
  1. 创建一个名为 main.py 的文件,其中包含以下内容:
cat > ./main.py << EOF import os from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): name = os.environ.get("NAME", "Worlds") return "Hello {}!".format(name) if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080))) EOF
  1. 使用 Cloud Build 构建容器并自动将其推送到 Artifact Registry。
gcloud builds submit . -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

点击检查我的进度以验证是否完成了以下目标: 创建 Artifact Registry 仓库。

任务 2. 映像签名

什么是证明者 (Attestor)

  • 此人/此进程负责系统信任链中的一个环节。
  • 他们持有加密密钥,将为通过审批流程的映像签名。
  • 政策创建者负责从宏观、抽象的角度定义政策,而证明者负责具体执行政策的某些方面。
  • 证明者可能是真人(例如质量保证测试人员或经理),也可能是 CI 系统中的机器人。
  • 系统的安全性取决于证明者的可信度,因此确保其私钥的安全性至关重要。

上述每一个角色都可以由组织中的个人或团队担任。在生产环境中,这些角色可能会由不同的 Google Cloud Platform 项目进行管理,并通过 Cloud IAM 以受限的方式共享项目资源访问权限。

证明者层次结构的运作方式

Binary Authorization 中的证明者基于 Cloud Container Analysis API 实现,因此在深入了解前,有必要先说明该 API 的运作方式。Container Analysis API 旨在让您能够将元数据与特定的容器映像进行关联。

例如,可以创建一个备注来跟踪心脏出血漏洞。随后,安全供应商会创建扫描程序来测试容器映像中是否存在该漏洞,并为每个受漏洞影响的容器创建一个关联的发生实例 (Occurrence)。

208aa5ebc53ff2b3.png

除了跟踪漏洞之外,Container Analysis 还是一个通用的 Metadata API。Binary Authorization 利用 Container Analysis 将签名与其验证的容器映像相关联。Container Analysis 备注代表单个证明者。对于证明者批准的每个容器,系统都会创建相应的发生实例并将其与容器相关联。

Binary Authorization API 使用“证明者”和“证明”的概念,但这些概念都是通过 Container Analysis API 中相应的备注和发生实例实现的。

Container Analysis 流程图

创建证明者备注

证明者备注 (Attestor Note) 本质上是一小段数据,充当所添加签名类型的标签。例如,一个备注可能代表漏洞扫描,而另一个备注可能用于质量保证签核。在签名过程中,系统会引用相应备注。

Container Analysis API 与 Binary Authorization 的关系流程图
  1. 创建备注:
cat > ./vulnz_note.json << EOM { "attestation": { "hint": { "human_readable_name": "Container Vulnerabilities attestation authority" } } } EOM
  1. 存储备注
NOTE_ID=vulnz_note curl -vvv -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ --data-binary @./vulnz_note.json \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
  1. 验证备注
curl -vvv \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"

您的备注现已保存在 Container Analysis API 中。

  1. 创建证明者

证明者负责执行实际的映像签名流程,并将备注的发生实例附加到映像,以供日后验证。若要使用证明者,您还必须向 Binary Authorization 注册该备注:

证明者与备注的发生实例已关联
  1. 创建证明者
ATTESTOR_ID=vulnz-attestor gcloud container binauthz attestors create $ATTESTOR_ID \ --attestation-authority-note=$NOTE_ID \ --attestation-authority-note-project=${PROJECT_ID}
  1. 验证证明者
gcloud container binauthz attestors list

最后一行显示 NUM_PUBLIC_KEYS: 0,您在后续步骤中需要提供密钥。

当您运行构建任务来生成映像时,Cloud Build 会自动在您的项目中创建 built-by-cloud-build 证明者。因此,上述命令会返回两个证明者,即 vulnz-attestorbuilt-by-cloud-build。成功构建映像后,Cloud Build 会自动为其签名并创建相应的证明。

  1. Binary Authorization 服务账号需要拥有查看证明备注的权限。请执行以下 API 调用,为对应的 IAM 角色提供访问权限:
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)") BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com" cat > ./iam_request.json << EOM { 'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}', 'policy': { 'bindings': [ { 'role': 'roles/containeranalysis.notes.occurrences.viewer', 'members': [ 'serviceAccount:${BINAUTHZ_SA_EMAIL}' ] } ] } } EOM
  1. 使用该文件创建 IAM 政策:
curl -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ --data-binary @./iam_request.json \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"

点击检查我的进度以验证是否完成了以下目标: 创建证明者。

任务 3. 添加 KMS 密钥

在您使用此证明者之前,您的授权方需要创建一个加密密钥对,以便为容器映像签名。这可以通过 Google Cloud Key Management Service (KMS) 来完成。

Google Cloud Key Management Service (KMS) 图表
  1. 首先,添加一些环境变量来描述新密钥:
KEY_LOCATION=global KEYRING=binauthz-keys KEY_NAME=codelab-key KEY_VERSION=1
  1. 创建密钥环来保存一组密钥:
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
  1. 为证明者创建新的非对称签名密钥对
gcloud kms keys create "${KEY_NAME}" \ --keyring="${KEYRING}" --location="${KEY_LOCATION}" \ --purpose asymmetric-signing \ --default-algorithm="ec-sign-p256-sha256"

您应该会在 Cloud 控制台的 KMS 页面上看到该密钥。

  1. 现在运行 gcloud binauthz 命令,将该密钥与您的证明者进行关联:
gcloud beta container binauthz attestors public-keys add \ --attestor="${ATTESTOR_ID}" \ --keyversion-project="${PROJECT_ID}" \ --keyversion-location="${KEY_LOCATION}" \ --keyversion-keyring="${KEYRING}" \ --keyversion-key="${KEY_NAME}" \ --keyversion="${KEY_VERSION}"
  1. 如果您再次输出授权方列表,现在应该会看到已注册的密钥:
gcloud container binauthz attestors list

点击检查我的进度以验证是否完成了以下目标: 添加 KMS 密钥。

任务 4. 创建签名证明

至此,您已配置好了为映像进行签名所必需的各项功能。现在,请使用您之前创建的证明者,为您一直在处理的容器映像进行签名。

展示证明与发生实例之间的关系的 KMS 图表

证明必须包含加密签名,以表明证明者已验证了特定容器映像,并且该映像可以在您的集群上安全运行。

  1. 如需指定要证明的容器映像,请运行以下命令来确定其摘要:
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \ --format='get(image_summary.digest)')
  1. 现在,您可以使用 gcloud 来创建证明。该命令需要输入您要用于签名的密钥的详细信息,以及您要批准的特定容器映像:
gcloud beta container binauthz attestations sign-and-create \ --artifact-url="${CONTAINER_PATH}@${DIGEST}" \ --attestor="${ATTESTOR_ID}" \ --attestor-project="${PROJECT_ID}" \ --keyversion-project="${PROJECT_ID}" \ --keyversion-location="${KEY_LOCATION}" \ --keyversion-keyring="${KEYRING}" \ --keyversion-key="${KEY_NAME}" \ --keyversion="${KEY_VERSION}"

按照 Container Analysis 的术语,这将创建一个新的发生实例,并将其附加到证明者的备注。

  1. 为确保一切运作都符合预期,请运行以下命令来列出您的证明:
gcloud container binauthz attestations list \ --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

任务 5. 准入控制政策

Binary Authorization 是 GKE 和 Cloud Run 中的一项功能,用于在容器映像获准运行之前对其进行规则验证。无论请求是来自受信任的 CI/CD 流水线,还是来自用户的手动部署尝试,该验证机制会对每一项运行映像的请求执行验证。相比仅进行 CI/CD 流水线检查,此功能可让您更有效地保护运行时环境。

为了解此功能,您需要修改默认的 GKE 政策,以强制执行严格的授权规则。

  1. 创建已启用 Binary Authorization 的 GKE 集群:
gcloud beta container clusters create binauthz \ --zone {{{ project_0.default_zone | "ZONE" }}} \ --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
  1. 允许 Cloud Build 部署到此集群:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/container.developer"

“全部允许”政策

首先,验证默认政策状态以及您部署任何映像的能力

  1. 查看现有政策:
gcloud container binauthz policy export
  1. 请注意,强制执行政策已设置为 ALWAYS_ALLOW

evaluationMode: ALWAYS_ALLOW

  1. 部署示例映像,以验证您可以部署任何映像:
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. 验证部署是否成功:
kubectl get pods

您将看到以下输出内容:

hello-server 的状态为“运行中”
  1. 删除部署:
kubectl delete pod hello-server

“全部拒绝”政策

现在,将政策更新为禁止所有映像。

  1. 将当前政策导出到可修改的文件:
gcloud container binauthz policy export > policy.yaml
  1. 在文本编辑器中,打开 policy.yaml' 文件并将 evaluationMode 由 `ALWAYS_ALLOW 更改为 ALWAYS_DENY
edit policy.yaml

确保修改后的 YAML 格式政策文件如下所示:

globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy

此政策相对简单。globalPolicyEvaluationMode 行声明该政策会继承 Google 定义的全局政策。因此,所有官方 GKE 容器在默认情况下都能运行。此外,该政策还声明了 defaultAdmissionRule,规定所有其他 Pod 都将被拒绝。该准入规则包含一个 enforcementMode 行,规定所有不符合此规则的 Pod 都会被屏蔽,并禁止在集群上运行。

如需了解如何构建更复杂的政策,请参阅 Binary Authorization 文档

流程图:Binary Authorization 政策仅允许指定的容器
  1. 在 Cloud Shell 中运行以下命令,以应用新政策:
gcloud container binauthz policy import policy.yaml

等待几秒钟,以便更改生效。

  1. 尝试部署示例工作负载:
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. 部署失败,并显示以下消息:
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule

将政策还原为“全部允许”

在继续学习下一部分之前,请先还原对政策所做的更改。

  1. 在文本编辑器中,将 evaluationModeALWAYS_DENY 更改为 ALWAYS_ALLOW
edit policy.yaml

修改后的 YAML 格式政策文件应如下所示:

globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
  1. 应用还原后的政策:
gcloud container binauthz policy import policy.yaml

点击检查我的进度以验证是否完成了以下目标: 创建 GKE 集群并更新政策。

任务 6. 自动为映像签名

您已经启用了映像签名功能,并手动使用证明者为您的示例映像进行了签名。但在实践中,您可能希望在 CI/CD 流水线等自动化流程中应用证明。

在本部分中,您将配置 Cloud Build 以实现自动为映像进行证明。

所需角色

  1. 将 Binary Authorization Attestor Viewer 角色添加到 Cloud Build 服务账号:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/binaryauthorization.attestorsViewer
  1. 将 Cloud KMS CryptoKey Signer/Verifier 角色添加到 Cloud Build 服务账号(基于 KMS 的签名):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/cloudkms.signerVerifier gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \ --role roles/cloudkms.signerVerifier
  1. 将 Container Analysis Notes Attacher 角色添加到 Cloud Build 服务账号:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/containeranalysis.notes.attacher

为 Cloud Build 服务账号提供访问权限

Cloud Build 需要拥有访问 On-Demand Scanning API 的权限。

  • 使用以下命令授予访问权限:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/ondemandscanning.admin"

准备 Cloud Build 自定义构建步骤

在 Cloud Build 中,您将使用自定义构建步骤来简化证明流程。Google 提供了此自定义构建步骤,其中包含一些辅助函数,可用于简化流程。在使用前,必须将自定义构建步骤的代码构建到容器中,并推送到 Cloud Build。

  • 为此,请运行以下命令:
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git cd cloud-builders-community/binauthz-attestation gcloud builds submit . --config cloudbuild.yaml cd ../.. rm -rf cloud-builders-community

向您的 cloudbuild.yaml 中添加签名步骤

将证明步骤添加到 Cloud Build 流水线中。

  1. 查看下方的签名步骤。

仅供查看,请勿复制

#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
  1. 编写一个 cloudbuild.yaml 文件,并在其中包含以下完整流水线:
cat > ./cloudbuild.yaml << EOF steps: # build - id: "build" name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.'] waitFor: ['-'] # additional CICD checks (not shown) #Retag - id: "retag" name: 'gcr.io/cloud-builders/docker' args: ['tag', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'] #pushing to artifact registry - id: "push" name: 'gcr.io/cloud-builders/docker' args: ['push', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'] #Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION' images: - {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good EOF
  1. 运行构建:
gcloud builds submit

在 Cloud Build 历史记录中查看构建记录

在 Cloud 控制台中,前往 Cloud Build > 构建记录页面,查看最新构建记录,并确认各构建步骤均已成功执行。

点击检查我的进度以验证是否完成了以下目标: 添加签名步骤。

任务 7. 授权已签名的映像

现在,您将更新 GKE,使其在允许映像运行之前,使用 Binary Authorization 来验证映像是否具有来自漏洞扫描的签名。

Binary Authorization 验证可信和不可信的映像

更新 GKE 政策以要求进行证明

向您的 GKE BinAuth 政策中添加 clusterAdmissionRules,要求映像必须由您的证明者签名。

目前,您的集群正在运行一项仅包含一条规则的政策:允许来自官方仓库的容器,拒绝所有其他容器。

  1. 运行以下命令,使用更新后的配置覆盖原有政策:
COMPUTE_ZONE={{{ project_0.default_region | "REGION" }}} cat > binauth_policy.yaml << EOM defaultAdmissionRule: enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG evaluationMode: REQUIRE_ATTESTATION requireAttestationsBy: - projects/${PROJECT_ID}/attestors/vulnz-attestor globalPolicyEvaluationMode: ENABLE clusterAdmissionRules: ${COMPUTE_ZONE}.binauthz: evaluationMode: REQUIRE_ATTESTATION enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG requireAttestationsBy: - projects/${PROJECT_ID}/attestors/vulnz-attestor EOM
  1. 现在,您的磁盘上应该有了一个名为 updated_policy.yaml 的新文件。并且,该政策的规则不再是默认拒绝所有映像,而是先检查其是否由您的证明者进行了验证。
除允许的容器外,经证明者签名的容器也获准运行
  1. 将新政策上传到 Binary Authorization:
gcloud beta container binauthz policy import binauth_policy.yaml

部署已签名的映像

  1. 获取优质映像的映像摘要:
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \ --format='get(image_summary.digest)')
  1. 在 Kubernetes 配置中使用该摘要:
cat > deploy.yaml << EOM apiVersion: v1 kind: Service metadata: name: deb-httpd spec: selector: app: deb-httpd ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: deb-httpd spec: replicas: 1 selector: matchLabels: app: deb-httpd template: metadata: labels: app: deb-httpd spec: containers: - name: deb-httpd image: ${CONTAINER_PATH}@${DIGEST} ports: - containerPort: 8080 env: - name: PORT value: "8080" EOM
  1. 将应用部署到 GKE
kubectl apply -f deploy.yaml

在 Cloud 控制台中,前往 Kubernetes Engine > 工作负载,然后查看映像是否已成功部署。

点击检查我的进度以验证是否完成了以下目标: 部署已签名的映像。

任务 8. 屏蔽未签名的映像

构建映像

  1. 使用本地 Docker 将映像构建到本地缓存中:
docker build -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .
  1. 将未签名的映像推送到仓库:
docker push {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
  1. 获取不良映像的映像摘要:
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \ --format='get(image_summary.digest)')
  1. 在 Kubernetes 配置中使用该摘要:
cat > deploy.yaml << EOM apiVersion: v1 kind: Service metadata: name: deb-httpd spec: selector: app: deb-httpd ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: deb-httpd spec: replicas: 1 selector: matchLabels: app: deb-httpd template: metadata: labels: app: deb-httpd spec: containers: - name: deb-httpd image: ${CONTAINER_PATH}@${DIGEST} ports: - containerPort: 8080 env: - name: PORT value: "8080" EOM
  1. 尝试将应用部署到 GKE
kubectl apply -f deploy.yaml

在控制台中查看工作负载,并记下指出部署被拒绝的错误:

No attestations found that were valid and signed by a key trusted by the attestor

点击检查我的进度以验证是否完成了以下目标: 部署未签名的映像。

恭喜!

您已了解如何创建证明者来为映像签名,从而在容器映像获准运行之前对其进行规则验证。另外还了解了如何编写政策,以告知 Cloud Build 是允许还是拒绝访问 GKE 集群。您还结合使用 Binary Authorization 与 Google Cloud KMS 验证了映像签名,并防止未签名的映像进入 Kubernetes 集群。

后续步骤/了解详情

Google Cloud 培训和认证

…可帮助您充分利用 Google Cloud 技术。我们的课程会讲解各项技能与最佳实践,可帮助您迅速上手使用并继续学习更深入的知识。我们提供从基础到高级的全方位培训,并有点播、直播和虚拟三种方式选择,让您可以按照自己的日程安排学习时间。各项认证可以帮助您核实并证明您在 Google Cloud 技术方面的技能与专业知识。

上次更新手册的时间:2024 年 9 月 10 日

上次测试实验的时间:2024 年 7 月 11 日

版权所有 2024 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名称和产品名称可能是其各自相关公司的商标。

准备工作

  1. 实验会创建一个 Google Cloud 项目和一些资源,供您使用限定的一段时间
  2. 实验有时间限制,并且没有暂停功能。如果您中途结束实验,则必须重新开始。
  3. 在屏幕左上角,点击开始实验即可开始

使用无痕浏览模式

  1. 复制系统为实验提供的用户名密码
  2. 在无痕浏览模式下,点击打开控制台

登录控制台

  1. 使用您的实验凭证登录。使用其他凭证可能会导致错误或产生费用。
  2. 接受条款,并跳过恢复资源页面
  3. 除非您已完成此实验或想要重新开始,否则请勿点击结束实验,因为点击后系统会清除您的工作并移除该项目

此内容目前不可用

一旦可用,我们会通过电子邮件告知您

太好了!

一旦可用,我们会通过电子邮件告知您

一次一个实验

确认结束所有现有实验并开始此实验

使用无痕浏览模式运行实验

Using an Incognito or private browser window is the best way to run this lab. This prevents any conflicts between your personal account and the Student account, which may cause extra charges incurred to your personal account.