Arbeitslasten zu anderen Maschinentypen migrieren


In dieser Anleitung wird gezeigt, wie Sie Arbeitslasten, die in einem Google Kubernetes Engine-Cluster (GKE) ausgeführt werden, zu einer neuen Gruppe von Knoten im selben Cluster migrieren, ohne dass eine Ausfallzeit für die Anwendung entsteht. Das kann nützlich sein, wenn Sie Arbeitslasten auf Knoten mit einem anderen Maschinentyp migrieren möchten.

Hintergrund

Ein Knotenpool ist eine Teilmenge von Computern, die hinsichtlich Maschinentyp (CPU und Arbeitsspeicher) und Autorisierungsbereichen gleich konfiguriert sind. Knotenpools fassen eine Knotenteilmenge in einem Cluster zusammen. Ein Containercluster kann einen oder mehrere Knotenpools enthalten.

Wenn Sie das Maschinenprofil Ihres Compute Engine-Clusters ändern möchten, können Sie einen neuen Knotenpool erstellen und Ihre Arbeitslasten dorthin migrieren.

Damit sich diese Migration ohne Ausfallzeit bewerkstelligen lässt, müssen Sie

  • den vorhandenen Knotenpool als nicht mehr planbar markieren,
  • die Arbeitslasten abziehen, die auf dem vorhandenen Knotenpool ausgeführt werden, und
  • den vorhandenen Knotenpool löschen.

Kubernetes, das Clusterorchestrierungssystem für GKE-Cluster, weist nach dem Entfernen des bisherigen Knotenpools die entfernten Pods automatisch dem neuen Knotenpool zu.

Ziele

  • Einen GKE-Cluster installieren
  • Beispielwebanwendung im Cluster bereitstellen
  • Einen neuen Knotenpool erstellen.
  • Pods ohne Unterbrechung auf den neuen Knotenpool migrieren.

Hinweis

Führen Sie folgende Schritte aus, um die Kubernetes Engine API zu aktivieren:
  1. Rufen Sie in der Google Cloud Console die Seite Kubernetes Engine auf.
  2. Erstellen Sie ein Projekt oder wählen Sie eines aus.
  3. Warten Sie, bis die API und die zugehörigen Dienste aktiviert worden sind. Dieser Vorgang kann einige Minuten dauern.
  4. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

Installieren Sie die folgenden Befehlszeilentools, die in dieser Anleitung verwendet werden:

  • Mit gcloud werden Kubernetes Engine-Cluster erstellt und gelöscht. gcloud ist im Google Cloud SDK enthalten.
  • kubectl wird zur Verwaltung von Kubernetes verwendet, dem Cluster-Orchestrierungssystem von Kubernetes Engine. Sie können kubectl mit gcloud installieren:
    gcloud components install kubectl

Klonen Sie den Beispielcode aus GitHub:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/migrating-node-pool

Standards für das gcloud-Befehlszeilentool festlegen

Wenn Sie die Projekt-ID und die Optionen für die Compute Engine-Zone nicht immer wieder neu in das gcloud-Befehlszeilentool eingeben möchten, können Sie die Standardwerte festlegen:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

GKE-Cluster erstellen

Im ersten Schritt erstellen Sie einen Containercluster, um Anwendungsarbeitslasten auszuführen. Mit dem folgenden Befehl erstellen Sie einen neuen Cluster mit fünf Knoten und dem Standardmaschinentyp (e2-medium):

gcloud container clusters create migration-tutorial --num-nodes=5

Repliziertes Anwendungs-Deployment ausführen

Das folgende Manifest beschreibt ein Deployment mit sechs Replikaten des Beispiel-Container-Images der Webanwendung:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 6
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: gcr.io/google-samples/hello-app:1.0

Führen Sie folgenden Befehl aus, um dieses Manifest bereitzustellen:

kubectl apply -f node-pools-deployment.yaml

Geben Sie zum Abrufen der Pod-Liste Folgendes ein:

kubectl get pods
Ausgabe:
NAME                   READY     STATUS    RESTARTS   AGE
web-2212180648-80q72   1/1       Running   0          10m
web-2212180648-jwj0j   1/1       Running   0          10m
web-2212180648-pf67q   1/1       Running   0          10m
web-2212180648-pqz73   1/1       Running   0          10m
web-2212180648-rrd3b   1/1       Running   0          10m
web-2212180648-v3b18   1/1       Running   0          10m

Knotenpool mit großem Maschinentyp erstellen

Standardmäßig erstellt GKE für jeden neuen Cluster den Knotenpool default-pool:

gcloud container node-pools list --cluster migration-tutorial
Ausgabe:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           1.16.13-gke.401

Damit Sie Instanzen mit einer anderen Konfiguration, etwa mit einem anderen Maschinentyp oder mit anderen Authentifizierungsbereichen, nutzen können, müssen Sie einen neuen Knotenpool erstellen.

Mit dem folgenden Befehl wird der neue Knotenpool larger-pool mit fünf Instanzen mit großem Arbeitsspeicher für den Maschinentyp e2-highmem-2 erstellt:

gcloud container node-pools create larger-pool \
  --cluster=migration-tutorial \
  --machine-type=e2-highmem-2 \
  --num-nodes=5

Der Containercluster sollte jetzt über zwei Knotenpools verfügen:

gcloud container node-pools list --cluster migration-tutorial
Ausgabe:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           v1.16.13-gke.401
larger-pool   e2-highmem-2   100           v1.16.13-gke.401

Mit folgendem Befehl können Sie die Instanzen des neuen Knotenpools, die Ihrem GKE-Cluster hinzugefügt wurden, anzeigen lassen:

kubectl get nodes
Ausgabe:
NAME                                                STATUS    AGE       VERSION
gke-migration-tutorial-default-pool-56e3af9a-059q   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready     4m        v1.16.13-gke.401

Arbeitslasten migrieren

Sie haben einen neuen Knotenpool erstellt, aber Ihre Arbeitslasten werden immer noch auf dem default-pool ausgeführt. Kubernetes kann Pods nicht neu zuweisen, wenn sie noch ausgeführt werden und verfügbar sind.

Führen Sie den folgenden Befehl aus, um zu sehen, auf welchem Knoten die Pods ausgeführt werden (siehe Spalte NODE):

kubectl get pods -o=wide
Ausgabe:
NAME                          READY     STATUS    IP         NODE
web-2212180648-80q72          1/1       Running   10.8.3.4   gke-migration-tutorial-default-pool-56e3af9a-k6jm
web-2212180648-jwj0j          1/1       Running   10.8.2.5   gke-migration-tutorial-default-pool-56e3af9a-0ng4
web-2212180648-pf67q          1/1       Running   10.8.4.4   gke-migration-tutorial-default-pool-56e3af9a-lkrv
web-2212180648-pqz73          1/1       Running   10.8.2.6   gke-migration-tutorial-default-pool-56e3af9a-0ng4
web-2212180648-rrd3b          1/1       Running   10.8.4.3   gke-migration-tutorial-default-pool-56e3af9a-lkrv
web-2212180648-v3b18          1/1       Running   10.8.1.4   gke-migration-tutorial-default-pool-56e3af9a-p9j4

Zum Migrieren dieser Pods auf den neuen Knotenpool müssen Sie folgende Schritte ausführen:

  1. Sperren Sie den vorhandenen Knotenpool. Dieser Vorgang markiert die Knoten im vorhandenen Knotenpool default-pool als nicht mehr planbar. Sobald die Knoten als nicht mehr planbar markiert sind, stellt Kubernetes die Zuweisung von neuen Pods für die Knoten ein.

  2. Leeren Sie den Inhalt des vorhandenen Knotenpools. Mit diesem Vorgang werden die Arbeitslasten entfernt, die auf den Knoten des vorhandenen Knotenpools default-pool ausgeführt werden.

Die vorherigen Schritte sorgen dafür, dass die auf dem vorhandenen Knotenpool ausgeführten Pods ordnungsgemäß beendet werden. Kubernetes weist sie anschließend den anderen verfügbaren Knoten zu. In diesem Fall befinden sich nur die Knoten im Knotenpool larger-pool.

Damit Kubernetes Ihre Anwendungen ordnungsgemäß beendet, müssen die Container das SIGTERM-Signal verarbeiten können. Mithilfe dieses Signals lassen sich aktive Clientverbindungen beenden und Datenbanktransaktionen können sauber per Commit abgeschlossen oder abgebrochen werden. Im Pod-Manifest können Sie im Feld spec.terminationGracePeriodSeconds angeben, wie lange Kubernetes warten muss, bevor die Container im Pod angehalten werden. Der Standardwert beträgt 30 Sekunden. Weitere Informationen über die Beendigung von Pods finden Sie in der Kubernetes-Dokumentation.

Sperren Sie zuerst die Knoten in default-pool. Mit dem folgenden Befehl rufen Sie dann eine Liste der Knoten in diesem Knotenpool ab:

kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool

Sperren Sie anschließend jeden Knoten durch Ausführen eines kubectl cordon NODE-Befehls. Ersetzen Sie dabei NODE durch die Namen aus dem vorherigen Befehl. Der folgende Befehl wird für jeden Knoten ausgeführt und markiert diese jeweils als nicht mehr planbar:

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl cordon "$node";
done
Ausgabe:
node "gke-migration-tutorial-default-pool-56e3af9a-059q" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-0ng4" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-k6jm" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-lkrv" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-p9j4" cordoned

Nun sollte für die Knoten des Pools default-pool der Status SchedulingDisabled in der Knotenliste angezeigt werden:

kubectl get nodes
Ausgabe:
NAME                                                STATUS                     AGE       VERSION
gke-migration-tutorial-default-pool-56e3af9a-059q   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready                      1h        v1.16.13-gke.401

Als Nächstes entfernen Sie ordnungsgemäß die Pods von den Knoten. Führen Sie dazu den Befehl kubectl drain aus.

Sie können kubectl drain --force NODE ausführen und dabei NODE durch die Namensliste ersetzen, die Sie an den Befehl kubectl cordon übergeben haben.

Der im Folgenden aufgeführte Shell-Befehl wird für jeden Knoten im Pool default-pool ausgeführt, um diese jeweils zu leeren. Dabei werden die Pods gemäß des festgelegten Beendigungszeitraums von zehn Sekunden ordnungsgemäß entfernt:

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 "$node";
done

Anschließend sollten Sie sehen können, dass die Pods nun auf den larger-pool-Knoten ausgeführt werden:

kubectl get pods -o=wide
Ausgabe:
NAME                   READY     STATUS    IP         NODE
web-2212180648-3n9hz   1/1       Running   10.8.9.4   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
web-2212180648-88q1c   1/1       Running   10.8.7.4   gke-migration-tutorial-larger-pool-b8ec62a6-2rhk
web-2212180648-dlmjc   1/1       Running   10.8.9.3   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
web-2212180648-hcv46   1/1       Running   10.8.5.4   gke-migration-tutorial-larger-pool-b8ec62a6-hs6p
web-2212180648-n0nht   1/1       Running   10.8.6.4   gke-migration-tutorial-larger-pool-b8ec62a6-7fl0
web-2212180648-s51jb   1/1       Running   10.8.8.4   gke-migration-tutorial-larger-pool-b8ec62a6-4bb2

Alten Knotenpool löschen

Wenn Kubernetes alle Pods im web-Deployment dem Pool larger-pool zugewiesen hat, können Sie den nicht mehr benötigten Pool default-pool problemlos löschen. Führen Sie den folgenden Befehl aus, um default-pool zu löschen:

gcloud container node-pools delete default-pool --cluster migration-tutorial

Am Ende des Vorgangs sollte mit larger-pool nur noch ein einziger Knotenpool für Ihren Containercluster vorhanden sein:

gcloud container node-pools list --cluster migration-tutorial
Ausgabe:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
larger-pool   e2-highmem-2   100           1.16.13-gke.401

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.

  • Containercluster löschen: Mit diesem Schritt werden Ressourcen gelöscht, die den Containercluster ausmachen, wie z. B. Compute-Instanzen, Laufwerke und Netzwerkressourcen.

    gcloud container clusters delete migration-tutorial

Nächste Schritte