Migrazione dei carichi di lavoro in tipi di macchine diversi


Questo tutorial illustra come eseguire la migrazione di carichi di lavoro in esecuzione su un cluster Google Kubernetes Engine (GKE) in un nuovo set di nodi all'interno dello stesso cluster senza comportare tempi di inattività per l'applicazione. Una migrazione di questo tipo può essere utile se vuoi eseguire la migrazione dei carichi di lavoro in nodi con un tipo di macchina diverso.

Contesto

Un pool di nodi è un sottoinsieme di macchine che hanno la stessa configurazione, inclusi gli ambiti di autorizzazione (CPU e memoria) delle macchine. I pool di nodi rappresentano un sottoinsieme di nodi all'interno di un cluster, che può contenere uno o più pool di nodi.

Quando devi modificare il profilo della macchina del cluster Compute Engine, puoi creare un nuovo pool di nodi ed eseguire la migrazione dei carichi di lavoro al nuovo pool di nodi.

Per eseguire la migrazione dei carichi di lavoro senza tempi di inattività, devi:

  • Contrassegna il pool di nodi esistente come non pianificabile.
  • Svuota i carichi di lavoro in esecuzione sul pool di nodi esistente.
  • Elimina il pool di nodi esistente.

Kubernetes, che è il sistema di orchestrazione dei cluster dei cluster GKE, riprogramma automaticamente i pod eliminati nel nuovo pool di nodi mentre svuota il pool di nodi esistente.

Obiettivi

  • Creare un cluster GKE.
  • Esegui il deployment dell'applicazione web di esempio nel cluster.
  • Crea un nuovo pool di nodi.
  • Esegui la migrazione dei pod nel nuovo pool di nodi senza tempi di inattività.

Costi

Questo tutorial utilizza 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 possono beneficiare di una prova gratuita.

Al termine di questo tutorial, puoi evitare una fatturazione continua eliminando le risorse che hai creato. Per scoprire di più, vedi Pulizia.

Prima di iniziare

Per abilitare l'API Kubernetes Engine:
  1. Vai alla pagina Kubernetes Engine in Google Cloud Console.
  2. Crea o seleziona un progetto.
  3. Attendi l'attivazione dell'API e dei servizi correlati. L'operazione potrebbe richiedere diversi minuti.
  4. Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.

Installa i seguenti strumenti a riga di comando utilizzati in questo tutorial:

  • gcloud viene utilizzato per creare ed eliminare i cluster di Kubernetes Engine. gcloud è incluso nell'interfaccia a riga di comando di gcloud.
  • kubectl viene utilizzato per gestire Kubernetes, il sistema di orchestrazione dei cluster utilizzato da Kubernetes Engine. Puoi installare kubectl utilizzando gcloud:
    gcloud components install kubectl

Clona il codice di esempio da GitHub:

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

Imposta i valori predefiniti per lo strumento a riga di comando gcloud

Per risparmiare tempo digitando le opzioni ID progetto e zona Compute Engine nello strumento a riga di comando gcloud, puoi impostare i valori predefiniti:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

Crea un cluster GKE

Il primo passaggio consiste nel creare un cluster di container per eseguire i carichi di lavoro delle applicazioni. Il comando seguente crea un nuovo cluster con cinque nodi con il tipo di macchina predefinito (e2-medium):

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

Esecuzione di un deployment di applicazioni replicato

Il file manifest seguente descrive un deployment di sei repliche dell'immagine container dell'applicazione web di esempio:


# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
---

Per il deployment del manifest, esegui questo comando:

kubectl apply -f node-pools-deployment.yaml

Puoi recuperare l'elenco dei pod eseguiti eseguendo:

kubectl get pods
Output:
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

Creazione di un pool di nodi con tipo di macchina di grandi dimensioni

Per impostazione predefinita, GKE crea un pool di nodi denominato default-pool per ogni nuovo cluster:

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

Per introdurre istanze con una configurazione diversa, ad esempio un tipo di macchina diverso o diversi ambiti di autenticazione, devi creare un nuovo pool di nodi.

Il comando seguente crea un nuovo pool di nodi denominato larger-pool con cinque istanze di memoria elevate del e2-highmem-2 tipo di macchina:

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

Ora il tuo cluster di container dovrebbe avere due pool di nodi:

gcloud container node-pools list --cluster migration-tutorial
Output:
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

Puoi visualizzare le istanze del nuovo pool di nodi aggiunte al tuo cluster GKE:

kubectl get nodes
Output:
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

Migrazione dei carichi di lavoro

Dopo aver creato un nuovo pool di nodi, i tuoi carichi di lavoro sono ancora in esecuzione su default-pool. Kubernetes non ripianifica i pod finché sono in esecuzione e disponibili.

Esegui questo comando per vedere su quale nodo sono in esecuzione i pod (vedi la colonna NODE):

kubectl get pods -o=wide
Output:
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

Per eseguire la migrazione di questi pod nel nuovo pool di nodi, devi:

  1. Cordon del pool di nodi esistente: questa operazione contrassegna i nodi nel pool esistente (default-pool) come non pianificabili. Kubernetes smette di pianificare nuovi pod in questi nodi dopo che li hai contrassegnati come non pianificabili.

  2. Svuota il pool di nodi esistente: questa operazione rimuove i carichi di lavoro in esecuzione sui nodi del pool di nodi esistente (default-pool).

I passaggi precedenti fanno sì che i pod in esecuzione nel pool di nodi esistenti vengano interrotti correttamente e Kubernetes li riprogramma su altri nodi disponibili. In questo caso, gli unici nodi disponibili si trovano nel pool di nodi larger-pool.

Per assicurarti che Kubernetes termina le tue applicazioni con grazia, i container devono gestire il segnale SIGTERM. Può essere utilizzato per chiudere le connessioni attive ai client ed eseguire il commit o interrompere le transazioni del database in modo pulito. Nel manifest del tuo pod puoi utilizzare il campo spec.terminationGracePeriodSeconds per specificare quanto tempo deve trascorrere Kubernetes prima di arrestare i container nel pod. Il valore predefinito è 30 secondi. Puoi trovare ulteriori informazioni sulla terminazione dei pod nella documentazione di Kubernetes.

Puoi comprimere e svuotare i nodi con il comando kubectl drain.

Innanzitutto, ottieni un elenco di nodi in default-pool:

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

Quindi, puoi eseguire un comando kubectl drain --force NODE (sostituisci NODE con i nomi del comando precedente). Il seguente comando shell esegue l'iterazione di ciascun nodo in default-pool, li contrassegna come non pianificabili e li svuote mediante l'eliminazione dei pod con un periodo di assegnazione controllato di 10 secondi.

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

Una volta completato il comando, dovresti vedere che lo stato dei nodi default-pool nell'elenco dei nodi è SchedulingDisabled:

kubectl get nodes
Output:
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

Inoltre, dovresti vedere che i pod sono ora in esecuzione sui nodi larger-pool:

kubectl get pods -o=wide
Output:
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

Eliminazione del pool di nodi precedente

Una volta che Kubernetes ha riprogrammato tutti i pod nel deployment web in larger-pool, ora è possibile eliminare default-pool poiché non è più necessario. Esegui questo comando per eliminare default-pool:

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

Al termine di questa operazione, dovresti avere un singolo pool di nodi per il tuo cluster di container, ovvero larger-pool:

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

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.

  • Elimina il cluster di container: questo passaggio elimina le risorse che costituiscono il cluster di container, ad esempio le istanze di calcolo, i dischi e le risorse di rete.

    gcloud container clusters delete migration-tutorial

Passaggi successivi