Soluciona problemas de grupos de nodos de GKE Standard


En esta página, se muestra cómo resolver problemas con los grupos de nodos del modo GKE Standard.

Problemas de creación de grupos de nodos

En esta sección, se enumeran los problemas que pueden ocurrir cuando se crean grupos de nodos nuevos en los clústeres de Standard y se proporcionan sugerencias para solucionarlos.

La creación del grupo de nodos falla debido a la disponibilidad de recursos

El siguiente problema ocurre cuando creas un grupo de nodos con hardware específico en una zona de Google Cloud que no tiene suficiente hardware disponible para cumplir con tus requisitos.

Para validar que la creación del grupo de nodos falló porque una zona no tenía suficientes recursos, verifica tus registros en busca de mensajes de error relevantes.

  1. Ve al Explorador de registros en la consola de Google Cloud:

    Ir al Explorador de registros

  2. En el campo Consulta, ingresa la siguiente consulta:

    log_id(cloudaudit.googleapis.com/activity)
    resource.labels.cluster_name="CLUSTER_NAME"
    protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")
    

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

  3. Haga clic en Ejecutar consulta.

Tal vez veas alguno de los siguientes mensajes de error:

  • resource pool exhausted
  • The zone does not have enough resources available to fulfill the request. Try a different zone, or try again later.
  • ZONE_RESOURCE_POOL_EXHAUSTED
  • ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS
  • Machine type with name '<code><var>MACHINE_NAME</var></code>' does not exist in zone '<code><var>ZONE_NAME</var></code>'

Resolver

Para resolver este problema, realiza las siguientes acciones:

  • Asegúrate de que la región o zona de Google Cloud seleccionada tenga el hardware específico que necesitas. Usa la tabla de disponibilidad de Compute Engine para verificar si las zonas específicas son compatibles con hardware específico. Elige una región o una zona de Google Cloud diferente para los nodos que podrían tener una mejor disponibilidad del hardware que necesitas.
  • Crea el grupo de nodos con tipos de máquina más pequeños. Aumenta la cantidad de nodos en el grupo de nodos para que la capacidad de procesamiento total permanezca igual.
  • Usa la reserva de capacidad de Compute Engine para reservar los recursos con anticipación.
  • Usa el aprovisionamiento de mejor esfuerzo, que se describe en la siguiente sección, para crear de forma correcta el grupo de nodos si puede aprovisionar al menos una cantidad mínima de nodos de la cantidad solicitada.

Aprovisionamiento de mejor esfuerzo

Para cierto hardware, puedes usar el aprovisionamiento de mejor esfuerzo, que le indica a GKE que cree correctamente el grupo de nodos si puede aprovisionar al menos una cantidad mínima de nodos especificada. GKE continúa intentando aprovisionar los nodos restantes para satisfacer la solicitud original con el tiempo. Para indicarle a GKE que use el aprovisionamiento de mejor esfuerzo, utiliza el siguiente comando:

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --node-locations=ZONE1,ZONE2,... \
    --machine-type=MACHINE_TYPE
    --best-effort-provision \
    --min-provision-nodes=MINIMUM_NODES

Reemplaza lo siguiente:

  • NODE_POOL_NAME: el nombre del grupo de nodos nuevo
  • ZONE1,ZONE2,...: son las zonas de Compute Engine para los nodos. Estas zonas deben ser compatibles con el hardware seleccionado.
  • MACHINE_TYPE: es el tipo de máquina de Compute Engine para los nodos. Por ejemplo, a2-highgpu-1g
  • MINIMUM_NODES: la cantidad mínima de nodos para que GKE aprovisione y cree de forma correcta el grupo de nodos. Si se omite, el valor predeterminado es 1.

Por ejemplo, imagina una situación en la que necesitas 10 nodos con GPU NVIDIA A100 de 40 GB conectadas en us-central1-c. Según la tabla de disponibilidad de regiones y zonas de GPU, esta zona admite GPU A100. Para evitar fallas en la creación de grupos de nodos si no hay 10 máquinas de GPU disponibles, usa el aprovisionamiento de mejor esfuerzo.

gcloud container node-pools create a100-nodes \
    --cluster=ml-cluster \
    --node-locations=us-central1-c \
    --num-nodes=10 \
    --machine-type=a2-highgpu-1g \
    --accelerator=type=nvidia-tesla-a100,count=1 \
    --best-effort-provision \
    --min-provision-nodes=5

GKE crea el grupo de nodos, incluso si solo hay cinco GPU disponibles en us-central1-c. Con el tiempo, GKE intenta aprovisionar más nodos hasta que haya 10 en el grupo de nodos.

Migra cargas de trabajo entre grupos de nodos

Usa las siguientes instrucciones para migrar las cargas de trabajo de un grupo de nodos a otro. Si deseas cambiar los atributos de máquina de los nodos de tu grupo de nodos, consulta Escala verticalmente mediante el cambio de los atributos de máquina de los nodos.

Cómo migrar Pods a un grupo de nodos nuevo

Para migrar Pods a un grupo de nodos nuevo, debes hacer lo siguiente:

  1. Acordona el grupo de nodos existente: esta operación marca los nodos en el grupo de nodos existente como no programables. Kubernetes deja de programar los Pods nuevos en estos nodos en el momento que los marcas como no programables.

  2. Desvía el grupo de nodos existente: esta operación expulsa las cargas de trabajo que se ejecutan en los nodos del grupo de nodos existente de forma correcta.

Estos pasos hacen que los pods que se ejecutan en tu grupo de nodos existentes se finalicen de forma correcta. Kubernetes los reprograma en otros nodos disponibles.

A fin de asegurarte de que Kubernetes finalice tus aplicaciones con éxito, tus contenedores deben manipular la señal SIGTERM. Usa este enfoque para cerrar conexiones activas con los clientes y confirmar o revertir las transacciones de la base de datos de una manera limpia. En el manifiesto de tu pod, puedes usar el campo spec.terminationGracePeriodSeconds para especificar cuánto debe esperar Kubernetes antes de detener los contenedores en el pod. Esto se encuentra predeterminado a 30 segundos. Puedes leer más sobre la finalización de pods en la documentación de Kubernetes.

Puedes acordonar y desviar los nodos mediante los comandos kubectl cordon y kubectl drain.

Crea un grupo de nodos y migra las cargas de trabajo

Para migrar tus cargas de trabajo a un grupo de nodos nuevo, crea el grupo de nodos nuevo y, luego, acordona y vacía los nodos en el grupo de nodos existente:

  1. Agrega un grupo de nodos a tu clúster.

    Ejecuta el siguiente comando para verificar que se creó el grupo de nodos nuevo:

    gcloud container node-pools list --cluster CLUSTER_NAME
    
  2. Ejecuta el siguiente comando para ver en qué nodo se están ejecutando los pods (consulta la columna NODE):

    kubectl get pods -o=wide
    
  3. Obtén una lista de nodos en el grupo de nodos existente y reemplaza EXISTING_NODE_POOL_NAME por el nombre:

    kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME
    
  4. Ejecuta el comando kubectl cordon NODE (sustituye NODE por los nombres del comando anterior). El siguiente comando de shell itera todos los nodos en el grupo de nodos existente y los marca como no programables:

    for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do
      kubectl cordon "$node";
    done
    
  5. De manera opcional, actualiza tus cargas de trabajo que se ejecutan en el grupo de nodos existente a fin de agregar un nodeSelector para la etiqueta cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME, en la que NEW_NODE_POOL_NAME es el nombre del grupo de nodos nuevo. Esto garantiza que GKE coloque esas cargas de trabajo en nodos en el grupo de nodos nuevo.

  6. Desvía cada nodo expulsando Pods con un período de finalización ordenada asignado de 10 segundos:

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

    Reemplaza GRACEFUL_TERMINATION_PERIOD_SECONDS por la cantidad de tiempo necesaria para la finalización ordenada.

  7. Ejecuta el siguiente comando para ver que los nodos del grupo de nodos existente tienen el estado SchedulingDisabled en la lista de nodos:

    kubectl get nodes
    

    Además, deberías ver que los Pods se están ejecutando en los nodos del grupo de nodos nuevo:

    kubectl get pods -o=wide
    
  8. Borra el grupo de nodos existente si ya no lo necesitas:

    gcloud container node-pools delete default-pool --cluster CLUSTER_NAME