In dieser Anleitung wird beschrieben, wie eine Anwendung, die für Knoten mit einem x86-Prozessor (Intel oder AMD) in einem Google Kubernetes Engine (GKE)-Cluster erstellt wurde, in eine Anwendung mit mehreren Architekturen migriert wird, die entweder auf x86- oder Arm-Knoten ausgeführt wird. Die Zielgruppe für diese Anleitung sind Plattformadministratoren, Anwendungsoperatoren und Anwendungsentwickler, die ihre vorhandenen x86-kompatiblen Arbeitslasten auf Arm ausführen möchten.
Mit GKE-Clustern können Sie Arbeitslasten auf Arm-Knoten mithilfe der Tau T2A-Maschinenserie ausführen. T2A-Knoten können in Ihrem GKE-Cluster wie jeder andere Knoten mit x86-Prozessoren (Intel oder AMD) ausgeführt werden. Sie eignen sich gut für horizontal skalierbare und rechenintensive Arbeitslasten.
Weitere Informationen finden Sie unter Arm-Arbeitslasten in GKE.
In dieser Anleitung wird davon ausgegangen, dass Sie mit Kubernetes und Docker vertraut sind. In dieser Anleitung werden Google Kubernetes Engine und Artifact Registry verwendet.
Ziele
In dieser Anleitung führen Sie die folgenden Aufgaben aus:
- Container-Images mit Docker in Artifact Registry speichern.
- Eine mit x86 kompatible Arbeitslast in einem GKE-Cluster bereitstellen.
- Eine x86-kompatible Arbeitslast neu erstellen, die auf Arm ausgeführt wird.
- Einem vorhandenen Cluster einen Arm-Knotenpool hinzufügen.
- Eine Arm-kompatible Arbeitslast bereitstellen, die auf einem Arm-Knoten ausgeführt werden soll.
- Ein Image für mehrere Architekturen erstellen, um eine Arbeitslast in mehreren Architekturen auszuführen.
- Arbeitslasten in mehreren Architekturen in einem GKE-Cluster ausführen.
Kosten
In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Hinweise
Führen Sie folgende Schritte aus, um die Kubernetes Engine API zu aktivieren:- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry and Google Kubernetes Engine APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry and Google Kubernetes Engine APIs.
Nach Abschluss dieser Anleitung können Sie weitere Kosten durch Löschen von erstellten Ressourcen vermeiden. Weitere Informationen finden Sie unter Bereinigen.
Cloud Shell starten
In dieser Anleitung verwenden Sie Cloud Shell, eine Shell-Umgebung für die Verwaltung von Ressourcen, die in Google Cloud gehostet werden.
Die Google Cloud CLI und das kubectl
-Befehlszeilentool sind in Cloud Shell vorinstalliert. die gcloud-CLI ist die primäre Befehlszeile für Google Cloud und kubectl
ist die primäre Befehlszeile zum Ausführen von Befehlen für Kubernetes-Cluster.
Cloud Shell aufrufen
Öffnen Sie die Google Cloud Console.
Klicken Sie in der oberen rechten Ecke der Console auf die Schaltfläche Cloud Shell aktivieren:
In der Console wird eine Cloud Shell-Sitzung angezeigt.
In dieser Shell führen Sie gcloud
- und kubectl
-Befehle aus.
Umgebung vorbereiten
In diesem Abschnitt bereiten Sie Ihre Umgebung für die Anleitung vor.
Standardeinstellungen für die gcloud CLI festlegen
Legen Sie Umgebungsvariablen für Ihre Projekt-ID, die Zone und den Namen des neuen Clusters fest.
export PROJECT_ID=PROJECT_ID
export ZONE=us-central1-a
export CLUSTER_NAME=my-cluster
Ersetzen Sie PROJECT_ID
durch die Projekt-ID, die Sie für diese Anleitung im Abschnitt Vorbereitung ausgewählt haben.
In dieser Anleitung erstellen Sie Ressourcen in der Region „us-central1-a“. Eine vollständige Liste der Verfügbarkeit der Maschinentypen T2A-Maschinen finden Sie unter Verfügbare Regionen und Zonen.
Git-Repository klonen
Klonen Sie das Repository:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Ändern Sie das aktuelle Arbeitsverzeichnis in das im vorherigen Schritt geklonte Repository:
cd kubernetes-engine-samples/workloads/migrate-x86-app-to-multi-arch/
GKE-Cluster erstellen und x86-Anwendung bereitstellen
Im ersten Teil dieser Anleitung erstellen Sie einen Cluster mit x86-Knoten und stellen eine x86-Anwendung bereit. Die Beispielanwendung ist ein Dienst, der auf HTTP-Anfragen reagiert. Sie wird mit der Programmiersprache Golang erstellt.
Diese Einrichtung stellt eine typische Clusterumgebung dar, in der x86-kompatible Anwendungen und x86-Knoten verwendet werden.
GKE-Cluster erstellen
Erstellen Sie zuerst eine GKE mithilfe von Knoten mit x86-Prozessoren. Mit dieser Konfiguration erstellen Sie eine typische Clusterumgebung zum Ausführen von x86-Anwendungen.
Erstellen Sie den Cluster:
gcloud container clusters create $CLUSTER_NAME \
--release-channel=rapid \
--zone=$ZONE \
--machine-type=e2-standard-2 \
--num-nodes=1 \
--async
Für diesen Cluster ist Autoscaling deaktiviert, um in späteren Schritten bestimmte Funktionen zu zeigen.
Es kann einige Minuten dauern, bis der Cluster erstellt ist. Mit dem Flag --async
kann dieser Vorgang im Hintergrund ausgeführt werden, während Sie die nächsten Schritte ausführen.
Sie können Cluster nur mit Arm-Knoten erstellen. Für diese Anleitung erstellen Sie jedoch zuerst einen Cluster mit nur x86-Knoten, um zu erfahren, wie Sie x86-basierte Anwendungen mit Arm kompatibel machen.
Artifact Registry-Docker-Repository erstellen
Erstellen Sie in Artifact Registry ein Repository, um Docker-Images zu speichern:
gcloud artifacts repositories create docker-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
Konfigurieren Sie das Docker-Befehlszeilentool für die Authentifizierung bei diesem Repository in Artifact Registry:
gcloud auth configure-docker us-central1-docker.pkg.dev
x86-Image erstellen und in Artifact Registry übertragen
Erstellen Sie die x86-kompatible Version der Anwendung:
docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1 .
Übertragen Sie das Image per Push an Artifact Registry.
docker push us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/x86-hello:v0.0.1
x86-Anwendung bereitstellen
Prüfen Sie mit dem folgenden Script, ob der Cluster bereit ist:
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
Wenn der Cluster bereit ist, sollte die Ausgabe in etwa so aussehen:
GKE Cluster 'my-cluster' is RUNNING
Rufen Sie die Clusteranmeldedaten ab, damit
kubectl
eine Verbindung zur Kubernetes API für den Cluster herstellen kann:gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE --project $PROJECT_ID
Aktualisieren Sie das Image mit kustomize und stellen Sie die x86-Anwendung bereit:
$(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
Stellen Sie einen Dienst bereit, um die Anwendung im Internet freizugeben:
kubectl apply -f k8s/hello-service.yaml
Prüfen Sie, ob die externe IP-Adresse für den Dienst
hello-service
bereitgestellt wurde: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
Nachdem die externe IP-Adresse bereitgestellt wurde, sollte die Ausgabe in etwa so aussehen:
External IP: 203.0.113.0
Senden Sie eine HTTP-Anfrage, um zu testen, ob die Bereitstellung wie erwartet funktioniert:
curl -w '\n' http://$external_ip
Die Ausgabe sieht etwa so aus:
Hello from NODE:gke-my-cluster-default-pool-32019863-b41t, POD:x86-hello-deployment-6b7b456dd5-mwfkd, CPU PLATFORM:linux/amd64
Die Ausgabe zeigt, dass diese x86-kompatible Bereitstellung auf einem Knoten im Standardknotenpool der
amd64
-Architektur ausgeführt wird. Die Knoten im Standardknotenpool des Clusters haben x86-Prozessoren (Intel oder AMD).
Arm-Knoten zum Cluster hinzufügen
Im nächsten Teil dieser Anleitung fügen Sie Ihrem vorhandenen Cluster Arm-Knoten hinzu. Auf diesen Knoten wird die Arm-kompatible Version Ihrer Anwendung bereitgestellt, wenn sie für die Ausführung auf Arm neu erstellt wird.
Checkpoint
Bisher haben Sie die folgenden Ziele erreicht:
- Einen GKE-Cluster mit x86-Knoten erstellen.
- Ein x86-kompatibles Container-Image mit Docker in Artifact Registry speichern.
- Eine mit x86 kompatible Arbeitslast in einem GKE-Cluster bereitstellen.
Eine Clusterumgebung mit x86-Knoten und einer x86-kompatiblen Arbeitslast konfigurieren. Diese Konfiguration ähnelt Ihren vorhandenen Clusterumgebungen, wenn Sie derzeit keine Arm-Knoten und Arm-kompatible Arbeitslasten verwenden.
Ihrem Cluster einen Arm-Knotenpool hinzufügen
Fügen Sie Ihrem vorhandenen Cluster einen Arm-Knotenpool hinzu:
gcloud container node-pools create arm-pool \
--cluster $CLUSTER_NAME \
--zone $ZONE \
--machine-type=t2a-standard-2 \
--num-nodes=1
Der Maschinentyp t2a-standard-2
ist eine ARM-VM aus der Tau T2A-Maschinenreihe (Vorschau).
Sie erstellen einen Knotenpool mit Arm-Knoten auf die gleiche Weise wie einen Knotenpool mit x86-Knoten. Nachdem dieser Knotenpool erstellt wurde, werden in diesem Cluster sowohl x86-Knoten als auch Arm-Knoten ausgeführt.
Weitere Informationen zum Hinzufügen von Arm-Knotenpools zu vorhandenen Clustern finden Sie unter Arm-Knotenpool zu einem GKE-Cluster hinzufügen.
Vorhandene Anwendung skalieren, die auf x86-basierten Knoten ausgeführt wird
Knoten mehrerer Architekturtypen können nahtlos in einem Cluster zusammenarbeiten. GKE plant vorhandene Arbeitslasten die auf x86-Knoten ausgeführt werden, nicht auf Arm-Knoten im Cluster ein, da auf Arm-Knoten automatisch eine Markierung platziert wird. Skalieren Sie Ihre vorhandene Anwendung, um dies zu sehen.
Aktualisieren Sie die Arbeitslast und skalieren Sie sie auf 6 Replikate:
$(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/
Warten Sie 30 Sekunden und führen Sie dann den folgenden Befehl aus, um den Status der Bereitstellung zu überprüfen:
kubectl get pods -l="app=hello" --field-selector="status.phase=Pending"
Die Ausgabe sollte in etwa so aussehen:
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
Diese Ausgabe zeigt Pods mit dem Status „Ausstehend“, da auf den x86-basierten Knoten kein Platz mehr vorhanden ist. Da Cluster Autoscaler deaktiviert ist und die Arm-Knoten markiert sind, werden die Arbeitslasten auf keinem der verfügbaren Arm-Knoten bereitgestellt. Diese Markierung verhindert, dass GKE x86-Arbeitslasten auf Arm-Knoten plant. Damit eine Bereitstellung auf Arm-Knoten möglich ist, müssen Sie angeben, dass die Bereitstellung mit Arm-Knoten kompatibel ist.
Prüfen Sie die Pods mit dem Status „Wird ausgeführt“:
kubectl get pods -l="app=hello" --field-selector="status.phase=Running" -o wide
Die Ausgabe sollte in etwa so aussehen:
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 dieser Ausgabe gibt die Spalte
NODE
an, dass alle Pods aus der Bereitstellung nur im Standardpool ausgeführt werden. Die x86-kompatiblen Pods werden also nur für die x86-Knoten geplant. Der ursprüngliche Pod, der bereits vor dem Erstellen des Arm-Knotenpools geplant wurde, wird noch auf demselben Knoten ausgeführt.Führen Sie den folgenden Befehl aus, um auf den Dienst zuzugreifen und die Ausgabe zu sehen:
for i in $(seq 1 6); do curl -w '\n' http://$external_ip; done
Die Ausgabe sieht etwa so aus:
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
Diese Ausgabe zeigt, dass alle Pods, die Anfragen verarbeiten, auf x86-Knoten ausgeführt werden. Einige Pods können nicht antworten, da sie sich noch im Status „Ausstehend“ befinden, da auf den vorhandenen x86-Knoten kein Speicherplatz vorhanden ist und sie nicht für Arm-Knoten geplant werden.
Anwendung für die Ausführung auf Arm neu erstellen
Im vorherigen Abschnitt haben Sie einen Arm-Knotenpool zu Ihrem vorhandenen Cluster hinzugefügt. Wenn Sie die vorhandene x86-Anwendung jedoch hochskaliert haben, wurden keine Arbeitslasten für die Arm-Knoten geplant. In diesem Abschnitt erstellen Sie die Anwendung neu, damit sie Arm-kompatibel ist, damit diese Anwendung auf den Arm-Knoten im Cluster ausgeführt werden kann.
Führen Sie für dieses Beispiel diese Schritte mit docker build
aus.
Dieser zweistufige Ansatz umfasst:
- Erste Phase: Den Code für ARM erstellen.
- Zweite Phase: Die ausführbare Datei in einen schlanken Container kopieren.
Nach dem Ausführen dieser Schritte haben Sie zusätzlich zum x86-kompatiblen Image ein Arm-kompatibles Image.
Der zweite Schritt, das Kopieren der ausführbaren Datei in einen anderen Container, folgt einer der Best Practices für die Erstellung eines Containers, nämlich das Erstellen des kleinstmöglichen Images.
In dieser Anleitung wird eine Beispielanwendung verwendet, die mit der Programmiersprache Golang erstellt wurde. Mit Golang können Sie eine Anwendung auf verschiedene Betriebssysteme und CPU-Plattformen kompilieren. Dazu stellen Sie die Umgebungsvariablen GOOS
bzw. GOARCH
bereit.
Führen Sie
cat Dockerfile_arm
aus, um das für Arm geschriebene Dockerfile anzusehen:# # 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
Das hier gezeigte Snippet zeigt nur die erste Phase. Die Datei enthält beide Phasen.
In dieser Datei weist die Einstellung
GOARCH=arm64
den Go-Compiler an, die Anwendung für den Arm-Befehlssatz zu erstellen. Sie müssenGOOS
nicht festlegen, da das Basis-Image in der ersten Phase ein Linux Alpine-Image ist.Erstellen Sie den Code für Arm und übertragen Sie ihn per Push in 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-Version Ihrer Anwendung bereitstellen
Nachdem die Anwendung für die Ausführung auf Arm-Knoten erstellt wurde, können Sie sie auf den Arm-Knoten in Ihrem Cluster bereitstellen.
Prüfen Sie die Datei
add_arm_support.yaml
mit dem Befehlcat k8s/overlays/arm/add_arm_support.yaml
:Die Ausgabe sieht etwa so aus:
nodeSelector: kubernetes.io/arch: arm64
Dieser
nodeSelector
gibt an, dass die Arbeitslast nur auf den Arm-Knoten ausgeführt werden soll. Wenn Sie dennodeSelector
verwenden, fügt GKE eine Toleranz hinzu, die der Markierung auf Arm-Knoten entspricht, sodass GKE die Arbeitslast auf diesen Knoten planen kann. Weitere Informationen zum Festlegen dieses Felds finden Sie unter Arm-Arbeitslast für die Bereitstellung vorbereiten.Stellen Sie ein Replikat der ARM-kompatiblen Version der Anwendung bereit:
$(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
Warten Sie fünf Sekunden und prüfen Sie dann, ob die Arm-Bereitstellung
curl
-Anfragen beantwortet:for i in $(seq 1 6); do curl -w '\n' http://$external_ip; done
Die Ausgabe sieht etwa so aus:
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
Diese Ausgabe sollte Antworten von den x86-kompatiblen und Arm-kompatiblen Anwendungen enthalten, die auf die
curl
-Anfrage antworten.
Image mit mehreren Architekturen erstellen, um eine Arbeitslast architekturübergreifend auszuführen
Sie können zwar die im vorherigen Abschnitt beschriebene Strategie verwenden und separate Arbeitslasten für x86 und Arm bereitstellen, dafür müssen Sie jedoch zwei Build-Prozesse und zwei Container-Images verwalten und organisieren.
Im Idealfall möchten Sie Ihre Anwendung nahtlos auf x86- und Arm-Plattformen erstellen und ausführen. Wir empfehlen diesen Ansatz. Um Ihre Anwendung mit einem Manifest auf mehreren Architekturplattformen auszuführen, müssen Sie Images mit mehreren Architekturen verwenden. Weitere Informationen zu Images mit mehreren Architekturen finden Sie unter Images mit mehreren Architekturen für Arm-Arbeitslasten erstellen.
Wenn Sie Images mit mehreren Architekturen verwenden möchten, müssen Sie dafür sorgen, dass Ihre Anwendung die folgenden Voraussetzungen erfüllt:
- Ihre Anwendung hat keine Architektur-spezifischen Abhängigkeiten.
- Alle Abhängigkeiten müssen für mehrere Architekturen oder zumindest für die Zielplattformen erstellt werden.
Die in dieser Anleitung verwendete Beispielanwendung erfüllt beide dieser Voraussetzungen. Wir empfehlen Ihnen jedoch, Ihre eigenen Anwendungen beim Erstellen ihrer Images für mehrere Architekturen zu testen, bevor Sie sie für die Produktion bereitstellen.
Images mit mehreren Architekturen erstellen und übertragen
Sie können Images mit mehreren Architekturen mit Docker Buildx erstellen, wenn Ihre Arbeitslast die folgenden Voraussetzungen erfüllt:
- Das Basis-Image unterstützt mehrere Architekturen. Prüfen Sie dies durch Ausführen von
docker manifest inspect
für das Basis-Image und prüfen Sie die Liste der Architekturplattformen. Am Ende dieses Abschnitts finden Sie ein Beispiel für die Prüfung eines Images. - Die Anwendung erfordert keine speziellen Build-Schritte für jede Architekturplattform. Wenn spezielle Schritte erforderlich waren, reichte Buildx möglicherweise nicht aus. Sie benötigen ein separates Dockerfile für jede Plattform und erstellen das Manifest manuell mit
docker manifest create
.
Das Basis-Image der Beispielanwendung ist Alpine, das mehrere Architekturen unterstützt. Es gibt auch keine plattformspezifischen Schritte, sodass Sie das Image für mehrere Architekturen mit Buildx erstellen können.
Prüfen Sie das Dockerfile mit
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" ]
Dieses Dockerfile definiert zwei Phasen: die Build-Phase und die Release-Phase. Sie verwenden dasselbe Dockerfile, das zum Erstellen der x86-Anwendung verwendet wird.
Führen Sie den folgenden Befehl aus, um einen neuen
docker buildx
-Builder zu erstellen und zu verwenden:docker buildx create --name multiarch --use --bootstrap
Nachdem Sie diesen neuen Builder erstellt haben, können Sie ein Image erstellen und mit dem Flag
--platform
kompatibel machen, das sowohl mitlinux/amd64
als auch mitlinux/arm64
kompatibel ist. Für jede mit dem Flag bereitgestellte Plattform erstellt Buildx ein Image auf der Zielplattform. Wenn Buildx das Imagelinux/arm64
erstellt, werdenarm64
-Basis-Images heruntergeladen. In der ersten Phase wird die Binärdatei auf dem Imagearm64 golang:1.18-alpine
fürarm64
erstellt. In der zweiten Phase wird das Alpine Linux-Imagearm64
heruntergeladen und die Binärdatei in eine Ebene dieses Images kopiert.Erstellen Sie das Image und übertragen Sie es per 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 .
Die Ausgabe sieht etwa so aus:
=> [linux/arm64 builder x/x] .. => [linux/amd64 builder x/x] ..
Diese Ausgabe zeigt, dass zwei Images generiert werden, eines für
linux/arm64
und eines fürlinux/amd64
.Prüfen Sie das Manifest Ihres neuen Images für mehrere Architekturen:
docker manifest inspect us-central1-docker.pkg.dev/$PROJECT_ID/docker-repo/multiarch-hello:v0.0.1
Die Ausgabe sieht etwa so aus:
{ "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 dieser Ausgabe enthält der Abschnitt
manifests
zwei Manifeste, eines mit der Plattformarchitekturamd64
und das andere mit der Plattformarchitekturarm64
.Wenn Sie dieses Container-Image in Ihrem Cluster bereitstellen, lädt GKE automatisch nur das Image herunter, das der Architektur des Knotens entspricht.
Version für mehrere Architekturen Ihrer Anwendung bereitstellen
Löschen Sie die ursprünglichen Arbeitslasten, bevor Sie das Image für mehrere Architekturen bereitstellen:
kubectl delete deploy x86-hello-deployment arm-hello-deployment
Prüfen Sie das Kustomize-Overlay
add_multiarch_support.yaml
mit dem Befehlcat k8s/overlays/multiarch/add_multiarch_support.yaml
:Die Ausgabe enthält den folgenden Toleranzsatz:
tolerations: - key: kubernetes.io/arch operator: Equal value: arm64 effect: NoSchedule
Diese Toleranz ermöglicht die Ausführung der Arbeitslast auf den Arm-Knoten in Ihrem Cluster, da die Toleranz mit der Markierung auf allen Arm-Knoten übereinstimmt. Da diese Arbeitslast jetzt auf jedem Knoten im Cluster ausgeführt werden kann, ist nur die Toleranz erforderlich. Nur mit der Toleranz kann GKE die Arbeitslast für x86- und Arm-Knoten planen. Wenn Sie angeben möchten, wo GKE Arbeitslasten planen kann, verwenden Sie Knotenselektoren und Knotenaffinitätsregeln. Weitere Informationen zum Festlegen dieser Felder finden Sie unter Arm-Arbeitslast für die Bereitstellung vorbereiten.
Stellen Sie das Container-Image für mehrere Architekturen mit 6 Replikaten bereit:
$(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
Warten Sie 10 Sekunden und prüfen Sie dann, ob alle Replikate der Anwendung ausgeführt werden:
kubectl get pods -l="app=hello" -o wide
Die Ausgabe sieht etwa so aus:
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>
Diese Ausgabe enthält eine
NODE
-Spalte, die angibt, dass die Pods sowohl auf den Knoten im Arm-Knotenpool als auch auf anderen Knoten im Standard-Knotenpool (x86) laufen.Führen Sie den folgenden Befehl aus, um auf den Dienst zuzugreifen und die Ausgabe zu sehen:
for i in $(seq 1 6); do curl -w '\n' http://$external_ip; done
Die Ausgabe sieht etwa so aus:
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
Sie sollten sehen, dass Pods, die auf Architekturplattformen ausgeführt werden, die Anfragen beantworten.
Sie haben ein Image für mehrere Architekturen erstellt und bereitgestellt, um eine Arbeitslast nahtlos über mehrere Architekturen auszuführen.
Bereinigen
Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.
Nachdem Sie die Anleitung abgeschlossen haben, können Sie die von Ihnen erstellten Ressourcen bereinigen, um die Kontingentnutzung zu reduzieren und die Abrechnungsgebühren zu stoppen. In den folgenden Abschnitten erfahren Sie, wie Sie diese Ressourcen löschen oder deaktivieren.
Projekt löschen
Am einfachsten vermeiden Sie weitere Kosten durch Löschen des für die Anleitung erstellten Projekts.
So löschen Sie das Projekt:
- 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.
Dienst, Cluster und Repository löschen
Wenn Sie nicht das gesamte Projekt löschen möchten, löschen Sie den Cluster und das Repository, das Sie für die Anleitung erstellt haben:
Löschen Sie den Dienst der Anwendung mit
kubectl delete
:kubectl delete service hello-service
Dieser Befehl löscht den Compute Engine-Load-Balancer, den Sie beim Freigeben der Bereitstellung erstellt haben.
Löschen Sie den Cluster mit
gcloud container clusters delete
:gcloud container clusters delete $CLUSTER_NAME --zone $ZONE
Löschen Sie das Repository:
gcloud artifacts repositories delete docker-repo —location=us-central1 --async
Nächste Schritte
- Arm-Arbeitslasten in GKE
- Cluster und Knotenpools mit Arm-Knoten erstellen
- Images mit mehreren Architekturen für Arm-Arbeitslasten erstellen
- Arm-Arbeitslast für die Bereitstellung vorbereiten
- Autopilot-Arbeitslasten in der Arm-Architektur vorbereiten
- Best Practices zum Ausführen kostenoptimierter Kubernetes-Anwendungen in GKE
- Referenzarchitekturen, Diagramme und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center