Memigrasikan aplikasi x86 di GKE ke multi-arch dengan Arm


Tutorial ini menjelaskan cara memigrasikan aplikasi yang dibuat untuk node menggunakan prosesor x86 (Intel atau AMD) di cluster Google Kubernetes Engine (GKE) ke aplikasi multi-arsitektur (multi-arch) yang berjalan pada salah satu node, yaitu node x86 atau Arm. Audiens yang dituju untuk tutorial ini adalah Admin Platform, Operator Aplikasi, dan Developer Aplikasi yang ingin menjalankan workload yang kompatibel dengan x86 yang ada di Arm.

Dengan cluster GKE, Anda dapat menjalankan workload pada node Arm menggunakan rangkaian mesin Tau T2A Arm. Node T2A dapat berjalan di cluster GKE Anda sama seperti node lainnya yang menggunakan prosesor x86 (Intel atau AMD). Opsi ini adalah pilihan yang baik untuk workload yang memerlukan penyebaran skala dan intensif komputasi.

Untuk mempelajari lebih lanjut, lihat Workload Arm di GKE.

Tutorial ini mengasumsikan bahwa Anda sudah memahami Kubernetes dan Docker. Tutorial ini menggunakan Google Kubernetes Engine dan Artifact Registry.

Tujuan

Di tutorial ini, Anda akan menyelesaikan tugas-tugas berikut:

  • Menyimpan image container dengan Docker di Artifact Registry.
  • Men-deploy workload yang kompatibel dengan x86 ke cluster GKE.
  • Mem-build ulang workload yang kompatibel dengan x86 untuk dijalankan di Arm.
  • Menambahkan node pool Arm ke cluster yang ada.
  • Men-deploy workload yang kompatibel dengan Arm untuk dijalankan di node Arm.
  • Mem-build image multi-arch untuk menjalankan workload di beberapa arsitektur.
  • Menjalankan workload di beberapa arsitektur dalam satu cluster GKE.

Biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.

Sebelum memulai

Lakukan langkah-langkah berikut untuk mengaktifkan Kubernetes Engine API:
  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  3. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  4. Enable the Artifact Registry and Google Kubernetes Engine APIs.

    Enable the APIs

  5. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  6. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  7. Enable the Artifact Registry and Google Kubernetes Engine APIs.

    Enable the APIs

Setelah menyelesaikan tutorial ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Lihat Clean up untuk detail selengkapnya.

Meluncurkan Cloud Shell

Dalam tutorial ini, Anda akan menggunakan Cloud Shell, yang merupakan lingkungan shell untuk mengelola resource yang dihosting di Google Cloud.

Cloud Shell telah diinstal lebih dulu dengan alat command line Google Cloud CLI dan kubectl. Gcloud CLI menyediakan antarmuka command line utama untuk Google Cloud, dan kubectl menyediakan antarmuka command line utama untuk menjalankan perintah terhadap cluster Kubernetes.

Meluncurkan Cloud Shell:

  1. Buka Konsol Google Cloud.

    Google Cloud console

  2. Dari pojok kanan atas konsol, klik tombol Activate Cloud Shell:

Sesi Cloud Shell akan muncul di dalam konsol. Anda menggunakan shell ini untuk menjalankan perintah gcloud dan kubectl.

Menyiapkan lingkungan Anda

Di bagian ini, Anda akan menyiapkan lingkungan untuk mengikuti tutorial.

Menetapkan setelan default untuk gcloud CLI

Tetapkan variabel lingkungan untuk project ID, zona, dan nama cluster baru Anda.

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

Ganti PROJECT_ID dengan project ID yang Anda pilih untuk tutorial ini di bagian Sebelum memulai.

Dalam tutorial ini, Anda akan membuat resource di us-central1-a. Untuk melihat daftar lengkap tempat rangkaian mesin Tau T2A tersedia, lihat Region dan zona yang tersedia.

Meng-clone repositori git

Tutorial ini menggunakan resource dari repositori GitHub Arm on GKE.

  1. Meng-cloning repository

    git clone https://github.com/GoogleCloudPlatform/gke-arm
    
  2. Ubah direktori tugas Anda saat ini ke gke-arm/migrate-x86-app-to-multi-arch/ dari repositori yang di-clone pada langkah sebelumnya:

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

Membuat cluster GKE dan men-deploy aplikasi x86

Di bagian pertama tutorial ini, Anda akan membuat cluster dengan node x86 dan men-deploy aplikasi x86. Aplikasi contoh adalah layanan yang merespons permintaan HTTP. Aplikasi ini dibuat dengan bahasa pemrograman Golang.

Penyiapan ini merepresentasikan tampilan lingkungan cluster pada umumnya, dengan menggunakan aplikasi yang kompatibel dengan x86 dan node x86.

Membuat cluster GKE

Pertama, buat GKE menggunakan node dengan prosesor x86. Dengan konfigurasi ini, Anda akan membuat lingkungan cluster standar untuk menjalankan aplikasi x86.

Membuat cluster:

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

Penskalaan otomatis pada cluster ini dinonaktifkan untuk mendemonstrasikan fungsi tertentu pada langkah-langkah berikutnya.

Proses pembuatan cluster ini memerlukan waktu beberapa menit. Flag --async memungkinkan operasi ini berjalan di latar belakang saat Anda menyelesaikan langkah berikutnya.

Anda dapat membuat cluster hanya dengan node Arm, tetapi dalam tutorial ini, Anda akan membuat cluster dengan hanya node x86 terlebih dahulu untuk mempelajari proses membuat aplikasi khusus x86 yang kompatibel dengan Arm.

Membuat repositori Docker Artifact Registry

  1. Membuat repositori di Artifact Registry untuk menyimpan image Docker:

    gcloud artifacts repositories create docker-repo \
          --repository-format=docker \
          --location=us-central1 \
          --description="Docker repository"
    
  2. Mengonfigurasi alat command line Docker untuk mengautentikasi ke repositori ini di Artifact Registry:

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

Mem-build image x86 dan mengirimnya ke Artifact Registry

  1. Membuat versi aplikasi yang kompatibel dengan x86:

    docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1 .
    
  2. Mengirim image ke Artifact Registry:

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

Men-deploy aplikasi x86

  1. Periksa kesiapan cluster dengan menjalankan skrip berikut:

    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
    

    Jika cluster sudah siap, output-nya akan terlihat seperti berikut:

    GKE Cluster 'my-cluster' is RUNNING
    
  2. Ambil kredensial cluster agar kubectl dapat terhubung ke Kubernetes API untuk cluster tersebut:

    gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE --project $PROJECT_ID
    
  3. Update image menggunakan kustomize dan deploy aplikasi 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. Deploy Service untuk mengekspos aplikasi ke Internet:

    kubectl apply -f k8s/hello-service.yaml
    
  5. Pastikan alamat IP eksternal untuk Service, hello-service, telah selesai disediakan:

    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
    

    Setelah alamat IP eksternal disediakan, output-nya akan mirip dengan berikut ini:

    External IP: 203.0.113.0
    
  6. Buat permintaan HTTP untuk menguji berfungsi atau tidaknya deployment seperti yang diharapkan:

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

    Outputnya mirip dengan hal berikut ini:

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

    Output menunjukkan bahwa deployment yang kompatibel dengan x86 ini berjalan di node dalam node pool default pada arsitektur amd64. Node di node pool default cluster Anda memiliki prosesor x86 (Intel maupun AMD).

Menambahkan node Arm ke cluster

Di bagian selanjutnya dari tutorial ini, tambahkan node Arm ke cluster yang ada. Node ini adalah tempat versi aplikasi Anda yang kompatibel dengan Arm di-deploy saat di-build ulang untuk berjalan di Arm.

Checkpoint

Sejauh ini Anda telah mencapai tujuan berikut:

  • membuat cluster GKE menggunakan node x86.
  • menyimpan image container yang kompatibel dengan x86 dengan Docker di Artifact Registry.
  • men-deploy workload yang kompatibel dengan x86 ke cluster GKE.

Anda telah mengonfigurasi lingkungan cluster dengan node x86 dan workload yang kompatibel dengan x86. Konfigurasi ini mirip dengan lingkungan cluster yang ada jika saat ini Anda tidak menggunakan node Arm dan workload yang kompatibel dengan Arm.

Menambahkan node pool Arm ke cluster

Tambahkan node pool Arm ke cluster yang ada:

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

Jenis mesin t2a-standard-2 adalah Arm VM dari rangkaian mesin Tau T2A (Pratinjau).

Anda membuat node pool dengan node Arm dengan cara yang sama seperti membuat node pool dengan node x86. Setelah node pool ini dibuat, Anda akan memiliki node x86 dan node Arm yang berjalan di cluster ini.

Untuk mempelajari lebih lanjut cara menambahkan node pool Arm ke cluster yang ada, lihat artikel Menambahkan node pool Arm ke cluster GKE.

Meningkatkan skala aplikasi yang ada yang berjalan di node berbasis x86

Node dari beberapa jenis arsitektur dapat bekerja sama dengan lancar dalam satu cluster. GKE tidak menjadwalkan workload yang ada yang berjalan pada node x86 ke node Arm dalam cluster karena taint secara otomatis ditempatkan pada node Arm. Anda dapat melihatnya dengan meningkatkan skala aplikasi yang sudah ada.

  1. Update workload, dengan menskalakan hingga 6 replika:

    $(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. Tunggu 30 detik, lalu jalankan perintah berikut untuk memeriksa status deployment:

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

    Output-nya akan terlihat seperti berikut:

    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
    

    Output ini menampilkan Pod dengan status Tertunda karena tidak ada ruang tersisa di node berbasis x86. Karena Autoscaler Cluster dinonaktifkan dan node Arm di-taint, workload tidak akan di-deploy di node Arm yang tersedia. Taint ini mencegah GKE agar tidak menjadwalkan workload x86 pada node Arm. Untuk men-deploy ke node Arm, Anda harus menunjukkan bahwa deployment tersebut kompatibel dengan node Arm.

  3. Periksa Pod yang ada dalam status Berjalan:

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

    Output-nya akan terlihat seperti berikut:

    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>
    

    Dalam output ini, kolom NODE menunjukkan bahwa semua Pod dari deployment hanya berjalan di pool default, yang berarti bahwa Pod yang kompatibel dengan x86 hanya dijadwalkan ke node x86. Pod asli yang sudah dijadwalkan sebelum pembuatan node pool Arm masih berjalan di node yang sama.

  4. Jalankan perintah berikut untuk mengakses layanan dan melihat output-nya:

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

    Outputnya mirip dengan yang berikut ini:

    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
    

    Output ini menunjukkan bahwa semua Pod yang menyajikan permintaan berjalan pada node x86. Beberapa Pod tidak dapat merespons karena masih dalam status Tertunda sebab tidak ada ruang pada node x86 yang ada dan tidak akan dijadwalkan ke node Arm.

Mem-build ulang aplikasi Anda untuk berjalan di Arm

Di bagian sebelumnya, Anda telah menambahkan node pool Arm ke cluster yang ada. Namun, ketika Anda meningkatkan skala aplikasi x86 yang sudah ada, aplikasi tersebut tidak menjadwalkan workload apa pun ke node Arm. Di bagian ini, Anda akan mem-build ulang aplikasi agar kompatibel dengan Arm, sehingga aplikasi ini dapat berjalan di node Arm di cluster.

Untuk contoh ini, selesaikan langkah-langkah ini menggunakan docker build. Pendekatan dua langkah ini meliputi:

  • Tahap pertama: Buat kode untuk Arm.
  • Tahap kedua: Salin file yang dapat dieksekusi ke container yang efisien.

Setelah mengikuti langkah-langkah ini, Anda akan memiliki image yang kompatibel dengan Arm selain image yang kompatibel dengan x86.

Langkah kedua untuk menyalin file yang dapat dieksekusi ke container lain adalah mengikuti salah satu praktik terbaik untuk mem-build container, yaitu mem-build image sekecil mungkin.

Tutorial ini menggunakan aplikasi contoh yang dibuat dengan bahasa pemrograman Golang. Dengan Golang, Anda dapat melakukan kompilasi silang aplikasi ke berbagai sistem operasi dan platform CPU dengan memberikan variabel lingkungan, GOOS dan GOARCH.

  1. Jalankan cat Dockerfile_arm untuk melihat Dockerfile ditulis untuk Arm:

    #
    # 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
    

    Cuplikan yang ditampilkan di sini hanya menampilkan tahap pertama. Kedua tahap disertakan dalam file tersebut.

    Dalam file ini, menyetel GOARCH=arm64 akan menginstruksikan compiler Go guna mem-build aplikasi untuk kumpulan petunjuk Arm. Anda tidak perlu menetapkan GOOS karena image dasar pada tahap pertama adalah image Alpine Linux.

  2. Build kode untuk Arm, dan kirim ke 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
    

Men-deploy versi Arm aplikasi Anda

Setelah aplikasi di-build untuk berjalan di node Arm, Anda dapat men-deploy aplikasi tersebut ke node Arm di cluster Anda.

  1. Periksa add_arm_support.yaml dengan menjalankan cat k8s/overlays/arm/add_arm_support.yaml:

    Outputnya mirip dengan hal berikut ini:

       nodeSelector:
          kubernetes.io/arch: arm64
    

    nodeSelector ini menentukan bahwa workload hanya boleh berjalan pada node Arm. Saat Anda menggunakan nodeSelector, GKE menambahkan toleransi yang cocok dengan taint pada node Arm, sehingga GKE menjadwalkan workload pada node tersebut. Untuk mempelajari lebih lanjut cara menetapkan kolom ini, lihat Menyiapkan workload Arm untuk deployment.

  2. Deploy satu replika versi aplikasi yang kompatibel dengan 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. Tunggu 5 detik, lalu pastikan deployment Arm menjawab permintaan curl:

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

    Outputnya mirip dengan hal berikut ini:

    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
    

    Output ini harus mencakup respons dari aplikasi yang kompatibel dengan x86 dan yang kompatibel dengan Arm yang merespons permintaan curl.

Mem-build image multi-arsitektur untuk menjalankan workload di seluruh arsitektur

Meskipun Anda dapat menggunakan strategi yang dijelaskan di bagian sebelumnya dan men-deploy workload terpisah untuk x86 dan Arm, hal ini mengharuskan Anda mengelola dan menjaga dua proses build dan dua image container tetap terorganisir.

Idealnya, Anda ingin mem-build dan menjalankan aplikasi dengan lancar di seluruh platform x86 dan Arm. Kami merekomendasikan pendekatan ini. Untuk menjalankan aplikasi dengan satu manifes di beberapa platform arsitektur, Anda perlu menggunakan image multi-arsitektur (multi-arch). Untuk mempelajari image multi-arsitektur lebih lanjut, lihat Mem-build image multi-arch untuk workload Arm.

Untuk menggunakan image multi-arsitektur, Anda harus memastikan bahwa aplikasi Anda memenuhi prasyarat berikut:

  • Aplikasi Anda tidak memiliki dependensi khusus platform arsitektur.
  • Semua dependensi harus dibuat untuk multi-arsitektur atau, setidaknya, platform yang ditargetkan.

Aplikasi contoh yang digunakan dalam tutorial ini memenuhi kedua prasyarat tersebut. Namun, sebaiknya uji aplikasi Anda sendiri saat mem-build image multi-arch sebelum men-deploy-nya ke produksi.

Mem-build dan mengirim image multi-arsitektur

Anda dapat mem-build image multi-arch dengan Docker Buildx jika workload Anda memenuhi prasyarat berikut:

  • Image dasar mendukung beberapa arsitektur. Periksa hal ini dengan menjalankan docker manifest inspect pada image dasar dan memeriksa daftar platform arsitektur. Lihat contoh cara memeriksa image pada akhir bagian ini.
  • Aplikasi tidak memerlukan langkah-langkah build khusus untuk setiap platform arsitektur. Jika langkah-langkah khusus diperlukan, Buildx mungkin tidak cukup. Anda harus memiliki Dockerfile terpisah untuk setiap platform dan membuat manifes secara manual dengan docker manifest create.

Contoh image dasar aplikasi adalah Alpine, yang mendukung beberapa arsitektur. Tidak ada juga langkah-langkah arsitektur khusus platform, sehingga Anda dapat mem-build image multi-arch dengan Buildx.

  1. Periksa Dockerfile dengan menjalankan cat 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 ini menentukan dua tahap: tahap build dan tahap rilis. Anda menggunakan Dockerfile yang sama dengan yang digunakan untuk mem-build aplikasi x86. Jika mengikuti praktik terbaik untuk mem-build container, Anda mungkin dapat mem-build ulang image container sendiri tanpa mengubah apa pun.

  2. Jalankan perintah berikut untuk membuat dan menggunakan builder docker buildx baru:

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

    Setelah membuat builder baru ini, Anda dapat mem-build dan mengirim image yang kompatibel dengan linux/amd64 dan linux/arm64 menggunakan tanda --platform. Untuk setiap platform yang diberikan dengan flag tersebut, Buildx mem-build image di platform target. Saat Buildx mem-build image linux/arm64, Buildx akan mendownload image dasar arm64. Pada tahap pertama, Buildx mem-build biner pada image arm64 golang:1.18-alpine untuk arm64. Pada tahap kedua, image Alpine Linux arm64 didownload dan biner disalin ke lapisan image tersebut.

  3. Build dan kirim image:

    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 .
    

    Outputnya mirip dengan hal berikut ini:

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

    Output ini menunjukkan bahwa dua image telah dibuat, satu untuk linux/arm64 dan satu untuk linux/amd64.

  4. Periksa manifes image multi-arch Anda yang baru:

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

    Outputnya mirip dengan hal berikut ini:

    {
       "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"
             }
          }
       ]
    

    Dalam output ini, bagian manifests menyertakan dua manifes, satu dengan arsitektur platform amd64, dan satunya lagi dengan arsitektur platform arm64.

    Saat Anda men-deploy image container ini ke cluster, GKE secara otomatis hanya mendownload image yang sesuai dengan arsitektur node.

Men-deploy versi multi-arch aplikasi Anda

  1. Sebelum men-deploy image multi-arch, hapus workload asli:

    kubectl delete deploy x86-hello-deployment arm-hello-deployment
    
  2. Periksa overlay add_multiarch_support.yaml kustomisasi dengan menjalankan cat k8s/overlays/multiarch/add_multiarch_support.yaml:

    Outputnya mencakup set toleransi berikut:

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

    Toleransi ini memungkinkan workload berjalan di node Arm di cluster Anda, karena toleransi cocok dengan taint yang ditetapkan di semua node Arm. Karena workload ini kini dapat berjalan pada node mana pun di cluster, hanya toleransi yang diperlukan. Hanya dengan toleransi, GKE dapat menjadwalkan workload ke node x86 dan Arm. Jika Anda ingin menentukan tempat GKE dapat menjadwalkan workload, gunakan pemilih node dan aturan afinitas node. Untuk mempelajari lebih lanjut cara menetapkan kolom ini, lihat Menyiapkan workload Arm untuk deployment.

  3. Deploy image container multi-arch dengan 6 replika:

    $(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. Tunggu selama 10 detik, lalu konfirmasi bahwa semua replika aplikasi sedang berjalan:

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

    Outputnya mirip dengan hal berikut ini:

    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>
    

    Output ini mencakup kolom NODE yang menunjukkan bahwa Pod berjalan di kedua node dalam node pool Arm dan yang lainnya di node pool default (x86).

  5. Jalankan perintah berikut untuk mengakses layanan dan melihat output-nya:

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

    Outputnya mirip dengan hal berikut ini:

    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
    

    Anda akan melihat bahwa Pod yang berjalan di berbagai platform arsitektur menjawab permintaan.

Anda telah mem-build dan men-deploy image multi-arch untuk menjalankan workload di beberapa arsitektur dengan lancar.

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Setelah menyelesaikan tutorial, Anda dapat membersihkan resource yang dibuat untuk mengurangi penggunaan kuota dan menghentikan biaya penagihan. Bagian berikut menjelaskan cara menghapus atau menonaktifkan resource ini.

Menghapus project

Cara termudah untuk menghilangkan penagihan adalah dengan menghapus project yang Anda buat untuk tutorial.

Untuk menghapus project:

  1. Di konsol Google Cloud, buka halaman Manage resource.

    Buka Manage resource

  2. Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Menghapus layanan, cluster, dan repositori

Jika Anda tidak ingin menghapus seluruh project, hapus cluster dan repositori yang Anda buat untuk tutorial:

  1. Hapus Service aplikasi dengan menjalankan kubectl delete:

    kubectl delete service hello-service
    

    Perintah ini menghapus load balancer Compute Engine yang Anda buat saat mengekspos Deployment.

  2. Hapus cluster Anda dengan menjalankan gcloud container clusters delete:

    gcloud container clusters delete $CLUSTER_NAME --zone $ZONE
    
  3. Hapus repositori:

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

Langkah selanjutnya