使用二进制身份验证控制部署

1. 简介

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

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

Cloud Build/Binary Authorization 证明流水线。**图 1.**用于创建 Binary Authorization 证明的 Cloud Build 流水线。

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

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

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

学习内容

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

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 项目名称 是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时更新它。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您可以尝试自己创建一个,并确认是否可用。此步骤完成后,项目 ID 便无法更改,并且在整个项目期间都将保持不变。
  • 此外,还有第三个值,即部分 API 使用的项目编号 ,供您参考。如需详细了解所有这三个值,请参阅 文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用 计划的条件。

环境设置

在 Cloud Shell 中,为您的项目设置项目 ID 和项目编号。将它们另存为 PROJECT_IDPROJECT_ID 变量。

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 

创建 Artifact Registry 仓库

在本实验中,您将使用 Artifact Registry 来存储和扫描映像。使用以下命令创建仓库。

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

将 Docker 配置为使用您的 gcloud 凭据访问 Artifact Registry。

gcloud auth configure-docker us-central1-docker.pkg.dev

创建并切换到工作目录

mkdir vuln-scan && cd vuln-scan

定义示例映像

创建一个名为 Dockerfile 且包含以下内容的文件。

cat > ./Dockerfile << EOF
from python:3.8-slim  

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0

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

构建映像并将其推送到 AR

使用 Cloud Build 构建容器并自动将其推送到 Artifact Registry。

gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

3. 映像签名

什么是证明者

证明者

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

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

a37eb2ed54b9c2eb.png

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 中相应的备注和发生实例实现的。

63a701bd0057ea17.png

创建证明者备注

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

919f997db0ffb881.png

创建记事

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 注册该备注:

ed05d438c79b654d.png

创建证明者

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-attestorbuilt-by-cloud-build。成功构建映像后,Cloud Build 会自动为其签名并创建相应的证明。

添加 IAM 角色

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"

添加 KMS 密钥

1e3af7c177f7a311.png

在您使用此证明者之前,您的授权方需要创建一个加密密钥对,以便为容器映像签名。这可以通过 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"

您应该会在 Google 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

创建签名证明

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

858d7e6feeb6f159.png

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

CONTAINER_PATH=us-central1-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}

4. 准入控制政策

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

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

创建 GKE 集群

创建已启用 Binary Authorization 的 GKE 集群:

gcloud beta container clusters create binauthz \
    --zone us-central1-a  \
    --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"

“全部允许”政策

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

  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

您将看到以下输出内容

161db370d99ffb13.png

  1. 删除部署
kubectl delete pod hello-server

“全部拒绝”政策

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

  1. 将当前政策导出到可修改的文件
gcloud container binauthz policy export  > policy.yaml
  1. 更改政策

在文本编辑器中,将 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 文档

657752497e59378c.png

  1. 打开终端并应用新政策,然后等待几秒钟,以便更改生效
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. 更改政策

在文本编辑器中,将 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
  1. 应用还原后的政策
gcloud container binauthz policy import policy.yaml

5. 为扫描的映像签名

您已经启用了映像签名功能,并手动使用证明者为您的示例映像进行了签名。但在实践中,您可能希望在 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

将 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'
    - 'us-central1-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', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-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',  'us-central1-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'
    - 'us-central1-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:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF

运行构建

gcloud builds submit

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

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

6. 授权已签名的映像

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

d5c41bb89e22fd61.png

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

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

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

运行以下命令,使用更新后的配置覆盖原有政策。

COMPUTE_ZONE=us-central1-a

cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  evaluationMode: ALWAYS_DENY
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 的新文件。并且,该政策的规则不再是默认拒绝所有映像,而是先检查其是否由您的证明者进行了验证。

822240fc0b02408e.png

将新政策上传到 Binary Authorization:

gcloud beta container binauthz policy import binauth_policy.yaml

部署已签名的映像

获取优质映像的映像摘要

CONTAINER_PATH=us-central1-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

在控制台中查看 工作负载,并记下映像是否已成功部署。

7. 屏蔽未签名的映像

构建映像

在此步骤中,您将使用本地 Docker 将映像构建到本地缓存中。

docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .

将未签名的映像推送到仓库

docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad

获取不良映像的映像摘要

CONTAINER_PATH=us-central1-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

8. 恭喜!

恭喜,您已完成此 Codelab!

所学内容:

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

后续步骤:

清理

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

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。

上次更新时间:2023 年 3 月 21 日