Migra Ingress a la API de Gateway

En esta página, se muestra cómo migrar la administración del tráfico en Google Kubernetes Engine (GKE) de la API de Ingress a la API de Gateway. La API de Gateway proporciona una solución Google Cloud completamente administrada para controlar el tráfico de tu aplicación.

Para minimizar el tiempo de inactividad y mitigar el riesgo, el enfoque más eficaz para migrar a la API de Gateway es ejecutar simultáneamente la API de Ingress existente y las nuevas configuraciones de la API de Gateway. Este método permite realizar pruebas exhaustivas de la nueva configuración de la puerta de enlace en un entorno activo sin afectar tus servicios actuales. Después de validar la nueva configuración de Gateway, puedes realizar una migración rápida de DNS para redireccionar el tráfico a la API de Gateway y garantizar una transición fluida y de bajo riesgo.

En términos generales, la estrategia de migración implica las siguientes fases:

  1. Configura el nuevo balanceador de cargas.
  2. Define reglas para controlar el tráfico entrante.
  3. Implementa la nueva configuración y prueba el flujo de tráfico a la nueva dirección IP de la puerta de enlace.
  4. Cambia el tráfico de producción a la API de Gateway.
  5. Limpia los recursos de Ingress restantes.

Configura el nuevo balanceador de cargas

En esta fase, implementarás un recurso de puerta de enlace de Kubernetes para balancear las cargas del tráfico a tu clúster de GKE. Cuando implementas un recurso de Gateway, GKE configura un balanceador de cargas de aplicaciones de capa 7 para exponer el tráfico HTTP(S) a las aplicaciones que se ejecutan en el clúster. Implementas un recurso de Gateway para cada clúster o para cada balanceador de cargas que necesites.

En el siguiente ejemplo, configurarás un balanceador de cargas de aplicaciones externo global. Para crear una Gateway, guarda el siguiente manifiesto como gateway.yaml:

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: external-http-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed # GKE's managed external Application Load Balancer
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: Same # Only allow HTTPRoutes from the same namespace

En el manifiesto anterior, se describe una puerta de enlace que incluye los siguientes campos:

  • gatewayClassName: gke-l7-global-external-managed: Especifica la GatewayClass para esta puerta de enlace. Esta clase de Gateway usa un balanceador de cargas de aplicaciones externo global.
  • protocol: HTTP y port: 80: Especifican que la puerta de enlace expone el puerto 80 para el tráfico HTTP.

Define reglas de tráfico para el tráfico entrante

Los recursos de ruta definen reglas específicas del protocolo para asignar tráfico de una puerta de enlace a servicios de backend.

En esta fase, traducirás tu manifiesto de Ingress en un recurso HTTPRoute. Para convertir el manifiesto de Ingress, sigue los pasos que se indican en la herramienta ingress2gateway.

En este ejemplo, se supone que tienes el siguiente recurso de Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        pathType: Prefix
        backend:
          service:
            name: tea-svc
            port:
              number: 80
      - path: /coffee
        pathType: Prefix
        backend:
          service:
            name: coffee-svc
            port:
              number: 80

Después de convertir el manifiesto con la herramienta ingress2gateway, el resultado es el manifiesto de HTTPRoute traducido.

Guarda el siguiente manifiesto de muestra como httproute.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: cafe-route
spec:
  # This route attaches to our new Gateway
  parentRefs:
  - name: external-http-gateway
  # The hostname is the same as before
  hostnames:
  - "cafe.example.com"
  # The routing rules are now more explicit
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /tea
    backendRefs:
    - name: tea-svc
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /coffee
    backendRefs:
    - name: coffee-svc
      port: 80

Ten en cuenta que el campo rules en el manifiesto de HTTPRoute corresponde directamente a las reglas de enrutamiento definidas en el manifiesto de Ingress original.

Implementa y prueba la configuración nueva

En esta fase, aplicarás los manifiestos de Gateway y HTTPRoute que creaste en las dos fases anteriores y probarás que el tráfico fluya a la nueva dirección IP de la Gateway.

  1. Aplica los manifiestos de Gateway y HTTPRoute:

    kubectl apply -f gateway.yaml
    kubectl apply -f httproute.yaml
    
  2. Obtén la dirección IP de la puerta de enlace. La asignación de la dirección IP puede tardar unos minutos:

    kubectl get gateway external-http-gateway -o=jsonpath="{.status.addresses[0].value}" --watch
    

    El resultado es la dirección IP externa de la puerta de enlace, por ejemplo, 203.0.113.90.

  3. Prueba la nueva dirección IP de la puerta de enlace. Usa el siguiente comando curl para enviar una solicitud a la dirección IP y especificar el nombre de host cafe.example.com. Por ejemplo:

    curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/tea
    curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/coffee
    

    Reemplaza 203.0.113.90 por la dirección IP externa que obtuviste en el paso anterior. El resultado confirma que la nueva dirección IP de Gateway enruta correctamente el tráfico de cafe.example.com sin realizar una búsqueda de DNS.

Dirige el tráfico a la nueva dirección IP de la puerta de enlace

En esta fase, actualiza tus registros DNS para que apunten a la nueva dirección IP de la puerta de enlace y, así, transfieras el tráfico en vivo de tu objeto Ingress anterior a la nueva puerta de enlace. Los pasos exactos para actualizar los registros DNS varían según tu proveedor de DNS.

Por ejemplo, si configuraste cafe.example.com en Ingress, deberás ubicar el registro A para cafe.example.com con tu proveedor de DNS y cambiar el valor de la antigua dirección IP de Ingress a 203.0.113.90, que es la nueva dirección IP de la puerta de enlace.

Después de actualizar el registro DNS, el tráfico comienza a cambiar de Ingress a Gateway, pero el corte no se produce de inmediato para todos los clientes. Los agentes de resolución de DNS que tienen el registro anterior almacenado en caché esperan a que caduque el valor del tiempo de vida (TTL) del registro antes de volver a consultar el registro y recibir la dirección IP actualizada. Por este motivo, debes seguir ejecutando tu objeto Ingress existente y tu nueva puerta de enlace en conjunto hasta que verifiques que el tráfico hacia el objeto Ingress haya cesado, lo que indica que la propagación de DNS se completó y que los clientes ya no se dirigen a la dirección IP anterior. Para verificarlo, supervisa el tráfico en tu balanceador de cargas o controlador de entrada. Para obtener más información, consulta Cómo verificar la propagación de DNS.

Si usas Cloud DNS, puedes usar pesos de destino para cambiar de forma incremental el tráfico de la dirección IP anterior a la nueva. Para obtener más información, consulta Configura políticas de enrutamiento de DNS y verificaciones de estado.

Limpia los recursos de Ingress restantes

Después de confirmar que tu puerta de enlace nueva se ejecuta correctamente, limpia los recursos de Ingress anteriores.

  1. Borra el recurso Ingress:

    kubectl delete ingress cafe-ingress
    
  2. Desinstala el controlador ingress-nginx. Por ejemplo, si usaste Helm para instalar el controlador, ejecuta el siguiente comando:

    helm uninstall ingress-nginx -n ingress-nginx
    

Comparación de funciones entre Ingress NGINX y GKE Gateway

La API de Gateway proporciona una forma más estandarizada de configurar la entrada y tiene paridad de funciones para la mayoría de las funciones comunes, como el enrutamiento, los encabezados y la división del tráfico.

En la siguiente tabla, se comparan las anotaciones que se usan para las funciones comunes en el controlador de Ingress y la API de Gateway.

Función Anotación en Ingress Anotación en GKE Gateway Paridad
Reescritura de URL nginx.ingress.kubernetes.io/rewrite-target HTTPRoute con un filtro urlRewrite. Paridad parcial. GKE Gateway solo admite reemplazos de prefijos.
Manipulación de encabezados nginx.ingress.kubernetes.io/proxy-set-headers o add-headers HTTPRoute con un modificador requestHeaderModifier o un filtro responseHeaderModifier Paridad total.
Enrutamiento basado en rutas spec.rules.http.paths en el objeto Ingress rules.matches.path en el objeto HTTPRoute Paridad total.
Enrutamiento basado en el host spec.rules.host en el objeto Ingress hostnames en el objeto HTTPRoute Paridad total.
División del tráfico nginx.ingress.kubernetes.io/canary anotaciones. HTTPRoute con backendRefs ponderado. Paridad total. Además, puedes dividir el tráfico con un control detallado.
Autenticación nginx.ingress.kubernetes.io/auth-url para la autenticación externa.
  • Identity-Aware Proxy (IAP): CRD de BackendPolicy
  • Otros: Requiere un enfoque más personalizado, posiblemente con una malla de servicios o filtros personalizados.
Paridad parcial. Identity-Aware Proxy es la forma recomendada de proteger tu puerta de enlace y se configura en el backend.

¿Qué sigue?