Por qué tu clúster de EKS cuesta el doble de lo que debería
Kubernetes esconde el desperdicio mejor que ninguna otra plataforma, porque todo parece ocupado. Cuatro medidas te dicen dónde se va el dinero, y tres cambios suelen reducirlo a la mitad.
Un clúster con 40 nodos al 22 por ciento de CPU media no es un problema de capacidad. Es un problema de requests, uno de empaquetado y uno de política de escalado, apilados uno sobre otro, y el panel enseñará los cuarenta nodos como "en uso" todo el rato.
Así desmontamos un clúster, en el orden que encuentra dinero más rápido.
Mide cuatro cosas primero
Requests frente a uso, por namespace. El número más útil de un clúster de Kubernetes es la razón entre CPU y memoria solicitadas y CPU y memoria realmente usadas. Por encima de 3x estás comprando tres nodos para ejecutar el trabajo de uno. Sácalo de kubectl top agregado por namespace, o bien de Prometheus con kube_pod_container_resource_requests contra container_cpu_usage_seconds_total.
Asignable frente a solicitado, por nodo. Si las requests son razonables y los nodos siguen vacíos, el problema es el empaquetado: unos pocos pods con requests grandes, reglas de antiafinidad o un DaemonSet que reserva más de lo que crees. Busca nodos cuyo mayor hueco no planificable sea más grande que el mayor pod pendiente.
Coste por namespace. Kubecost u OpenCost, o un reparto casero de la factura de nodos por requests. Sin esto ningún equipo se cree que el número es suyo y no cambia nada.
Tráfico entre zonas. En un clúster de tres AZ con servicios que ignoran la topología, en torno a dos tercios del tráfico entre pods cruza una frontera de zona y se factura. En entornos de microservicios habladores esto es una línea real, no un redondeo — la misma que aparece en la capa cuatro de la factura de AWS.
Tres cambios que suelen partirlo por la mitad
Fija las requests a partir del uso observado, y pon límites con cuidado. Las requests deberían estar cerca del p95 del uso real, no en un número redondo que alguien tecleó en 2023. El Vertical Pod Autoscaler en modo recomendación te da las cifras sin actuar; déjalo dos semanas y aplica la salida a mano. Sobre los límites: pon límites de memoria, porque la alternativa es un OOM de nodo entero, pero ten cuidado con los de CPU, que provocan throttling en el p99 mientras el nodo está ocioso. Una request de CPU sin límite de CPU es el valor por defecto correcto para la mayoría de servicios sensibles a latencia.
Sustituye Cluster Autoscaler por Karpenter. Cluster Autoscaler escala grupos de nodos que definiste de antemano, así que tu empaquetado está limitado por los tipos de instancia que adivinaste. Karpenter aprovisiona la instancia que encaja con los pods pendientes, consolida cargas en menos nodos cuando encogen y usará Spot con un conjunto diversificado. Solo la consolidación suele quitar entre un 20 y un 30 por ciento de los nodos de un clúster que lleva un año funcionando. Define un presupuesto de disruption y anotaciones do-not-disrupt para las cargas con estado antes de encenderlo.
Pon en Spot lo que toca. Cargas sin estado, replicadas y tolerantes a reinicio en Spot con un conjunto diversificado de instancias, y un núcleo bajo demanda para las piezas cercanas al plano de control. Spot es entre un 60 y un 90 por ciento más barato y las interrupciones se gestionan bien cuando la carga es de verdad sin estado. Lo que mata a los equipos es poner un servicio con estado de una sola réplica en Spot y descubrir el aviso de reclamación a las tres de la mañana.
Lo que se olvida
- Plano de control y NAT. Cada clúster es una cuota mensual fija de plano de control más el NAT gateway que usa. Cuatro clústeres pequeños donde bastaría uno es puro sobrecoste.
- Clústeres de desarrollo ociosos. Escala los grupos de nodos a cero fuera de horario. Un cron y una Lambda; una tarde de trabajo.
- DaemonSets sobredimensionados. Un agente de logs pidiendo 500m de CPU en 40 nodos son 20 núcleos que pagas y no usas.
- Volúmenes EBS antiguos sin asociar de PersistentVolumeClaims borrados con política de reclamación
Retain.
Cómo se ve lo bueno
Un clúster sano corre entre el 55 y el 70 por ciento de asignación media de CPU con requests dentro de 1,5x del uso, escala en menos de dos minutos y puede perder cualquier nodo sin generar una alerta. Llegar ahí son dos o tres semanas de trabajo y no exige reescribir nada — por eso suele ser lo primero que tocamos en un proyecto cloud.
Qué hacer esta semana
Calcula la razón requests/uso de tus tres namespaces más grandes. Si está por encima de 2,5x ya tienes la respuesta, y el Vertical Pod Autoscaler en modo recomendación te dará las cifras corregidas en quince días.