GSP1183

概览
Binary Authorization 是一种部署时安全控制措施,可确保在 Google Kubernetes Engine (GKE) 或 Cloud Run 上仅部署可信的容器映像。借助 Binary Authorization,您可以要求在开发过程中由可信授权方对映像进行签名,然后在部署时强制执行签名验证。通过强制执行验证,您可以确保仅将经过验证的映像集成到构建和发布流程中,从而对容器环境实施更严格的控制。
下图显示了 Binary Authorization/Cloud Build 设置中的组件:
Cloud Build 流水线,用于创建 Binary Authorization 证明。
此流水线的具体步骤如下:
- 首先,系统将用于构建容器映像的代码推送到源代码库,例如 Cloud Source Repositories。
- 持续集成 (CI) 工具 Cloud Build 构建并测试容器。
- 构建流程将容器映像推送到 Container Registry 或其他存储已构建映像的注册表。
-
Cloud Key Management Service 对加密密钥对进行密钥管理,并为容器映像签名。然后,生成的签名将存储在新创建的证明中。
- 在部署时,证明者使用密钥对中的公钥来验证证明。Binary Authorization 强制执行政策,要求必须具有已签名的证明才能部署容器映像。
在本实验中,您将学习如何使用各种工具和技术来保护已部署的制品。本实验重点关注已完成创建、但尚未部署到任何特定环境的制品(容器)。
学习内容
- 映像签名
- 准入控制政策
- 为扫描的映像签名
- 授权已签名的映像
- 屏蔽未签名的映像
设置和要求
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。
此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。我们会为您提供新的临时凭证,让您可以在实验规定的时间内用来登录和访问 Google Cloud。
为完成此实验,您需要:
- 能够使用标准的网络浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
- 有充足时间完成实验 - 请注意,实验开始后无法暂停。
注意:如果您已有自己的个人 Google Cloud 账号或项目,请不要在此实验中使用,以避免您的账号产生额外的费用。
如何开始实验并登录 Google Cloud 控制台
-
点击开始实验按钮。如果该实验需要付费,系统会打开一个弹出式窗口供您选择付款方式。左侧是实验详细信息面板,其中包含以下各项:
-
打开 Google Cloud 控制台按钮
- 剩余时间
- 进行该实验时必须使用的临时凭证
- 帮助您逐步完成本实验所需的其他信息(如果需要)
-
点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。
该实验会启动资源并打开另一个标签页,显示登录页面。
提示:将这些标签页安排在不同的窗口中,并排显示。
注意:如果您看见选择账号对话框,请点击使用其他账号。
-
如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。
{{{user_0.username | "<用户名>"}}}
您也可以在实验详细信息面板中找到用户名。
-
点击下一步。
-
复制下面的密码,然后将其粘贴到欢迎对话框中。
{{{user_0.password | "<密码>"}}}
您也可以在实验详细信息面板中找到密码。
-
点击下一步。
重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭证。
注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
-
继续在后续页面中点击以完成相应操作:
- 接受条款及条件。
- 由于这是临时账号,请勿添加账号恢复选项或双重验证。
- 请勿注册免费试用。
片刻之后,系统会在此标签页中打开 Google Cloud 控制台。
注意:如需查看列有 Google Cloud 产品和服务的菜单,请点击左上角的导航菜单。
激活 Cloud Shell
Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。
- 点击 Google Cloud 控制台顶部的激活 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 自动补全功能。
- (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
- 点击授权。
输出:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (可选)您可以通过此命令列出项目 ID:
gcloud config list project
输出:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注意:如需查看在 Google Cloud 中使用 gcloud 的完整文档,请参阅 gcloud CLI 概览指南。
环境设置
在 Cloud Shell 中,为您的项目设置项目 ID 和项目编号。将这两者保存为 PROJECT_ID 和 PROJECT_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 来存储和扫描映像。
- 使用以下命令创建仓库:
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location={{{ project_0.default_region | "REGION" }}} \
--description="Docker repository"
- 将 Docker 配置为使用您的 gcloud 凭证访问 Artifact Registry:
gcloud auth configure-docker {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev
- 创建并切换到工作目录:
mkdir vuln-scan && cd vuln-scan
- 接下来定义一个示例映像。创建一个名为
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
- 创建一个名为
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
- 使用 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)。
除了跟踪漏洞之外,Container Analysis 还是一个通用的 Metadata API。Binary Authorization 利用 Container Analysis 将签名与其验证的容器映像相关联。Container Analysis 备注代表单个证明者。对于证明者批准的每个容器,系统都会创建相应的发生实例并将其与容器相关联。
Binary Authorization API 使用“证明者”和“证明”的概念,但这些概念都是通过 Container Analysis API 中相应的备注和发生实例实现的。
创建证明者备注
证明者备注 (Attestor Note) 本质上是一小段数据,充当所添加签名类型的标签。例如,一个备注可能代表漏洞扫描,而另一个备注可能用于质量保证签核。在签名过程中,系统会引用相应备注。
- 创建备注:
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
- 存储备注
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}"
- 验证备注
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
您的备注现已保存在 Container Analysis API 中。
- 创建证明者
证明者负责执行实际的映像签名流程,并将备注的发生实例附加到映像,以供日后验证。若要使用证明者,您还必须向 Binary Authorization 注册该备注:
- 创建证明者
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
- 验证证明者
gcloud container binauthz attestors list
最后一行显示 NUM_PUBLIC_KEYS: 0,您在后续步骤中需要提供密钥。
当您运行构建任务来生成映像时,Cloud Build 会自动在您的项目中创建 built-by-cloud-build 证明者。因此,上述命令会返回两个证明者,即 vulnz-attestor 和 built-by-cloud-build。成功构建映像后,Cloud Build 会自动为其签名并创建相应的证明。
-
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
- 使用该文件创建 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) 来完成。
- 首先,添加一些环境变量来描述新密钥:
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
- 创建密钥环来保存一组密钥:
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
- 为证明者创建新的非对称签名密钥对
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
您应该会在 Cloud 控制台的 KMS 页面上看到该密钥。
- 现在运行 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}"
- 如果您再次输出授权方列表,现在应该会看到已注册的密钥:
gcloud container binauthz attestors list
点击检查我的进度以验证是否完成了以下目标:
添加 KMS 密钥。
任务 4. 创建签名证明
至此,您已配置好了为映像进行签名所必需的各项功能。现在,请使用您之前创建的证明者,为您一直在处理的容器映像进行签名。

证明必须包含加密签名,以表明证明者已验证了特定容器映像,并且该映像可以在您的集群上安全运行。
- 如需指定要证明的容器映像,请运行以下命令来确定其摘要:
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)')
- 现在,您可以使用 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 的术语,这将创建一个新的发生实例,并将其附加到证明者的备注。
- 为确保一切运作都符合预期,请运行以下命令来列出您的证明:
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
任务 5. 准入控制政策
Binary Authorization 是 GKE 和 Cloud Run 中的一项功能,用于在容器映像获准运行之前对其进行规则验证。无论请求是来自受信任的 CI/CD 流水线,还是来自用户的手动部署尝试,该验证机制会对每一项运行映像的请求执行验证。相比仅进行 CI/CD 流水线检查,此功能可让您更有效地保护运行时环境。
为了解此功能,您需要修改默认的 GKE 政策,以强制执行严格的授权规则。
- 创建已启用 Binary Authorization 的 GKE 集群:
gcloud beta container clusters create binauthz \
--zone {{{ project_0.default_zone | "ZONE" }}} \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
- 允许 Cloud Build 部署到此集群:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
“全部允许”政策
首先,验证默认政策状态以及您部署任何映像的能力
- 查看现有政策:
gcloud container binauthz policy export
- 请注意,强制执行政策已设置为
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- 部署示例映像,以验证您可以部署任何映像:
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- 验证部署是否成功:
kubectl get pods
您将看到以下输出内容:
- 删除部署:
kubectl delete pod hello-server
“全部拒绝”政策
现在,将政策更新为禁止所有映像。
- 将当前政策导出到可修改的文件:
gcloud container binauthz policy export > policy.yaml
- 在文本编辑器中,打开
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 文档。
- 在 Cloud Shell 中运行以下命令,以应用新政策:
gcloud container binauthz policy import policy.yaml
等待几秒钟,以便更改生效。
- 尝试部署示例工作负载:
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- 部署失败,并显示以下消息:
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
将政策还原为“全部允许”
在继续学习下一部分之前,请先还原对政策所做的更改。
- 在文本编辑器中,将
evaluationMode 从 ALWAYS_DENY 更改为 ALWAYS_ALLOW。
edit policy.yaml
修改后的 YAML 格式政策文件应如下所示:
globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
evaluationMode: ALWAYS_ALLOW
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
- 应用还原后的政策:
gcloud container binauthz policy import policy.yaml
点击检查我的进度以验证是否完成了以下目标:
创建 GKE 集群并更新政策。
任务 6. 自动为映像签名
您已经启用了映像签名功能,并手动使用证明者为您的示例映像进行了签名。但在实践中,您可能希望在 CI/CD 流水线等自动化流程中应用证明。
在本部分中,您将配置 Cloud Build 以实现自动为映像进行证明。
所需角色
- 将 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
- 将 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
- 将 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 流水线中。
- 查看下方的签名步骤。
仅供查看,请勿复制
#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'
- 编写一个
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
- 运行构建:
gcloud builds submit
在 Cloud Build 历史记录中查看构建记录
在 Cloud 控制台中,前往 Cloud Build > 构建记录页面,查看最新构建记录,并确认各构建步骤均已成功执行。
点击检查我的进度以验证是否完成了以下目标:
添加签名步骤。
任务 7. 授权已签名的映像
现在,您将更新 GKE,使其在允许映像运行之前,使用 Binary Authorization 来验证映像是否具有来自漏洞扫描的签名。
更新 GKE 政策以要求进行证明
向您的 GKE BinAuth 政策中添加 clusterAdmissionRules,要求映像必须由您的证明者签名。
目前,您的集群正在运行一项仅包含一条规则的政策:允许来自官方仓库的容器,拒绝所有其他容器。
- 运行以下命令,使用更新后的配置覆盖原有政策:
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
- 现在,您的磁盘上应该有了一个名为
updated_policy.yaml 的新文件。并且,该政策的规则不再是默认拒绝所有映像,而是先检查其是否由您的证明者进行了验证。
- 将新政策上传到 Binary Authorization:
gcloud beta container binauthz policy import binauth_policy.yaml
部署已签名的映像
- 获取优质映像的映像摘要:
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)')
- 在 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
- 将应用部署到 GKE
kubectl apply -f deploy.yaml
在 Cloud 控制台中,前往 Kubernetes Engine > 工作负载,然后查看映像是否已成功部署。
点击检查我的进度以验证是否完成了以下目标:
部署已签名的映像。
任务 8. 屏蔽未签名的映像
构建映像
- 使用本地 Docker 将映像构建到本地缓存中:
docker build -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .
- 将未签名的映像推送到仓库:
docker push {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
- 获取不良映像的映像摘要:
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)')
- 在 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
- 尝试将应用部署到 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 的商标。其他所有公司名称和产品名称可能是其各自相关公司的商标。