Saltar a contenido

Escalar envoy pods

Hay dos formas de escalar los pods de Envoy en kgateway: réplicas fijas vía GatewayParameters, o escalado automático con HPA. Acá el procedimiento completo para ambas:

Opción 1 — Réplicas fijas con GatewayParameters

Este es el punto de entrada. Las réplicas iniciales se configuran usando el campo spec.kube.deployment.replicas en el recurso GatewayParameters.

Paso 1: Crear el GatewayParameters

# gateway-params.yaml
apiVersion: gateway.kgateway.dev/v1alpha1
kind: GatewayParameters
metadata:
  name: prod-gateway-params
  namespace: infra-gateway
spec:
  kube:
    deployment:
      replicas: 3          # número fijo de pods Envoy
      resources:
        requests:
          cpu: "500m"
          memory: "256Mi"
        limits:
          cpu: "2"
          memory: "512Mi"
kubectl apply -f gateway-params.yaml

Paso 2: Referenciar el GatewayParameters desde el Gateway

# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shared-gateway
  namespace: infra-gateway
spec:
  gatewayClassName: kgateway
  infrastructure:
    parametersRef:
      group: gateway.kgateway.dev/v1alpha1
      kind: GatewayParameters
      name: prod-gateway-params    # <-- apunta al recurso de arriba
  listeners:
    - name: https
      port: 443
      protocol: HTTPS
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: "true"
kubectl apply -f gateway.yaml

# verificar que levantaron los 3 pods
kubectl get pods -n infra-gateway -l app=shared-gateway

Opción 2 — HPA (escalado automático, recomendado para producción)

Para permitir la integración con HPA, no se debe especificar replicas en el GatewayParameters. Así el HPA puede escalar el proxy basándose en tu estrategia de autoscaling.

Paso 1: Instalar metrics-server (si no lo tienes)

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# verificar que está corriendo
kubectl get deployment metrics-server -n kube-system

Paso 2: GatewayParameters SIN replicas

# gateway-params-hpa.yaml
apiVersion: gateway.kgateway.dev/v1alpha1
kind: GatewayParameters
metadata:
  name: prod-gateway-params
  namespace: infra-gateway
spec:
  kube:
    deployment:
      # NO poner replicas aquí — el HPA tomará control
      resources:
        requests:
          cpu: "500m"
          memory: "256Mi"
        limits:
          cpu: "2"
          memory: "1Gi"

Paso 3: Identificar el nombre del Deployment de Envoy

kgateway genera un Deployment cuyo nombre coincide con el del objeto Gateway:

kubectl get deployments -n infra-gateway
# Verás algo como: shared-gateway   1/1   ...

Paso 4: Crear el HorizontalPodAutoscaler

# hpa-gateway.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: envoy-hpa
  namespace: infra-gateway
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: shared-gateway       # nombre del Deployment generado por kgateway
  minReplicas: 2               # nunca bajar de 2 (HA mínimo)
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: AverageValue
          averageValue: 400Mi
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30    # reacciona rápido al alza
      policies:
        - type: Pods
          value: 2
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300   # conservador al bajar
kubectl apply -f hpa-gateway.yaml

# monitorear el HPA
kubectl get hpa envoy-hpa -n infra-gateway -w

Distribuir los pods entre zonas/nodos

Una vez que tienes más de un pod, necesitas asegurarte de que no caigan en el mismo nodo. Agrega esto al GatewayParameters:

spec:
  kube:
    deployment:
      podTemplate:
        topologySpreadConstraints:
          - maxSkew: 1
            topologyKey: topology.kubernetes.io/zone
            whenUnsatisfiable: DoNotSchedule
            labelSelector:
              matchLabels:
                app: shared-gateway
        affinity:
          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  topologyKey: kubernetes.io/hostname
                  labelSelector:
                    matchLabels:
                      app: shared-gateway

Resumen de comandos de verificación

# Ver pods del data plane
kubectl get pods -n infra-gateway

# Ver estado del HPA (TARGETS muestra CPU/MEM actual vs objetivo)
kubectl describe hpa envoy-hpa -n infra-gateway

# Ver eventos de escalado
kubectl get events -n infra-gateway --sort-by='.lastTimestamp' | grep -i scale

# Métricas actuales de los pods
kubectl top pods -n infra-gateway

Cuándo usar cada opción

Situación Recomendación
Dev / staging Réplicas fijas (replicas: 2)
Producción con tráfico estable HPA (CPU 70%, minReplicas: 2)
Producción con picos impredecibles HPA + scaleUp agresivo
Control plane en HA Helm values controller.horizontalPodAutoscaler