Cette page explique comment utiliser des VM préemptives dans Google Kubernetes Engine (GKE).
Présentation
Les VM préemptives sont des instances de VM Compute Engine dont le prix est inférieur à celui des VM standards et qui n'offrent aucune garantie de disponibilité. Les VM préemptives présentent des fonctionnalités semblables aux Spot VMs, mais ne durent que jusqu'à 24 heures après leur création.
Dans certains cas, une VM préemptive peut durer plus de 24 heures. Cela peut se produire lorsque la nouvelle instance Compute Engine est générée trop rapidement et que Kubernetes ne détecte pas la création d'une VM Compute Engine différente. L'instance Compute Engine sous-jacente a une durée maximale de 24 heures et suit le comportement attendu de la VM préemptive.
Comparaison avec les Spot VMs
Les VM préemptives présentent de nombreuses similitudes avec les Spot VMs, y compris les suivantes :
- Elles sont arrêtées lorsque Compute Engine a besoin des ressources pour exécuter des VM standards.
- Elles sont utiles pour exécuter des charges de travail sans état, par lots ou tolérantes aux pannes.
- Tarifs inférieurs aux VM standards.
- Sur les clusters exécutant GKE version 1.20 ou ultérieure, la fonctionnalité d'arrêt progressif des nœuds est activée par défaut.
- Fonctionne avec l'autoscaler de cluster et le provisionnement automatique des nœuds.
Contrairement aux Spot VMs qui n'ont pas de délai d'expiration maximal, les VM préemptives ne durent que jusqu'à 24 heures après leur création.
Vous pouvez activer des VM préemptives sur les nouveaux clusters et pools de nœuds, utiliser nodeSelector
ou l'affinité de nœuds pour contrôler la planification, et utiliser des rejets et des tolérances pour éviter les problèmes liés aux charges de travail du système lorsque les nœuds sont préemptés.
Résiliation et arrêt progressif des VM préemptives
Lorsque Compute Engine doit récupérer les ressources utilisées par les VM préemptives, un avis de préemption est envoyé à GKE. Les VM préemptives s'arrêtent 30 secondes après la réception d'une notification d'arrêt.
Par défaut, les clusters utilisent l'arrêt en douceur des nœuds. Le kubelet détecte la notification d'arrêt et met fin aux pods en cours d'exécution sur le nœud de façon progressive. Si les pods font partie d'un déploiement, le contrôleur crée et planifie de nouveaux pods pour remplacer les pods arrêtés.
Dans la mesure du possible, le kubelet accorde un délai de grâce de 15 secondes aux pods non système, après quoi les pods système (avec les priorityClasses system-cluster-critical
ou system-node-critical
) disposent de 15 secondes pour s'arrêter progressivement.
Lors de l'arrêt progressif d'un nœud, le kubelet met à jour l'état des pods, en attribuant la phase Failed
et un motif Terminated
aux pods arrêtés.
Lorsque le nombre de pods arrêtés atteint un seuil de 1 000 pour les clusters de moins de 100 nœuds ou de 5 000 pour les clusters de 100 nœuds ou plus, la récupération de mémoire nettoie les pods.
Vous pouvez également supprimer manuellement des pods arrêtés à l'aide des commandes suivantes :
kubectl get pods --all-namespaces | grep -i NodeShutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
kubectl get pods --all-namespaces | grep -i Terminated | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
Modifications du comportement de Kubernetes
L'utilisation de VM préemptives sur GKE modifie certaines garanties et contraintes fournies par Kubernetes, telles que les suivantes :
GKE arrête les VM préemptives sans délai de grâce pour les pods, 30 secondes après la réception d'une notification de préemption de Compute Engine.
La récupération des VM préemptives est involontaire et n'est pas couverte par les garanties de
PodDisruptionBudgets
. Vous risquez de rencontrer une indisponibilité supérieure à la valeurPodDisruptionBudget
configurée.
Limites
- La fonctionnalité d'arrêt en douceur des nœuds kubelet n'est activée que sur les clusters exécutant GKE version 1.20 et ultérieure. Pour les versions de GKE antérieures à 1.20, vous pouvez utiliser le gestionnaire d'événements d'arrêt de nœuds Kubernetes sur GCP pour arrêter vos pods progressivement lorsque les VM préemptives sont arrêtées.
- Les VM préemptives ne sont pas compatibles avec les pools de nœuds Windows Server.
Créer un cluster ou un pool de nœuds doté de VM préemptives
Vous pouvez utiliser la CLI Google Cloud pour créer un cluster ou un pool de nœuds doté de machines virtuelles préemptives.
Pour créer un cluster avec des VM préemptives, exécutez la commande suivante :
gcloud container clusters create CLUSTER_NAME \
--preemptible
Remplacez CLUSTER_NAME
par le nom de votre nouveau cluster.
Pour créer un pool de nœuds avec des VM préemptives, exécutez la commande suivante :
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--preemptible
Remplacez POOL_NAME
par le nom de votre nouveau pool de nœuds.
Utiliser nodeSelector pour planifier des pods sur des VM préemptives
GKE ajoute les libellés cloud.google.com/gke-preemptible=true
et cloud.google.com/gke-provisioning=preemptible
(pour les nœuds exécutant la version 1.25.5-gke.2500 de GKE ou une version ultérieure) aux nœuds qui utilisent des VM préemptives. Vous pouvez utiliser un nodeSelector
dans vos déploiements pour indiquer à GKE de programmer les pods sur des VM préemptives.
Par exemple, le déploiement suivant filtre les VM préemptives à l'aide du libellé cloud.google.com/gke-preemptible
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-app
spec:
replicas: 3
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
resources:
requests:
cpu: 200m
nodeSelector:
cloud.google.com/gke-preemptible: "true"
Utiliser des rejets de nœuds pour les VM préemptives
Vous pouvez rejeter les nœuds qui utilisent des VM préemptives afin que GKE ne puisse placer que les pods avec la tolérance correspondante sur ces nœuds.
Pour ajouter un rejet de nœud à un pool de nœuds utilisant des VM préemptives, utilisez l'option --node-taints
lors de la création du pool de nœuds, comme pour la commande suivante :
gcloud container node-pools create POOL2_NAME \
--cluster=CLUSTER_NAME \
--node-taints=cloud.google.com/gke-preemptible="true":NoSchedule
Désormais, seuls les pods qui tolèrent le rejet de nœud spécifié pourront être programmés sur ce nœud.
Pour ajouter la tolérance appropriée à vos pods, modifiez vos déploiements et ajoutez les éléments suivants à la spécification de pod :
tolerations:
- key: cloud.google.com/gke-preemptible
operator: Equal
value: "true"
effect: NoSchedule
Rejets de nœuds pour les VM préemptives de GPU
Les VM préemptives sont compatibles avec l'utilisation des GPU. Vous devez créer au moins un autre pool de nœuds dans votre cluster qui n'utilise pas de VM préemptives avant d'ajouter un pool de nœuds GPU utilisant des VM préemptives. Le fait de disposer d'un pool de nœuds standards garantit que GKE peut placer en toute sécurité des composants système tels que DNS.
Si vous créez un cluster avec des pools de nœuds GPU utilisant des VM préemptives ou si vous ajoutez un pool de nœuds GPU qui utilise des VM préemptives à un cluster qui n'a pas encore de pool de nœuds standards, GKE n'ajoute pas automatiquement le rejet nvidia.com/gpu=present:NoSchedule
aux nœuds. GKE peut planifier des pods système sur les VM préemptives, ce qui peut entraîner des perturbations. Ce comportement augmente également la consommation de ressources, car les nœuds GPU coûtent plus cher que les nœuds non GPU.
Étapes suivantes
- Découvrez comment exécuter une application GKE sur des VM Spot avec des nœuds à la demande en tant que remplacement.
- Apprenez-en plus sur les Spot VM dans GKE.
- Apprenez-en plus sur les rejets et les tolérances.