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

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,看看是否可用。完成此步骤后便无法更改该 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 配置为在访问 Artifact Registry 时使用 gcloud 凭据。

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. 图片签名

什么是证明者

证明者

  • 此人/进程负责系统信任链中的一个链接。
  • 他们持有加密密钥,并在图片通过审批流程后签署图片。
  • 虽然政策创建者是以概括、抽象的方式确定政策,但证明者负责具体强制执行政策的某些方面。
  • 可能是真人(如 QA 测试人员或经理),也可能是 CI 系统中的聊天机器人。
  • 系统的安全性取决于其可信度,因此确保私钥的安全非常重要。

这些角色中的每一个都可以代表个人或组织中的一组人员。在生产环境中,这些角色可能由单独的 Google Cloud Platform (GCP) 项目管理,并且他们将使用 Cloud IAM 以有限的方式在它们之间共享资源访问权限。

a37eb2ed54b9c2eb.png

Binary Authorization 中的证明者在 Cloud Container Analysis API 之上实现,因此请务必先介绍其工作原理,然后再进行说明。Container Analysis API 旨在允许您将元数据与特定容器映像相关联。

例如,系统可能会创建一条备注来跟踪“心脏出血”漏洞。然后,安全供应商会创建扫描程序来测试容器映像是否存在漏洞,并创建一个与每个受损容器关联的发生实例。

208aa5ebc53ff2b3

除了跟踪漏洞外,Container Analysis 还被设计为一个通用元数据 API。Binary Authorization 利用 Container Analysis,将签名与其正在验证的容器映像相关联**。**容器分析备注用于表示单个证明者,系统会创建出现次数并将其与证明者批准的每个容器相关联。

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

63a701bd0057ea17

创建证明者备注

证明者备注只是一小段数据,用作所应用的签名类型的标签。例如,一条备注可能表示漏洞扫描,另一条可能用于 QA 签核。签名过程中会引用该备注。

919f997db0ffb881

创建记事

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 调用提供访问权限

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

在使用此证明者之前,您的授权机构需要创建可用于对容器映像进行签名的加密密钥对。这可以通过 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

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

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

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

拒绝所有政策

现在,更新该政策以禁止发布所有映像。

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

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

  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. 更改政策

在文本编辑器中,将 AssessmentMode 从 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 需要有权访问按需扫描 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 政策以要求提供证明

通过将 clusterAdmissionRules 添加到 GKE BinAuth 政策中,要求证明者对映像进行签名

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

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

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

将新政策上传到 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 日