Nube e infraestructura

Kubernetes v1.33 introduce respuestas de lista en streaming para reducir el uso de memoria del API server

Kubernetes v1.33 añade codificación en streaming para las respuestas List, reduciendo el uso de memoria de kube-apiserver hasta 20 veces durante la obtención de grandes conjuntos de datos y mejorando la estabilidad del clúster.

Kubernetes v1.33 introduce respuestas de lista en streaming para reducir el uso de memoria del API server
Imagen: Kubernetes Blog, con licencia CC BY 4.0

Traducido automáticamente del original en inglés.

En una publicación en el Kubernetes Blog en mayo de 2025, los mantenedores Marek Siarkowicz y Wei Fu describieron un cambio arquitectónico importante en Kubernetes v1.33. La actualización introduce la codificación en streaming para las respuestas List, una función diseñada para reducir drásticamente el consumo de memoria en el API server al manejar grandes conjuntos de datos. Esta mejora aborda problemas de estabilidad de larga data en clústeres a gran escala, donde la obtención de listas extensas de recursos previamente arriesgaba causar errores de falta de memoria.

Qué ocurrió

Operar clústeres de Kubernetes a gran escala siempre ha implicado gestionar el equilibrio entre la accesibilidad de los datos y el consumo de recursos. Uno de los desafíos más persistentes ha sido el manejo de solicitudes List, que recuperan conjuntos de datos sustanciales desde el estado del clúster. En versiones anteriores, el API server serializaba toda la respuesta en un único bloque contiguo de memoria antes de enviarla al cliente. Aunque HTTP/2 puede dividir las respuestas en tramas más pequeñas para su transmisión, el servidor subyacente mantenía el búfer completo de datos en memoria hasta que finalizaba toda la transferencia. Esto significaba que si la congestión de red ralentizaba la transmisión, cientos de megabytes de memoria permanecían bloqueados durante segundos o minutos.

Esta ineficiencia se volvía crítica a gran escala. Cuando múltiples solicitudes List grandes ocurrían simultáneamente, el uso acumulado de memoria podía dispararse rápidamente, llevando a situaciones de Out-of-Memory (OOM) que comprometían la estabilidad del clúster. El problema se veía agravado por cómo el paquete encoding/json de Go gestiona la memoria. Utiliza sync.Pool para reutilizar búferes, lo cual es eficiente para cargas de trabajo estables pero problemático para respuestas grandes esporádicas. Una vez que una respuesta grande expandía el pool de memoria, esos búferes sobredimensionados permanecían reservados para solicitudes pequeñas posteriores, impidiendo la recolección de basura y manteniendo el uso de memoria artificialmente alto mucho después de que la carga pesada hubiera pasado.

Cómo funciona

El nuevo codificador en streaming cambia la forma en que el API server procesa las respuestas List enfocándose en el campo Items, que contiene la mayor parte de los datos en estructuras de colección. En lugar de codificar todo el array como un bloque monolítico, el servidor ahora procesa y transmite cada elemento individualmente. A medida que cada fragmento se envía al cliente, la memoria asociada con él se libera inmediatamente. Este enfoque incremental asegura que la huella de memoria del API server permanezca predecible y manejable, independientemente del número total de objetos en la lista.

Figure from the original article: Kubernetes v1.33 introduce respuestas de lista en streaming para reducir el uso de memoria del API server
Figura del artículo original · Kubernetes Blog · CC BY 4.0

Dado que los objetos de Kubernetes están típicamente limitados a 1.5 MiB en etcd, el streaming mantiene las asignaciones individuales de memoria pequeñas. El sistema mantiene una estricta compatibilidad hacia atrás validando las etiquetas de struct de Go antes de la activación, asegurando que la salida sea idéntica byte por byte a la del codificador original. La codificación estándar sigue manejando todos los campos excepto Items, por lo que los clientes no necesitan cambiar su código ni siquiera ser conscientes de que el mecanismo subyacente ha cambiado. Esta integración transparente soporta todos los tipos List de Kubernetes, incluyendo listas integradas y Custom Resource UnstructuredLists.

Detalles clave

  • Versión: La función fue introducida en Kubernetes v1.33, anunciada en mayo de 2025.
  • Reducción de memoria: Los benchmarks mostraron una mejora de 20x en el uso de memoria para operaciones de listas grandes, pasando de 70-80GB a solo 3GB.
  • Mecanismo: El codificador transmite elementos individuales dentro del campo Items en lugar de serializar todo el array a la vez.
  • Compatibilidad: No se requieren cambios en el lado del cliente; la salida permanece consistente byte por byte con versiones anteriores.
  • Activador: El codificador en streaming se activa solo tras una rigurosa validación de las etiquetas de struct para garantizar la seguridad.
  • Alcance: Se aplica a todos los tipos List de Kubernetes, incluyendo recursos estándar y recursos personalizados.

Por qué importa

Para ingenieros que construyen y mantienen infraestructura de Kubernetes a gran escala, esta actualización impacta directamente en la fiabilidad y la eficiencia de costos. El alto uso de memoria en kube-apiserver a menudo obliga a los equipos a sobreaprovisionar hardware para manejar picos de carga, aumentando los costos operativos. Al reducir la huella de memoria de las solicitudes List grandes en un margen tan significativo, las organizaciones pueden ejecutar planos de control más ligeros sin sacrificar rendimiento. También reduce el riesgo de terminaciones inesperadas por OOM, que pueden causar interrupciones del servicio y complicar los esfuerzos de depuración durante la respuesta a incidentes.

Además, este cambio mejora la previsibilidad del comportamiento del clúster bajo carga. En entornos donde herramientas de monitoreo, controladores o pipelines de CI/CD listan frecuentemente grandes números de recursos, los picos de memoria previos podían crear fallos en cascada. Con la codificación en streaming, estas operaciones ya no retienen memoria excesiva durante retrasos en la transmisión. Esto permite al API server manejar más solicitudes concurrentes y conjuntos de datos más grandes sin problemas, facilitando escalar clústeres para soportar miles de nodos y decenas de miles de pods.

Qué puedes hacer

  • Actualiza tu plano de control a Kubernetes v1.33 o posterior para beneficiarte del codificador en streaming.
  • Monitorea el uso de memoria de kube-apiserver durante operaciones List grandes para observar la reducción en el consumo pico.
  • Revisa cualquier controlador personalizado u operador que realice llamadas List grandes para asegurar que manejen las respuestas en streaming correctamente, aunque no se requieren cambios estrictos en el código.
  • Verifica la configuración del horizontal pod autoscaler de tu clúster, ya que la menor carga en el API server podría permitir umbrales de escalado más ajustados.
  • Valida que tu stack de monitoreo no dependa de tamaños de búfer fijos para el análisis de respuestas de la API, aunque la compatibilidad byte por byte debería prevenir problemas.
  • Considera ajustar las solicitudes y límites de recursos para kube-apiserver si previamente sobreaprovisionaste memoria para mitigar riesgos de OOM.

Herramientas de la Tienda de Bytechap

Seguir leyendo

Todos los artículos