Usa VM interrupibles para ejecutar cargas de trabajo tolerantes a errores


En esta página, se muestra cómo usar VM interrumpibles en Google Kubernetes Engine (GKE).

Descripción general

Las VM interrumpibles son instancias de VM de Compute Engine que tienen un precio menor que las VM estándar y no proporcionan garantía de disponibilidad. Las VM interrumpibles ofrecen una funcionalidad similar a las VM Spot, pero solo duran hasta 24 horas después de la creación.

En algunos casos, una VM interrumpible puede durar más de 24 horas. Esto puede ocurrir cuando la nueva instancia de Compute Engine surge demasiado rápido y Kubernetes no reconoce que se creó una VM diferente. La instancia subyacente de Compute Engine tendrá una duración máxima de 24 horas y seguirá el comportamiento esperado de una VM interrumpible.

Comparación con las VM Spot

Las VM interrumpibles comparten muchas similitudes con las VM Spot, incluidas las siguientes:

A diferencia de las VM Spot, que no tienen un tiempo de vencimiento máximo, las VM interrumpibles solo duran hasta 24 horas después de la creación.

Puedes habilitar las VM interrumpibles en clústeres y grupos de nodos nuevos, usar nodeSelector o la afinidad de nodos para controlar la programación, y usar taints y tolerancias a fin de evitar problemas con las cargas de trabajo del sistema cuando se interrumpen los nodos.

Finalización y cierre ordenado de VM interrumplibles.

Cuando Compute Engine necesita reclamar los recursos que usan las VM interrumpibles, se envía un aviso de interrupción a GKE. Las VM interrumpibles finalizan 30 segundos después de recibir una notificación de finalización.

De forma predeterminada, los clústeres usan el apagado ordenado de los nodos. kubelet observa el aviso de finalización y finaliza sin problemas los Pods que se ejecutan en el nodo. Si los Pods son parte de una implementación, el controlador crea y programa Pods nuevos para reemplazar los Pods cerrados.

En función del mejor esfuerzo, kubelet otorga un período de finalización ordenado de 15 segundos para Pods que no son del sistema, después de los cuales los Pods del sistema (con priorityClasses system-cluster-critical o system-node-critical) tienen 15 segundos para finalizar de forma correcta.

Durante la finalización correcta del nodo, kubelet actualiza el estado de los Pods y asigna una fase Failed y un motivo Terminated a los Pods terminados.

Cuando la cantidad de Pods finalizados alcanza un umbral de 1,000 para los clústeres con menos de 100 nodos o 5,000 para los clústeres con 100 nodos o más, la recolección de elementos no utilizados limpia los Pods.

También puedes borrar los Pods finalizados de forma manual con los siguientes comandos:

  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

Modificaciones del comportamiento de Kubernetes

El uso de VM interrumpibles en GKE modifica algunas garantías y restricciones que proporciona Kubernetes, como las siguientes:

  • GKE cierra las VMs interrumpibles sin un período de gracia para Pods, 30 segundos después de recibir una notificación de interrupción de Compute Engine.

  • La reclamación de VM interrumpibles es involuntaria y no está cubierta por las garantías de PodDisruptionBudgets. Es posible que experimentes una falta de disponibilidad superior al PodDisruptionBudget configurado.

Limitaciones

Crea un clúster o un grupo de nodos con VM interrumpibles

Puedes usar Google Cloud CLI para crear un clúster o grupo de nodos con VM interrumpibles.

Para crear un clúster con VM interrumpibles, ejecuta el siguiente comando:

gcloud container clusters create CLUSTER_NAME \
    --preemptible

Reemplaza CLUSTER_NAME por el nombre de tu clúster nuevo.

Para crear un grupo de nodos con VM interrumpibles, ejecuta el siguiente comando:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --preemptible

Reemplaza POOL_NAME por el nombre de tu grupo de nodos nuevo.

Usa nodeSelector para programar Pods en VM interrumpibles

GKE agrega las etiquetas cloud.google.com/gke-preemptible=true y cloud.google.com/gke-provisioning=preemptible (para nodos que ejecutan la versión 1.25.5-gke.2500 o una posterior de GKE) a los nodos que usan VMs interrumpibles. Puedes usar un nodeSelector en tus implementaciones para indicarle a GKE que programe Pods en VMs interrumpibles.

Por ejemplo, el siguiente objeto Deployment filtra las VMs interrumpibles con la etiqueta 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"

Usa taints de nodo para VM interrumpibles

Puedes aplicar un taint a los nodos que usen VM interrumpibles para que GKE solo pueda colocar Pods con la tolerancia correspondiente en esos nodos.

Para agregar un taint de nodo a un grupo de nodos que usa VM interrumpibles, usa la marca --node-taints cuando crees el grupo de nodos, similar al siguiente comando:

gcloud container node-pools create POOL2_NAME \
    --cluster=CLUSTER_NAME \
    --node-taints=cloud.google.com/gke-preemptible="true":NoSchedule

Ahora, solo los Pods que toleran el taint de nodo están programados en el nodo.

Para agregar la tolerancia relevante para los Pods, modifica las implementaciones y agrega lo siguiente a la especificación del Pod:

tolerations:
- key: cloud.google.com/gke-preemptible
  operator: Equal
  value: "true"
  effect: NoSchedule

Taints de nodo para VM interrumpibles de GPU

Las VM interrumpibles son compatibles con las GPU. Debes crear al menos otro grupo de nodos en tu clúster que no use VM interrumpibles antes de agregar un grupo de nodos de GPU que use VM interrumpibles. Tener un grupo de nodos estándar garantiza que GKE pueda colocar componentes del sistema como DNS de forma segura.

Si creas un clúster nuevo con grupos de nodos de GPU que usan VM interrumpibles o si agregas un grupo de nodos de GPU nuevo que usa VM interrumpibles a un clúster que aún no tiene un grupo de nodos estándar, GKE no agrega de forma automática el taint nvidia.com/gpu=present:NoSchedule a los nodos. GKE podría programar Pods del sistema en las VM interrumpibles, lo que puede provocar interrupciones. Este comportamiento también aumenta el consumo de los recursos, puesto que los nodos de GPU son más caros que los que no son de GPU.

¿Qué sigue?