このチュートリアルでは、Google Kubernetes Engine(GKE)クラスタで x86(Intel または AMD)プロセッサを使用してノード用にビルドされたアプリケーションを、x86 ノードまたは Arm ノードで動作するマルチ アーキテクチャ(マルチ アーキテクチャ)アプリケーションに移行する方法について説明します。このチュートリアルは、既存の x86 互換ワークロードを Arm で実行するプラットフォーム管理者、アプリ オペレータ、アプリ デベロッパーを対象としています。
GKE クラスタでは、Tau T2A Arm マシンシリーズを使用して Arm ノードでワークロードを実行できます。T2A ノードは、x86(Intel または AMD)プロセッサを使用するほかのノードと同様に GKE クラスタで実行できます。スケールアウトやコンピューティング負荷の高いワークロードに適しています。
詳細については、GKE での Arm ワークロードをご覧ください。
このチュートリアルは、Kubernetes と Docker の知識があることを前提としています。このチュートリアルでは、Google Kubernetes Engine と Artifact Registry を使用します。
目標
このチュートリアルでは、次のタスクを行います。
- Docker を使用してコンテナ イメージを Artifact Registry に保存します。
- x86 互換のワークロードを GKE クラスタにデプロイします。
- x86 互換のワークロードを再ビルドして Arm で実行します。
- Arm ノードプールを既存のクラスタに追加します。
- Arm ノードで実行する Arm 互換のワークロードをデプロイします。
- 複数のアーキテクチャでワークロードを実行するマルチ アーキテクチャ イメージをビルドします。
- 1 つの GKE クラスタ内の複数のアーキテクチャでワークロードを実行します。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
次の手順で Kubernetes Engine API を有効にします。- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Enable the Artifact Registry and Google Kubernetes Engine APIs.
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Enable the Artifact Registry and Google Kubernetes Engine APIs.
このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。
Cloud Shell を起動する
このチュートリアルでは、Google Cloud でホストされているリソースを管理するためのシェル環境である Cloud Shell を使用します。
Cloud Shell には、Google Cloud CLI と kubectl
コマンドライン ツールがプリインストールされています。gcloud CLI は Google Cloud への主要なコマンドライン インターフェースを提供し、kubectl
は Kubernetes クラスタにコマンドを実行するためのコマンドライン インターフェースを提供します。
Cloud Shell を起動します。
Google Cloud コンソールに移動します。
コンソールの右上隅にある [Cloud Shell をアクティブにする] ボタン
をクリックします。
コンソール内に Cloud Shell セッションが表示されます。このシェルで gcloud
コマンドと kubectl
コマンドを実行します。
環境を準備する
このセクションでは、チュートリアルに沿って環境を準備します。
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 リポジトリのリソースを使用します。
リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/gke-arm
現在の作業ディレクトリを、前の手順でクローンを作成したリポジトリの
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 リポジトリを作成する
Artifact Registry に、Docker イメージを保存するリポジトリを作成します。
gcloud artifacts repositories create docker-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
Docker コマンドライン ツールを構成して、Artifact Registry でこのリポジトリに対して認証します。
gcloud auth configure-docker us-central1-docker.pkg.dev
x86 イメージをビルドし、Artifact Registry に push する
x86 互換バージョンのアプリケーションをビルドします。
docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1 .
イメージを Artifact Registry に push します。
docker push us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1
x86 アプリケーションをデプロイする
次のスクリプトを実行して、クラスタの準備ができていることを確認します。
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
クラスタ認証情報を取得して、
kubectl
がクラスタの Kubernetes API に接続できるようにします。gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE --project $PROJECT_ID
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
アプリケーションをインターネットに公開するために Service をデプロイします。
kubectl apply -f k8s/hello-service.yaml
Service の外部 IP アドレス
hello-service
のプロビジョニングが完了したことを確認します。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
HTTP リクエストを発行して、Deployment が期待どおりに動作するかテストします。
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 互換バージョンのアプリケーションがデプロイされる場所です。
チェックポイント
ここまでで、次の目標を達成しました。
- x86 ノードを使用して GKE クラスタを作成します。
- Docker を使用して x86 互換のコンテナ イメージを Artifact Registry に保存します。
- 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 VM です。
x86 ノードを含むノードプールを作成する際と同じ方法で、Arm ノードを含むノードプールを作成します。このノードプールが作成されると、このクラスタで x86 ノードと Arm ノードの両方が実行されます。
既存のクラスタに Arm ノードプールを追加する方法について詳しくは、GKE クラスタに Arm ノードプールを追加するをご覧ください。
x86 ベースのノードで実行されている既存のアプリケーションをスケールアップする
複数のアーキテクチャ タイプのノードを 1 つのクラスタでシームレスに連携させることができます。Arm ノードには taint が自動的に配置されるため、GKE は、x86 ノードで実行されている既存のワークロードをクラスタ内の Arm ノードにスケジューリングしません。これは、既存のアプリケーションをスケールアップすることで確認できます。
ワークロードを更新して、最大 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/
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
この出力では、x86 ベースのノードに空きが残っていないため、保留中ステータスの Pod が表示されます。クラスタ オートスケーラーが無効になり、Arm ノードが taint されるため、ワークロードは使用可能な Arm ノードにデプロイされません。この taint によって、GKE が Arm ノードに x86 ワークロードをスケジューリングすることが禁止されます。Arm ノードにデプロイするには、Deployment が Arm ノードと互換性があることを示す必要があります。
実行状態の 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
列は、Deployment のすべての Pod がデフォルト プールでのみ実行されていることを示しています。つまり、x86 と互換性のある Pod は x86 ノードにのみスケジュールされます。Arm ノードプールの作成前にすでにスケジュールされていた元の Pod は同じノードで引き続き実行されます。次のコマンドを実行してサービスにアクセスし、出力を確認します。
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
を使用してこれらの手順を完了します。この 2 段階のアプローチは次のとおりです。
- 第 1 ステージ: Arm にコードをビルドします。
- 第 2 ステージ: 実行可能ファイルをリーンコンテナにコピーします。
次の手順で操作すると、x86 互換イメージに加えて Arm 互換イメージが作成されます。
実行可能ファイルを別のコンテナにコピーする 2 番目のステップは、コンテナをビルドするためのベスト プラクティスの一つです。つまり、可能な限り小さいイメージをビルドすることです。
このチュートリアルでは、Golang プログラミング言語でビルドされたサンプル アプリケーションを使用します。Golang では、環境変数 GOOS
と GOARCH
をそれぞれ指定することで、アプリケーションを異なるオペレーティング システムと CPU プラットフォームにクロスコンパイルできます。
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 命令セット用のアプリケーションのビルドが指示されます。最初のステージのベースイメージは Linux Alpine イメージであるため、GOOS
を設定する必要はありません。Arm のコードをビルドし、Artifact Registry に push します。
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 ノードにデプロイできます。
cat k8s/overlays/arm/add_arm_support.yaml
を実行してadd_arm_support.yaml
を調べます。出力は次のようになります。
nodeSelector: kubernetes.io/arch: arm64
この
nodeSelector
は、ワークロードを Arm ノードでのみ実行することを指定します。nodeSelector
を使用すると、GKE は Arm ノード上の taint に一致する toleration を追加し、GKE がこれらのノード上のワークロードをスケジュールできるようにします。このフィールドの設定の詳細については、デプロイ用に Arm ワークロードを準備するをご覧ください。Arm 互換バージョンのアプリケーションのレプリカを 1 つデプロイします。
$(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
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
この出力には、
curl
リクエストに応答する x86 互換アプリケーションと Arm 互換アプリケーションの両方からのレスポンスが含まれています。
アーキテクチャ間でワークロードを実行するマルチ アーキテクチャ イメージをビルドする
前のセクションで説明した戦略を使用して、x86 と Arm に別々のワークロードをデプロイできますが、これには 2 つのビルドプロセスと 2 つのコンテナ イメージを維持して整理する必要があります。
x86 と Arm プラットフォームの両方でアプリケーションをシームレスにビルドして実行するのが理想的です。このアプローチをおすすめします。1 つのマニフェストを使用して複数のアーキテクチャ プラットフォームでアプリケーションを実行するには、マルチアーキテクチャ(マルチアーキテクチャ)イメージを使用する必要があります。マルチアーキテクチャ イメージの詳細については、Arm ワークロード用のマルチアーキテクチャ イメージをビルドするをご覧ください。
マルチ アーキテクチャ イメージを使用するには、アプリケーションが次の前提条件を満たしていることを確認する必要があります。
- アプリケーションにアーキテクチャ プラットフォーム固有の依存関係がない。
- すべての依存関係は、マルチ アーキテクチャまたは少なくともターゲット プラットフォーム向けにビルドされている必要がある。
このチュートリアルで使用するサンプル アプリケーションは、これらの前提条件を両方とも満たしています。ただし、マルチアーキテクチャ イメージを本番環境にデプロイする前に、独自のアプリケーションをテストすることをおすすめします。
マルチアーキテクチャ イメージをビルドして push する
ワークロードが次の前提条件を満たしている場合、Docker Buildx を使用してマルチアーキテクチャ イメージをビルドできます。
- ベースイメージは複数のアーキテクチャをサポートしています。これを確認するには、ベースイメージで
docker manifest inspect
を実行し、アーキテクチャ プラットフォームのリストを確認します。このセクションの最後で画像を検査する方法の例をご覧ください。 - このアプリケーションでは、アーキテクチャ プラットフォームごとに特別なビルドステップは必要ありません。特別な手順が必要な場合は、Buildx では不十分な場合があります。プラットフォームごとに個別の Dockerfile を用意し、
docker manifest create
を使用してマニフェストを手動で作成する必要があります。
サンプル アプリケーションのベースイメージは Alpine で、複数のアーキテクチャをサポートしています。また、アーキテクチャ プラットフォーム固有の手順もないため、Buildx を使用してマルチアーキテクチャ イメージをビルドできます。
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 では、ビルドステージとリリース ステージの 2 つのステージが定義されています。x86 アプリケーションのビルドに使用したものと同じ Dockerfile を使用します。コンテナビルドのベスト プラクティスに沿って対応すれば、何も変更せずに独自のコンテナ イメージを再ビルドできる可能性があります。
次のコマンドを実行して、新しい
docker buildx
ビルダーを作成して使用します。docker buildx create --name multiarch --use --bootstrap
新しいビルダーが作成されたので、
--platform
フラグを使用して、linux/amd64
とlinux/arm64
の両方と互換性のあるイメージをビルドして push できます。このフラグで指定されたプラットフォームごとに、Buildx はターゲット プラットフォームにイメージをビルドします。Buildx はlinux/arm64
イメージをビルドする際に、arm64
ベースイメージをダウンロードします。第 1 ステージで、arm64
のarm64 golang:1.18-alpine
イメージにバイナリをビルドします。第 2 ステージで、arm64
Alpine Linux イメージがダウンロードされ、そのイメージのレイヤにバイナリがコピーされます。イメージをビルドして push します。
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] ..
この出力は、2 つのイメージ(
linux/arm64
用とlinux/amd64
用)が生成されたことを示しています。新しいマルチ アーキテクチャ イメージのマニフェストを検査します。
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
プラットフォーム アーキテクチャのマニフェストの 2 つのマニフェストが含まれています。このコンテナ イメージをクラスタにデプロイすると、GKE はノードのアーキテクチャに一致するイメージのみを自動的にダウンロードします。
アプリケーションのマルチ アーキテクチャ バージョンをデプロイする
マルチアーキテクチャ イメージをデプロイする前に、元のワークロードを削除します。
kubectl delete deploy x86-hello-deployment arm-hello-deployment
cat k8s/overlays/multiarch/add_multiarch_support.yaml
を実行して、add_multiarch_support.yaml
Kustomize オーバーレイを検査します。出力には、次の toleration セットが含まれます。
tolerations: - key: kubernetes.io/arch operator: Equal value: arm64 effect: NoSchedule
この toleration は、すべての Arm ノードに設定された taint と一致するため、クラスタ内の Arm ノードでワークロードを実行できます。このワークロードがクラスタ内のどのノードでも実行できるようになったため、toleration のみが必要になりました。toleration のみを使用して、GKE は x86 ノードと Arm ノードの両方にワークロードをスケジューリングできます。GKE がワークロードをスケジューリングできる場所を指定する場合は、ノードセレクタとノード アフィニティ ルールを使用します。これらのフィールドの設定の詳細については、デプロイ用の Arm ワークロードの準備をご覧ください。
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
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>
この出力には、Pod が Arm ノードプール内のノードとデフォルト(x86)ノードプール内の他のノードの両方で実行されていることを示す
NODE
列が含まれています。次のコマンドを実行してサービスにアクセスし、出力を確認します。
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 アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
チュートリアルが終了したら、作成したリソースをクリーンアップして、割り当ての使用量を減らし、課金を停止できます。以下のセクションで、リソースを削除または無効にする方法を説明します。
プロジェクトを削除する
課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
プロジェクトを削除するには:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
サービス、クラスタ、リポジトリを削除する
プロジェクト全体を削除しない場合は、チュートリアル用に作成したクラスタとリポジトリを削除します。
kubectl delete
を実行して、アプリケーションの Service を削除します。kubectl delete service hello-service
このコマンドにより、Deployment の公開時に作成した Compute Engine ロードバランサが削除されます。
gcloud container clusters delete
を実行して、クラスタを削除します。gcloud container clusters delete $CLUSTER_NAME --zone $ZONE
リポジトリを削除します。
gcloud artifacts repositories delete docker-repo —location=us-central1 --async
次のステップ
- GKE での Arm ワークロード
- Arm ノードを使用してクラスタとノードプールを作成する
- Arm ワークロード向けのマルチアーキテクチャ イメージをビルドする
- デプロイする Arm ワークロードを準備する
- Arm アーキテクチャでの Autopilot ワークロードの準備
- コストが最適化された Kubernetes アプリケーションを GKE で実行するためのベスト プラクティス
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センター をご覧ください。