ADR-008 — Estratégia de failover DNS
Status
Vigente — 2026-05-01.
Contexto
Hoje a infra CPPS não tem failover de DNS. Cloudflare é usado apenas como:
- DNS authoritative (records A/CNAME apontando pra IPs fixos)
- DNS-01 challenge pro Let’s Encrypt (via Traefik) — ver
apps/traefik/values.yaml:217-228 - ClusterIssuer
letsencrypt-cloudflareemapps/mongodb/clusterissuer.yaml
Se Traefik Franca cair, app.colabh.org (apontando pra IP Franca) continua resolvendo pro IP morto até intervenção manual ou TTL expirar (1-5 min).
Como o objetivo é autonomia local com integração quando possível, falha de site não pode significar serviço inacessível.
Opções consideradas:
| Opção | Custo | Complexidade | Cobertura |
|---|---|---|---|
| DNS round-robin manual | Grátis | Baixa | ~50% fail durante incidente (não é failover) |
| External DNS Operator + script healthcheck | Grátis | Média | Bom, mas script é ponto de falha |
| Cloudflare Health Checks + Load Balancer | ~$5-10/origin/mês | Baixa | Excelente, gratuito não tem |
Cloudflare Tunnel (cloudflared) | Grátis (limites generosos) | Média | Failover origin nativo entre túneis |
| Cilium ClusterMesh + Service Global | Grátis (após Fase 5) | Alta | Não cobre — só funciona pra tráfego já no cluster |
Decisão
MVP: Cloudflare Tunnel (cloudflared) com 2 túneis ativos (1 por site) por hostname crítico — quando o serviço tiver cópia funcional em ambos os sites.
Limitação fundamental que não pode ser ignorada
DNS failover não substitui replicação de estado. Pra lms.colabh.org (Tutor) realmente falhar de Franca pra SP, Tutor precisa estar:
- Rodando em ambos os sites (replicação de manifest via ApplicationSet — Fase 6/7)
- Com dados sincronizados (replicação MySQL+Mongo cross-site — Fase 9 ou pós)
Sem isso, redirecionar tráfego pra SP entrega “Tutor vazio” — pior que erro 503.
Apps elegíveis pra failover real hoje:
- Stateless (estado em git, sem DB): ArgoCD UI (após ADR-001 implementar 2 ArgoCDs)
- Replicação interna nativa (SeaweedFS data-center replication, MongoDB ReplicaSet)
Apps não elegíveis até replicação cross-site:
- Tutor, Invenio, OJS, Superset, Airflow, Authentik, OpenObserve, Rancher
Ver Inventário de hostnames pra lista completa com tier e elegibilidade.
Cloudflare Tunnel:
- Cada site roda
cloudflaredque estabelece túneis outbound pra Cloudflare - Múltiplos túneis pro mesmo hostname → Cloudflare faz failover automático se um cair
- Detecção de túnel down ≈ segundos (não depende de TTL DNS)
- Plano gratuito cobre até ~50 túneis e tráfego ilimitado pra uso institucional típico
- Integra com DNS Cloudflare já em uso
Cilium ClusterMesh + Service Global complementa em Fase 5 (camada 5) pro tráfego já dentro do cluster — não substitui, complementa.
Cloudflare Load Balancer pago e External DNS Operator ficam deferidos.
Alternativas rejeitadas
- DNS round-robin manual: rejeitado — não é failover real, ~50% das requisições falham durante incidente
- External DNS Operator + script de healthcheck: rejeitado pra MVP — manter script de healthcheck próprio é trabalho adicional sem valor único; Cloudflare Tunnel cobre o caso
- Cloudflare Load Balancer pago: deferido — feature comercial ($5-10/origin/mês), não justificável enquanto Tunnel cobrir
- Cilium Service Global como solução única: rejeitado — só funciona pra tráfego já no cluster; falha do edge (Traefik down) não é coberta por Cilium
Consequências
Positivas:
- Failover automático SP↔Franca em ~segundos pra hostnames protegidos
- Sem novo serviço crítico self-hosted (Cloudflare opera o data plane)
- Sem custo (plano free)
- Integra com DNS Cloudflare já em uso
- Sobrevive partição de UnespNet —
cloudflaredé outbound, não exposto
Negativas:
- Adiciona dependência de Cloudflare como SaaS crítico
- Latência ligeiramente maior (tráfego passa pelo edge Cloudflare)
- Cada hostname protegido requer config de Tunnel + record CNAME proxied
- Logs de tráfego ficam parcialmente na Cloudflare (privacidade/dados acadêmicos)
- Sem observabilidade no nível IP (Cloudflare proxy mascara origem)
Riscos:
- Falha global Cloudflare = todo failover indisponível (mitigação: documentar fallback manual)
- Se UnespNet bloqueia outbound em portas usadas por
cloudflared: precisa avaliar antes - Limite de tráfego/sessões do plano free pode ser atingido com workloads grandes (vGPU streaming, Tutor com muitos alunos, etc.) — monitorar
Critério de revisão
Migrar pra Cloudflare Load Balancer ($) se:
- Tráfego ultrapassar limites razoáveis do plano free
- Necessário monitoramento granular de health (latency, P99) por origin
- Geo-routing virar requisito (pesquisador SP → origin SP por padrão)
Adotar External DNS Operator se:
- Mais de 30 hostnames pra gerenciar (manutenção manual de Tunnels vira insustentável)
- Self-service de hostnames pra pesquisadores virar requisito
Avaliar alternativa com self-hosted edge se:
- Restrição institucional/legal proibir tráfego via Cloudflare
- Cloudflare mudar política de uso acadêmico
- Custo do plano pago ficar incompatível com orçamento
Notas operacionais
- Cada hostname crítico tem 2 instances de
cloudflared(1 SP, 1 Franca) com mesma config - Token de Cloudflare Tunnel via secrets management (ver ADR-006)
- Health check do Tunnel é nativo; logs em Cloudflare Dashboard + opcionalmente exportados pra OpenObserve
- DNS record fica como CNAME
<tunnel-id>.cfargotunnel.com(proxied) - Hostname não-crítico (interno, dev, debug) pode continuar com A record direto sem Tunnel
- Documentar fallback manual: se Cloudflare cair globalmente, atualizar A records via console pra apontar direto
Implementação ordenada (sub-tarefas)
- POC:
argocd.colabh.org— único hostname elegível pra failover real hoje (estado em git, sem DB), assim que ArgoCD SP entrar em produção - Validação: derrubar
cloudflaredSP, verificar failover pra Franca; testar com login + sync de app - Tier 3 quick wins:
traefik.*.org(3 dashboards admin) — sem dado, fácil migrar - Tier 2:
o2.colabh.orgquando OpenObserve tiver ingestor por site - Tier 1 (apps de pesquisa): bloqueados por replicação cross-site — não migrar até replicação implementada
- Runbook “Cloudflare offline”: documentar fallback manual com A records diretos
- Métricas no OpenObserve: tunnel up/down, latência por origin, taxa de failover
- Adicionar DNS secundário fora de Cloudflare (futuro): plano B se Cloudflare cair globalmente — hoje não temos
Ver Inventário de hostnames pra sequência completa de adoção.