Rede & Ingress¶
Nenhuma porta é aberta diretamente no roteador de casa. Todo o tráfego externo entra via Cloudflare Tunnel, que fala com um único ponto de entrada dentro do cluster: o NGINX Gateway Fabric, implementando a Gateway API do Kubernetes (não Ingress clássico, não Istio).
flowchart LR
user["Usuário"] -->|HTTPS público| cf["Cloudflare<br/>(edge + TLS público)"]
cf -->|"Tunnel<br/>(cloudflared, sem porta exposta)"| pod["Pod cloudflared<br/>no cluster"]
pod -->|"HTTPS interno<br/>TLS self-signed"| gw{"Gateway<br/>(NGINX Gateway Fabric)"}
gw -->|HTTPRoute| svc1["Service: teupadel-ui"]
gw -->|HTTPRoute| svc2["Service: teupadel-api"]
gw -->|HTTPRoute| svc3["Service: sara-ui"]
gw -->|HTTPRoute| svc4["Service: sara-api"]
gw -->|HTTPRoute| svc5["Service: argocd, headlamp, litellm, ..."]
Duas Gateways, dois domínios¶
O cluster expõe dois Gateway (recurso da Gateway API, definidos em
gitops.core-addons), cada um dono de um domínio wildcard:
| Gateway | Domínio | Uso |
|---|---|---|
nginx-gateway-cmoreira-dev |
*.cmoreira.dev |
ferramentas internas e Sara (local.cmoreira.dev, argocd.cmoreira.dev, headlamp.cmoreira.dev, llm.cmoreira.dev) |
nginx-gateway-teupadel-com |
*.teupadel.com |
produto público teupadel.com (www.teupadel.com, api.teupadel.com) |
Cada app declara seu próprio HTTPRoute (via o
chart genérico de apps) apontando para uma
dessas duas Gateways pelo nome.
TLS: dois níveis diferentes¶
- Borda pública: a Cloudflare termina o TLS que o usuário vê — certificado público, gerenciado pela Cloudflare.
- Túnel → Gateway: o
cloudflaredfala HTTPS com o Gateway usando um certificado self-signed (cert-managercomClusterIssuer/selfsigned) enoTLSVerify: trueno lado do túnel — essa perna é interna à rede do cluster, então o certificado não precisa ser publicamente confiável, só criptografar o salto.
Roteamento por hostname (cloudflared)¶
O cloudflared (também em gitops.core-addons) mapeia cada hostname público
para a Gateway correta via SNI, dentro do próprio cluster — não existe DNS
público apontando direto para IPs da rede local:
ingress:
- hostname: local.cmoreira.dev → nginx-gateway-cmoreira-dev
- hostname: argocd.cmoreira.dev → nginx-gateway-cmoreira-dev
- hostname: headlamp.cmoreira.dev → nginx-gateway-cmoreira-dev
- hostname: llm.cmoreira.dev → nginx-gateway-cmoreira-dev
- hostname: api.teupadel.com → nginx-gateway-teupadel-com
- hostname: www.teupadel.com → nginx-gateway-teupadel-com
- service: http_status:404 # fallback
Dois padrões de roteamento por app¶
Dentro de uma mesma Gateway, uma app pode ser exposta de duas formas, e ambas convivem hoje no cluster:
Hostname dedicado (teupadel.com) — cada componente tem seu próprio
subdomínio (www.teupadel.com, api.teupadel.com), sem reescrita de path. É o
padrão para produtos com domínio próprio.
Path compartilhado (Sara, sob local.cmoreira.dev) — UI e API dividem o
mesmo hostname, diferenciadas por prefixo de path (/sara para a UI,
/sara/api para a API). A Gateway API resolve o conflito por
longest-prefix-match, sem configuração extra. A UI precisa saber que está
montada sob /sara (basePath do Next.js); a API não precisa saber de nada —
o HTTPRoute da API remove o prefixo /sara/api via URLRewrite antes de
encaminhar, então as rotas da API continuam simples (/health, /search, ...).
Qual padrão usar é uma decisão por app, tomada no values.yaml de cada
gitops.<app> (campo httpRoute) — ver
Chart genérico de apps.