Saltar al contenido
Todos los artículos

Costes de Kubernetes en EKS y GKE: el mismo método, otras palancas

Mi método para AKS llevó un clúster de producción de 7 a 4 nodos dimensionando los requests según el uso p95 real y dejando que el autoscaler hiciera la reducción. El método vale tal cual para Amazon EKS y Google Kubernetes Engine. Lo que cambia es de dónde sale la factura y qué palancas te da cada cloud: Karpenter y split cost allocation en AWS, la facturación por Pod de Autopilot y la asignación de costes en Google Cloud. Este es el artículo complementario para ambos.

10 min de lectura

1. Saber de dónde sale la factura

Las dos clouds cobran una tarifa fija por el plano de control gestionado: 0,10 dólares por clúster y hora en Amazon EKS e igual en GKE, donde la capa gratuita abona cada mes un clúster Autopilot o Standard zonal por cuenta de facturación. Son unos 73 dólares al mes por clúster, y rara vez es lo que duele. La factura de verdad es la computación de debajo: instancias EC2 o pods de Fargate en AWS, y en GKE los nodos de un clúster Standard o, en Autopilot, los recursos que piden tus Pods.

Hay una partida que merece un recordatorio en el calendario. Cuando un clúster de EKS ejecuta una versión de Kubernetes que ha salido del soporte estándar, pasa al soporte extendido y la tarifa del clúster sube a 0,60 dólares por hora. Mantener las versiones al día sale más barato que pagar el retraso.

Adónde va el dinero en EKS y GKE y qué palancas lo mueven. El ciclo en sí es el mismo en todas las clouds.
Palancas de coste de Kubernetes en EKS y GKE lado a lado: en AWS el plano de control de EKS a 0,10 dólares por hora, Karpenter consolidando nodos EC2 con spot y on-demand, Fargate facturado por pod, split cost allocation data en el Cost and Usage Report y Compute Savings Plans; en Google Cloud la tarifa de gestión de GKE a 0,10 dólares por hora con un clúster en la capa gratuita, Autopilot facturado por los requests de los Pods, Standard con el perfil optimize-utilization y Spot VMs, asignación de costes en BigQuery y descuentos por compromiso de uso.

2. Poner precio a cada namespace

Sin atribución, un clúster compartido es una cifra grande que no es de nadie. AWS lo resuelve con split cost allocation data: el Cost and Usage Report incluye entonces filas a nivel de contenedor, y los pods de EKS reciben su parte de la instancia en la que corrieron, por CPU y memoria. En Google Cloud, la asignación de costes de GKE añade el namespace y las etiquetas de Kubernetes de tus cargas a la exportación de Cloud Billing, donde una consulta en BigQuery muestra el coste por equipo o por servicio.

Actívalo antes de cambiar nada y poneos de acuerdo en dos o tres etiquetas que use todo el mundo, como team y service. El primer informe casi siempre saca a la luz un namespace que nadie recuerda haber creado.

bash
# GKE: namespace and label breakdown in the Cloud Billing export (BigQuery)
gcloud container clusters update prod-cluster \
  --location=europe-west6 --enable-cost-allocation

# EKS: enable split cost allocation data in the Billing and Cost Management
# preferences; the CUR then has pod-level rows you can sum per namespace and label

3. Dimensionar requests según el p95, igual que en AKS

Este paso no depende de la cloud. Saca de Prometheus la CPU y la memoria por contenedor durante dos a cuatro semanas que incluyan un pico real, pon los requests de CPU en torno al p95 más margen y los de memoria en torno al máximo observado más un colchón, y cambia un namespace cada vez a través de Git. En EKS, Amazon Managed Service for Prometheus recoge las métricas; en GKE, Google Cloud Managed Service for Prometheus. Las consultas son las mismas que en mi artículo sobre AKS.

La calculadora de abajo muestra cuántos nodos necesitas cuando los requests siguen el uso real y no suposiciones. Esa cifra es tu objetivo para los dos pasos siguientes.

Interactivo

¿Cuántos nodos necesitan de verdad tus requests?

Mueve los controles a tus cifras. Las requests deciden dónde caben los pods, así que unas requests infladas compran nodos que nadie usa.

Tamaño de nodo

5

nodos hoy

2

nodos tras el ajuste (200m)

60%

menos capacidad de nodos

Solo CPU, alrededor del 90 % de un nodo es asignable, mínimo 2 nodos por disponibilidad. Revisa la memoria igual antes de quitar un nodo.

Todas las calculadoras y checklists

4. EKS: que Karpenter elija y empaquete los nodos

En EKS, Karpenter sustituye los grupos de nodos fijos por NodePools que describen lo permitido: familias de instancias, arquitecturas, spot u on-demand. Lanza la instancia que encaja con los pods pendientes y, con la política de consolidación por defecto WhenEmptyOrUnderutilized, retira o sustituye nodos cuando sus pods caben en otro sitio o en una máquina más barata. Ese es el momento en que unos requests honestos se convierten en menos nodos.

Permite capacidad spot para las cargas que toleran interrupciones, como capas web sin estado, workers y runners de CI, y deja en on-demand las bases de datos y todo lo que tarda en apagarse. Si tus imágenes se construyen para las dos arquitecturas, incluye arm64 para que entren las instancias Graviton. Los trabajos pequeños y a picos pueden ir a Fargate, que factura por pod y no por nodo.

yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: general
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]   # spot only where interruptions are fine
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
  limits:
    cpu: "200"                            # a ceiling, so a bug can't scale the bill
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m

Consejo práctico

Pon limits en cada NodePool. Karpenter lanzará sin problema lo que pidan los pods pendientes, incluido el resultado de un despliegue que pide por error 64 réplicas.

5. GKE: elegir Autopilot o ajustar Standard

GKE ofrece dos modelos de facturación y cada uno premia una cosa. En Autopilot, las cargas de uso general se facturan por los recursos que piden sus Pods. No hay nodos que empaquetar; cada milicore que quitas de un request sale directamente de la factura. Eso hace de Autopilot el sitio donde el right-sizing compensa antes, y donde los requests inflados duelen más.

En modo Standard pagas los nodos, como en AKS, así que empaquetar vuelve a importar. El cluster autoscaler tiene un perfil optimize-utilization que prioriza usar los nodos a fondo frente a mantener capacidad libre y retira nodos con más decisión. Añade Spot VMs para las cargas tolerantes en un node pool aparte y deja el pool por defecto con VMs normales para todo lo demás.

bash
# GKE Standard: pack nodes tighter, scale down sooner
gcloud container clusters update prod-cluster \
  --location=europe-west6 --autoscaling-profile optimize-utilization

# A separate Spot pool for workloads that tolerate interruptions
gcloud container node-pools create spot-pool --cluster=prod-cluster \
  --location=europe-west6 --spot --enable-autoscaling --min-nodes=0 --max-nodes=5

6. Comprometerse al final, en las dos clouds

Solo cuando la huella ya se ha reducido tienen sentido los compromisos. En AWS, los Compute Savings Plans cubren EC2, Fargate y Lambda con un compromiso de uno o tres años medido en dólares por hora, así que siguen funcionando cuando Karpenter cambia de familia de instancias. En Google Cloud, los descuentos por compromiso de uso se basan en recursos o en gasto. Cubre la base estable que queda tras el right-sizing y deja los picos y el spot en precio bajo demanda.

El orden importa más que el descuento: un compromiso comprado antes de la limpieza ata capacidad que estás a punto de retirar, y las reglas de devolución de los compromisos son estrictas en todas las clouds.

7. Mantenerlo pequeño en ambas

Los clústeres vuelven a crecer igual en todas las clouds: requests copiados, namespaces de prueba olvidados, un pool escalado tras una prueba de carga. La rutina también es la misma. Un informe diario breve de costes por namespace en el chat del equipo, construido a partir del CUR en AWS o de la exportación de facturación en Google Cloud. Presupuestos con alertas de previsión. Un ResourceQuota por namespace para que los requests no crezcan sin que nadie lo vea. Y un recordatorio en el calendario para las actualizaciones de Kubernetes, para que ningún clúster de EKS acabe en soporte extendido.

El método es el mismo en AKS, EKS y GKE: medir el p95, cambiar a través de Git, dejar que los nodos sigan, comprometerse al final e informar a diario. Solo los botones se llaman distinto.

Conclusión

EKS y GKE necesitan la misma disciplina que AKS: atribuir por namespace, dimensionar los requests según el p95, dejar que Karpenter o el autoscaler reduzcan y comprometerse solo con lo que queda.

Más artículos

    Hablemos

    Cuéntame qué estás construyendo; te respondo en 1 o 2 días laborables.

    Dominik Heinrich
    Empresa
    MADO Consulting

    Disponible en todo el mundo en remoto. Presencial bajo petición, según el país.

    Te respondo en 1 o 2 días laborables. Huecos libres: mira el calendario

    Abre aquí el calendario de reservas de Calendly. Al cargarlo se envían datos a Calendly (ver aviso legal).