Un clúster que funciona no es un clúster listo para producción#

Hay una idea peligrosa que se repite en muchos equipos: pensar que un clúster está listo porque “funciona”. Funciona en staging, funciona con tres servicios, funciona el día de la demo. Pero un clúster que funciona no es lo mismo que un clúster diseñado para producción, y la diferencia casi siempre está en un terreno que pocos revisan a tiempo: los límites de Kubernetes.

Kubernetes es flexible, pero no es infinito. Detrás de cada componente hay topes (del API server, de etcd, del kubelet, de las reglas de nombres) que rara vez aparecen en un runbook interno y que se manifiestan justo cuando el clúster crece. El resultado típico: despliegues que fallan sin causa evidente, costos que suben, troubleshooting eterno y decisiones de arquitectura que hay que rehacer bajo presión.

Esta guía recorre los límites con más impacto en la operación real, explica de dónde sale cada uno y cómo vigilarlos. Todos los valores remiten a la documentación oficial; donde un proveedor administrado cambia el número, lo indicamos.

Documentación: Kubernetes · Consideraciones para clústeres grandes ↗

Por qué los límites no son un detalle técnico#

Los límites de Kubernetes no son trivia para entrevistas: son restricciones que condicionan la arquitectura del clúster desde el primer día.

El ejemplo más conocido: la documentación oficial indica que Kubernetes está diseñado para configuraciones que cumplan a la vez no más de 110 pods por nodo, no más de 5.000 nodos, no más de 150.000 pods en total y no más de 300.000 contenedores en total por clúster. No son números arbitrarios: marcan el rango en el que el proyecto garantiza un comportamiento predecible del control plane.

Cuando un equipo se acerca a esos topes o los ignora, no recibe un error claro que diga “te pasaste”. Lo que suele ver es latencia creciente en el API server, scheduling más lento, addons que se reinician por falta de memoria y un clúster cada vez más difícil de operar. El límite no desaparece por no conocerlo; se manifiesta como incidente.

Lo mismo aplica al almacenamiento. Kubernetes guarda todo el estado del clúster en etcd, y etcd tiene sus propios límites: por defecto, el tamaño máximo de una solicitud es 1,5 MiB y la cuota de almacenamiento es de 2 GiB, con 8 GiB como máximo sugerido para entornos normales. Si etcd llega a su cuota, deja de aceptar escrituras: no cae “un servicio más”, se congela la memoria del clúster entero.

Documentación: Kubernetes · Consideraciones para clústeres grandes ↗ · etcd · Límites del sistema ↗

No todos los límites vienen del mismo lugar#

Un error frecuente es tratar todos los límites como si tuvieran el mismo origen. Entender quién impone cada uno cambia la forma de diagnosticar.

  • API server. Los Secrets individuales están limitados a 1 MiB para evitar objetos enormes que agoten la memoria del API server y del kubelet; los datos de un ConfigMap tampoco pueden superar 1 MiB. Además, el total de anotaciones de un objeto (claves y valores) no puede superar 256 KiB.
  • etcd. El tope de 1,5 MiB por solicitud es de etcd y se puede configurar con --max-request-bytes; la cuota de la base de datos se ajusta con --quota-backend-bytes. En servicios administrados no controlas estos flags.
  • Metadatos y nombres. Las claves de labels y anotaciones tienen un nombre de hasta 63 caracteres y un prefijo opcional de hasta 253; los valores de labels, hasta 63. La mayoría de los objetos, como los Pods, usan nombres de subdominio DNS (hasta 253 caracteres), mientras que otros, como los Services, exigen etiquetas DNS de 63 caracteres como máximo.
  • Kubelet y nodo. Aquí viven valores operativos como el periodo de gracia de terminación (30 segundos por defecto) y los umbrales de eviction por defecto en Linux: memory.available<100Mi, nodefs.available<10 %, imagefs.available<15 % y nodefs.inodesFree<5 %. Al cruzarlos, el kubelet empieza a expulsar pods.

Un caso real que confunde a muchos equipos: aplicar con kubectl apply (client-side) un ConfigMap de, por ejemplo, 400 KiB. Los datos están por debajo de 1 MiB, pero kubectl guarda una copia completa del manifiesto en la anotación kubectl.kubernetes.io/last-applied-configuration, y esa anotación supera el límite de 256 KiB. El error menciona anotaciones, no el ConfigMap. La solución es usar server-side apply, que no depende de esa anotación, o reducir el objeto.

Parecen detalles menores, pero un nombre demasiado largo generado por un chart de Helm o una anotación que crece sin control pueden romper un operador o una automatización completa, y a menudo de forma intermitente, que es la peor manera de fallar.

Documentación: Kubernetes · Secrets (límite de tamaño) ↗ · Kubernetes · ConfigMaps ↗ · Kubernetes · Annotations ↗ · Kubernetes · Labels y selectores ↗ · Kubernetes · Nombres e IDs de objetos ↗ · etcd · Límites del sistema ↗ · Kubernetes · Node-pressure eviction ↗ · Kubernetes · Ciclo de vida del Pod (terminación) ↗ · Kubernetes · Gestión declarativa con kubectl apply ↗ · Kubernetes · Server-Side Apply ↗

Tabla de referencia rápida#

Valores por defecto del proyecto upstream y componente que impone cada límite. Algunos cambian según proveedor, versión o plugin de red, como verás en la siguiente sección.

LímiteValor por defectoQuién lo impone
Pods por nodo110 (upstream)kubelet (maxPods) / diseño del clúster
Nodos por clúster5.000Límite de diseño del proyecto
Pods totales por clúster150.000Límite de diseño del proyecto
Contenedores totales por clúster300.000Límite de diseño del proyecto
Tamaño máximo de solicitud1,5 MiBetcd (--max-request-bytes)
Cuota de la base de datos2 GiB (8 GiB máximo sugerido)etcd (--quota-backend-bytes)
Tamaño de un Secret1 MiBAPI server
Datos de un ConfigMap1 MiBAPI server
Total de anotaciones por objeto256 KiBAPI server
Nombre de clave de label/anotación63 caracteres (prefijo: 253)API server
Nombre de objeto (subdominio DNS)253 caracteresReglas de nombres
Nombre de objeto (etiqueta DNS)63 caracteresReglas de nombres
Rango de NodePort30000–32767kube-apiserver (--service-node-port-range)
Periodo de gracia de terminación30 sEspecificación del Pod / kubelet
Puerto de kube-apiserver6443kube-apiserver
Puerto de la API del kubelet10250kubelet
Puertos de etcd2379–2380etcd

Documentación: Kubernetes · Consideraciones para clústeres grandes ↗ · etcd · Límites del sistema ↗ · Kubernetes · Secrets (límite de tamaño) ↗ · Kubernetes · ConfigMaps ↗ · Kubernetes · Annotations ↗ · Kubernetes · Nombres e IDs de objetos ↗ · Kubernetes · Service (NodePort) ↗ · Kubernetes · Puertos y protocolos ↗ · Kubernetes · Ciclo de vida del Pod (terminación) ↗

Los valores por defecto no son los valores recomendados#

Este es quizá el malentendido más caro. Un valor por defecto o un límite máximo es un techo, no una recomendación para producción.

El límite de 1 MiB en Secrets y ConfigMaps lo ilustra bien. Técnicamente puedes acercarte a ese tope, pero la propia documentación recuerda que un ConfigMap no está diseñado para guardar grandes bloques de datos y que muchos Secrets pequeños también pueden agotar memoria. Mantén estos objetos lo más pequeños posible y, si necesitas más, monta un volumen o usa un servicio externo. El límite te dice qué es posible; la buena práctica te dice qué es sano.

Lo mismo ocurre con etcd: 2 GiB es la cuota por defecto, pero operar un clúster grande exige planificar compactación del historial, desfragmentación periódica para recuperar espacio y monitoreo continuo del tamaño de la base de datos. Sin eso, la base crece hasta la cuota y etcd pasa a modo de solo lectura.

Documentación: Kubernetes · ConfigMaps ↗ · Kubernetes · Secrets (límite de tamaño) ↗ · etcd · Mantenimiento (compactación y desfragmentación) ↗

Algunos límites cambian en EKS, GKE y AKS#

Si tu clúster corre en un servicio administrado, varios de estos números no aplican igual que en un clúster autogestionado. El caso más claro es el de pods por nodo:

  • Amazon EKS: con la VPC CNI, cada pod recibe una IP de la VPC, así que el máximo depende de las interfaces y direcciones IP que admite el tipo de instancia. En managed node groups sin AMI personalizada, EKS además aplica un tope de 110 pods en instancias de menos de 30 vCPU y de 250 en las mayores.
  • Google GKE: los clústeres Standard usan 110 por defecto y pueden configurarse hasta 512 pods por nodo; en Autopilot, GKE elige un máximo entre 8 y 256 según la densidad esperada.
  • Azure AKS: el máximo es 250 pods por nodo, y el valor por defecto varía según el plugin de red y el método de despliegue (CLI, plantilla ARM o portal).

La conclusión operativa es directa: no asumas que el número “oficial” es el de tu entorno. Consulta la documentación del proveedor, el tipo de instancia y el plugin de red que usas, y verifica el valor real en cada nodo. Afirmar que “Kubernetes funciona igual en todas partes” es exactamente el tipo de suposición que genera incidentes. En servicios administrados tampoco controlas los flags de etcd, así que conviene conocer las cuotas publicadas por el proveedor.

bash
# 1. Pods permitidos por nodo (lo que realmente configuró tu proveedor)
kubectl get nodes -o custom-columns=NODE:.metadata.name,MAX_PODS:.status.allocatable.pods

# 2. Pods programados por nodo, de mayor a menor
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.nodeName}{"\n"}{end}' \
  | sort | uniq -c | sort -rn | head

# 3. ConfigMaps más grandes (tamaño aproximado del objeto serializado)
kubectl get configmaps -A -o json \
  | jq -r '.items[] | "\(tojson | length)\t\(.metadata.namespace)/\(.metadata.name)"' \
  | sort -rn | head

# 4. Objetos grandes: aplícalos con server-side apply para no crear
#    la anotación last-applied-configuration
kubectl apply --server-side -f big-configmap.yaml
Comprobaciones rápidas de solo lectura. Requieren kubectl y jq; el tamaño calculado con jq es aproximado.

Documentación: Amazon EKS · Elegir tipo de instancia y maxPods ↗ · Google Cloud · Máximo de Pods por nodo en GKE ↗ · Microsoft Learn · Cuotas y límites de AKS ↗ · Kubernetes · Server-Side Apply ↗

Buenas prácticas para equipos DevOps y Platform Engineering#

Conocer los límites es el primer paso. El segundo es construir una operación que no dependa de que cada ingeniero los recuerde de memoria.

  • Documenta los límites como estándar interno: pods por nodo de cada pool, tamaño máximo aceptado para Secrets y ConfigMaps, convenciones de nombres y comportamiento de etcd deben vivir en un estándar de plataforma, no en la cabeza de una persona.
  • Valida en CI/CD y en la admisión, no en producción: la validación de manifiestos en el pipeline y políticas de admisión como ValidatingAdmissionPolicy pueden frenar objetos demasiado grandes o nombres inválidos antes del despliegue.
  • Usa la observabilidad como alerta temprana: vigila el tamaño de la base de etcd frente a su cuota, los pods por nodo y la latencia del API server para saber cuándo te acercas a un límite, no cuando ya lo cruzaste.
  • Diseña la capacidad como variable explícita: decide pods por nodo y nodos por clúster a partir de límites reales, incluidos los del proveedor, y no del crecimiento accidental.
  • Mantén los objetos pequeños: Secrets, ConfigMaps y anotaciones livianos reducen la carga sobre etcd y el API server, y hacen el clúster más estable y más barato de operar.
yaml
groups:
  - name: kubernetes-limits
    rules:
      # etcd autogestionado: alerta antes de llegar a la cuota de la base de datos
      - alert: EtcdDatabaseNearQuota
        expr: etcd_mvcc_db_total_size_in_bytes / etcd_server_quota_backend_bytes > 0.8
        for: 15m
        labels:
          severity: warning
      # Latencia p99 del API server por verbo (excluye WATCH y CONNECT, que son largos)
      - alert: KubeAPIServerHighLatency
        expr: |
          histogram_quantile(0.99,
            sum by (le, verb) (
              rate(apiserver_request_duration_seconds_bucket{verb!~"WATCH|CONNECT"}[5m])
            )
          ) > 1
        for: 10m
        labels:
          severity: warning
Reglas de Prometheus de ejemplo. Las métricas de etcd solo están disponibles si puedes scrapear etcd (clústeres autogestionados); el umbral de latencia es ilustrativo y debe ajustarse a tu línea base.

Esto es justamente lo que aporta una práctica madura de Platform Engineering: convertir conocimiento disperso en estándares, automatización y guardarraíles que escalan con el equipo.

Documentación: Kubernetes · Validating Admission Policy ↗ · Kubernetes · Referencia de métricas ↗ · etcd · Mantenimiento (compactación y desfragmentación) ↗

Conclusión#

La madurez con Kubernetes no se mide por cuántos workloads despliegas, sino por lo bien que entiendes el comportamiento del clúster bajo carga. Los límites de pods, etcd, Secrets, nombres y kubelet no son obstáculos: son la información que te permite diseñar para escalar en lugar de improvisar y corregir.

Un clúster preparado para producción es uno donde los límites están entendidos, verificados contra el proveedor, monitoreados y traducidos en estándares operativos. Todo lo demás es una falla esperando su momento.

Fuentes y alcance

Documentación consultada el 25 de septiembre de 2026. Los ejemplos y criterios de decisión son propuestas editoriales; adáptalos al contrato de tu aplicación y valídalos en tu entorno de pruebas autorizado.

Del diseño a la decisión

Compara soluciones cloud

Revisa tarifas, límites, condiciones y fuentes de cada opción.

Abrir comparador