Ainda me lembro da primeira vez que perdemos o sono por algo que não era um bug.
Era uma terça-feira. Os dashboards do Grafana mostravam painéis em branco para métricas de rede do Cilium. O Hubble funcionava perfeitamente — visibilidade de DNS, fluxos TCP e latência HTTP estavam todos lá na UI do Hubble. Mas o engenheiro de plantão olhando para o Grafana às 2h da manhã não via nada disso. O motivo? O Prometheus não tinha ServiceMonitors conectados aos pods agent e operator do Cilium. Dois projetos da CNCF, ambos instalados corretamente, estavam completamente invisíveis um para o outro.
Isso é o que chamamos de imposto da integração. É o custo oculto de executar múltiplos projetos CNCF juntos em produção, e é onde a maioria dos times de plataforma gasta 80% do tempo — não instalando projetos ou ajustando cada um individualmente, mas conectando-os para que eles realmente conversem entre si.
"Isto é o que chamamos de imposto da integração. É o custo oculto de executar múltiplos projetos CNCF juntos em produção."
Onde os projetos CNCF colidem?
cert-manager versus ingress controllers. Encontramos esse problema em três provedores de nuvem. O desafio HTTP-01 do ACME no cert-manager espera servir um token via HTTP simples. Mas se o seu ingress controller impõe um redirect global de HTTP para HTTPS — o que deveria fazer por segurança — toda requisição de validação ACME leva um 301 antes de chegar ao pod solver. As renovações de certificado falham silenciosamente. Você descobre quando clientes veem avisos de certificado expirado no navegador. A solução? Desafios DNS-01 via Route53, Cloud DNS ou Azure DNS. Mas isso exige scoping de IAM específico de cada nuvem que nenhum Helm chart configura por padrão. Você só descobre essas limitações depois do incidente.
Prometheus versus kubelet. Esse nos levou semanas para diagnosticar. O kubelet expõe métricas em quatro caminhos de scrape. Dois deles — /metrics e /metrics/probes — emitem process_start_time_seconds com timestamps idênticos porque são o mesmo processo. O Prometheus scrapper ambos, vê amostras duplicadas e dispara PrometheusDuplicateTimestamps. O alerta é ruidoso. A causa raiz é invisível sem ler o código-fonte do kubelet. A correção é uma regra de relabeling no Jsonnet que descarta um endpoint inteiro de scrape. Nenhum desses são bugs. Cada projeto funciona exatamente como documentado. As falhas vivem nos gaps.
Como o Cluster API resolveu a orquestração multi-cloud?
Antes do Cluster API (CAPI), provisionar clusters significava escolher a CLI do provedor de nuvem: eksctl para AWS, gcloud container clusters create para GCP, az aks create para Azure. Cada um tinha seu próprio modelo de lifecycle, caminho de upgrade e história de disaster recovery. Você não estava apenas preso a uma nuvem; estava preso às opiniões dela sobre gerenciamento de Kubernetes.
O CAPI mudou o jogo. Seu cluster agora é um conjunto de recursos nativos do Kubernetes — Cluster, MachineDeployment, MachinePool — e um provider específico de nuvem os traduz em infraestrutura. Rodamos CAPA na AWS, CAPG no GCP, CAPZ no Azure e CAPH no Hetzner bare metal. A sequência de bootstrap é idêntica em todos: cluster de gerenciamento K3D → deploy do provider → criar workload cluster → clusterctl move para torná-lo autogerenciado.
Mas é aqui que o valor real aparece: operações de Day 2. Um upgrade de versão do Kubernetes vira uma alteração de uma linha no MachineDeployment. O CAPI cuida de cordon, drain e substituição rolling. Um MachineHealthCheck remove automaticamente nós não saudáveis. Disaster recovery significa recriar o cluster de gerenciamento, restaurar backups do Velero do cloud storage e deixar os recursos CAPI reconciliarem. O cluster inteiro se reconstrói a partir do estado Git. É aqui que o Cluster API — como o resto da stack CNCF — revela se seu trabalho de integração realmente se sustenta sob pressão.
Qual arquitetura finalmente parou o sangramento?
Depois de anos apagando incêndios de integração entre nuvens, chegamos a um padrão que tornou tudo sustentável: um split GitOps de dois repositórios. Essa abordagem funciona tanto se você usa plataformas comerciais quanto se monta sua própria stack com projetos open source.
- Repositório de plataforma: 100+ Helm charts com defaults testados em produção. Cilium NetworkPolicies embutidas em cada chart. ServiceMonitors do Prometheus pré-conectados. Anotações do cert-manager configuradas para o tipo de desafio correto. Essa configuração é compartilhada entre todos os clusters em todas as nuvens.
- Repositório de configuração: Um por cliente ou ambiente. Apenas valores que realmente variam entre clusters: nomes de domínio, contagens de nós, IDs de projeto GCP, roles de conta AWS e tipos de servidor Hetzner.
O ArgoCD observa ambos. Quando corrigimos o problema de timestamps duplicados no Prometheus no repositório de plataforma, essa correção se propaga para todos os clusters (AWS, GCP, Azure, bare metal) via um bump de versão. Um pull request. Nenhum ticket por cluster. Nenhuma memória humana de "ah, precisamos atualizar a regra de relabeling em três sistemas diferentes"; a lógica de integração vive em código.
Lições aprendidas a duras penas na produção
Gere seu monitoramento, não monte manualmente. Usamos Jsonnet para produzir toda a stack kube-prometheus a partir de um único arquivo vars por cluster. Custom alerting mixins — idade do backup do Velero, lag de replicação do CloudNativePG, expiração de certificado do kubelet — vivem como bibliotecas Jsonnet junto com as regras upstream. Um único build.sh produz tudo. Reproduzível. Diferenciável. Versionado. Quando um upgrade do Prometheus quebra suas regras customizadas, o diff é imediato, e a correção é testável antes de chegar à produção.
Embute NetworkPolicies nos charts, não em runbooks pós-deploy. Enviamos templates de Cilium NetworkPolicy dentro de 20+ Helm charts. Cada chart declara suas próprias necessidades de egress: quais APIs externas ele chama e quais serviços internos precisa. Reverter engenharia de regras de rede a partir de logs de fluxo do Hubble após o deploy é como escrever testes depois de enviar o código. Suas políticas derivam. A segurança vira adivinhação. Embuti-las nos charts significa que a política vive onde é mantida.
Automatize disaster recovery no bootstrap. Nosso provisionamento cria buckets de cloud storage (S3, GCS, Azure Blob) para backups do Velero durante a configuração inicial do cluster — não como uma tarefa pendente que vive em um ticket Jira por seis meses. Se você consegue rodar o bootstrap, consegue se recuperar de uma perda total de cluster. Disaster recovery deixa de ser uma esperança e se torna uma realidade testável.
Criptografe secrets, depois commite. Toda credencial — deploy keys, IAM de nuvem, certificados TLS — é criptografada com Sealed Secrets antes de tocar no Git. A chave de decriptação é armazenada em cloud storage. Seu repositório Git se torna um registro completo e auditável do estado de cada cluster, incluindo secrets. Detecção de drift funciona. Recuperação é um pull request e um clusterctl move de distância.
Deixe máquinas aplicarem política. Kyverno bloqueia deployments sem resource limits. Kubescape escaneia continuamente benchmarks CIS e alimenta violações em alertas do Prometheus. Combinado com segmentação de rede do Cilium, sua postura de segurança vira algo que auditores verificam a partir do histórico Git e do estado atual do cluster — não de uma planilha atualizada há dois trimestres.
O custo que se acumula
O imposto da integração não é uma taxa única. Cada bump de versão do Kubernetes, cada upgrade de Helm chart, cada novo projeto CNCF introduz novas superfícies de integração. Se seu monitoramento é YAML artesanal, atualizar o kube-prometheus da v0.13 para a v0.17 significa fazer diff manual de centenas de arquivos gerados. Se for Jsonnet, é uma linha — a dívida se acumula.
O ecossistema CNCF é extraordinariamente poderoso. Mas poder sem integração é apenas uma lista de helm install. O trabalho que realmente importa — detecção de drift, atualizações coordenadas e automação de disaster recovery — acontece na fiação. É aí que sua plataforma ou sobrevive ao segundo ano ou se torna apenas uma coleção de ferramentas nas quais você para de confiar.
Perguntas Frequentes
-
Por que o Prometheus não enxerga métricas do Cilium mesmo com ambos instalados?
O Prometheus precisa de ServiceMonitors configurados para descobrir os endpoints de métricas dos pods do Cilium agent e operator. Sem esse wiring, os dois projetos funcionam corretamente mas ficam invisíveis um para o outro. O problema não é um bug, é a falta de integração explícita. -
Qual o impacto do redirect HTTP-para-HTTPS na renovação de certificados com cert-manager?
O cert-manager usa o desafio HTTP-01 da ACME, que espera servir um token via HTTP simples. Se o ingress controller força um redirect global para HTTPS, a solicitação de renovação recebe um 301 antes de chegar ao pod solver, e o certificado expira silenciosamente. A solução é usar desafios DNS-01, que exigem configuração específica de IAM para cada provedor de nuvem. -
Como o Cluster API simplifica upgrades e disaster recovery multi-cloud?
Com o Cluster API, um cluster Kubernetes é definido como recursos nativos (Cluster, MachineDeployment). Upgrade de versão vira uma linha de alteração no MachineDeployment, e o CAPI gerencia cordon, drain e substituição rolling. Disaster recovery consiste em recriar o management cluster, restaurar backups do Velero e deixar os recursos CAPI reconciliarem — tudo a partir do estado Git. -
O que é o 'imposto da integração' e como evitá-lo?
É o custo oculto de conectar múltiplos projetos CNCF em produção — não a instalação ou tuning individual, mas o wiring entre eles. Para evitá-lo, use um split GitOps de dois repositórios (plataforma + configuração), gere monitoramento com Jsonnet, embuta NetworkPolicies nos Helm charts, automatize disaster recovery desde o bootstrap e criptografe secrets antes de commitá-los. -
Qual a vantagem de usar Jsonnet em vez de YAML manual para monitoramento?
Jsonnet permite gerar toda a stack kube-prometheus a partir de um único arquivo de variáveis por cluster. Custom alerts (backup do Velero, lag de replicação, expiração de certificados) vivem como bibliotecas Jsonnet. Quando o Prometheus atualiza e quebra regras customizadas, o diff é imediato e o reparo testável antes de ir para produção. YAML manual exige diff de centenas de arquivos a cada upgrade.
Artigo originalmente publicado por Rishi Mondal, SRE at Obmondo and CNCF KubeStellar Maintainer em Cloud Native Computing Foundation.