Introducción

Durante una década, Kubernetes operó bajo una división funcional clara y eficiente: el scheduler ubicaba pods en nodos existentes, mientras que el autoscaler agregaba capacidad cuando no había espacio. Esta arquitectura funcionaba porque los recursos computacionales eran fungibles y las decisiones de ambos componentes podían tomarse de forma independiente. La irrupción de cargas de trabajo intensivas en IA ha desestabilizado este modelo. Los aceleradores de hardware, con sus topologías complejas y costos elevados, requieren una coordinación que el diseño original no contempla.

El problema se manifiesta cuando un pod permanece en estado Pending a pesar de que el cluster no está agotado. El autoscaler intenta añadir un nodo genérico que el scheduler rechaza porque no cumple con los requisitos de topología o particionamiento del acelerador. Este escenario deja recursos costosos sin usar y aumenta la latencia de despliegue. No es una falla de capacidad regional, sino una desconexión semántica entre el componente que decide cuándo escalar y el que decide dónde ubicar la carga.

Qué ocurrió

La evolución de Kubernetes hacia cargas de trabajo de alto rendimiento y IA ha expuesto las limitaciones de tratar los recursos como contadores simples. Históricamente, un nodo anunciaba nvidia.com/gpu: 4 y un pod solicitaba nvidia.com/gpu: 1. El scheduler simplemente igualaba estos enteros. Esta simplificación ignoraba factores críticos como la conectividad PCIe, los dominios NUMA y la proximidad física entre dispositivos, elementos vitales para el rendimiento en entrenamiento distribuido.

Con la introducción de Dynamic Resource Allocation (DRA) en las versiones recientes del kernel de Kubernetes, el paradigma cambió. Los workloads ahora pueden declarar recursos estructurados que incluyen relaciones jerárquicas y dependencias de hardware. Sin embargo, la mayoría de los autoscalers tradicionales no fueron diseñados para interpretar estas declaraciones complejas. Como resultado, se produce una asimetría: el scheduler entiende que necesita una GPU conectada a una NIC específica en un rack particular, pero el autoscaler solo ve una solicitud de «más recursos» y provee un nodo que, aunque tenga GPUs, no satisface la topología requerida.

Esta ruptura se ha agudizado en entornos cloud como AWS, donde la disponibilidad de instancias con aceleradores específicos fluctúa. El autoscaler, al carecer de visibilidad sobre los requisitos de colocación fina, puede solicitar instancias que quedan inutilizables para la carga pendiente, incurriendo en costos innecesarios y tiempo de espera prolongado.

Impacto para DevOps / Infraestructura / Cloud / Seguridad

Para los equipos de infraestructura, el impacto directo es financiero y operativo. La capacidad de aceleradores es extremadamente cara; dejar un nodo provisionado pero sin pods asignados debido a incompatibilidades de topología es un desperdicio directo de presupuesto. En clusters con cientos de GPUs, esta ineficiencia escala linealmente, generando miles de dólares en costos ocultos mensuales.

Además, la experiencia de usuario de los desarrolladores de IA se degrada. Los tiempos de cola para pods Pending aumentan no por falta de hardware físico, sino por la incapacidad del sistema para encontrar la configuración lógica correcta. Esto afecta los SLA de entrenamiento de modelos y reduce la agilidad del equipo de Data Science, que debe diagnosticar si el problema es de capacidad, configuración o coordinación del planificador.

Desde una perspectiva de seguridad y gobernanza, la falta de alineación entre scheduler y autoscaler complica la gestión de cuotas y reservas. Si el autoscaler no comprende que una carga de trabajo específica debe usar capacidad reservada o cumplir con estrictas políticas de colocación multi-tenant, puede violar contratos de servicio o exponer datos sensibles en nodos no aprobados.

Detalles técnicos

La solución técnica central recae en la adopción de Dynamic Resource Allocation (DRA). A diferencia del modelo anterior basado en recursos extendidos (extended resources), DRA permite a los workloads presentar «claims» estructurados. Estos claims pueden especificar que un acelerador debe compartir un bus PCIe con una interfaz de red o residir en el mismo dominio NUMA que la CPU asignada.

El segundo componente crítico es el Workload-Aware Scheduling. A través de las APIs Workload y PodGroup (actualmente en beta upstream y deshabilitadas por defecto), el scheduler puede tratar un conjunto de pods como una unidad atómica, conocida como gang scheduling. Esto evita el «deadlock» parcial donde algunos pods de un trabajo distribuido se ubican y otros no, bloqueando recursos sin progreso.

Sin embargo, el autoscaler sigue operando bajo un modelo pod-por-pod. Aunque mecanismos como Provisioning Requests permiten a un workload solicitar capacidad para un grupo entero, la implementación sigue siendo un «bolt-on». Herramientas como Kueue actúan como puente: reservan la cuota, crean la solicitud de aprovisionamiento y esperan a que la capacidad sea reportada como lista antes de admitir el workload.

El problema persiste en la duplicación de lógica. El autoscaler simula el placement del scheduler para decidir qué nodo lanzar, pero como no comparte el mismo estado de conocimiento profundo de la topología que el scheduler, la simulación es aproximada. Esto lleva a escenarios donde el autoscaler añade un nodo que el scheduler finalmente rechaza porque no cumple con las restricciones finas de DRA, como la partición de dispositivos o el consumable capacity.

Qué deberían hacer los administradores y equipos técnicos

  • Evaluar la migración a DRA: Si utilizas cargas de trabajo con GPUs en Kubernetes, revisa la compatibilidad de tus versiones actuales. Asegúrate de que tu distribución de Kubernetes soporte DRA de forma estable. En entornos gestionados como AWS EKS, verifica la versión de los add-ons y la compatibilidad con los drivers de NVIDIA.
  • Activar y configurar Workload-Aware Scheduling: Para cargas de trabajo de entrenamiento distribuido, habilita las APIs de Workload y PodGroup. Esto requiere actualizar el scheduler de Kubernetes a una versión que soporte estas features beta y configurar los perfiles de colocación para permitir gang scheduling.
  • Implementar Kueue o equivalentes: No dependas únicamente del autoscaler nativo para cargas de grupos. Utiliza Kueue para gestionar la cola de workloads y las solicitudes de aprovisionamiento. Kueue puede interactuar con el autoscaler para solicitar capacidad de forma atómica, reduciendo la fragmentación de recursos.
  • Monitorear la discrepancia Scheduler-Autoscaler: Configura alertas específicas para pods que permanecen Pending más de un tiempo umbral (ej. 5 minutos) mientras el cluster tiene nodos «libres» o en proceso de escalado. Analiza los eventos del scheduler para identificar rechazos por topología o falta de recursos específicos definidos en los claims de DRA.
  • Revisar políticas de reservas de capacidad: Alinea tus estrategias de compra de capacidad (Reservations en AWS o GCP) con las declaraciones de DRA. Asegúrate de que el autoscaler esté configurado para priorizar instancias que cumplan con las reservas existentes y los requisitos de topología definidos en los manifests de los workloads.
  • Conclusión

    La convergencia entre el scheduler y el autoscaler en Kubernetes no es opcional para entornos intensivos en IA. La separación histórica ya no sostiene la complejidad de la topología de aceleradores modernos. Las herramientas como DRA y Workload-Aware Scheduling ofrecen el vocabulario común necesario, pero su implementación requiere una configuración intencional y el uso de orquestadores de colas como Kueue para cerrar la brecha operativa. Los equipos que no adapten sus estrategias de autoscaling para ser «scheduler-aware» enfrentarán costos inflados y tiempos de entrega degradados.

    Fuentes

    https://www.cncf.io/blog/2026/10/19/how-ai-workloads-are-reshaping-kubernetes-autoscaling/

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *