使用 Arm 将 GKE 上的 x86 应用迁移到多架构


本教程介绍如何将针对 Google Kubernetes Engine (GKE) 集群中使用 x86(Intel 或 AMD)处理器的节点构建的应用迁移到在 x86 或 Arm 节点上运行的多架构应用。本教程的目标受众是想要在 Arm 上运行现有 x86 兼容工作负载的平台管理员、应用运维人员和应用开发者。

借助 GKE 集群,您可以使用 Tau T2A Arm 机器系列在 Arm 节点上运行工作负载。 T2A 节点可以在 GKE 集群中运行,就像使用 x86(Intel 或 AMD)处理器的任何其他节点一样。它们是扩容和计算密集型工作负载的理想选择。

如需了解详情,请参阅 GKE 上的 Arm 工作负载

本教程假定您熟悉 Kubernetes 和 Docker,并且使用 Google Kubernetes Engine 和 Artifact Registry。

目标

在本教程中,您将完成以下任务:

  • 使用 Docker 在 Artifact Registry 中存储容器映像。
  • 将 x86 兼容工作负载部署到 GKE 集群。
  • 重新构建与 x86 兼容的工作负载以在 Arm 上运行。
  • 将 Arm 节点池添加到现有集群。
  • 部署与 Arm 兼容的工作负载,以在 Arm 节点上运行。
  • 构建多架构映像以跨多个架构运行工作负载。
  • 在一个 GKE 集群内的多个架构中运行工作负载。

费用

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

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

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

准备工作

请按照以下步骤启用 Kubernetes Engine API:
  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

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

  4. 启用 Artifact Registry and Google Kubernetes Engine API。

    启用 API

  5. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

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

  7. 启用 Artifact Registry and Google Kubernetes Engine API。

    启用 API

完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理

启动 Cloud Shell

在本教程中,您将使用 Cloud Shell,这是一个用于管理 Google Cloud 上托管资源的 Shell 环境。

Cloud Shell 预安装有 Google Cloud CLIkubectl 命令行工具。gcloud CLI 为 Google Cloud 提供了主要的命令行界面,kubectl 则为 Kubernetes 集群运行命令提供了主要命令行界面。

启动 Cloud Shell:

  1. 前往 Google Cloud 控制台。

    Google Cloud 控制台

  2. 在控制台的右上角,点击激活 Cloud Shell 按钮:

控制台中会显示 Cloud Shell 会话。您可以使用此 shell 运行 gcloudkubectl 命令。

准备环境

在本部分中,您将准备环境,以便按照本教程进行操作。

设定 gcloud CLI 的默认设置

为项目 ID、可用区和新集群的名称设置环境变量。

export PROJECT_ID=PROJECT_ID
export ZONE=us-central1-a
export CLUSTER_NAME=my-cluster

PROJECT_ID 替换为您在准备工作部分中为本教程选择的项目 ID。

在本教程中,您将在 us-central1-a 中创建资源。如需查看可以使用 Tau T2A 机器系列的完整位置列表,请参阅可用的区域和可用区

克隆 Git 代码库

本教程使用 Arm on GKE GitHub 代码库中的资源。

  1. 克隆代码库:

    git clone https://github.com/GoogleCloudPlatform/gke-arm
    
  2. 将当前工作目录更改为上一步中克隆的代码库的 gke-arm/migrate-x86-app-to-multi-arch/

    cd gke-arm/migrate-x86-app-to-multi-arch/
    

创建 GKE 集群并部署 x86 应用

在本教程的第一部分,您将创建一个具有 x86 节点的集群并部署 x86 应用。示例应用是用于响应 HTTP 请求的服务。它使用 Golang 编程语言构建。

此设置代表使用 x86 兼容应用和 x86 节点的典型集群环境的可能情况。

创建 GKE 集群

首先,使用具有 x86 处理器的节点创建 GKE。利用此配置,您可以创建一个典型的集群环境来运行 x86 应用。

创建集群:

gcloud container clusters create $CLUSTER_NAME \
    --release-channel=rapid \
    --zone=$ZONE \
    --machine-type=e2-standard-2 \
    --num-nodes=1 \
    --async

此集群已停用自动扩缩功能,以便在后续步骤中演示特定功能。

集群创建过程可能需要几分钟才能完成。--async 标志允许此操作在后台运行,同时您可以执行后续步骤。

您可以创建仅包含 Arm 节点的集群,但在本教程中,您将首先创建仅包含 x86 节点的集群,以了解使仅适用于 x86 的应用与 Arm 兼容的过程。

创建 Artifact Registry Docker 代码库

  1. 在 Artifact Registry 中创建代码库以存储 Docker 映像:

    gcloud artifacts repositories create docker-repo \
          --repository-format=docker \
          --location=us-central1 \
          --description="Docker repository"
    
  2. 配置 Docker 命令行工具以向 Artifact Registry 中的此代码库进行身份验证:

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

构建 x86 映像并将其推送到 Artifact Registry

  1. 构建与 x86 兼容的应用版本:

    docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1 .
    
  2. 将该映像推送到 Artifact Registry。

    docker push us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1
    

部署 x86 应用

  1. 通过运行以下脚本来检查集群是否已准备就绪:

    echo
    echo -ne "Waiting for GKE cluster to finish provisioning"
    gke_status=""
    while [ -z $gke_status ]; do
       sleep 2
       echo -ne '.'
       gke_status=$(gcloud container clusters list --format="value(STATUS)" --filter="NAME=$CLUSTER_NAME AND STATUS=RUNNING")
    done
    echo
    echo "GKE Cluster '$CLUSTER_NAME' is $gke_status"
    echo
    

    集群准备就绪后,输出应类似于以下内容:

    GKE Cluster 'my-cluster' is RUNNING
    
  2. 检索集群凭据,以便 kubectl 可以连接到集群的 Kubernetes API:

    gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE --project $PROJECT_ID
    
  3. 使用 kustomize 更新映像并部署 x86 应用:

    $(cd k8s/overlays/x86 && kustomize edit set image hello=us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1)
    kubectl apply -k k8s/overlays/x86
    
  4. 部署 Service 以向互联网公开应用:

    kubectl apply -f k8s/hello-service.yaml
    
  5. 检查 Service (hello-service) 的外部 IP 地址是否已预配完毕:

    echo
    echo -ne "Waiting for External IP to be provisioned"
    external_ip=""
    while [ -z $external_ip ]; do
       sleep 2
       echo -ne '.'
       external_ip=$(kubectl get svc hello-service --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}")
    done
    echo
    echo "External IP: $external_ip"
    echo
    

    预配外部 IP 地址后,输出应类似于以下内容:

    External IP: 203.0.113.0
    
  6. 发出 HTTP 请求以测试部署是否按预期工作:

    curl -w '\n' http://$external_ip
    

    输出类似于以下内容:

    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-mwfkd, CPU PLATFORM:linux/amd64
    

    输出显示此与 x86 兼容的部署在 amd64 架构上默认节点池中的节点上运行。集群的默认节点池中的节点具有 x86(Intel 或 AMD)处理器。

将 Arm 节点添加到集群

在本教程的下一部分中,将 Arm 节点添加到现有集群。在重新构建与 Arm 兼容的应用版本以在 Arm 上运行时,与 Arm 兼容的应用版本在这些节点上运行。

Checkpoint

到目前为止,您已实现以下目标:

  • 使用 x86 节点创建 GKE 集群。
  • 使用 Docker 在 Artifact Registry 中存储与 x86 兼容的容器映像。
  • 将 x86 兼容工作负载部署到 GKE 集群。

您已配置了具有 x86 节点和 x86 兼容工作负载的集群环境。如果您当前未使用 Arm 节点和 Arm 兼容工作负载,则此配置类似于现有集群环境。

将 Arm 节点池添加到集群

将 Arm 节点池添加到现有集群:

gcloud container node-pools create arm-pool \
    --cluster $CLUSTER_NAME \
    --zone $ZONE \
    --machine-type=t2a-standard-2 \
    --num-nodes=1

t2a-standard-2 机器类型是 Tau T2A 机器系列(预览版)中的 Arm 虚拟机。

创建具有 Arm 节点的节点池的方式与创建具有 x86 节点的节点池的方式相同。创建此节点池后,在此集群中将同时运行 x86 节点和 Arm 节点。

如需详细了解如何将 Arm 节点池添加到现有集群,请参阅将 Arm 节点池添加到 GKE 集群

对基于 x86 的节点上运行的现有应用进行纵向扩容

多个架构类型的节点可以在一个集群中无缝协作。GKE 不会将 x86 节点上运行的现有工作负载调度到集群中的 Arm 节点,因为污点会自动放置在 Arm 节点上。您可以通过对现有应用进行纵向扩容来查看此情况。

  1. 更新工作负载,将其扩容到 6 个副本:

    $(cd k8s/overlays/x86_increase_replicas && kustomize edit set image hello=us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1)
    kubectl apply -k k8s/overlays/x86_increase_replicas/
    
  2. 等待 30 秒,然后运行以下命令检查部署的状态:

    kubectl get pods -l="app=hello" --field-selector="status.phase=Pending"
    

    输出应类似如下所示:

    NAME                                    READY   STATUS    RESTARTS   AGE
    x86-hello-deployment-6b7b456dd5-6tkxd   0/1     Pending   0          40s
    x86-hello-deployment-6b7b456dd5-k95b7   0/1     Pending   0          40s
    x86-hello-deployment-6b7b456dd5-kc876   0/1     Pending   0          40s
    

    此输出显示处于“待处理”状态的 Pod,因为基于 x86 的节点上没有剩余空间。由于集群自动扩缩器已停用,并且 Arm 节点已具有污点,因此工作负载不会部署在任何可用的 Arm 节点上。此污点可防止 GKE 在 Arm 节点上调度 x86 工作负载。如需部署到 Arm 节点,您必须指明部署与 Arm 节点兼容。

  3. 检查处于“正在运行”状态的 Pod:

    kubectl get pods -l="app=hello" --field-selector="status.phase=Running" -o wide
    

    输出应类似如下所示:

    NAME                                    READY   STATUS    RESTARTS   AGE   IP            NODE                                        NOMINATED NODE   READINESS GATES
    x86-hello-deployment-6b7b456dd5-cjclz   1/1     Running   0          62s   10.100.0.17   gke-my-cluster-default-pool-32019863-b41t   <none>           <none>
    x86-hello-deployment-6b7b456dd5-mwfkd   1/1     Running   0          34m   10.100.0.11   gke-my-cluster-default-pool-32019863-b41t   <none>           <none>
    x86-hello-deployment-6b7b456dd5-n56rg   1/1     Running   0          62s   10.100.0.16   gke-my-cluster-default-pool-32019863-b41t   <none>           <none>
    

    在此输出中,NODE 列表示部署中的所有 Pod 仅在默认池中运行,这意味着与 x86 兼容的 Pod 仅调度到 x86 节点。在创建 Arm 节点池之前已调度的原始 Pod 仍在同一节点上运行。

  4. 运行以下命令以访问服务并查看输出:

    for i in $(seq 1 6); do curl -w '\n' http://$external_ip; done
    

    输出类似于以下内容:

    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-cjclz, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-cjclz, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-n56rg, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-n56rg, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-cjclz, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-cjclz, CPU PLATFORM:linux/amd64
    

    此输出显示所有处理请求的 Pod 正在 x86 节点上运行。某些 Pod 无法响应,其原因是它们仍处于“待处理”状态,因为现有 x86 节点上没有空间,并且它们不会调度到 Arm 节点。

重新构建您的应用以在 Arm 上运行

在上一部分中,您已将 Arm 节点池添加到现有集群。但是,当您对现有 x86 应用进行纵向扩容时,它不会将任何工作负载安排到 Arm 节点。在本部分中,您需要将应用重新构建为与 Arm 兼容,以便此应用可以在集群中的 Arm 节点上运行。

在此示例中,请使用 docker build 完成以下步骤。这个由两个步骤组成的方法包括:

  • 第一阶段:将代码构建到 Arm 上。
  • 第二阶段:将可执行文件复制到精简容器。

按照这些步骤执行操作后,除了与 x86 兼容的映像之外,您还拥有与 Arm 兼容的映像。

将可执行文件复制到另一个容器的第二步是按照构建容器的最佳实践之一执行操作,即构建尽可能小的映像

本教程使用通过 Golang 编程语言构建的示例应用。借助 Golang,您可以通过分别提供环境变量 GOOSGOARCH,将应用交叉编译到不同的操作系统和 CPU 平台。

  1. 运行 cat Dockerfile_arm 以查看为 Arm 编写的 Dockerfile:

    #
    # Build: 1st stage
    #
    FROM golang:1.18-alpine as builder
    WORKDIR /app
    COPY go.mod .
    COPY hello.go .
    RUN GOARCH=arm64 go build -o /hello && \
       apk add --update --no-cache file && \
       file /hello
    

    此处显示的代码段只是第一阶段。该文件包含这两个阶段。

    在此文件中,设置 GOARCH=arm64 会指示 Go 编译器为 Arm 指令集构建应用。您无需设置 GOOS,因为第一阶段的基础映像是 Linux Alpine 映像。

  2. 构建 Arm 的代码,并将其推送到 Artifact Registry:

    docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/arm-hello:v0.0.1 -f Dockerfile_arm .
    docker push us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/arm-hello:v0.0.1
    

部署应用的 Arm 版本

现在应用已构建为在 Arm 节点上运行,您接下来可以将其部署到集群中的 Arm 节点。

  1. 通过运行 cat k8s/overlays/arm/add_arm_support.yaml 检查 add_arm_support.yaml

    输出类似于以下内容:

       nodeSelector:
          kubernetes.io/arch: arm64
    

    nodeSelector 指定工作负载应仅在 Arm 节点上运行。使用 nodeSelector 时,GKE 会添加容忍,它可与 Arm 节点上的污点匹配,让 GKE 在这些节点上调度工作负载。如需详细了解如何设置此字段,请参阅准备 Arm 工作负载以进行部署

  2. 部署一个与 Arm 兼容的应用版本的副本:

    $(cd k8s/overlays/arm && kustomize edit set image hello=us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/arm-hello:v0.0.1)
    kubectl apply -k k8s/overlays/arm
    
  3. 等待 5 秒,然后检查 Arm 部署是否正在响应 curl 请求:

    for i in $(seq 1 6); do curl -w '\n' http://$external_ip; done
    

    输出类似于以下内容:

    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-n56rg, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-n56rg, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-mwfkd, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-mwfkd, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-arm-pool-e172cff7-shwc, POD:arm-hello-deployment-69b4b6bdcc-n5l28, CPU PLATFORM:linux/arm64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-n56rg, CPU PLATFORM:linux/amd64
    

    此输出应包括 x86 兼容应用和 Arm 兼容应用对 curl 请求作出的响应。

构建多架构映像以跨架构运行工作负载

虽然您可以使用上一部分中所述的策略并为 x86 和 Arm 部署单独的工作负载,但这需要维护并组织好两个构建流程和两个容器映像。

理想情况下,您希望在 x86 和 Arm 平台上无缝构建和运行您的应用。我们建议使用此方法。如需跨多个架构平台使用一个清单来运行应用,您需要使用多架构(多架构)映像。如需详细了解多架构映像,请参阅为 Arm 工作负载构建多架构映像

如需使用多架构映像,您必须确保应用满足以下前提条件:

  • 您的应用没有任何特定于架构平台的依赖项。
  • 所有依赖项都必须针对多架构或至少针对目标平台构建。

本教程中使用的示例应用同时满足这两个前提条件。不过,我们建议您在构建多架构映像时测试您自己的应用,然后将其部署到生产环境中。

构建和推送多架构映像

如果您的工作负载满足以下前提条件,则可以使用 Docker Buildx 构建多架构映像:

  • 基础映像支持多个架构。如需检查这一点,请在基础映像上运行 docker manifest inspect 并查看架构平台列表。请参阅本部分结尾处展示如何检查映像的示例。
  • 应用无需为每个架构平台执行特殊的构建步骤。如果需要特殊步骤,Buildx 可能不够。您需要为每个平台提供单独的 Dockerfile,并使用 docker manifest create 手动创建清单。

示例应用的基础映像为 Alpine,它支持多个架构。由于您也无需执行特定于架构平台的步骤,因此可以使用 Buildx 构建多架构映像。

  1. 通过运行 cat Dockerfile 来检查 Dockerfile:

    # This is a multi-stage Dockerfile.
    # 1st stage builds the app in the target platform
    # 2nd stage create a lean image coping the binary from the 1st stage
    
    #
    # Build: 1st stage
    #
    FROM golang:1.18-alpine as builder
    ARG BUILDPLATFORM
    ARG TARGETPLATFORM
    RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM"
    WORKDIR /app
    COPY go.mod .
    COPY hello.go .
    RUN go build -o /hello && \
       apk add --update --no-cache file && \
       file /hello
    
    #
    # Release: 2nd stage
    #
    FROM alpine
    WORKDIR /
    COPY --from=builder /hello /hello
    CMD [ "/hello" ]
    

    此 Dockerfile 定义了两个阶段:构建阶段和发布阶段。您使用与构建 x86 应用时相同的 Dockerfile。如果您遵循构建容器的最佳做法,则可以重新构建自己的容器映像,而无需更改任何内容。

  2. 运行以下命令以创建并使用新的 docker buildx 构建器:

    docker buildx create --name multiarch --use --bootstrap
    

    现在您创建了这个新的构建器,接下来可以使用 --platform 标志构建和推送与 linux/amd64linux/arm64 兼容的映像。对于带有此标志的每个平台,Buildx 会在目标平台中构建映像。当 Buildx 构建 linux/arm64 映像时,它会下载 arm64 基础映像。在第一阶段,它在 arm64arm64 golang:1.18-alpine 映像上构建二进制文件。在第二阶段,系统会下载 arm64 Alpine Linux 映像,并将二进制文件复制到该映像的层。

  3. 构建并推送映像:

    docker buildx build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/multiarch-hello:v0.0.1 -f Dockerfile --platform linux/amd64,linux/arm64 --push .
    

    输出类似于以下内容:

    => [linux/arm64 builder x/x] ..
    => [linux/amd64 builder x/x] ..
    

    此输出会显示系统生成了两个映像,一个用于 linux/arm64,另一个用于 linux/amd64

  4. 检查新的多架构映像的清单:

    docker manifest inspect us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/multiarch-hello:v0.0.1
    

    输出类似于以下内容:

    {
       "schemaVersion": 2,
       "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
       "manifests": [
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 739,
             "digest": "sha256:dfcf8febd94d61809bca8313850a5af9113ad7d4741edec1362099c9b7d423fc",
             "platform": {
                "architecture": "amd64",
                "os": "linux"
             }
          },
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 739,
             "digest": "sha256:90b637d85a93c3dc03fc7a97d1fd640013c3f98c7c362d1156560bbd01f6a419",
             "platform": {
                "architecture": "arm64",
                "os": "linux"
             }
          }
       ]
    

    在此输出中,manifests 部分包含两份清单,一份具有 amd64 平台架构,另一份具有 arm64 平台架构。

    将此容器映像部署到集群时,GKE 仅自动下载与节点架构匹配的映像。

部署应用的多架构版本

  1. 在部署多架构映像之前,请删除原始工作负载:

    kubectl delete deploy x86-hello-deployment arm-hello-deployment
    
  2. 通过运行 cat k8s/overlays/multiarch/add_multiarch_support.yaml 检查 add_multiarch_support.yaml kustomize 叠加层:

    输出包括以下容忍集:

       tolerations:
          - key: kubernetes.io/arch
             operator: Equal
             value: arm64
             effect: NoSchedule
    

    此容忍设置允许工作负载在集群的 Arm 节点上运行,因为容忍设置与所有 Arm 节点中设置的污点匹配。由于此工作负载现在可以在集群中的任何节点上运行,因此只需要容忍设置。只要具有容忍设置,GKE 就可以将工作负载调度到 x86 和 Arm 节点。如果您想指定 GKE 可以调度工作负载的位置,请使用节点选择器和节点亲和性规则。如需详细了解如何设置这些字段,请参阅准备 Arm 工作负载以进行部署

  3. 部署具有 6 个副本的多架构容器映像:

    $(cd k8s/overlays/multiarch && kustomize edit set image hello=us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/multiarch-hello:v0.0.1)
    kubectl apply -k k8s/overlays/multiarch
    
  4. 等待 10 秒,然后确认应用的所有副本正在运行:

    kubectl get pods -l="app=hello" -o wide
    

    输出类似于以下内容:

    NAME                                         READY   STATUS    RESTARTS   AGE   IP            NODE                                        NOMINATED NODE   READINESS GATES
    multiarch-hello-deployment-65bfd784d-5xrrr   1/1     Running   0          95s   10.100.1.5    gke-my-cluster-arm-pool-e172cff7-shwc       <none>           <none>
    multiarch-hello-deployment-65bfd784d-7h94b   1/1     Running   0          95s   10.100.1.4    gke-my-cluster-arm-pool-e172cff7-shwc       <none>           <none>
    multiarch-hello-deployment-65bfd784d-7qbkz   1/1     Running   0          95s   10.100.1.7    gke-my-cluster-arm-pool-e172cff7-shwc       <none>           <none>
    multiarch-hello-deployment-65bfd784d-7wqb6   1/1     Running   0          95s   10.100.1.6    gke-my-cluster-arm-pool-e172cff7-shwc       <none>           <none>
    multiarch-hello-deployment-65bfd784d-h2g2k   1/1     Running   0          95s   10.100.0.19   gke-my-cluster-default-pool-32019863-b41t   <none>           <none>
    multiarch-hello-deployment-65bfd784d-lc9dc   1/1     Running   0          95s   10.100.0.18   gke-my-cluster-default-pool-32019863-b41t   <none>           <none>
    

    此输出包含 NODE 列,该列指示 Pod 正在 Arm 节点池中的节点以及默认 (x86) 节点池中的其他节点上运行。

  5. 运行以下命令以访问服务并查看输出:

    for i in $(seq 1 6); do curl -w '\n' http://$external_ip; done
    

    输出类似于以下内容:

    Hello from NODE:gke-my-cluster-arm-pool-e172cff7-shwc, POD:multiarch-hello-deployment-65bfd784d-7qbkz, CPU PLATFORM:linux/arm64
    Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:multiarch-hello-deployment-65bfd784d-lc9dc, CPU PLATFORM:linux/amd64
    Hello from NODE:gke-my-cluster-arm-pool-e172cff7-shwc, POD:multiarch-hello-deployment-65bfd784d-5xrrr, CPU PLATFORM:linux/arm64
    Hello from NODE:gke-my-cluster-arm-pool-e172cff7-shwc, POD:multiarch-hello-deployment-65bfd784d-7wqb6, CPU PLATFORM:linux/arm64
    Hello from NODE:gke-my-cluster-arm-pool-e172cff7-shwc, POD:multiarch-hello-deployment-65bfd784d-7h94b, CPU PLATFORM:linux/arm64
    Hello from NODE:gke-my-cluster-arm-pool-e172cff7-shwc, POD:multiarch-hello-deployment-65bfd784d-7wqb6, CPU PLATFORM:linux/arm64
    

    您应该会看到跨架构平台运行的 Pod 正在响应请求。

您构建并部署了多架构映像,以跨多个架构无缝运行工作负载。

清理

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

学完本教程后,您可以清理您创建的资源,以减少配额用量并避免产生结算费用。以下部分介绍如何删除或关闭这些资源。

删除项目

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

如需删除项目,请执行以下操作:

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

    转到“管理资源”

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

删除服务、集群和代码库

如果您不想删除整个项目,请删除您为教程创建的集群和代码库:

  1. 运行 kubectl delete 以删除应用的 Service:

    kubectl delete service hello-service
    

    此命令会删除您在公开 Deployment 时创建的 Compute Engine 负载均衡器。

  2. 运行 gcloud container clusters delete 以删除您的集群:

    gcloud container clusters delete $CLUSTER_NAME --zone $ZONE
    
  3. 删除代码库:

    gcloud artifacts repositories delete docker-repo —location=us-central1 --async
    

后续步骤