Gestionar las interrupciones de nodos de GKE para GPUs y TPUs

Durante el ciclo de vida de un clúster de GKE de larga duración, se producen interrupciones periódicas en las cargas de trabajo debido a interrupciones en la infraestructura queTrusted Cloud by S3NS problemas. Estos eventos automáticos pueden producirse para responder a decisiones de programación (eventos de preferencia), actualizaciones del plano de control o de los nodos, que incluyen actualizaciones automáticas de nodos de GKE (eventos de mantenimiento) o correcciones de problemas detectados (eventos de finalización).

En esta página se explica qué significa la interrupción de nodos en GKE, cómo monitorizar las notificaciones de mantenimiento y cómo minimizar el impacto de las interrupciones en los nodos de GKE con GPUs y TPUs conectadas.

Este documento está dirigido a administradores y operadores de la plataforma que gestionan el ciclo de vida de la infraestructura tecnológica subyacente. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido de Trusted Cloud by S3NS , consulta Roles y tareas de usuario habituales de GKE.

¿Qué significa interrupción de la infraestructura en GKE?

Tus clústeres de GKE gestionan el ciclo de vida de los nodos de GKE. Estos nodos se aprovisionan en máquinas virtuales de Compute Engine, que experimentan periódicamente las siguientes interrupciones:

  • Corrección de problemas detectados (TerminationEvent): estos eventos se producen porque Trusted Cloud by S3NS detecta un problema e interrumpe la infraestructura de tu clúster. Los eventos TerminationEvent no admiten el cierre ordenado. Los eventos TerminationEvent se activan por los siguientes problemas:

    • La reparación automática se produce cuando GKE repara un nodo después de que no supere repetidas comprobaciones del estado.
    • HostError se produce cuando un error de hardware o software en la máquina física provoca que la máquina virtual se detenga.
  • Eventos de mantenimiento o actualización (MaintenanceEvent): estos eventos se producen cuando Trusted Cloud by S3NS necesita interrumpir una VM para realizar tareas de mantenimiento. Los eventos de MaintenanceEvent se activan con las siguientes tareas de mantenimiento:

    Para obtener más información sobre cómo gestionáis los cambios tú y GKE durante el ciclo de vida de un clúster, consulta Tipos de cambios.

  • Respuesta a las decisiones de programación (PreemptionEvent): se producen cuandoTrusted Cloud by S3NS necesita desalojar VMs para que haya capacidad disponible para recursos de mayor prioridad. Los eventos PreemptionEvent pueden ser cualquiera de los siguientes:

    • La evicción se produce cuando se interrumpe la infraestructura preemptible o Spot para dar cabida a una VM de mayor prioridad.
    • Desfragmentación: se produce cuando GKE interrumpe un sector de TPU más pequeño para dar cabida a un sector de TPU más grande. La desfragmentación solo se produce en las porciones de TPU.

Durante el ciclo de vida de un clúster de GKE de larga duración, los nodos pueden experimentar interrupciones periódicas en las cargas de trabajo de entrenamiento o de servicio. Cuando estas interrupciones afectan a los nodos de GKE que ejecutan cargas de trabajo de IA o aprendizaje automático, GKE debe reiniciar tanto las cargas de trabajo en ejecución como el nodo subyacente.

Por qué las GPUs y las TPUs requieren gestión de interrupciones

La mayoría de las VMs de Compute Engine, con algunas excepciones, tienen la política de mantenimiento del host definida como migración activa, lo que significa que las cargas de trabajo en ejecución suelen experimentar pocas interrupciones o ninguna. Sin embargo, determinados tipos de máquinas virtuales no admiten la migración en caliente, como las máquinas virtuales con GPUs y TPUs conectadas. Cuando se produce un evento de host en la VM de una porción de TPU, se interrumpe toda la porción y, a continuación, se reprograma, ya que todos los eventos de mantenimiento se coordinan a nivel de porción. Por lo tanto, si creas un segmento de TPU que tiene cientos de VMs, todas esas VMs recibirán la misma programación de eventos de mantenimiento.

Cuando se produce un evento de host, GKE finaliza el nodo y sus pods. Si los pods se implementan como parte de una carga de trabajo más grande, como un trabajo o una implementación, GKE reinicia los pods en el nodo afectado.

Tú o los frameworks que utilices debéis gestionar la configuración de la carga de trabajo para reaccionar adecuadamente a los eventos de mantenimiento. Por ejemplo, puedes guardar el estado de tu tarea de entrenamiento de IA para reducir la pérdida de datos.

Para gestionar las interrupciones en las cargas de trabajo de IA o aprendizaje automático, puedes hacer lo siguiente:

Monitorizar las interrupciones de los nodos

La siguiente métrica del sistema de GKE informa del número de interrupciones de un nodo de GKE desde la última muestra (la métrica se muestrea cada 60 segundos):

  • kubernetes.io/node/interruption_count

Los campos interruption_type (como TerminationEvent, MaintenanceEvent o PreemptionEvent) y interruption_reason (como HostError, Eviction o AutoRepair) pueden ayudar a explicar por qué se ha interrumpido un nodo.

Para obtener un desglose de las interrupciones y sus causas en los nodos de TPU de los clústeres de tu proyecto, usa la siguiente consulta de PromQL:

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node"}[${__interval}]))

Para ver solo los eventos de mantenimiento del host, actualice la consulta para filtrar el valor HW/SW Maintenance del interruption_reason. Usa la siguiente consulta de PromQL:

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node", interruption_reason="HW/SW Maintenance"}[${__interval}]))

Para ver el recuento de interrupciones agregado por grupo de nodos, usa la siguiente consulta de PromQL:

  sum by (node_pool_name,interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_pool_interruption_count{monitored_resource="k8s_node_pool", interruption_reason="HW/SW Maintenance", node_pool_name=NODE_POOL_NAME }[${__interval}]))

Monitorizar las notificaciones de mantenimiento

Compute Engine envía notificaciones cuando se programan eventos del host disruptivos para los nodos y sus VMs subyacentes, y cuando estos eventos se activan. Las notificaciones incluyen información sobre la hora de inicio programada, el tipo de evento y otros detalles.

En GKE 1.31.1-gke.2008000 y versiones posteriores, puedes monitorizar los próximos eventos de mantenimiento, incluidos los que se describen en esta sección.

El mantenimiento programado aún no está activo

Antes de que una máquina virtual con GPUs o TPUs adjuntas tenga un evento de mantenimiento programado, Compute Engine envía notificaciones a todas sus máquinas virtuales. Estas notificaciones informan del inicio de la ventana de mantenimiento. Cuando la VM programa un mantenimiento próximo, pero no está activo, GKE añade scheduled-maintenance-time a la etiqueta del nodo.

Para consultar estas notificaciones a nivel de nodo, ejecuta el siguiente comando:

kubectl get nodes -l cloud.google.com/scheduled-maintenance-time \
    -L cloud.google.com/scheduled-maintenance-time

El resultado debería ser similar al siguiente:

NAME                         STATUS    SCHEDULED-MAINTENANCE-TIME
<gke-accelerator-node-name>  Ready     1733083200
<gke-accelerator-node-name>  Ready     1733083200
[...]

La columna SCHEDULED-MAINTENANCE-TIME representa los segundos, que se muestran en formato de tiempo de época de Unix.

Para consultar estas notificaciones a nivel de metadatos de nodo, consulta las instancias para ver si hay notificaciones de eventos de mantenimiento.

En las familias de máquinas optimizadas para aceleradores que admiten el mantenimiento avanzado, puedes acceder al endpoint upcoming-maintenance, que proporciona información sobre los eventos de mantenimiento programados e iniciados.

Minimizar el impacto de las interrupciones

Compute Engine envía notificaciones sobre los próximos eventos de mantenimiento y programa una ventana de mantenimiento. Entre la hora de la notificación y la hora de inicio de la ventana de mantenimiento, puedes hacer lo siguiente:

  • Iniciar manualmente un evento de mantenimiento del host.
  • Permite que Compute Engine inicie el evento de mantenimiento según lo programado.

Iniciar manualmente un evento de mantenimiento de host

Cuando Compute Engine emite una notificación sobre un evento de mantenimiento programado, puedes iniciar manualmente el mantenimiento a una hora que se ajuste a tu programación operativa, por ejemplo, durante los periodos de menor actividad.

En un nodo del grupo de nodos, asigna la etiqueta de nodo cloud.google.com/perform-maintenance a true. Por ejemplo:

kubectl label nodes <node-name> cloud.google.com/perform-maintenance=true

Si inicias un evento de mantenimiento, GKE ejecuta las siguientes operaciones:

  1. Marca el nodo.
  2. Expulsa los pods de forma correcta.
  3. Solicita a Compute Engine que inicie el evento de mantenimiento inmediatamente, en lugar de esperar a la hora programada.

Compute Engine inicia el evento de mantenimiento según lo programado

Si no inicias un evento de mantenimiento del host, Compute Engine iniciará el evento de mantenimiento programado por su cuenta. A partir de la versión 1.33 de GKE, el nodo no se contamina y los pods no se expulsan cuando empieza la ventana de mantenimiento.

Cuando se inicia el evento de mantenimiento, es posible que un nodo se apague una o varias veces con un breve tiempo de notificación antes de su finalización inminente. En estos casos, GKE hace todo lo posible para finalizar las cargas de trabajo y expulsar los pods de forma correcta.

Se inicia el mantenimiento programado

Cuando empieza el mantenimiento programado, Compute Engine actualiza los metadatos del directorio http://metadata.google.internal/computeMetadata/v1/instance/attributes/. Compute Engine actualiza las etiquetas de metadatos de la siguiente manera:

  • Asigna el valor TERMINATE_ON_HOST_MAINTENANCE a maintenance-event.
  • En upcoming-maintenance, asigna el valor ONGOING a maintenance_status.

GKE gestiona un evento de mantenimiento de host programado en función de si lo activas manualmente o dejas que GKE lo haga automáticamente.

Configurar GKE para que finalice las cargas de trabajo correctamente

En esta sección, configurarás GKE para gestionar el ciclo de vida de tu aplicación y minimizar las interrupciones en tu carga de trabajo. Si no configuras un periodo de gracia, se aplicará el periodo de gracia predeterminado de 30 segundos.

GKE hace todo lo posible para finalizar estos pods correctamente y ejecutar la acción de finalización que definas (por ejemplo, guardar un estado de entrenamiento). GKE envía una señal SIGTERM a los pods al principio del periodo de gracia. Si los pods no salen al final del periodo de gracia, GKE envía una señal SIGKILL de seguimiento a los procesos que aún se estén ejecutando en cualquier contenedor del pod.

Para configurar el periodo de finalización gradual, define el periodo de gracia de finalización (en segundos) en el campo spec.terminationGracePeriodSeconds del manifiesto de tu pod. Por ejemplo, para recibir una notificación 10 minutos después, define el campo spec.terminationGracePeriodSeconds en el manifiesto de tu pod como 600 segundos, de la siguiente manera:

    spec:
      terminationGracePeriodSeconds: 600

Te recomendamos que definas un periodo de gracia de finalización lo suficientemente largo para que las tareas en curso se completen dentro del plazo de notificación. Si tu carga de trabajo usa un framework de aprendizaje automático como MaxText, Pax o JAX con Orbax, las cargas de trabajo pueden capturar la señal SIGTERM de cierre e iniciar un proceso de creación de puntos de control. Para obtener más información, consulta Autocheckpoint de TPU.

Proceso de finalización correcta

Cuando empieza un evento de mantenimiento iniciado manualmente, Compute Engine indica el cierre inminente de la máquina actualizando la clave de metadatos maintenance-event. GKE inicia la finalización ordenada.

En el siguiente flujo de trabajo se muestra cómo ejecuta GKE la finalización correcta de nodos cuando se va a apagar un nodo:

  1. En un plazo de 60 segundos, ocurre lo siguiente:
    1. Los componentes del sistema aplican el cloud.google.com/active-node-maintenance conjunto de etiquetas de nodo ONGOING para indicar que se están deteniendo las cargas de trabajo.
    2. GKE aplica el taint de nodo para evitar que se programen nuevos pods en el nodo. La intolerancia tiene la clave cloud.google.com/impending-node-termination:NoSchedule. Te recomendamos que no modifiques tus cargas de trabajo para tolerar este taint debido a la finalización conocida que se produce.
  2. El componente maintenance-handler empieza a expulsar pods. Primero, expulsa los pods de carga de trabajo y, después, los pods del sistema (por ejemplo, kube-system).
  3. GKE envía una señal de SIGTERMapagado a los pods de carga de trabajo que se ejecutan en el nodo para alertarlos de un apagado inminente. Los pods pueden usar esta alerta para finalizar las tareas en curso. GKE hace todo lo posible para terminar estos pods correctamente.
  4. Una vez que finaliza el desalojo, GKE actualiza el valor de la etiqueta cloud.google.com/active-node-maintenance terminating para indicar que el nodo está listo para finalizar.

Después, se termina el nodo y se asigna un nodo de sustitución. GKE borra las etiquetas y los taints cuando finaliza el proceso. Para aumentar el periodo de finalización de las cargas de trabajo que usan GPUs o TPUs, siga los pasos que se indican en la sección Iniciar manualmente un evento de mantenimiento de host.

Monitorizar el progreso de una finalización correcta activa

Puede filtrar los registros de GKE por los siguientes eventos de finalización correcta:

  • Cuando la VM detecta una interrupción debido a una finalización de nodo inminente, como un evento de mantenimiento del host de Compute Engine, GKE asigna el valor cloud.google.com/active-node-maintenance a ONGOING cuando se detienen las cargas de trabajo y el valor terminating cuando las cargas de trabajo han finalizado y el nodo está listo para finalizar.
  • Cuando se restringe la programación de cargas de trabajo nuevas, GKE aplica el taint cloud.google.com/impending-node-termination:NoSchedule.

Minimizar las interrupciones de las cargas de trabajo en ejecución con el mantenimiento oportunista

Puedes minimizar la interrupción de las cargas de trabajo en ejecución activando automáticamente el mantenimiento cuando GKE detecte que los nodos con GPUs o TPUs están inactivos. Para habilitar esta función, crea un grupo de nodos. No puedes habilitar el mantenimiento oportunista en un grupo de nodos que ya tengas.

Crear un grupo de nodos con mantenimiento oportunista

El siguiente comando muestra cómo puedes crear un grupo de nodos con el mantenimiento oportunista habilitado:

gcloud beta container node-pools create NODE_POOL_NAME \
    --cluster CLUSTER_NAME \
    --accelerator ACCELERATOR_ARG \
    --machine-type MACHINE_TYPE \
    --num-nodes NODE_COUNT \
    --zone ZONE \
    --project=PROJECT_ID \
    --opportunistic-maintenance=node-idle-time=NODE_IDLE_TIME,min-nodes=MIN_NODES,window=WINDOW

Sustituye los siguientes valores:

  • NODE_POOL_NAME: el nombre de tu grupo de nodos de GKE.
  • CLUSTER_NAME : el nombre de tu clúster de GKE.
  • NODE_IDLE_TIME : el tiempo que un nodo puede permanecer inactivo (es decir, sin cargas de trabajo que consuman aceleradores) antes de que se active el mantenimiento. El valor representa la duración en segundos, con hasta nueve dígitos fraccionarios, y termina con el carácter s. Por ejemplo: 80000s.
  • MIN_NODES : el número mínimo de nodos que debe haber en un grupo de nodos. Esta opción bloquea el mantenimiento si provoca que el número de nodos en ejecución sea inferior a este valor. Por ejemplo, 10.
  • WINDOW : el periodo, en segundos, durante el que se puede realizar el mantenimiento oportunista. El valor termina con el carácter s. Por ejemplo, si el valor es 14 días (1209600s), el mantenimiento oportunista solo se puede realizar en las dos semanas anteriores a la fecha de mantenimiento programada. Si el valor es de 28 días (2419200s), el mantenimiento oportunista se puede ejecutar en cualquier momento durante la ventana de mantenimiento programada. Esta ventana de mantenimiento del host de Compute Engine es distinta de las ventanas de mantenimiento de GKE, que determinan cuándo se puede llevar a cabo el mantenimiento de los clústeres de GKE y se configuran por separado.

Ejemplo de configuración para el mantenimiento oportunista

Veamos un ejemplo. Tienes un grupo de nodos con cuatro nodos y la configuración de mantenimiento oportunista está definida como --opportunistic-maintenance=node-idle-time=600s,window=2419200s,min-nodes=3. En este caso, ocurre lo siguiente:

  • node1 tiene una carga de trabajo de GPU en ejecución. Este nodo no está inactivo, por lo que se omite.
  • node2 ha estado inactivo durante 60 segundos. Este nodo no ha estado inactivo durante el tiempo suficiente, por lo que se ha omitido.
  • node3 ha estado inactivo durante 600 segundos. Este nodo cumple el requisito de inactividad.
  • node4 ha estado inactivo durante 600 segundos. Este nodo cumple el requisito de inactividad.

Tanto node3 como node4 cumplen el requisito de inactividad. Sin embargo, solo uno de estos nodos activará el mantenimiento oportunista, ya que el valor de la opción min-nodes se ha definido como 3.

Comprobar la configuración y el estado de los nodos con mantenimiento oportunista

Para comprobar si el mantenimiento oportunista está configurado en un nodo, ejecuta el siguiente comando:

kubectl describe node NODE_NAME | grep node.gke.io/opportunistic-config

Sustituye NODE_NAME por el nombre del nodo que quieras comprobar.

Para comprobar si un nodo configurado con mantenimiento oportunista está en mantenimiento, haz lo siguiente:

kubectl describe node NODE_NAME | grep node.gke.io/maintenance-state

Si el nodo se activa mediante un mantenimiento oportunista, la anotación maintenance-state muestra opportunistic-triggered como true.

Limitaciones

Ten en cuenta las siguientes limitaciones del mantenimiento oportunista:

  • Esta función solo se puede usar con grupos de nodos de GPU y TPU.
  • El mantenimiento oportunista no es compatible con el autoescalado de clústeres porque el autoescalador de clústeres ya reduce la escala de los nodos inactivos.
  • En los grupos de nodos de TPU multihost, el valor del ajuste min-nodes-per-pool debe ser 0, ya que estos grupos de nodos son atómicos.
  • La versión mínima compatible de GKE es la 1.33.3-gke.1118000.
  • Solo se admite el mantenimiento planificado que incluye la can_reschedule=TRUE notificación.
  • Para inhabilitar esta función, debes volver a crear el grupo de nodos sin las marcas correspondientes. También puedes inhabilitar manualmente la función en nodos específicos con cloud.google.com/opportunistic-disable=true.
  • En casos excepcionales, el mantenimiento puede tardar más en completarse en un nodo. Los clientes que usen esta función podrían tener menos nodos disponibles, hasta el valor del ajuste min-nodes-per-pool, durante un periodo.

Siguientes pasos