Acerca de la asignación dinámica de recursos en GKE

Puedes usar la asignación dinámica de recursos (DRA) para asignar GPUs a tus cargas de trabajo de Google Kubernetes Engine (GKE). En este documento, se explican los conceptos básicos de la DRA, cómo usarla en GKE y los beneficios de usarla.

Este documento está dirigido a las siguientes funciones:

Ya deberías tener conocimientos sobre lo siguiente:

Introducción a la DRA

La DRA es una función integrada de Kubernetes que te permite solicitar, asignar y compartir hardware de forma flexible en tu clúster entre Pods y contenedores. La DRA mejora la experiencia de asignar hardware adjunto, como aceleradores, ya que permite que los proveedores de dispositivos y los administradores de plataformas declaren clases de dispositivos que se pueden solicitar y asignar. Los operadores de apps pueden solicitar configuraciones de dispositivos específicas dentro de esas clases y, luego, solicitar esas configuraciones en sus cargas de trabajo. Kubernetes y GKE administran la programación de Pods, las asignaciones de nodos y la asignación de dispositivos según las solicitudes de carga de trabajo.

Por ejemplo, un administrador de la plataforma podría definir una clase de dispositivo que solo tenga GPU NVIDIA A100. Luego, los operadores de la app pueden filtrar los dispositivos de esa clase según los requisitos de carga de trabajo, por ejemplo, filtrar para obtener un mínimo de 80 GB de memoria de GPU. Cuando el operador de la app implementa una carga de trabajo que solicita la configuración filtrada, GKE coloca los Pods en nodos que cumplen con los criterios seleccionados. En este ejemplo, GKE encuentra nodos que tienen GPUs A100 (80 GB) disponibles. El operador de la app no necesita seleccionar nodos específicos ni configuraciones de dispositivos en el manifiesto de la carga de trabajo.

Beneficios de la DRA

Sin la DRA, la asignación de dispositivos de hardware en Kubernetes depende de los complementos de dispositivos. Para adjuntar recursos de hardware a los Pods con complementos de dispositivos, usa etiquetas de nodos para colocar los Pods en nodos específicos. Además, para dedicar todos los recursos de un nodo a un solo Pod, debes solicitar la cantidad exacta de dispositivos conectados a los nodos.

Con DRA, la asignación de dispositivos a Pods es similar a la asignación de volúmenes para el almacenamiento. Defines clases de dispositivos, solicitas dispositivos dentro de esas clases y, luego, asignas esos dispositivos solicitados a las cargas de trabajo. La DRA proporciona una superficie mucho más extensible para filtrar dispositivos según la carga de trabajo y las necesidades comerciales. El enfoque de DRA de usar expresiones y plantillas para reclamar hardware y programar Pods tiene los siguientes beneficios:

  • Asignación declarativa de dispositivos: Los administradores de la plataforma pueden definir configuraciones de dispositivos para tipos específicos de cargas de trabajo o equipos.
  • Menor complejidad entre equipos: Cuando los administradores de la plataforma aprovisionan nodos que tienen configuraciones de hardware especializadas, los operadores de la app no necesitan saber qué nodos tienen configuraciones específicas. Los administradores de la plataforma no necesitan etiquetar nodos ni comunicar información sobre nodos y dispositivos específicos a los operadores.
  • Menor complejidad para los desarrolladores: Kubernetes programa los Pods según la configuración del dispositivo al que se hace referencia. Los operadores de apps no necesitan seleccionar nodos específicos en sus cargas de trabajo ni asegurarse de que cada Pod solicite exactamente la cantidad de dispositivos conectados a esos nodos.
  • Administración de infraestructura centralizada: Los administradores de la plataforma pueden definir de forma centralizada configuraciones de hardware que satisfagan requisitos comerciales específicos. Por ejemplo, un administrador de la plataforma podría declarar una configuración de alto rendimiento que tenga GPU H100 junto con una pequeña configuración de inferencia que tenga GPU Tesla T4.
  • Selección de hardware flexible: Puedes usar expresiones de CEL para filtrar dispositivos que tengan atributos específicos. El uso de expresiones proporciona la flexibilidad necesaria para filtrar los dispositivos que son óptimos para cargas de trabajo específicas.

Cuándo usar la DRA

El motivo principal para usar DRA en GKE es la flexibilidad con la que puedes solicitar dispositivos para las cargas de trabajo. Puedes escribir un manifiesto una vez y, luego, implementar la carga de trabajo en diferentes clústeres con diferentes tipos de dispositivos sin necesidad de cambiar el manifiesto. Esta flexibilidad es ideal para casos de uso como los siguientes:

  • Mejora la disponibilidad de la GPU: Para las cargas de trabajo que necesitan acceso al hardware de la GPU, puedes usar DRA para solicitar cualquier GPU disponible en el clúster en lugar de tener que especificar un modelo de GPU. Si esas cargas de trabajo tienen requisitos específicos de memoria de GPU (VRAM), puedes solicitar cualquier GPU del clúster que tenga una cantidad mínima de memoria. Este tipo de solicitud flexible expande el conjunto de nodos de GPU en los que se puede ejecutar una carga de trabajo, lo que reduce el riesgo de que no se programe la carga de trabajo debido a la falta de recursos.
  • Optimiza la disponibilidad de nodos durante el ajuste de escala: La cantidad de dispositivos que requiere una carga de trabajo puede cambiar según factores como el tipo de dispositivo y sus capacidades. Puedes usar ComputeClasses de GKE para colocar Pods acelerados en grupos de nodos específicos según la disponibilidad del dispositivo. Luego, puedes configurar tus Pods para que reclamen los dispositivos en cualquier nodo en el que GKE coloque los Pods.

    Usar DRA con ComputeClasses te permite minimizar el riesgo de cargas de trabajo no programadas y, al mismo tiempo, te ayuda a ejecutar cargas de trabajo en hardware optimizado.

Terminología

Los proveedores de Kubernetes de código abierto y Kubernetes administrado, como GKE, usan los siguientes tipos principales de la API de DRA:

ResourceSlice
Un objeto ResourceSlice enumera uno o más dispositivos de hardware en el clúster a los que pueden acceder los nodos. Por ejemplo, en un nodo que puede acceder a una sola GPU, ResourceSlice enumera la GPU y el nombre del nodo. Los controladores de dispositivos de DRA en cada nodo crean ResourceSlices. El programador de Kubernetes usa ResourceSlices para decidir qué dispositivos asignar para satisfacer las solicitudes de carga de trabajo.
DeviceClass
Un DeviceClass define una categoría de dispositivos, como las GPUs, que están disponibles para solicitar cargas de trabajo. Algunos controladores de dispositivos proporcionan DeviceClasses integradas, como gpu.nvidia.comDeviceClass para las GPUs de NVIDIA. Los administradores de la plataforma también pueden crear DeviceClasses personalizadas que definan parámetros de configuración específicos del dispositivo.
ResourceClaim

Un ResourceClaim permite que un Pod o un usuario soliciten recursos de hardware filtrando ciertos parámetros dentro de un DeviceClass. Cuando una carga de trabajo hace referencia a un ResourceClaim, Kubernetes asigna dispositivos que coinciden con los parámetros especificados a ese ResourceClaim.

Por ejemplo, considera una situación en la que creas un ResourceClaim para una GPU A100 (40 GB) y, luego, implementas una carga de trabajo que selecciona ese ResourceClaim. Kubernetes asigna una GPU A100 (40 GB) disponible al ResourceClaim y programa tu Pod en un nodo que pueda acceder a esa GPU.

ResourceClaimTemplate

Un ResourceClaimTemplate define una plantilla que los Pods pueden usar para crear automáticamente nuevos ResourceClaims por Pod. Los ResourceClaimTemplates son útiles cuando tienes varias cargas de trabajo que necesitan acceso a configuraciones de dispositivos similares, en especial cuando usas un controlador de carga de trabajo como Deployments o StatefulSets.

Los operadores de la app implementan ResourceClaimTemplates y, luego, hacen referencia a las plantillas en las cargas de trabajo. Kubernetes crea ResourceClaims para cada Pod según la plantilla especificada, asigna dispositivos y programa los Pods. Cuando finalizan los Pods, Kubernetes limpia los ResourceClaims correspondientes.

Para obtener más información sobre los tipos de API de la DRA, consulta la terminología de la DRA.

Cómo funciona la DRA

Usar DRA en tus clústeres y cargas de trabajo es un proceso similar a usar StorageClasses, PersistentVolumeClaims y PersistentVolumes para aprovisionar volúmenes de forma dinámica para Pods.

En el siguiente diagrama, se muestran los pasos que siguen los administradores de clústeres y los operadores de apps para asignar dispositivos con la DRA:

En este diagrama, los administradores del clúster y los operadores de la app hacen lo siguiente:

  1. Los administradores del clúster instalan controladores de dispositivos que admiten DRA en los nodos.
  2. Los administradores de clústeres crean DeviceClasses que filtran el hardware que cumple con requisitos específicos, como todas las GPUs con más de 40 GB de memoria. Algunos dispositivos también pueden incluir DeviceClasses integradas.
  3. Los operadores de aplicaciones crean ResourceClaimTemplates o ResourceClaims que solicitan configuraciones de dispositivos. El caso de uso principal para cada tipo de reclamo es el siguiente:
    • Un objeto ResourceClaim permite que varios Pods compartan el acceso al mismo dispositivo.
    • Un ResourceClaimTemplate permite que varios Pods accedan a dispositivos separados y similares generando automáticamente ResourceClaims por Pod.
  4. Los operadores de aplicaciones agregan los objetos ResourceClaimTemplates o ResourceClaims a sus manifiestos de carga de trabajo.
  5. Los operadores de aplicaciones implementan la carga de trabajo.

Cuando implementas una carga de trabajo que hace referencia a un ResourceClaimTemplate o a un ResourceClaim, Kubernetes realiza los siguientes pasos de programación:

  1. Si la carga de trabajo hace referencia a un ResourceClaimTemplate, Kubernetes crea un objeto ResourceClaim nuevo para cada instancia de la carga de trabajo (por ejemplo, cada réplica en una Deployment).
  2. El programador de Kubernetes usa los ResourceSlices del clúster para asignar dispositivos disponibles y aptos a cada ResourceClaim del Pod.
  3. El programador coloca cada Pod en un nodo que tiene acceso a los dispositivos que se asignaron al ResourceClaim del Pod.
  4. El kubelet en el nodo de destino llama al controlador de DRA en el nodo para adjuntar el hardware asignado al Pod y satisfacer su solicitud de recursos.

Cuándo usar ResourceClaims y ResourceClaimTemplates

Puedes usar ResourceClaims o ResourceClaimTemplates para indicarle a Kubernetes que deseas dispositivos que cumplan con requisitos específicos. Cuando se hace referencia a un ResourceClaim en un Pod, Kubernetes asigna dispositivos al recurso de la API de ResourceClaim correspondiente en el servidor de la API de Kubernetes. Esta asignación se produce independientemente de si creaste el ResourceClaim o si Kubernetes lo creó a partir de un ResourceClaimTemplate.

Si creas un objeto ResourceClaim y, luego, haces referencia a él en varios Pods, todos esos Pods podrán acceder a los dispositivos que Kubernetes asigne para ese objeto ResourceClaim. Por ejemplo, este acceso compartido puede ocurrir si haces referencia a un ResourceClaim específico en un manifiesto de Deployment que tiene varias réplicas. Sin embargo, si los dispositivos asignados no están configurados para ser compartidos por varios procesos, este acceso compartido a los dispositivos en los Pods podría generar un comportamiento no deseado.

Para asignar dispositivos separados a los Pods, puedes usar un ResourceClaimTemplate, que es una plantilla que Kubernetes usa para crear automáticamente ResourceClaims individuales. Por ejemplo, si haces referencia a un ResourceClaimTemplate en una Deployment que tiene varias réplicas, Kubernetes crea un ResourceClaim independiente para cada Pod replicado. Como resultado, cada Pod obtiene su propio dispositivo asignado en lugar de compartir el acceso al dispositivo con otros Pods. Estos ResourceClaims generados automáticamente están vinculados a la vida útil del Pod correspondiente y se borran cuando finaliza el Pod. Si tienes Pods independientes que necesitan acceder a configuraciones de dispositivos similares, usa un ResourceClaimTemplate para asignar dispositivos a cada Pod por separado.

En la siguiente tabla, se describen algunas diferencias entre la creación manual de ResourceClaims y la creación de ResourceClaims por parte de Kubernetes a partir de un ResourceClaimTemplate:

Tabla 1. Comparación de ResourceClaims y ResourceClaimTemplates
ResourceClaims creados manualmente ResourceClaims creados automáticamente
Administrados por ti Administrados por Kubernetes
Proporciona acceso a los mismos dispositivos desde varios Pods Proporciona acceso a dispositivos desde un solo Pod
Existe en el clúster de forma independiente de los Pods. Vinculado al ciclo de vida del Pod correspondiente
Ideal para varias cargas de trabajo que necesitan compartir un dispositivo específico Ideal para varias cargas de trabajo que necesitan acceso independiente a los dispositivos

Comparación de la DRA con la asignación manual de dispositivos

La DRA hace que la asignación de dispositivos conectados sea una experiencia similar al aprovisionamiento dinámico de PersistentVolumes. Kubernetes también admite la asignación de dispositivos con complementos de dispositivos. Este método implica los siguientes pasos:

  1. Un administrador de clústeres crea nodos que tienen dispositivos adjuntos, como GPUs.
  2. El administrador del clúster comunica información sobre nodos específicos y sus dispositivos adjuntos a los operadores de cargas de trabajo.
  3. Un operador de carga de trabajo solicita dispositivos en el manifiesto de carga de trabajo de la siguiente manera:
    • Selecciona un nodo que tenga la configuración del dispositivo requerida, como el modelo de GPU, con un campo nodeSelector.
    • Especifica la cantidad exacta de dispositivos que consumirán los contenedores con el campo resources en la especificación del Pod.

Este método de asignación manual requiere que los operadores de la aplicación y los administradores del clúster se comuniquen sobre qué nodos o grupos de nodos específicos tienen ciertas configuraciones de dispositivos. Deben coordinar las solicitudes de carga de trabajo para que coincidan con los dispositivos de los nodos; de lo contrario, la implementación fallará. En comparación, DRA te permite usar expresiones para filtrar de forma flexible los dispositivos según los atributos y no requiere que los operadores de cargas de trabajo conozcan la configuración exacta de los nodos del clúster.

En la siguiente tabla, se compara la DRA con los complementos para dispositivos:

Tabla 2. Comparación entre la DRA y la asignación manual de dispositivos
DRA Asignación manual
Selección flexible de dispositivos con expresiones CEL Selección de nodos específicos con selectores y solicitudes de recursos
Decisiones de programación que toma Kubernetes Decisiones de programación que toma el operador con selectores de nodos
El filtrado de dispositivos es independiente de la creación de cargas de trabajo El filtrado de dispositivos se debe realizar en el manifiesto de la carga de trabajo.
Filtrado de dispositivos centralizado y clases basadas en las necesidades, administrados por los administradores de la plataforma Filtrado de dispositivos aislados por operadores de aplicaciones
Los operadores de la app no necesitan conocer la capacidad del nodo, la información de la etiqueta del nodo ni los modelos de dispositivos adjuntos para cada nodo. Los operadores de la app deben saber qué nodos tienen modelos específicos y qué cantidades de ciertos dispositivos están conectados.

DRA y ajuste de escala automático de la infraestructura

Para ajustar automáticamente la cantidad de nodos en un grupo de nodos en modo Standard, usa el escalador automático de clúster. Puedes habilitar el escalador automático del clúster en cualquier grupo de nodos creado manualmente, incluidos los grupos de nodos que tienen controladores de DRA.

En el caso de los grupos de nodos que usan DRA, la utilización del dispositivo afecta la forma en que el escalador automático del clúster agrega y quita nodos en un grupo de nodos. Para calcular la utilización del dispositivo en un grupo de nodos, el escalador automático del clúster considera los siguientes factores:

  • Todos los dispositivos de un grupo de recursos deben ser locales para un nodo específico. Si un ResourceSlice tiene un grupo de dispositivos conectados a varios nodos, el escalador automático del clúster ignora esos dispositivos.
  • Todos los dispositivos del grupo de nodos son igualmente importantes y son idénticos.
  • Los dispositivos DRA tienen mayor prioridad que la CPU o la memoria. En los grupos de nodos de DRA, el escalador automático del clúster ignora el uso de CPU y memoria.

Estos factores pueden significar que observes un comportamiento diferente de reducción de escala en los grupos de nodos de DRA que en otros grupos de nodos.

Dispositivos de GKE compatibles con DRA

En la siguiente tabla, se describen los dispositivos que puedes asignar a cargas de trabajo con DRA en GKE:

Tabla 3. Dispositivos compatibles con DRA en GKE
Dispositivos compatibles con la DRA
GPU Cualquier tipo de GPU que esté disponible en tu ubicación Para obtener más información, consulta Ubicaciones de GPU.
Interfaces de red Varios tipos de interfaces de red, como interfaces compatibles con RDMA, instalando el controlador DRANET administrado Para obtener más información, consulta Asigna recursos de red con DRANET administrado por GKE.

Limitaciones

Se aplican las siguientes limitaciones cuando usas la DRA:

  • Modo de operación: La DRA solo está disponible en clústeres en modo estándar.

  • Tipo de acelerador: Durante la versión preliminar, la DRA en GKE solo admite GPUs.

  • GPUs:

  • Interfaces de red (vista previa): Consulta las limitaciones en "Asigna recursos de red con DRANET administrado por GKE".

  • Ajuste de escala automático:

    • En el caso de los controladores de DRA de terceros que instales, el escalador automático del clúster requiere que tus grupos de nodos tengan al menos un nodo. Para evitar que los grupos de nodos que usan controladores de terceros se ajusten a cero nodos, establece la cantidad mínima de nodos en al menos 1.
    • Es posible que el escalador automático de clústeres no funcione correctamente con los controladores de DRA de terceros. Si usas controladores de terceros, verifica que estos publiquen información solo para los dispositivos locales de nodos específicos.
    • En el caso de los DaemonSets en grupos de nodos con ajuste de escala automático que usan un ResourceClaim estático para compartir el acceso a dispositivos entre los Pods, el ajuste de escala automático admite hasta 128 Pods de DaemonSet. Para evitar esta limitación, realiza una de las siguientes acciones:
    • Si tus Pods hacen referencia a ResourceClaims y tienen una PriorityClass que establece la política de interrupción en PreemptLowerPriority, es posible que aumente la latencia del ajuste de escala automático. PreemptLowerPriority es la política de interrupción predeterminada para PriorityClass, por lo que debes asegurarte de que tus PriorityClasses establezcan explícitamente el campo preemptionPolicy en Never. Para obtener más información, consulta PriorityClass sin prioridad.

En esta sección, se proporcionan recomendaciones para los administradores de plataformas o los operadores de apps que deseen usar DRA para asignar dispositivos a cargas de trabajo. La DRA cambia significativamente el método por el cual solicitas dispositivos adjuntos, tanto en GKE como en Kubernetes. Para aprovechar casos de uso más avanzados, como la resiliencia multidispositivo o el filtrado y la selección detallados de dispositivos, considera las siguientes recomendaciones:

¿Qué sigue?