在 Kubernetes 清单中使用容器映像摘要

Last reviewed 2023-07-21 UTC

本教程向将容器部署到 Kubernetes 的开发者和运维人员介绍了如何使用容器映像摘要来识别容器映像。容器映像摘要是唯一且不可改变地标识容器映像。

与使用映像标记相比,使用映像摘要部署容器映像有诸多好处。如需详细了解映像摘要,请参阅使用容器映像摘要的随附文档,然后再继续本教程。

Kubernetes pod 规范中的容器的 image 参数接受包含摘要的映像。此参数适用于所有使用 Pod 规范的位置,例如 Deployment、StatefulSet、DaemonSet、ReplicaSet、CronJob 和 Job 资源的 template 部分。

如需使用摘要部署映像,请使用映像名称,后跟 @sha256: 和摘要值。以下是使用包含摘要的映像的 Deployment 资源示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deployment
spec:
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        ports:
        - containerPort: 8080

使用映像摘要的一个缺点是,在将映像发布到注册表之前,您不知道摘要值。构建新映像时,摘要值会发生变化,您需要在每次部署时更新 Kubernetes 清单。

本教程介绍了如何使用 Skaffoldkptdigesterkustomizegke-deployko 等工具在清单中使用映像摘要。

建议

本文档介绍了几种在 Kubernetes 部署中使用映像摘要的方法。本文档中介绍的工具互为补充。例如,您可以结合使用 kpt 函数的输出和 kustomize 来为不同环境创建变体。Skaffold 可以使用 ko 构建映像,并使用 kubectl 或 kpt 将映像部署到 Kubernetes 集群。

这些工具互为补充的原因是它们根据 Kubernetes 资源模型 (KRM) 执行结构化修改。此模型使工具成为可插入工具,您可以改进这些工具的用途,创建可帮助您部署应用和服务的流程和流水线。

首先,我们建议您使用最适合您的现有工具和流程的方法:

  • Skaffold 可以向映像引用添加摘要。您只需进行细微的配置更改即可启用此功能。采用 Skaffold 具有额外优势,例如总结不同的工具构建和部署容器映像的方式。

  • 通过使用 digester 工具作为 Kubernetes 集群中的可变准入网络钩子,您可以向所有部署添加摘要,同时将对构建和部署容器映像的当前流程的影响降至最低。Digester 网络钩子也简化了 Binary Authorization 的采用,因为它只需要将标签添加到命名空间。

  • 如果您需要灵活的工具来处理 Kubernetes 清单,kpt 不失为一种很不错的选择。Digester 工具可以在 kpt 流水线中用作客户端 KRM 函数

  • 如果您已使用 kustomize 跨环境管理 Kubernetes 清单,我们建议您利用其映像转换器以摘要的形式部署映像。

  • ko 是构建和发布 Go 应用映像的好方法,它可用于 KnativeTektonsigstore 等开源项目。

如果您没有使用本文档中所述的任何工具,我们建议您从 Skaffold 和 digester 网络钩子开始。Skaffold 是开发者和发布团队使用的常用工具,与本教程中所述的其他工具集成。随着需求的变化,您可以利用这些集成选项。Digester Kubernetes webhook 通过为整个集群启用基于摘要的部署来补充 Skaffold。

目标

  • 使用 Skaffold 构建和推送映像,并在 Kubernetes 清单中插入映像名称和摘要。
  • 使用 digester 客户端函数和可变准入网络钩子,将摘要添加到 Kubernetes Pod 和 Pod 模板中的映像。
  • 使用 kpt setter 将 Kubernetes 清单中的映像标记替换为映像摘要。
  • 使用 kustomize 生成带有映像摘要的 Kubernetes 清单。
  • 使用 gke-deploy 将映像标记解析为 Kubernetes 清单中的摘要。
  • 使用 ko 构建和推送映像,并在 Kubernetes 清单中插入映像名称和摘要。

费用

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

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

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

须知事项

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  3. 启用 Artifact Registry API。

    启用 API

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  5. 在 Cloud Shell 中,设置 Google Cloud CLI 的默认项目:

    gcloud config set project PROJECT_ID
    

    PROJECT_ID 替换为您的[项目 ID]。

  6. 在 Artifact Registry 中创建容器映像制品库:

    gcloud artifacts repositories create REPOSITORY \
        --location=LOCATION \
        --repository-format=docker
    

    替换以下内容:

    • REPOSITORY:您要用于制品库的名称,例如 digest-tutorial
    • LOCATIONArtifact Registry 位置,例如 us-central1
  7. 为本教程中使用的 CLI 工具配置对 Artifact Registry 位置的身份验证:

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    

使用 Skaffold

Skaffold 是一种命令行工具,用于持续开发应用并将应用持续部署到 Kubernetes 集群。

使用 Skaffold 构建映像,将映像推送到 Artifact Registry,然后将 Kubernetes 清单模板中的 image 占位值替换为推送映像的名称、标记和摘要:

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/skaffold
    cd ~/container-image-digests-tutorial/skaffold
    
  2. 克隆 Skaffold Git 代码库:

    git clone https://github.com/GoogleContainerTools/skaffold.git
    
  3. 转到 getting-started 示例的目录:

    cd skaffold/examples/getting-started
    
  4. 查看与您的 Skaffold 版本匹配的 Git 标记:

    git checkout $(skaffold version)
    
  5. 查看 skaffold.yaml 配置文件:

    cat skaffold.yaml
    

    该文件类似于以下内容:

    apiVersion: skaffold/v4beta6
    kind: Config
    build:
      artifacts:
      - image: skaffold-example
    manifests:
      rawYaml:
      - k8s-pod.yaml
    

    build.artifacts 部分包含占位符映像名称。Skaffold 会在输入清单文件中查找此占位符。

    manifests 部分指示 Skaffold 读取当前目录中名为 k8s-pod.yaml 的输入清单。

    如需大致了解所有可用选项,请参阅 skaffold.yaml 参考文档

  6. 查看 Kubernetes 清单模板:

    cat k8s-pod.yaml
    

    该文件如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - name: getting-started
        image: skaffold-example
    

    image 字段中的 skaffold-example 占位值与 skaffold.yaml 文件中的 image 字段的值匹配。Skaffold 会在渲染的输出中将此占位值替换为完整的映像名称和摘要。

  7. 构建映像并将其推送到 Artifact Registry:

    skaffold build \
        --default-repo=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY \
        --file-output=artifacts.json \
        --interactive=false \
        --push=true \
        --update-check=false
    

    此命令使用以下标志:

    • --file-output 标志指定 Skaffold 用于保存有关构建映像的信息(包括摘要值)的文件。
    • --push 标志指示 Skaffold 将构建的映像推送到由 --default-repo 标志指定的容器映像注册表。
    • --interactive--update-check 标志均设置为 false。在非交互式环境(如构建流水线)中,将这些标志设置为 false;对于本地开发,请将这些标志保留为默认值(两个标志均为 true)。

    如果您使用 Cloud Deploy 部署到 GKE,请在创建版本时使用 --file-output 标志中的文件作为 --build-artifacts 标志的值。

  8. 使用上一步中的容器映像的名称、标记和摘要渲染展开的 Kubernetes 清单:

    skaffold render \
        --build-artifacts=artifacts.json \
        --digest-source=none \
        --interactive=false \
        --offline=true \
        --output=rendered.yaml \
        --update-check=false
    

    此命令使用以下标志:

    • --build-artifacts 标志引用上一步中 skaffold build 命令的输出文件。
    • --digest-source=none 标志表示 Skaffold 使用 --build-artifacts 标志提供的文件中的摘要值,而不是解析容器映像注册表中的摘要。
    • --offline=true 标志表示您可以在无需访问 Kubernetes 集群的情况下运行该命令。
    • --output 标志指定渲染的清单的输出文件。
  9. 查看呈现的清单:

    cat rendered.yaml
    

    输出类似以下内容:

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - image: LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/skaffold-example:TAG@sha256:DIGEST
        name: getting-started
    

    在此输出中,您会看到以下值:

    • TAG:Skaffold 分配给映像的标记。
    • DIGEST:映像摘要值

使用 digester

Digester 向 Kubernetes Pod 和 Pod 模板规范中的容器和 init 容器映像添加摘要。Digester 会替换使用标记的容器映像引用:

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10

对于使用映像摘要的引用,请注意以下事项:

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

Digester 可在 Kubernetes 集群中作为变更准入 webhook 运行,也可使用 kpt 或 kustomize 命令行工具作为客户端 KRM 函数运行。

使用 digester KRM 函数

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/digester-fn
    cd ~/container-image-digests-tutorial/digester-fn
    
  2. 下载 digester 二进制文件:

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    curl -L "https://github.com/google/k8s-digester/releases/download/${DIGESTER_VERSION}/digester_$(uname -s)_$(uname -m)" --output ${HOME}/bin/digester
    chmod +x ${HOME}/bin/digester
    
  3. 使用标记 1.10 创建引用映像 gcr.io/google-containers/echoserver 的 Kubernetes Pod 清单:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. 使用 kpt 和当前目录 (.) 中的清单运行摘要 KRM 函数:

    kpt fn eval . --exec digester
    

    运行此命令时,kpt 会对当前目录中的清单执行就地更新。如果您希望 kpt 在控制台中显示更新后的清单,并保持清单文件不变,请添加 --output unwrap 标志。

  5. 查看更新后的清单:

    cat pod.yaml
    

    该文件如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
        - name: echoserver
          image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
          ports:
            - containerPort: 8080
    

使用 digester 准入网络钩子

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/digester-webhook
    cd ~/container-image-digests-tutorial/digester-webhook
    
  2. 使用 kind 创建本地 Kubernetes 集群:

    kind create cluster
    

    kind 是一种命令行工具,用于使用 Docker 运行本地 Kubernetes 集群。

  3. 部署 digester 网络钩子:

    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    kustomize build "https://github.com/google/k8s-digester.git/manifests?ref=${DIGESTER_VERSION}" | kubectl apply -f -
    
  4. 在种类集群中创建一个名为 digester-demo 的 Kubernetes 命名空间:

    kubectl create namespace digester-demo
    
  5. digest-resolution: enabled 标签添加到 digester-demo 命名空间:

    kubectl label namespace digester-demo digest-resolution=enabled
    

    Digester 网络钩子会将摘要添加到带有此标签的命名空间中的 pod。

  6. 使用标记 1.10 创建引用映像 gcr.io/google-containers/echoserver 的 Kubernetes Deployment 清单:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  7. digester-demo 命名空间中应用清单:

    kubectl apply --filename deployment.yaml --namespace digester-demo \
        --output jsonpath='{.spec.template.spec.containers[].image}{"\n"}'
    

    --output 标志指示 kubectl 将映像名称输出到控制台,后跟换行符。输出如下所示:

    gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    

    此输出表明 digester 网络钩子将映像摘要添加到了 Deployment 资源中的 Pod 模板规范。

  8. 删除种类集群以释放 Cloud Shell 会话中的资源:

    kind delete cluster
    

使用 kpt setter

kpt 是一个命令行工具,用于管理、操作、自定义和应用 Kubernetes 资源清单。

您可以在构建新映像时使用 kpt Functions 目录中的 create-settersapply-setters KRM 函数更新 Kubernetes 清单中的映像摘要。

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/kpt
    cd ~/container-image-digests-tutorial/kpt
    
  2. 在当前目录中创建 kpt 软件包:

    kpt pkg init --description "Container image digest tutorial"
    
  3. 使用标记 1.10 创建引用映像 gcr.io/google-containers/echoserver 的 Kubernetes Pod 清单:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. 使用 kpt 为清单字段创建一个名为 echoimage 的 setter,现有值为 gcr.io/google-containers/echoserver:1.10

    kpt fn eval . \
        --image gcr.io/kpt-fn/create-setters@sha256:0220cc87f29ff9abfa3a3b5643aa50f18d355d5e9dc9e1f518119633ddc4895c \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10"
    
  5. 查看清单:

    cat pod.yaml
    

    该文件如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    
  6. 获取容器映像的摘要值:

    DIGEST=$(gcloud container images describe \
        gcr.io/google-containers/echoserver:1.10 \
        --format='value(image_summary.digest)')
    
  7. 设置新字段值:

    kpt fn eval . \
        --image gcr.io/kpt-fn/apply-setters@sha256:4d4295727183396f0c3c6a75d2560254c2f9041a39e95dc1e5beffeb49cc1a12 \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10@$DIGEST"
    

    运行此命令时,kpt 将就地替换清单中的 image 字段值。

  8. 查看更新后的清单:

    cat pod.yaml
    

    该文件如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    

使用 kustomize 映像转换器

kustomize 是一个命令行工具,可让您使用叠加层、补丁程序和转换器自定义 Kubernetes 清单。

您可以使用 kustomize 映像转换器来更新现有清单中的映像名称、标记和摘要。

以下 kustomization.yaml 代码段介绍如何将映像转换器配置为将转换器 digest 值用于映像,这些映像中的 Pod 规范 image 值与转换器 name 值匹配:

images:
- name: gcr.io/google-containers/echoserver
  digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

如需使用含有映像摘要的映像转换器,请执行以下操作:

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/kustomize
    cd ~/container-image-digests-tutorial/kustomize
    
  2. 创建 kustomization.yaml 文件:

    kustomize init
    
  3. 通过使用标记 1.10 引用映像 gcr.io/google-containers/echoserver 的 Pod 规范创建一个 Kubernetes 清单:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. 将清单作为资源添加到 kustomization.yaml 文件中:

    kustomize edit add resource pod.yaml
    
  5. 使用映像转换器更新映像的摘要:

    kustomize edit set image \
        gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    
  6. kustomization.yaml 文件中查看映像转换器:

    cat kustomization.yaml
    

    该文件如下所示:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - pod.yaml
    images:
    - digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
      name: gcr.io/google-containers/echoserver
    
  7. 查看生成的清单:

    kustomize build .
    

    输出如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        name: echoserver
        ports:
        - containerPort: 8080
    
  8. 如需通过一个步骤运行 kustomize 转换器并将生成的清单应用于 Kubernetes 集群,您可以将 kubectl apply 命令与 --kustomize 标志结合使用:

    kubectl apply --kustomize .
    

    如果您之后要应用输出,可以将 kustomize build 命令的输出重定向到一个文件。

使用 gke-deploy

gke-deploy 是一个与 Google Kubernetes Engine (GKE) 搭配使用的命令行工具。gke-deploy 封装了 kubectl 命令行工具,并且可以修改您按照 Google 推荐的做法创建的资源。

如果您使用 gke-deploy 子命令 preparerungke-deploy 会默认将您的映像标记解析为摘要并使用映像摘要将展开后的清单保存到文件 output/expanded/aggregated-resources.yaml

您可以使用 gke-deploy run 将映像标记替换为摘要,并将展开的清单应用于 GKE 集群。虽然此命令使用方便,但存在一个缺点:映像标记会在部署时被替换。与标记关联的映像可能会在您决定部署与部署之间发生更改,导致部署异常映像。对于生产部署,我们建议将生成和应用清单步骤分开执行。

如需使用映像摘要替换 Kubernetes 部署清单中的映像标记,请执行以下操作:

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/gke-deploy
    cd ~/container-image-digests-tutorial/gke-deploy
    
  2. 安装 gke-deploy

    go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
    
  3. 使用标记 1.10 创建引用映像 gcr.io/google-containers/echoserver 的 Kubernetes Deployment 清单:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  4. 根据 deployment.yaml 清单生成展开的清单:

    gke-deploy prepare \
        --filename deployment.yaml \
        --image gcr.io/google-containers/echoserver:1.10 \
        --version 1.10
    
  5. 查看展开的清单:

    cat output/expanded/aggregated-resources.yaml
    

    输出如下所示:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/managed-by: gcp-cloud-build-deploy
        app.kubernetes.io/version: "1.10"
      name: echo-deployment
      namespace: default
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
            app.kubernetes.io/managed-by: gcp-cloud-build-deploy
            app.kubernetes.io/version: "1.10"
        spec:
          containers:
          - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
            name: echoserver
            ports:
            - containerPort: 8080
    

    在展开的清单中,映像标记会被替换为摘要。

    gke-deploy 命令结合使用的 --version 参数会设置部署中 app.kubernetes.io/version 标签的值以及扩展清单的 Pod 模板元数据。

    如需了解如何将 gke-deploy 与 Cloud Build 结合使用,请参阅 gke-deploy 的 Cloud Build 文档

使用 ko

ko 是一种命令行工具和库,用于构建 Go 容器映像并将其部署到 Kubernetes 集群。ko 可以在不使用 Docker 守护程序的情况下构建映像,以便您可以在无法安装 Docker 的环境中使用映像。

ko 子命令 build 会构建映像并将其发布到容器映像注册表或将其加载到本地 Docker 守护程序。

ko 子命令 resolve 会执行以下操作:

  • 通过在 Kubernetes 清单的 image 字段中查找您使用 --filename 参数提供的占位符来找到要构建的映像。
  • 构建和发布映像。
  • image 值占位符替换为所构建映像的名称和摘要。
  • 输出展开的清单。

ko 子命令 applycreaterun 会执行与 resolve 相同的步骤,然后使用展开的清单执行 kubectl applycreaterun

如需通过 Go 源代码构建映像,并将映像摘要添加到 Kubernetes 部署清单,请执行以下操作:

  1. 在 Cloud Shell 中,创建并转到用于存储您在本部分创建的文件的目录:

    mkdir -p ~/container-image-digests-tutorial/ko
    cd ~/container-image-digests-tutorial/ko
    
  2. 下载 ko 并将其添加到您的 PATH

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    KO_VERSION=$(curl -sL https://api.github.com/repos/ko-build/ko/releases/latest | jq -r .tag_name | cut -c2-)
    curl -L "https://github.com/ko-build/ko/releases/download/v${KO_VERSION}/ko_${KO_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar -zxC ${HOME}/bin ko
    
  3. 在名为 app 的新目录中创建模块名称为 example.com/hello-world 的 Go 应用:

    mkdir -p app/cmd/ko-example
    
    cd app
    
    go mod init example.com/hello-world
    
    cat << EOF > cmd/ko-example/main.go
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("hello world")
    }
    EOF
    
  4. 定义 ko 用于发布映像的映像代码库:

    export KO_DOCKER_REPO=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY
    

    此示例使用 Artifact Registry,但您可以将 ko 与其他容器映像注册表结合使用。

  5. 如需为您的应用构建和发布映像,请执行以下步骤之一:

    • 通过提供 Go 主软件包的路径,为应用构建并发布映像:

      ko build --base-import-paths ./cmd/ko-example
      

      可选参数 --base-import-paths 表示 ko 使用主软件包目录的短名称作为映像名称。

      ko 采用以下格式将映像名称和摘要输出到 stdout

      LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
      

      在此输出中,DIGEST 是映像摘要值。

    • 使用 ko 将清单占位符替换为其构建并发布的映像的名称和摘要:

      1. 创建 Kubernetes pod 清单。清单使用占位符 ko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE 作为 image 字段的值:

        cat << EOF > ko-pod.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: ko://example.com/hello-world/cmd/ko-example
        EOF
        
      2. 为应用构建和发布映像,并将清单占位符替换为映像名称和摘要:

        ko resolve --base-import-paths --filename ko-pod.yaml
        

        ko 会将包含映像名称和清单的摘要输出到 stdout

        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
        

        在此输出中,DIGEST 是映像摘要值。

清理

避免产生费用的最简单方法是删除您为本教程创建的 Google Cloud 项目。或者,您也可以删除各个资源。

删除项目

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除资源

如果您希望保留在本教程中使用的 Google Cloud 项目,请删除单个资源:

  1. 在 Cloud Shell 中,删除您在本教程中创建的文件:

    cd
    rm -rf ~/container-image-digests-tutorial
    
  2. 删除 Artifact Registry 中的容器映像制品库:

    gcloud artifacts repositories delete REPOSITORY \
        --location=LOCATION --async --quiet
    

后续步骤