Escalado sin reinicio: Redimensionamiento in situ de Pods en Kubernetes y DRA para Puentes de Simulación con Estado

Quick answer
Escalado sin reinicio: Usando DRA y Redimensionamiento in situ en Kubernetes: localhost tunnel answer
A localhost tunnel gives your local app a public HTTPS URL without opening router ports, which is useful for demos, QA, mobile testing, and provider callbacks.
How do I expose localhost without opening ports?
Use a reverse HTTPS tunnel. Your machine connects outbound to the tunnel service, and the public URL forwards requests back to your local app.
When should I use a localhost tunnel?
Use one for webhook testing, OAuth callbacks, client demos, QA previews, mobile device checks, and short-lived development reviews.
Killing y reprogramar un pod solo para otorgarle más memoria GPU es una interrupción catastrófica para puentes de renderizado en tiempo real con estado. Esta guía explica cómo el Redimensionamiento in situ de Pods de Kubernetes (estable desde v1.35) y la Asignación Dinámica de Recursos (DRA, estable desde v1.34 y en expansión en v1.36) permiten escalar pipelines de redes espaciales verticalmente sin perder cuadros — y dónde aún hay margen de mejora.
Introducción: La Disrupción de Alto Riesgo en la Reprogramación de Pods
La simulación 3D en tiempo real y la sincronización de gemelos digitales se han convertido en cargas de trabajo críticas en la computación industrial. Plataformas como NVIDIA Omniverse se usan para crear réplicas digitales de alta fidelidad de plantas industriales, centros logísticos y sistemas aeroespaciales, y estos entornos son altamente con estado — procesan flujos continuos de telemetría espacial y datos densos de nubes de puntos.
Para conectar hardware físico con motores de simulación en la nube, los equipos suelen ejecutar pods de enrutamiento de datos localizados — “puentes de simulación” — dentro de clústeres Kubernetes en la nube o en el borde. Estos puentes mantienen conexiones WebSocket o gRPC de larga duración, bufferizan secuencias de cuadros en memoria y a menudo usan aceleración GPU local para decimar o pre-renderizar datos CAD/nubes de puntos densos antes de enviarlos a un entorno de visualización centralizado.
Históricamente, si un pod puente alcanzaba sus límites de recursos, Kubernetes solo tenía una herramienta: desalojar y reprogramar. Un autoscaler vertical o un operador debía matar el pod, buscar un nodo con capacidad libre, volver a montar volúmenes y reiniciar el contenedor. Para un servicio web sin estado, esto es un pequeño contratiempo. Para un puente de simulación con estado, es disruptivo en varias formas concretas:
- Túneles rotos — las sesiones TCP/WebSocket en vivo con sensores físicos se caen instantáneamente, provocando cascadas de timeout en dispositivos de borde.
- Invalidación de caché — los buffers de cuadros en memoria y los índices espaciales se borran, forzando una re-inicialización lenta.
- Tartamudeo visual — la sincronización de renderizado en tiempo real se congela o pierde cuadros para operadores humanos y sistemas de inspección automatizados.
Dos funciones de Kubernetes cierran esta brecha: Redimensionamiento in situ de Pods (mutación de CPU/memoria del contenedor sin reinicio) y Asignación Dinámica de Recursos, o DRA (reclamaciones de dispositivos de hardware basadas en atributos que no requieren recrear el pod para cambiar). Ninguna es completamente nueva, y entender la historia de versiones es importante si planeas un despliegue en producción — aquí está el estado actual.
La Cronología Correcta
Es importante ser precisos sobre cuándo cada función se estabilizó, porque estas dos funciones se lanzaron en versiones diferentes, no juntas como un paquete único:
| Función | Alpha | Beta | Estable (GA) |
|---|---|---|---|
| Redimensionamiento in situ de Pods (nivel de contenedor, KEP-1287) | v1.27 (2023) | v1.33 (mayo 2025) | v1.35 (17 dic 2025) |
Asignación Dinámica de Recursos (core, resource.k8s.io/v1) |
v1.26 | v1.32–1.33 | v1.34 (ago/sept 2025) |
| Redimensionamiento a nivel de Pod (agregado de recursos, KEP-5419) | v1.35 | v1.36 (22 abr 2026) | — (aún en beta) |
Así, para cuando Kubernetes 1.35 (“Timbernetes”) fue lanzado, DRA ya había alcanzado GA en una versión anterior. Lo que entregó la versión 1.35 fue la graduación del redimensionamiento in situ a estable, construyendo sobre una base de DRA ya estable — ambas funciones se complementan, pero en diferentes líneas de tiempo. La versión v1.35 también eliminó una restricción antigua: las disminuciones en el límite de memoria, que antes estaban completamente prohibidas, ahora se permiten, condicionado a una comprobación de kubelet de mejor esfuerzo contra el uso actual.
La última versión de Kubernetes al momento de escribir esto es v1.36 (“Haru”), lanzada el 22 de abril de 2026, que extiende ambas funciones aún más — cubierto casi al final de este documento.
El Rol de cgroups v2
El redimensionamiento in situ depende de la jerarquía unificada de cgroups v2 del kernel Linux, que permite al kubelet reescribir los límites de recursos (cpu.max, memory.max) en el cgroup de un proceso en ejecución sin enviarle una señal de terminación. El kernel aplica el nuevo límite inmediatamente; el PID del proceso, los sockets abiertos y el estado en memoria permanecen intactos.
Por contraste, la programación tradicional de GPU dependía del modelo Device Plugin, que solicita GPUs como conteos enteros (nvidia.com/gpu: 1). No hay forma de solicitar un aumento fraccional de VRAM ni de cambiar un perfil de dispositivo sin destruir el pod — esta es la brecha que llena DRA.
Análisis Detallado: Mecánica del Redimensionamiento in situ de Pods
El subrecurso resize, no un PATCH simple
Una corrección importante: un redimensionamiento in situ no se aplica mediante un PATCH genérico contra el objeto del pod. Kubernetes expone esto como un subrecurso /resize dedicado, y kubectl requiere la versión v1.32 o superior para usarlo:
kubectl patch pod omniverse-local-bridge \
--subresource resize \
--type='json' \
-p='[
{"op": "replace", "path": "/spec/containers/0/resources/requests/cpu", "value": "8"},
{"op": "replace", "path": "/spec/containers/0/resources/limits/cpu", "value": "8"},
{"op": "replace", "path": "/spec/containers/0/resources/requests/memory", "value": "32Gi"},
{"op": "replace", "path": "/spec/containers/0/resources/limits/memory", "value": "32Gi"}
]'
El enrutamiento de redimensionamientos a través de su propio subrecurso también tiene implicaciones operativas: permite otorgar un verbo patch en pods/resize a un controlador de escalado automático sin concederle acceso de escritura al resto de la especificación del pod — una superficie RBAC mucho más restringida que una actualización general del pod.
Cómo Kubernetes rastrea un redimensionamiento
El ciclo de vida se sigue mediante campos y condiciones en el estado del pod, no un único enum de nivel superior:
| Campo / Condición | Significado |
|---|---|
spec.containers[*].resources |
Recursos deseados — lo que solicitaste. |
status.containerStatuses[*].resources |
Recursos reales/asignados actualmente en el contenedor en ejecución. |
PodResizePending (razón: Deferred) |
El nodo carece temporalmente de capacidad; kubelet reintentará. |
PodResizePending (razón: Infeasible) |
La solicitud nunca podrá satisfacerse en este nodo (por ejemplo, excede la capacidad total del nodo, o el pod usa una política de gestor de CPU/memoria estática). El pod sigue en ejecución con la asignación previa. |
PodResizeInProgress |
El kubelet aceptó el redimensionamiento y lo está aplicando activamente. |
Inmutabilidad de la clase QoS
La clase QoS de un pod (Guaranteed, Burstable, BestEffort) se calcula a partir de la relación entre solicitudes y límites, y no puede cambiar como resultado de un redimensionamiento — esto sigue siendo uno de los objetivos no alcanzados de KEP-1287. Si un pod puente Guaranteed (solicitudes == límites) tiene su límite modificado sin un cambio equivalente en la solicitud, el servidor API rechaza la modificación. Escala ambos campos juntos.
La protección contra la reducción
Antes del lanzamiento GA, disminuir un límite de memoria estaba completamente bloqueado. Desde v1.35, las disminuciones están permitidas, pero el kubelet realiza una comprobación de seguridad de mejor esfuerzo: lee el uso actual de memoria del contenedor a través de estadísticas de cgroup antes de establecer un límite menor en memory.max. Si el uso excede el límite propuesto, el kubelet mantiene el redimensionamiento en PodResizePending (razón Deferred) en lugar de arriesgar un OOM-kill. Esta comprobación no está garantizada — es una carrera entre la comprobación y la aplicación, por lo que reducir agresivamente en cargas de trabajo con huellas de memoria volátiles (como un puente de simulación en ráfaga) aún requiere precaución.
Cuando un nodo no puede satisfacer todos los redimensionamientos pendientes a la vez, las solicitudes diferidas se reintentan en orden de prioridad: primero por PriorityClass, luego por clase QoS (Guaranteed antes que Burstable), y finalmente por cuánto tiempo han estado en espera.
Análisis Detallado: DRA para GPUs
Las API principales de DRA se encuentran bajo el estable grupo API resource.k8s.io/v1 (no v1alpha3, que era la versión pre-GA usada durante el período beta 1.32–1.33):
- DeviceClass — definición a nivel de clúster (creada por administradores o vendedores de dispositivos) que clasifica un grupo de hardware usando expresiones CEL (Common Expression Language), por ejemplo, coincidiendo con dispositivos donde
device.driver == "gpu.nvidia.com". - ResourceSlice — inventario en vivo publicado por el controlador de dispositivo por nodo, describiendo dispositivos disponibles, atributos y capacidad.
- ResourceClaim — el análogo de dispositivo de un
PersistentVolumeClaim: una solicitud concreta de hardware que coincide con unDeviceClass, con ciclo de vida independiente de cualquier pod individual. - ResourceClaimTemplate — incrustado en la especificación del pod para que Kubernetes genere automáticamente un
ResourceClaimdedicado por instancia de pod y lo elimine cuando el pod termina.
Comparación arquitectónica
| Dispositivos heredados (Device Plugins) | DRA (resource.k8s.io/v1) |
|
|---|---|---|
| Asignación | Contadores enteros (nvidia.com/gpu: 1) |
Basado en atributos (VRAM, perfil MIG, controlador, topología) vía CEL |
| Reconfiguración en vivo | Requiere recrear el pod completo | Las reclamaciones pueden actualizarse en base a plantillas; nuevas reclamaciones sin tocar otros campos del pod |
| Compartición de dispositivos | Hacks estáticos específicos del vendedor | Compartición nativa (y, en beta de v1.36, partición nativa de GPU) |
Arquitectura para un Puente de Simulación sin Tiempo de Inactividad
Aquí un manifiesto corregido usando el esquema estable de DRA (nota la sección exactly: que envuelve deviceClassName y selectors, que requiere la API estable actual):
apiVersion: v1
kind: Pod
metadata:
name: omniverse-local-bridge
namespace: spatial-net
labels:
app: simulation-pipeline
spec:
resourceClaims:
- name: dynamic-gpu-allocation
resourceClaimTemplateName: omniverse-gpu-template
containers:
- name: spatial-router-container
image: cr.enterprise.internal/spatial/omniverse-bridge:v2026.2.1
imagePullPolicy: IfNotPresent
# Controla si un cambio de recurso fuerza reinicio del contenedor
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: NotRequired
# Recursos base — QoS Garantizado (solicitudes == límites)
resources:
requests:
cpu: "4"
memory: "16Gi"
limits:
cpu: "4"
memory: "16Gi"
claims:
- name: dynamic-gpu-allocation
ports:
- containerPort: 8080
name: websocket-sync
- containerPort: 9090
name: grpc-telemetry
---
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
name: omniverse-gpu-template
namespace: spatial-net
spec:
spec:
devices:
requests:
- name: primary-rendering-core
exactly:
deviceClassName: enterprise-nvidia-gpu
selectors:
- cel:
expression: |-
device.attributes["gpu.nvidia.com"].profile == "1g.5gb" ||
device.attributes["gpu.nvidia.com"].profile == "3g.20gb"
Para escalar este pod, un controlador de autoscaling envía un parche JSON contra el subrecurso /resize del pod (como se muestra arriba), mientras actualiza por separado la ResourceClaim correspondiente para solicitar un perfil MIG mayor. El kubelet verifica la capacidad no asignada del nodo, coordina con el controlador DRA vía gRPC para remapear la GPU, y actualiza los límites del cgroup — todo mientras el ciclo de WebSocket en spatial-router-container continúa sin interrupciones.
Casos de Uso en Producción y Guardas
Capacidad diferida. Si un nodo está casi saturado, una solicitud de redimensionamiento permanece en PodResizePending (Deferred) hasta que se libere capacidad — reintentada automáticamente según el orden de prioridad descrito, pero sin un límite de tiempo garantizado. Para un puente sensible a la latencia, conviene establecer un umbral de fallback (por ejemplo, una escalada manual si un redimensionamiento se ha diferido más de unos segundos) en lugar de confiar en una espera indefinida durante un pico de carga.
Desviación del controlador/especificación. Un redimensionamiento aplicado directamente vía el subrecurso /resize no actualiza la plantilla del Deployment o StatefulSet que lo posee. Si el nodo falla y el controlador reprograma un reemplazo, este generará un pod con el perfil de recursos original, sin escalar. Las configuraciones de producción suelen combinar redimensionamiento in situ con un VPA en modo InPlaceOrRecreate (beta, basado en KEP-1287) o un operador personalizado que refleje el redimensionamiento en la anotación del controlador, para que una reprogramación comience con el tamaño correcto.
Políticas estáticas de gestión de recursos. Redimensionar un pod Guaranteed QoS está explícitamente fuera del alcance de KEP-1287 cuando el nodo usa una política de gestión de CPU/memoria estática (para fijar núcleos o memoria NUMA exclusivos a un pod) — tal redimensionamiento es rechazado como Infeasible. Si tus nodos puente dependen de fijación estática de CPU para cargas sensibles a jitter, planifica en consecuencia, en lugar de asumir que el redimensionamiento in situ será universal; algunos debates comunitarios han propuesto soporte futuro para esto, pero no forma parte de la función estable en v1.36.
Novedades desde GA: Kubernetes v1.36 (“Haru”, abril 2026)
Desde que esta pila alcanzó GA, la siguiente versión (v1.36, lanzada el 22 de abril de 2026 y la línea estable actual a mediados de 2026) extendió ambas funciones aún más — relevante si diseñas una arquitectura de puente hoy en lugar de en diciembre de 2025:
- Redimensionamiento in situ a nivel de pod (beta, activado por defecto, requiere
cgroups v2) extiende el redimensionamiento desde contenedores individuales hasta el conjunto de recursos del pod, condicionado a cuatro banderas de función (PodLevelResources,InPlacePodVerticalScaling,InPlacePodLevelResourcesVerticalScaling,NodeDeclaredFeatures). Útil para pods de puente con múltiples contenedores (por ejemplo, un enrutador más un sidecar de telemetría) donde quieres escalar un presupuesto de recursos compartido en lugar de cada contenedor individualmente. - Dispositivos particionables y Capacidad Consumible en DRA pasaron a beta y se habilitan por defecto — esto es el equivalente nativo a solicitar manualmente slices MIG vía selectores CEL como en el manifiesto anterior, permitiendo que DRA entienda las particiones GPU directamente en lugar de tratar un slice MIG como un dispositivo opaco.
- Taints y Tolerations en dispositivos (beta) permiten que un controlador DRA marque una GPU degradada directamente en su
ResourceSlice(por ejemplo, tras un error ECC), para que nuevas reclamaciones la eviten sin que el controlador tenga que quitar el dispositivo del inventario por completo. - Estado de salud de recursos para Pods (
allocatedResourcesStatus, en beta) muestra la salud de cada dispositivo en el estado del pod y mediantekubectl describe pod— útil para distinguir “el contenedor del puente falló” de “la GPU asignada está en mal estado,” en DRA y en plugins de dispositivos legacy.
Nada de esto altera la arquitectura central descrita arriba, pero las funciones de estado de salud y marcas en dispositivos cierran una brecha real de observabilidad para este tipo de puentes GPU sensibles a la latencia: ahora puedes saber si un dispositivo se está degradando antes de que fuerce una migración no planificada.
Conclusión
El Redimensionamiento in situ de Pods (GA en v1.35) y la Asignación Dinámica de Recursos (GA en v1.34) — lanzados en ciclos diferentes, no simultáneamente — eliminan la necesidad de destruir un pod para cambiar su huella de recursos, ya sea CPU/memoria o GPU. Para puentes de simulación con estado que mantienen conexiones WebSocket/gRPC en vivo, esa es la diferencia entre una canalización que se expande y contrae con la carga del sensor, y otra que pierde conexiones cada vez que la carga aumenta. La mecánica importa en la práctica: los redimensionamientos se hacen a través de un subrecurso /resize dedicado, la clase QoS es inmutable, la reducción de tamaño se comprueba pero no se garantiza segura, y la fijación estática de CPU/memoria sigue siendo una brecha explícita. Construir en torno a esas limitaciones — en lugar de la versión idealizada de la función — es lo que hace que una arquitectura sin reinicio sea realmente sin reinicio en producción.
Registro de cambios
Correcciones al borrador original:
1. El GA de DRA fue en v1.34, no en v1.35. El borrador sugería que DRA “graduó a estabilidad completa junto con v1.35.” La API principal (resource.k8s.io/v1) de DRA alcanzó GA en Kubernetes 1.34 (ago/sept 2025); v1.35 (dic 2025) es cuando el Redimensionamiento in situ (KEP-1287) llegó a GA. Se añadió una tabla de historia de versiones para aclararlo.
2. Corrección en la mecánica del API de redimensionamiento. El ejemplo original de JSON-patch modificaba directamente el objeto del pod. Kubernetes requiere que los redimensionamientos pasen por el subrecurso dedicado /resize (kubectl patch --subresource resize, que requiere kubectl v1.32+). Se actualizó el ejemplo y se añadió la implicación en RBAC.
3. Corrección en el modelo de estado del pod. La tabla del borrador implicaba que Allocated, Resources, PodResizePending y Infeasible eran campos paralelos de nivel superior. En realidad: los recursos deseados y reales viven en spec/status.containerStatuses, y Deferred/Infeasible son razones en la condición PodResizePending, con PodResizeInProgress como condición separada. Se reconstruyó la tabla para reflejar esto.
4. Corrección en la versión de la API del manifiesto de DRA. El YAML original usaba resource.k8s.io/v1alpha3, una versión pre-GA. Se actualizó a la versión estable resource.k8s.io/v1, incluyendo la envoltura exactly: que requiere la API actual alrededor de deviceClassName y selectors.
5. Se añadió el cambio en la disminución del límite de memoria y el orden de reintento del redimensionamiento diferido — ambos nuevos en la versión v1.35 y no mencionados en el borrador.
6. Se añadió matiz a la limitación de políticas estáticas de gestión de recursos — confirmada como un objetivo no alcanzado explícitamente por KEP-1287 (redimensionamiento marcado como Infeasible) en lugar de una incompatibilidad total, con nota de que sigue siendo un área abierta.
7. Se añadió una sección “Novedades en v1.36” que cubre redimensionamiento a nivel de pod (beta), dispositivos particionables, marcas y tolerancias en dispositivos, y estado de salud de recursos en DRA — dado que v1.36 (“Haru,” abril 2026) es la versión estable actual al momento de escribir, seis meses después de cuando el borrador original describía el estado “más reciente”.
8. Se eliminaron artefactos residuales de SEO/IA y se reformateó todo como Markdown limpio.
Fuentes principales consultadas: - Kubernetes 1.35: In-Place Pod Resize Graduates to Stable — blog oficial de K8s - Resize CPU and Memory Resources assigned to Containers — documentación oficial - Resize CPU and Memory Resources assigned to Pods — documentación oficial (redimensionamiento a nivel de pod) - In-Place Update of Pod Resources, KEP-1287 — propuesta de mejora - Kubernetes v1.34: DRA has graduated to GA — blog oficial de K8s - Dynamic Resource Allocation — documentación oficial - Allocate Devices to Workloads with DRA — ejemplos API estables - Kubernetes v1.36: ハル (Haru) — blog oficial de K8s - Kubernetes v1.36 Release: New Features, Stable APIs Breaking Changes — PerfectScale - Kubernetes releases — matriz de versiones y soporte
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.