Introducción
Hasta hace poco, Kubernetes programaba Pods de a uno: evaluaba recursos disponibles, aplicaba políticas de afinidad y asignaba nodos. Pero con cargas de trabajo de AI/ML o batch que requieren gang scheduling, co-localización forzada o alocación dinámica de recursos, este modelo se queda corto. En clusters donde 30% de los nodos ejecutan jobs distribuidos o modelos de inference que dependen de baja latencia entre Pods, un scheduling secuencial puede generar:
- Deadlocks por dependencias ocultas entre Pods de un mismo grupo.
- Fragmentación de recursos por schedulings parciales que dejan recursos libres pero inaccesibles.
- Latencia en redes por colocación arbitraria de Pods que deberían estar en el mismo rack o zona de disponibilidad.
Kubernetes 1.36 ataca este problema con un cambio arquitectónico radical: separa el Workload API (template estático) del PodGroup API (estado en runtime), introduce un ciclo de scheduling atómico para grupos de Pods, y suma soporte nativo para topología y preemptión consciente de workloads. La novedad no es solo teórica: el Job controller ya integra esta API y el kube-scheduler evalúa grupos enteros de Pods en una sola operación atómica.
Qué ocurrió
1. Separación del Workload API y el PodGroup API
En Kubernetes 1.35, el objeto Workload (API scheduling.k8s.io/v1alpha1) mezclaba:
- Template estático: definición del grupo de Pods (ej: 20 replicas de un Pod con 4 GPUs cada uno).
- Estado en runtime: número de Pods schedulados, condiciones de scheduling, política de gang.
Esto generaba:
- Overhead en el scheduler: debía parsear un objeto híbrido para extraer políticas y estado.
- Inconsistencias en escalado: al modificar el template, el estado podía quedar desincronizado.
- Falta de sharding: todos los nodos del cluster debían sincronizar cambios en el mismo objeto.
En Kubernetes 1.36, se migra a scheduling.k8s.io/v1alpha2 con dos APIs separadas:
| API | Rol | Ejemplo de uso |
|---|---|---|
| **Workload** | Template estático (definición) |
