O que aprendemos ao migrar controladores de entrada do Kubernetes em Digital.ai

Neste post, Digital.aiA equipe de CloudOps da [nome da empresa] compartilha informações sobre as decisões e a abordagem por trás de uma recente migração do Ingress.

Os clientes esperam estabilidade. Digital.ai Nosso MSA padrão garante 99.5% de tempo de atividade ou pouco menos de quatro horas de interrupções não programadas por mês. No início de 2025, mudamos nosso Kubernetes Migrar o controlador de entrada do NGINX para o Traefik para suportar algumas funcionalidades personalizadas. Precisávamos encontrar uma maneira de fazer isso. safemas isso nos permitiu flexibilidade. Optamos por usar DNS ponderado registros com a Amazon Route 53.

DNS ponderado

O DNS ponderado (ou roteamento ponderado) funciona associando um nome de domínio totalmente qualificado (por exemplo, www.digital.aiO DNS ponderado permite minimizar riscos sem sacrificar a capacidade de experimentar e ajustar em tempo real. Por exemplo, a primeira onda de alterações de peso pode direcionar 10% do tráfego para o novo endpoint, enquanto 90% continua indo para o endpoint antigo. Ondas subsequentes podem aumentar o peso do tráfego para o novo endpoint. Aumente e diminuir os pesos em ondas permite monitorar padrões de tráfego em busca de problemas inesperados, minimizando o impacto.

Monitoramento

O monitoramento dos padrões de tráfego para erros 4xx/5xx orientará sua escolha em relação aos pesos. Se os erros estiverem aumentando no seu novo endpoint, mas mantendo uma taxa semelhante no endpoint antigo, investigue o motivo do mau funcionamento do novo endpoint, faça ajustes, monitore e repita conforme necessário.

Traefik

Embora o NGINX tenha nos atendido bem, chegamos a um ponto em que sentimos que o Traefik era o controlador Ingress do nosso futuro. O Traefik está pronto para produção, testado em batalha e oferece muitas funcionalidades. A melhor observabilidade proporcionada pelo Traefik nos permite determinar a causa raiz dos problemas mais rapidamente.

Implementação

Fase 1 (configuração)

  • Deployed Traefik em paralelo com NGINX
  • Regras de roteamento idênticas configuradas
  • Criou anotações em entradas para gerar registros DNS ponderados.
    • Inicialmente, os registros foram ponderados para direcionar o tráfego exclusivamente para o NGINX.

Fase 2 (migração)

  • Comece com um peso arbitrariamente baixo (10%) no Traefik.
  • Monitore as métricas de taxa de transferência, erros e latência.
  • Aumente o peso na entrada do Traefik

Anotações DNS externas

Utilizando anotações fornecidas pelo ExternalDNS, podemos criar registros DNS ponderados no Route53.

external-dns.alpha.kubernetes.io/aws-weight Indica ao ExternalDNS para criar um registro ponderado e atribuir um peso a ele. A AWS permite que registros ponderados tenham valores entre 0 e 255. Se você preferir enviar uma quantidade muito pequena de tráfego para um endpoint, pode definir o peso como 1, o que enviaria (1/(1+255)) do tráfego para o endpoint de teste e os outros (255/(1+255)) para o outro endpoint. Isso permite pesos diferentes para balancear o tráfego entre os diferentes endpoints. Para simplificar, usamos 100 como nosso peso.

external-dns.alpha.kubernetes.io/set-identifier é uma anotação específica do provedor que cria um identificador de conjunto. Um identificador de conjunto permite que vários registros DNS com a mesma combinação de tipo e domínio sejam diferenciados uns dos outros. Por exemplo, você pode ter um conjunto apontando para o nginx e outro apontando para o traefik. Combinando isso com pesos, você pode direcionar uma parte do tráfego para um servidor e outra parte para o outro.

Implementação Técnica

Vamos começar com todo o tráfego indo para o nginx. Podemos ver que criamos um set-identifier chamado nginx. Criamos outro set-identifier para o Traefik e não há tráfego passando por lá.

# 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

O ExternalDNS monitora as anotações nos Ingresses e cria registros DNS ponderados no Route53, sem necessidade de gerenciamento manual de DNS. O ExternalDNS nos permite redirecionar o tráfego atualizando as anotações.

# 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"}}}'

Lições Aprendidas

Obtivemos zero tempo de inatividade durante a migração do NGINX para o Traefik, ao mesmo tempo que melhoramos nossa disponibilidade. Atribuímos esse sucesso aos seguintes fatores:

  1. Tráfego mudando gradualmenteO DNS ponderado permitiu-nos redirecionar o tráfego facilmente, enquanto monitorávamos a transição.
  2. MonitoramentoA visibilidade tanto da infraestrutura antiga quanto da nova nos permitiu ganhar confiança em nossa capacidade de movimentar pesos.
  3. DNS externoUtilizar o ExternalDNS nos permitiu adotar uma abordagem mais independente em relação ao DNS.

Práticas recomendadas de migração

Nosso conselho para quem estiver considerando um caminho semelhante:

  • Comece pequenoComece sua migração com serviços não essenciais.
  • CompletaAutomatize o máximo possível e utilize uma abordagem GitOps para alterar pesos.
  • Não tenha pressaDê a si mesmo o tempo necessário para fazer as mudanças.
  • Monitore continuamenteConfigure alertas para garantir que você seja notificado sobre quaisquer problemas potenciais.
  • DocumentaçãoDocumentar processos, procedimentos e roteiros para cada fase da migração.

Conclusão

A migração de controladores de entrada não precisa envolver tempo de inatividade planejado. Utilizando registros DNS ponderados, conseguimos migrar os controladores de entrada e alcançar maior disponibilidade. A chave do nosso sucesso foi tratar a migração como um processo gradual, em vez de uma mudança abrupta. Isso nos permitiu monitorar cada fase da migração. Migrar em fases nos deu a segurança de que nossas alterações estavam gerando um impacto significativo.

Também recomendamos