Quando um sistema tem dezenas de serviços, o mesmo código de rede aparece em todos eles: retries, timeouts, TLS entre serviços, métricas por chamada, divisão de tráfego para releases. Um service mesh tira esse código dos serviços e o coloca no caminho da rede, onde um único time pode configurá-lo para todos.
Este artigo explica como um mesh é montado, o que o control plane e o data plane fazem, como o mTLS automático funciona e os custos que fazem de um mesh a escolha errada para muitos times. O diagrama mostra o design clássico com sidecars.
Data plane e control plane
O data plane é um conjunto de proxies que fica no caminho de cada requisição entre serviços. No modelo sidecar, cada pod ganha seu próprio contêiner de proxy. A aplicação fala HTTP simples com o proxy local; o proxy cuida de tudo o que passa pela rede: criptografia, retries, balanceamento de carga, métricas. O Istio usa o Envoy como sidecar; o Linkerd usa um proxy próprio, feito para isso e escrito em Rust.
O control plane nunca toca no tráfego das requisições. Ele observa os serviços e endpoints do cluster, transforma suas políticas em configuração de proxy, envia essa configuração para cada proxy e emite os certificados que os proxies usam para se identificar. No Istio, esse papel é do istiod; veja a página de arquitetura do Istio. A referência de arquitetura do Linkerd descreve as peças equivalentes.
mTLS automático e identidade de workload
TLS mútuo entre cada par de serviços é o recurso que convence a maioria dos times. Cada proxy recebe do control plane um certificado de curta duração que nomeia o workload, normalmente como um ID SPIFFE derivado do namespace e da service account do Kubernetes, como spiffe://cluster.local/ns/shop/sa/orders. Quando dois proxies se conectam, ambos apresentam certificados, ambos os verificam e a conexão é criptografada.
Duas consequências importam:
- A identidade substitui a localização na rede. Uma política pode dizer "payments só aceita chamadas da service account de orders", o que é mais forte do que "desta sub-rede".
- A rotação é automática. Os certificados duram algumas horas, e ninguém abre um ticket para renová-los.
Ative o modo strict quando tudo estiver no mesh, para que conexões em texto puro sejam recusadas em vez de aceitas em silêncio.
Uma requisição pelo mesh
Siga uma chamada de orders para payments:
- A aplicação orders envia uma requisição HTTP simples para o nome do serviço payments. O redirecionamento de tráfego a envia para o sidecar local em vez da rede.
- O sidecar de orders busca endpoints saudáveis de payments na configuração que o control plane enviou, escolhe um com seu algoritmo de balanceamento e aplica o timeout dessa rota.
- Ele abre, ou reutiliza, uma conexão mTLS com o sidecar de payments, apresentando o certificado de orders.
- O sidecar de payments verifica o certificado, checa a política de autorização (orders pode chamar payments?) e repassa a requisição para a aplicação payments via localhost.
- Os dois sidecars registram a requisição, seu status e sua latência. Se a chamada falhar com um status que permite retry, o sidecar de orders pode tentar de novo dentro do seu orçamento.
Nenhuma das aplicações sabe que nada disso aconteceu, e esse é o objetivo e também o risco: um comportamento que não aparece no código precisa ficar visível em outro lugar, como no diagrama.
Adotando um mesh
Adote em etapas. Instale o control plane, adicione os serviços um namespace por vez em modo permissivo para que o texto puro continue funcionando, acompanhe as métricas e depois mude cada namespace para mTLS strict. Adicione as políticas de autorização por último, começando pelos serviços que guardam dados sensíveis.
Políticas de tráfego
Como toda chamada passa por um proxy, o mesh pode aplicar as mesmas regras em todo lugar:
- Timeouts e retries, com orçamentos para que os retries não se multipliquem durante uma falha.
- Circuit breaking e outlier detection: parar de mandar tráfego para instâncias que continuam falhando.
- Divisão de tráfego por peso ou header, que é como os releases canary são implementados num mesh.
- Injeção de falhas para testes: adicionar atrasos ou erros a uma porcentagem das chamadas.
Cuidado com retries em dois lugares. Se a aplicação faz retry e o sidecar também, uma chamada que falha vira muitas. Escolha um único dono para os retries e deixe isso registrado.
Observabilidade (quase) de graça
Os proxies reportam contagem de requisições, taxas de erro e latência por origem e destino, sem mudar as aplicações. Eles também podem iniciar e propagar spans de trace, mas a aplicação ainda precisa repassar os headers de trace das requisições de entrada para as de saída, ou os traces se quebram a cada serviço.
Sidecars vs. modo ambient
Sidecars têm custos reais: um proxy em cada pod consome CPU e memória, adiciona latência a cada salto e complica a inicialização dos pods e os upgrades. O modo ambient do Istio remove o sidecar por pod. Um proxy por nó chamado ztunnel cuida do mTLS e das políticas de camada 4, e proxies waypoint opcionais cuidam dos recursos de camada 7 só para os serviços que precisam deles. Em troca, há um modelo de operação diferente e menos anos de histórico em produção do que os sidecars.
O diagrama de arquitetura
Conteúdo do diagrama
- Ingress gateway
- orders pod
- Sidecar proxy
- orders app
- payments pod
- payments app
- inventory pod
- inventory app
- Control plane
- Metrics and traces
- mTLS
- localhost
- config + certificates
Como ler:
- Esquerda: o ingress gateway recebe o tráfego externo e abre uma conexão mTLS com o sidecar do pod de orders.
- Centro: dentro de cada pod, o sidecar repassa para a aplicação via localhost. O sidecar de orders chama os sidecars de payments e inventory por mTLS; as aplicações nunca lidam com certificados.
- Embaixo: o control plane envia configuração e certificados aos proxies (arestas tracejadas). Ele não está no caminho das requisições.
- Direita: os sidecars reportam métricas e traces (pontilhado). O bloco Markdown mostra uma política para payments: quem pode chamá-lo, timeouts e retries, ejeção de outliers e mTLS strict.
Quando não usar um mesh
- Um punhado de serviços, ou um monólito com alguns satélites. Uma biblioteca ou um API gateway cobre as necessidades por uma fração do custo.
- Nenhum time para cuidar dele. Um mesh é infraestrutura que exige upgrades, habilidade de debugging e experiência de plantão.
- Quando o objetivo principal é só criptografia. Muitas nuvens e plugins CNI conseguem criptografar o tráfego entre pods sem um mesh completo.
O que colocar num diagrama de mesh
- Os dois planos, bem separados, com o control plane fora do caminho das requisições.
- Onde o TLS começa e termina: de proxy para proxy, e HTTP simples no localhost.
- As identidades, pelo menos dos serviços com políticas de acesso.
- As políticas que mudam o comportamento: timeouts, retries, circuit breaking.
O diagrama de arquitetura do Kubernetes mostra o cluster em que o mesh roda, o diagrama de arquitetura zero trust explica por que políticas baseadas em identidade importam, e o diagrama de arquitetura de microsserviços cobre os próprios serviços.
Monte no Archboard
- Entre com Google ou GitHub e crie um diagrama.
- Adicione um Contêiner do pack Modelo C4 para o ingress gateway.
- Para cada pod, adicione uma Moldura do pack Básico com um Componente para o sidecar e um Contêiner para a aplicação dentro.
- Adicione um Contêiner para o control plane e Métricas do pack DevOps.
- Desenhe arestas mTLS entre os sidecars, arestas tracejadas a partir do control plane e arestas de telemetria pontilhadas, e adicione um bloco Markdown do pack Básico com a política de um serviço.
O exemplo usa 13 nós de diagrama e fica dentro do plano Free.
Perguntas frequentes
Qual a diferença entre um service mesh e um API gateway? Um API gateway gerencia o tráfego que entra no sistema vindo de fora. Um service mesh gerencia o tráfego entre os serviços lá dentro. Muitos sistemas usam os dois.
Um service mesh adiciona latência? Sim, cada salto por um proxy adiciona um pouco, geralmente bem menos do que alguns milissegundos por salto, além de CPU e memória para os proxies. Meça com o seu tráfego.
Preciso mudar o código da minha aplicação para usar um mesh? Na maior parte, não. A exceção é o tracing: as aplicações precisam repassar os headers de trace para que os traces se conectem entre os serviços.
O que é o modo ambient? Um data plane do Istio sem sidecars: um proxy por nó cuida do mTLS e da camada 4, e proxies waypoint opcionais cuidam dos recursos de camada 7 onde for preciso.
Quem deve ser dono do mesh? Um time de plataforma. Os times de serviço usam os recursos dele por meio de políticas, mas alguém precisa fazer o upgrade, monitorar e depurar.