Lo que aprendimos al migrar los controladores de ingreso de Kubernetes en Digital.ai

En este post, Digital.aiEl equipo de CloudOps comparte información sobre las decisiones y el enfoque detrás de una reciente migración de Ingress.

Los clientes esperan estabilidad. En Digital.ai Nuestro MSA estándar proporciona un tiempo de actividad del 99.5 % o poco menos de cuatro horas de cortes no programados por mes. A principios de 2025, cambiamos nuestra Kubernetes Controlador de entrada de NGINX a Traefik para admitir algunas funciones personalizadas. Necesitábamos encontrar la manera de hacerlo. safepero eso nos dio flexibilidad. Decidimos usar DNS ponderado registros con Amazon Route 53.

DNS ponderado

El DNS ponderado (o enrutamiento ponderado) funciona asociando un nombre de dominio completo (por ejemplo, www.digital.ai) con varios registros, cada uno con un peso asignado. Un mayor peso indica que se dirige más tráfico a un registro específico. El DNS ponderado permite minimizar el riesgo sin sacrificar la capacidad de experimentar y ajustar sobre la marcha. Por ejemplo, la primera ola de cambios de peso puede dirigir el 10 % del tráfico a su nuevo endpoint, mientras que el 90 % restante se dirige al endpoint anterior. Las olas posteriores pueden aumentar el peso del nuevo endpoint. Aumentar o disminuir el peso de las olas permite monitorear los patrones de tráfico para detectar problemas inesperados, a la vez que minimiza el radio de propagación.

Monitoring

Monitorear los patrones de tráfico para detectar errores 4xx/5xx determinará su elección de ponderaciones. Si los errores aumentan en su nuevo endpoint, pero mantienen una tasa similar en el anterior, investigue por qué el nuevo endpoint presenta problemas, realice ajustes, monitoree y repita el proceso según sea necesario.

Traefik

Aunque NGINX nos dio buenos resultados, llegamos a un punto en el que sentimos que Traefik era el controlador de Ingress del futuro. Traefik está listo para producción, ha sido probado en campo y ofrece numerosas capacidades. Una mejor observabilidad con Traefik nos permite determinar la causa raíz de los problemas con mayor rapidez.

Implementación

Fase 1 (configuración)

  • Deployed Traefik en paralelo con NGINX
  • Se configuraron reglas de enrutamiento idénticas
  • Se crearon anotaciones en los ingresos para crear registros DNS ponderados
    • Inicialmente, se ponderan los registros para dirigir el tráfico únicamente a NGINX.

Fase 2 (migración)

  • Comience con un peso arbitrariamente bajo (10%) en Traefik
  • Supervisar las métricas de rendimiento, errores y latencia
  • Aumente el peso en la entrada de Traefik

Anotaciones de DNS externo

Usando las anotaciones proporcionadas por ExternalDNS podemos crear registros DNS ponderados en Route53.

external-dns.alpha.kubernetes.io/aws-weight Indica a ExternalDNS que cree un registro ponderado y le asigne un peso. AWS permite que los registros ponderados tengan valores entre 0 y 255. Si prefiere enviar una cantidad muy pequeña de tráfico a un punto final, puede establecer el peso en 1, lo que enviaría (1/(1+255)) del tráfico al punto final de prueba y el resto (255/(1+255)) al otro punto final. Esto permite que diferentes pesos equilibren el tráfico a diferentes puntos finales. Para simplificar, hemos utilizado 100 como peso.

external-dns.alpha.kubernetes.io/set-identifier Es una anotación específica del proveedor que crea un identificador de conjunto. Un identificador de conjunto permite diferenciar varios registros DNS con la misma combinación de tipo y dominio. Por ejemplo, puede tener un conjunto que apunte a nginx y otro que apunte a traefik. Al combinarlo con ponderaciones, puede tener una parte del tráfico dirigida a uno y otra a otro.

Implementación técnica

Comencemos con todo el tráfico que va a nginx, podemos ver que hemos creado un set-identifier llamado nginx. Creamos otro set-identifier para traefik y no tienen tráfico que vaya allí.

# NGINX example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-nginx
  annotations:
    external-dns.alpha.kubernetes.io/aws-weight: "100"
    external-dns.alpha.kubernetes.io/set-identifier: "nginx"
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
# Traefik example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-traefik
  annotations:
    external-dns.alpha.kubernetes.io/aws-weight: "0"
    external-dns.alpha.kubernetes.io/set-identifier: "traefik"
spec:
  ingressClassName: traefik
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

ExternalDNS supervisará las anotaciones en los Ingresses y creará registros DNS ponderados en Route53, sin necesidad de administración manual de DNS. ExternalDNS nos permite desviar el tráfico actualizando las anotaciones.

# Shift to 50/50 traffic split
kubectl patch ingress api-nginx -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"50"}}}'
kubectl patch ingress api-traefik -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"50"}}}'

# Both endpoints should now be handling half the traffic.
# Monitor traffic to ensure that traffic is behaving as expected.
# Use additional waves to update the balance of traffic until you feel confident.

# Switch to 100% Traefik
kubectl patch ingress api-nginx -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"0"}}}'
kubectl patch ingress api-traefik -p '{"metadata":{"annotations":{"external-dns.alpha.kubernetes.io/aws-weight":"100"}}}'

Lecciones aprendidas

Logramos cero tiempo de inactividad durante la migración de NGINX a Traefik, a la vez que mejoramos nuestra disponibilidad. Atribuimos este éxito a los siguientes factores:

  1. Tráfico cambiando gradualmenteEl DNS ponderado nos permitió cambiar el tráfico fácilmente mientras monitoreamos la transición.
  2. MonitoringLa visibilidad de la infraestructura antigua y nueva nos permitió ganar confianza en nuestra capacidad para cambiar el peso.
  3. DNS externo:El uso de ExternalDNS nos permitió despreocuparnos de nuestro enfoque hacia el DNS.

Prácticas recomendadas de migración

Nuestro consejo para cualquiera que esté considerando un camino similar:

  • Comience con algo pequeño:Comience su migración con servicios no críticos
  • Automatización :Automatiza todo lo que puedas, usa un enfoque GitOps para cambiar los pesos
  • Tómate tu tiempo:Permítete el tiempo adecuado para hacer cambios
  • Monitorear continuamente:Configure alertas para asegurarse de recibir notificaciones sobre cualquier problema potencial.
  • Documentación:Documentar procesos, procedimientos y manuales de ejecución para cada fase de la migración.

Conclusión

La migración de controladores de Ingress no implica necesariamente un tiempo de inactividad planificado. Gracias a los registros DNS ponderados, pudimos migrar los controladores de Ingress y lograr una mayor disponibilidad. La clave de nuestro éxito fue considerar la migración como un proceso gradual, en lugar de un cambio binario. Esto nos permitió supervisar cada fase de la migración. La migración por fases nos dio la confianza de que nuestros cambios estaban teniendo un impacto significativo.

También puede interesarle