Migrer des charges de travail vers différents types de machines

Ce tutoriel explique comment migrer des charges de travail exécutées sur un cluster GKE vers un nouvel ensemble de nœuds au sein du même cluster sans provoquer de temps d'arrêt pour votre application. Une telle migration peut être utile si vous souhaitez migrer vos charges de travail vers des nœuds avec un type de machine différent.

Contexte

Un pool de nœuds est un sous-ensemble de machines ayant toutes la même configuration, y compris les champs d'application des autorisations du type de machine (processeur et mémoire). Les pools de nœuds représentent un sous-ensemble de nœuds au sein d'un cluster. Un cluster de conteneurs peut contenir un ou plusieurs pools de nœuds.

Lorsque vous devez modifier le profil de machine de votre cluster Compute Engine, vous pouvez créer un nouveau pool de nœuds, puis migrer vos charges de travail vers le nouveau pool de nœuds.

Pour migrer vos charges de travail sans temps d'arrêt, vous devez :

  • marquer le pool de nœuds existant comme non planifiable ;
  • drainer les charges de travail s'exécutant sur le pool de nœuds existant ;
  • supprimer le pool de nœuds existant.

Kubernetes, le système d'orchestration de clusters GKE, reprogramme automatiquement les pods supprimés sur le nouveau pool de nœuds lorsqu'il draine le pool de nœuds existant.

Avant de commencer

Pour activer l'API Kubernetes Engine, procédez comme suit :
  1. Accédez à la page Kubernetes Engine dans Google Cloud Console.
  2. Créez ou sélectionnez un projet.
  3. Patientez le temps de l'activation de l'API et des services associés. Cette opération peut prendre plusieurs minutes.
  4. Vérifiez que la facturation est activée pour votre projet Google Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

Installez les outils de ligne de commande suivants utilisés dans ce tutoriel :

  • gcloud permet de créer et de supprimer des clusters Kubernetes Engine. gcloud est inclus dans le SDK Google Cloud.
  • kubectl permet de gérer Kubernetes, le système d'orchestration de clusters utilisé par Kubernetes Engine. Vous pouvez installer kubectl avec gcloud :
    gcloud components install kubectl

Définir des valeurs par défaut pour l'outil de ligne de commande gcloud

Pour gagner du temps lors de la saisie de vos options d'ID de projet et de zone Compute Engine dans l'outil de ligne de commande gcloud, vous pouvez définir les valeurs par défaut suivantes :
gcloud config set project project-id
gcloud config set compute/zone compute-zone

Étape 1 : Créer un cluster GKE

La première étape consiste à créer un cluster de conteneurs pour exécuter les charges de travail de l'application. La commande suivante crée un cluster comportant cinq nœuds avec le type de machine par défaut (e2-medium) :

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

Étape 2 : exécuter un déploiement d'application répliquée

La commande suivante crée un déploiement à six instances dupliquées de l'exemple d'image de conteneur d'application Web :

kubectl run web --image=gcr.io/google-samples/hello-app:1.0 \
  --replicas=6 --limits='cpu=100m,memory=80Mi'

Vous pouvez récupérer la liste des pods démarrés en exécutant la commande suivante :

kubectl get pods
Résultat :
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

Étape 3 : Créer un pool de nœuds avec un type de machine volumineux

Par défaut, GKE crée un pool de nœuds nommé default-pool pour chaque nouveau cluster :

gcloud container node-pools list --cluster migration-tutorial
Sortie :
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           1.5.7

Pour introduire des instances de configuration différente, par exemple un type de machine différent ou des champs d'application d'authentification différents, vous devez créer un pool de nœuds.

La commande suivante crée un pool de nœuds nommé larger-pool contenant cinq instances à haute capacité de mémoire avec un type de machine n1-highmem-2 :

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

Le cluster de conteneurs doit maintenant comporter deux pools de nœuds :

gcloud container node-pools list --cluster migration-tutorial
Résultat :
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           1.5.7
larger-pool   n1-highmem-2   100           1.5.7

Vous pouvez voir les instances du nouveau pool de nœuds ajouté au cluster GKE :

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

Étape 4 : Migrer les charges de travail

Une fois que vous avez créé un nouveau pool de nœuds, vos charges de travail continuent de s'exécuter sur le default-pool. Kubernetes ne replanifie pas les pods tant qu'ils sont en cours d'exécution et disponibles.

Exécutez la commande suivante pour voir sur quel nœud les pods s'exécutent (voir la colonne NODE) :

kubectl get pods -o=wide
Résultat :
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

Pour migrer ces pods vers le nouveau pool de nœuds, procédez comme suit :

  1. Marquez le pool de nœuds existant comme non ordonnançable : cette opération marque les nœuds du pool existant (default-pool) comme non ordonnançables. Kubernetes arrête de planifier de nouveaux pods sur ces nœuds lorsque vous les marquez comme non ordonnançables.

  2. Drainez le pool de nœuds existant : cette opération supprime de manière optimale les charges de travail s'exécutant sur les nœuds du pool de nœuds existant (default-pool).

Les étapes ci-dessus entraînent la fermeture des pods exécutés dans votre pool de nœuds existants et Kubernetes les replanifie sur d'autres nœuds disponibles. Dans ce cas, les seuls nœuds disponibles sont ceux du larger-pool créé à l'étape 3.

Pour vous assurer que Kubernetes arrête correctement vos applications, vos conteneurs doivent gérer le signal SIGTERM. Cela permet de fermer les connexions actives vers les clients, et de valider ou d'annuler correctement les transactions de base de données. Dans le fichier manifeste de votre pod, vous pouvez utiliser le champ spec.terminationGracePeriodSeconds pour spécifier la durée pendant laquelle Kubernetes doit attendre avant de supprimer les conteneurs du pod. La durée par défaut est de 30 secondes. Pour en savoir plus sur l'arrêt de pods, consultez la documentation de Kubernetes.

Commencez par marquer les nœuds du pool par défaut default-pool comme non ordonnançables. Vous pouvez exécuter la commande suivante pour obtenir la liste des nœuds de ce pool :

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

Ensuite, marquez chaque nœud comme non ordonnançable en exécutant une commande kubectl cordon NODE (remplacez NODE par les noms issus de la commande précédente). La commande suivante parcourt chaque nœud et les marque comme non ordonnançables :

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl cordon "$node";
done
Sortie :
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

Vous devriez maintenant constater que les nœuds default-pool ont l'état SchedulingDisabled dans la liste des nœuds :

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

Vous pouvez ensuite procéder de manière optimale au drainage des pods sur chaque nœud. Pour effectuer le drainage, utilisez la commande kubectl drain qui supprime les pods sur chaque nœud.

Vous pouvez exécuter kubectl drain --force NODE en remplaçant NODE par la même liste de noms transmise à la commande kubectl cordon.

La commande d'interface système suivante parcourt chaque nœud dans default-pool et les draine en expulsant les pods avec un délai de grâce attribué de 10 secondes :

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

Une fois cette commande terminée, vous devriez voir que les pods s'exécutent maintenant sur les nœuds de larger-pool :

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

Étape 5  : Supprimer l'ancien pool de nœuds

Une fois que Kubernetes a reprogrammé tous les pods du déploiement web sur le pool plus volumineux larger-pool, vous pouvez désormais supprimer le pool par défaut default-pool en toute sécurité car il n'est plus nécessaire. Exécutez la commande suivante pour supprimer le pool par défaut default-pool :

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

Une fois cette opération terminée, vous devez disposer d'un pool de nœuds unique pour votre cluster de conteneurs, le larger-pool :

gcloud container node-pools list --cluster migration-tutorial
Sortie :
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
larger-pool   n1-highmem-2   100           1.5.7

Nettoyer

Afin d'éviter que des frais ne soient facturés sur votre compte Google Cloud Platform pour les ressources utilisées dans ce tutoriel, procédez comme suit :

  • Supprimez le cluster de conteneurs : cette étape supprime les ressources qui constituent le cluster de conteneurs, telles que les instances de calcul, les disques et les ressources réseau.

    gcloud container clusters delete migration-tutorial

Étapes suivantes