Esegui la migrazione di un'applicazione x86 su GKE a multi-arch con Arm


Questo tutorial descrive come eseguire la migrazione di un'applicazione creata per nodi che utilizzano un processore x86 (Intel o AMD) in un cluster Google Kubernetes Engine (GKE) a un'applicazione multiarchitettura (multi-arch) che viene eseguita su nodi x86 o Arm. Il pubblico di destinazione di questo tutorial è costituito da amministratori di piattaforme, operatori di app e sviluppatori di app che vogliono eseguire i carichi di lavoro esistenti compatibili con x86 su Arm.

Con i cluster GKE, puoi eseguire i workload sui nodi Arm utilizzando la serie di macchine C4A o la serie di macchine Tau T2A. Questo tutorial utilizza i nodi C4A, che, come i nodi T2A, possono essere eseguiti nel cluster GKE come qualsiasi altro nodo utilizzando processori x86 (Intel o AMD). I nodi C4A offrono prestazioni elevate e uniformi basate su ARM per i tuoi carichi di lavoro.

Per saperne di più, consulta la pagina Workload Arm su GKE.

Questo tutorial presuppone che tu abbia familiarità con Kubernetes e Docker. Il tutorial utilizza Google Kubernetes Engine e Artifact Registry.

Obiettivi

In questo tutorial completerai le seguenti attività:

  • Archiviare immagini container con Docker in Artifact Registry.
  • Esegui il deployment di un carico di lavoro compatibile con x86 in un cluster GKE.
  • Ricrea un workload compatibile con x86 per eseguirlo su Arm.
  • Aggiungi un pool di nodi Arm a un cluster esistente.
  • Esegui il deployment di un workload compatibile con Arm da eseguire su un nodo Arm.
  • Crea un'immagine multi-architettura per eseguire un carico di lavoro su più architetture.
  • Esegui carichi di lavoro su più architetture in un unico cluster GKE.

Costi

In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova gratuita.

Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la sezione Pulizia.

Prima di iniziare

Per abilitare l'API Kubernetes Engine, segui questi passaggi:
  1. 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.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

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

    Enable the APIs

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

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

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

    Enable the APIs

  8. Al termine di questo tutorial, puoi evitare l'addebito di ulteriori costi eliminando le risorse create. Per maggiori dettagli, vedi Esegui la pulizia.

Avvia Cloud Shell

In questo tutorial utilizzerai Cloud Shell, un ambiente shell per la gestione delle risorse ospitate su Google Cloud.

Cloud Shell include gli strumento a riga di comando Google Cloud CLI e kubectl. gcloud CLI fornisce l'interfaccia a riga di comando principale per Google Cloud, mentre kubectl fornisce l'interfaccia a riga di comando principale per l'esecuzione di comandi sui cluster Kubernetes.

Avvia Cloud Shell:

  1. Vai alla Google Cloud console.

    Google Cloud console

  2. Nell'angolo in alto a destra della console, fai clic sul pulsante Attiva Cloud Shell:

All'interno della console viene visualizzata una sessione di Cloud Shell. Utilizza questa shell per eseguire i comandi gcloud e kubectl.

prepara l'ambiente

In questa sezione, preparerai l'ambiente per seguire il tutorial.

Imposta le impostazioni predefinite per gcloud CLI

Imposta le variabili di ambiente per l'ID progetto, la posizione di Compute Engine per il tuo cluster e il nome del nuovo cluster.

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

Sostituisci PROJECT_ID con l'ID progetto che hai scelto per questo tutorial nella sezione Prima di iniziare.

In questo tutorial, creerai risorse in us-central1-a. Per visualizzare un elenco completo delle regioni e delle zone in cui è disponibile la serie di macchine C4A, consulta Regioni e zone disponibili.

Clona il repository Git

  1. Clona il repository:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  2. Cambia la directory di lavoro attuale con il repository clonato nel passaggio precedente:

    cd kubernetes-engine-samples/workloads/migrate-x86-app-to-multi-arch/
    

    Questo repository contiene i file necessari per completare questo tutorial. Questo tutorial utilizza i deployment Kubernetes. Un deployment è un oggetto API Kubernetes che consente di eseguire più repliche di pod distribuite tra i nodi di un cluster.

Crea un cluster GKE ed esegui il deployment dell'applicazione x86

Nella prima parte di questo tutorial, crei un cluster con nodi x86 ed esegui il deployment di un'applicazione x86. L'applicazione di esempio è un servizio che risponde alle richieste HTTP. È creato con il linguaggio di programmazione Golang.

Questa configurazione rappresenta l'aspetto di un tipico ambiente cluster, utilizzando applicazioni compatibili con x86 e nodi x86.

Crea un cluster GKE

Innanzitutto, crea un cluster GKE utilizzando nodi con processori x86. Con questa configurazione, crei un ambiente cluster tipico per eseguire applicazioni x86.

Crea il cluster:

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

Questo cluster ha la scalabilità automatica disabilitata per dimostrare funzionalità specifiche nei passaggi successivi.

Il processo di creazione del cluster potrebbe richiedere alcuni minuti. Il flag --async consente di eseguire questa operazione in background mentre completi i passaggi successivi.

Puoi creare cluster solo con nodi Arm, tuttavia per questo tutorial creerai prima un cluster solo con nodi x86 per scoprire come rendere compatibili con Arm le applicazioni solo x86.

Crea il repository Docker di Artifact Registry

  1. Crea un repository in Artifact Registry per archiviare le immagini Docker:

    gcloud artifacts repositories create docker-repo \
          --repository-format=docker \
          --location=us-central1 \
          --description="Docker repository"
    
  2. Configura lo strumento a riga di comando Docker per eseguire l'autenticazione a questo repository in Artifact Registry:

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

Crea l'immagine x86 ed eseguine il push in Artifact Registry

  1. Crea la versione dell'applicazione compatibile con x86:

    docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1 . 
    
  2. Esegui il push dell'immagine in Artifact Registry:

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

Esegui il deployment dell'applicazione x86

  1. Verifica che il cluster sia pronto eseguendo questo script:

    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
    

    Quando il cluster è pronto, l'output dovrebbe essere simile al seguente:

    GKE Cluster 'my-cluster' is RUNNING
    
  2. Recupera le credenziali del cluster in modo che kubectl possa connettersi all'API Kubernetes per il cluster:

    gcloud container clusters get-credentials $CLUSTER_NAME --location $CONTROL_PLANE_LOCATION --project $PROJECT_ID
    
  3. Aggiorna l'immagine utilizzando kustomize e implementa l'applicazione 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. Esegui il deployment di un servizio per esporre l'applicazione a internet:

    kubectl apply -f k8s/hello-service.yaml
    
  5. Verifica che il provisioning dell'indirizzo IP esterno per il servizio hello-service sia terminato:

    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
    

    Una volta eseguito il provisioning dell'indirizzo IP esterno, l'output dovrebbe essere simile al seguente:

    External IP: 203.0.113.0
    
  6. Invia una richiesta HTTP per verificare che il deployment funzioni come previsto:

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

    L'output è simile al seguente:

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

    L'output mostra che questo deployment compatibile con x86 è in esecuzione su un nodo nel pool di nodi predefinito sull'architettura amd64. I nodi nel pool di nodi predefinito del cluster hanno processori x86 (Intel o AMD).

Aggiungi nodi Arm al cluster

Nella parte successiva di questo tutorial, aggiungi nodi Arm al cluster esistente. Questi nodi sono quelli in cui viene implementata la versione compatibile con Arm dell'applicazione quando viene ricompilata per essere eseguita su Arm.

Checkpoint

Finora hai raggiunto i seguenti obiettivi:

  • crea un cluster GKE utilizzando nodi x86.
  • memorizzare un'immagine container compatibile con x86 con Docker in Artifact Registry.
  • eseguire il deployment di un carico di lavoro compatibile con x86 in un cluster GKE.

Hai configurato un ambiente cluster con nodi x86 e un carico di lavoro compatibile con x86. Questa configurazione è simile agli ambienti cluster esistenti se al momento non utilizzi nodi Arm e carichi di lavoro compatibili con Arm.

Aggiungere un pool di nodi Arm al cluster

Aggiungi un pool di nodi Arm al cluster esistente:

gcloud container node-pools create arm-pool \
    --cluster $CLUSTER_NAME \
    --location $CONTROL_PLANE_LOCATION \
    --machine-type=c4a-standard-2 \
    --num-nodes=1

Il tipo di macchina c4a-standard-2 è una VM Arm della serie di macchine C4A.

Crea un pool di nodi con nodi Arm nello stesso modo in cui crei un pool di nodi con nodi x86. Dopo la creazione di questo pool di nodi, nel cluster saranno in esecuzione sia nodi x86 sia nodi Arm.

Per saperne di più sull'aggiunta di node pool Arm ai cluster esistenti, consulta Aggiungere un pool di nodi Arm a un cluster GKE.

Scalare l'applicazione esistente in esecuzione su nodi basati su x86

I nodi di più tipi di architettura possono funzionare perfettamente insieme in un unico cluster. GKE non pianifica i workload esistenti in esecuzione su nodi x86 sui nodi Arm nel cluster perché viene inserito automaticamente un taint sui nodi Arm. Puoi verificarlo scalando la tua applicazione esistente.

  1. Aggiorna il carico di lavoro, aumentandolo a 6 repliche:

    $(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. Attendi 30 secondi, quindi esegui il comando seguente per controllare lo stato del deployment:

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

    L'output dovrebbe essere simile al seguente:

    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
    

    Questo output mostra i pod con stato In attesa perché non è rimasto spazio sui nodi basati su x86. Poiché il gestore della scalabilità automatica dei cluster è disabilitato e i nodi Arm sono tainted, i workload non verranno distribuiti su nessuno dei nodi Arm disponibili. Questa incompatibilità impedisce a GKE di pianificare i workload x86 sui nodi Arm. Per eseguire il deployment sui nodi Arm, devi indicare che il deployment è compatibile con i nodi Arm.

  3. Controlla i pod in stato Running:

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

    L'output dovrebbe essere simile al seguente:

    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>
    

    In questo output, la colonna NODE indica che tutti i pod del deployment vengono eseguiti solo nel pool predefinito, il che significa che i pod compatibili con x86 vengono pianificati solo sui nodi x86. Il pod originale già pianificato prima della creazione del pool di nodi Arm è ancora in esecuzione sullo stesso nodo.

  4. Esegui questo comando per accedere al servizio e visualizzare l'output:

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

    L'output è simile al seguente:

    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
    

    Questo output mostra che tutti i pod che gestiscono le richieste sono in esecuzione sui nodi x86. Alcuni pod non possono rispondere perché sono ancora in stato In attesa in quanto non c'è spazio sui nodi x86 esistenti e non verranno pianificati per i nodi Arm.

Ricompila l'applicazione per l'esecuzione su Arm

Nella sezione precedente hai aggiunto un pool di nodi Arm al cluster esistente. Tuttavia, quando hai eseguito lo scale up dell'applicazione x86 esistente, non ha pianificato nessuno dei workload sui nodi Arm. In questa sezione, ricompilerai l'applicazione in modo che sia compatibile con Arm, in modo che possa essere eseguita sui nodi Arm nel cluster.

Per questo esempio, completa questi passaggi utilizzando docker build. Questo approccio in due passaggi include:

  • Prima fase: crea il codice per Arm.
  • Seconda fase: copia l'eseguibile in un container lean.

Dopo aver seguito questi passaggi, avrai un'immagine compatibile con Arm oltre all'immagine compatibile con x86.

Il secondo passaggio di copia dell'eseguibile in un altro container segue una delle best practice per la creazione di un container, ovvero creare l'immagine più piccola possibile.

Questo tutorial utilizza un'applicazione di esempio creata con il linguaggio di programmazione Golang. Con Golang, puoi compilare in modo incrociato un'applicazione per diversi sistemi operativi e piattaforme CPU fornendo variabili di ambiente, GOOS e GOARCH, rispettivamente.

  1. Esegui cat Dockerfile_arm per visualizzare il Dockerfile scritto per 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
    

    Lo snippet mostrato qui mostra solo la prima fase. Nel file sono incluse entrambe le fasi.

    In questo file, l'impostazione GOARCH=arm64 indica al compilatore Go di creare l'applicazione per il set di istruzioni Arm. Non è necessario impostare GOOS perché l'immagine di base nella prima fase è un'immagine Linux Alpine.

  2. Crea il codice per Arm ed eseguine il push su 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
    

Esegui il deployment della versione Arm dell'applicazione

Ora che l'applicazione è stata creata per essere eseguita sui nodi Arm, puoi eseguirne il deployment sui nodi Arm del tuo cluster.

  1. Controlla add_arm_support.yaml eseguendo cat k8s/overlays/arm/add_arm_support.yaml:

    L'output è simile al seguente:

       nodeSelector:
          kubernetes.io/arch: arm64
    

    Questo nodeSelector specifica che il workload deve essere eseguito solo sui nodi Arm. Quando utilizzi nodeSelector, GKE aggiunge una tolleranza che corrisponde al taint sui nodi Arm, consentendo a GKE di pianificare il carico di lavoro su questi nodi. Per scoprire di più sull'impostazione di questo campo, vedi Preparare un workload Arm per il deployment.

  2. Esegui il deployment di una replica della versione dell'applicazione compatibile con 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. Attendi 5 secondi, poi verifica che il deployment di Arm risponda alle richieste curl:

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

    L'output è simile al seguente:

    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
    

    Questo output deve includere le risposte delle applicazioni compatibili con x86 e Arm alla richiesta curl.

Crea un'immagine multi-architettura per eseguire un carico di lavoro su più architetture

Sebbene tu possa utilizzare la strategia descritta nella sezione precedente e implementare carichi di lavoro separati per x86 e Arm, ciò richiederebbe di mantenere e organizzare due processi di build e due immagini container.

L'ideale sarebbe creare ed eseguire l'applicazione senza problemi su piattaforme x86 e Arm. Ti consigliamo questo approccio. Per eseguire l'applicazione con un manifest su più piattaforme di architettura, devi utilizzare immagini multi-architettura (multi-arch). Per scoprire di più sulle immagini multi-architettura, consulta Creare immagini multi-architettura per i carichi di lavoro Arm.

Per utilizzare immagini multi-architettura, devi assicurarti che la tua applicazione soddisfi i seguenti prerequisiti:

  • La tua applicazione non ha dipendenze specifiche della piattaforma di architettura.
  • Tutte le dipendenze devono essere create per più architetture o, come minimo, per le piattaforme di destinazione.

L'applicazione di esempio utilizzata in questo tutorial soddisfa entrambi questi prerequisiti. Tuttavia, ti consigliamo di testare le tue applicazioni quando crei le relative immagini multi-architettura prima di eseguirne il deployment in produzione.

Crea ed esegui il push di immagini multi-architettura

Puoi creare immagini multi-architettura con Docker Buildx se il tuo workload soddisfa i seguenti prerequisiti:

  • L'immagine di base supporta più architetture. Controlla eseguendo docker manifest inspect sull'immagine di base e controllando l'elenco delle piattaforme di architettura. Vedi un esempio di come ispezionare un'immagine alla fine di questa sezione.
  • L'applicazione non richiede passaggi di build speciali per ogni piattaforma di architettura. Se sono stati necessari passaggi speciali, Buildx potrebbe non essere sufficiente. Dovrai avere un Dockerfile separato per ogni piattaforma e creare il manifest manualmente con docker manifest create.

L'immagine di base dell'applicazione di esempio è Alpine, che supporta più architetture. Inoltre, non esistono passaggi specifici per la piattaforma di architettura, quindi puoi creare l'immagine multi-architettura con Buildx.

  1. Controlla il Dockerfile eseguendo 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" ]
    

    Questo Dockerfile definisce due fasi: la fase di build e la fase di rilascio. Utilizza lo stesso Dockerfile utilizzato per creare l'applicazione x86.

  2. Esegui il comando seguente per creare e utilizzare un nuovo builder docker buildx:

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

    Ora che hai creato questo nuovo builder, puoi creare e inviare un'immagine compatibile sia con linux/amd64 sia con linux/arm64 utilizzando il flag --platform. Per ogni piattaforma fornita con il flag, Buildx crea un'immagine nella piattaforma di destinazione. Quando Buildx crea l'immagine linux/arm64, scarica le immagini di base arm64. Nella prima fase, crea il file binario sull'immagine arm64 golang:1.18-alpine per arm64. Nella seconda fase, l'immagine arm64 Alpine Linux viene scaricata e il file binario viene copiato in un livello di questa immagine.

  3. Crea ed esegui il push dell'immagine:

    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 .
    

    L'output è simile al seguente:

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

    Questo output mostra che vengono generate due immagini, una per linux/arm64 e una per linux/amd64.

  4. Ispeziona il manifest della nuova immagine multi-architettura:

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

    L'output è simile al seguente:

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

    In questo output, la sezione manifests include due manifest, uno con l'architettura della piattaforma amd64 e l'altro con l'architettura della piattaforma arm64.

    Quando esegui il deployment di questa immagine container nel tuo cluster, GKE scarica automaticamente solo l'immagine che corrisponde all'architettura del nodo.

Esegui il deployment della versione multi-architettura dell'applicazione

  1. Prima di eseguire il deployment dell'immagine multi-architettura, elimina i workload originali:

    kubectl delete deploy x86-hello-deployment arm-hello-deployment
    
  2. Controlla l'overlay kustomize add_multiarch_support.yaml eseguendo cat k8s/overlays/multiarch/add_multiarch_support.yaml:

    L'output include il seguente insieme di tolleranze:

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

    Questa tolleranza consente al workload di essere eseguito sui nodi Arm nel cluster, poiché la tolleranza corrisponde al taint impostato su tutti i nodi Arm. Poiché questo workload ora può essere eseguito su qualsiasi nodo del cluster, è necessaria solo la tolleranza. Con la sola tolleranza, GKE può pianificare il workload sia sui nodi x86 che su quelli Arm. Se vuoi specificare dove GKE può pianificare i workload, utilizza i selettori di nodi e le regole di affinità dei nodi. Per scoprire di più sull'impostazione di questi campi, consulta Prepara un workload Arm per il deployment.

  3. Esegui il deployment dell'immagine container multi-architettura con 6 repliche:

    $(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. Attendi 10 secondi, poi verifica che tutte le repliche dell'applicazione siano in esecuzione:

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

    L'output è simile al seguente:

    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>
    

    Questo output include una colonna NODE che indica che i pod vengono eseguiti su entrambi i nodi nel pool di nodi Arm e su altri nel pool di nodi predefinito (x86).

  5. Esegui questo comando per accedere al servizio e visualizzare l'output:

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

    L'output è simile al seguente:

    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
    

    Dovresti vedere che i pod in esecuzione sulle piattaforme di architettura rispondono alle richieste.

Hai creato e implementato un'immagine multi-architettura per eseguire senza problemi un carico di lavoro su più architetture.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Al termine del tutorial, puoi eliminare le risorse che hai creato per ridurre l'utilizzo della quota e interrompere gli addebiti. Le seguenti sezioni descrivono come eliminare o disattivare queste risorse.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto creato per il tutorial.

Per eliminare il progetto:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Elimina il servizio, il cluster e il repository

Se non vuoi eliminare l'intero progetto, elimina il cluster e il repository che hai creato per il tutorial:

  1. Elimina il servizio dell'applicazione eseguendo kubectl delete:

    kubectl delete service hello-service
    

    Questo comando elimina il bilanciatore del carico Compute Engine che hai creato quando hai esposto il deployment.

  2. Elimina il cluster eseguendo gcloud container clusters delete:

    gcloud container clusters delete $CLUSTER_NAME --location $CONTROL_PLANE_LOCATION
    
  3. Elimina il repository:

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

Passaggi successivi