A maioria das quedas começa com um deploy. O código passou pela revisão e pelos testes e então encontrou tráfego real, dados reais e dependências reais. Uma estratégia de deploy decide quanto do seu tráfego encontra a nova versão de uma vez, quão rápido você percebe um problema e quão rápido consegue desfazê-lo.
Este artigo compara as três estratégias entre as quais a maioria dos times escolhe: rolling update, blue-green e canary. Ele mostra como o tráfego se move em cada uma, como fica o rollback, e termina com um diagrama de um deploy canary em que a decisão de continuar ou voltar atrás é automatizada.
Rolling update
Substitua as instâncias da versão antiga pela nova algumas de cada vez. Os Deployments do Kubernetes fazem isso por padrão: na estratégia RollingUpdate, maxSurge e maxUnavailable controlam quantos pods a mais e a menos são permitidos durante o rollout, e ambos têm 25% como padrão.
- Tráfego: durante o rollout, as duas versões atendem requisições ao mesmo tempo, na proporção de quantos pods cada uma tem.
- Rollback: outro rolling update de volta para a versão antiga. Minutos, não segundos.
- Custo: quase nada a mais; no máximo a capacidade de surge.
- Risco: qualquer usuário pode cair cedo na nova versão, e as readiness probes são a única barreira automática. Uma versão que sobe bem mas falha sob carga acaba implantada por completo.
Rolling update é o padrão certo para mudanças de baixo risco e serviços internos com bons testes e probes. Faça a readiness probe verificar o que o serviço precisa para funcionar, não só se o processo está de pé, ou o rollout vai trocar alegremente pods saudáveis por pods quebrados.
Blue-green
Rode dois ambientes completos. O blue atende a produção; o green recebe a nova versão e é testado ali mesmo. Depois, o balanceador de carga ou o DNS muda todo o tráfego do blue para o green de uma vez. A descrição do deploy blue-green de Martin Fowler é a referência clássica.
- Tráfego: todo no blue, depois todo no green. Nunca nos dois, pelo menos não por muito tempo.
- Rollback: voltar para o blue, que continua rodando. Segundos.
- Custo: o dobro da capacidade enquanto os dois estão no ar.
- Risco: a troca move 100% dos usuários de uma vez, então um problema que só aparece com tráfego real atinge todo mundo. O banco de dados é compartilhado, então as mudanças de schema precisam funcionar com as duas versões.
Canary
Mande uma pequena parte do tráfego real, digamos 5%, para a nova versão, compare-a com a versão estável e aumente a parte aos poucos se ela se comportar bem. O nome vem do canário na mina de carvão; veja o artigo sobre canary release no site de Fowler.
- Tráfego: dividido por peso, por header ou por segmento de usuários.
- Rollback: zere o peso do canary. Segundos, e só uma pequena porcentagem dos usuários foi exposta.
- Custo: alguns pods a mais, além das ferramentas de divisão de tráfego e análise.
- Risco: o menor dos três, se você observar as métricas certas. Um canary que ninguém observa é um rolling update lento.
Lado a lado
| Rolling | Blue-green | Canary | |
|---|---|---|---|
| Usuários expostos a uma versão ruim | Até todos, aos poucos | Todos, de uma vez | Uma pequena parte |
| Tempo de rollback | Minutos | Segundos | Segundos |
| Capacidade extra | Só o surge | 100% durante a troca | Alguns pods |
| Precisa dividir tráfego | Não | Uma chave | Roteamento ponderado |
| Mudanças no banco de dados | Retrocompatíveis | Retrocompatíveis | Retrocompatíveis |
A última linha é igual em todas por um motivo: em qualquer estratégia, duas versões do código encontram o mesmo banco de dados em algum momento. Use migrations expand-and-contract: adicione primeiro as novas colunas e tabelas, faça deploy de um código que funcione com os dois formatos e remova o formato antigo numa versão posterior.
Tráfego espelhado antes do canary
Alguns times adicionam um passo antes do canary: copiam uma parte das requisições de produção para a nova versão e descartam as respostas. Envoy e Istio conseguem espelhar tráfego assim. Isso pega quedas e regressões de latência sem nenhum impacto nos usuários, mas só para leituras e requisições idempotentes. Gravações espelhadas repetem seus efeitos colaterais, como e-mails, pagamentos e mudanças de estoque, então deixe-as fora do espelho ou aponte a versão espelhada para dependências isoladas em sandbox.
Automatizando a decisão do canary
O valor de um canary está na comparação, e pessoas são ruins em olhar dashboards por uma hora. Ferramentas como Argo Rollouts e Flagger automatizam isso no Kubernetes: movem o tráfego em etapas, consultam seu provedor de métricas entre as etapas e promovem ou abortam de acordo com os limites que você define.
Boas métricas de análise são poucas e próximas do usuário:
- Taxa de erros (respostas 5xx) do canary, comparada com a estável.
- Latência num percentil alto, como o p99.
- Um sinal de negócio quando possível, como checkouts concluídos por minuto.
Compare o canary com a versão estável, não com um número fixo, para que uma noite ruim de uma dependência não reprove todos os deploys.
O diagrama de arquitetura
Conteúdo do diagrama
- CI pipeline
- Rollout controller
- Users
- Ingress
- Stable v1
- Canary v2
- Metrics
- Canary within thresholds?
- Next step: 25, 50, 100 percent
- Abort: all traffic to v1
- image v2
- 95%
- 5%
- error rate, p99 latency
- yes
- no
- set weights
Como ler:
- Em cima, o caminho do tráfego: os usuários chegam ao ingress, que envia 95% das requisições para o ReplicaSet estável e 5% para o canary. Os dois reportam às métricas.
- Embaixo, o loop de controle: o CI entrega a nova imagem ao controlador de rollout. O controlador ajusta os pesos do ingress (aresta tracejada), lê a taxa de erros e a latência p99 das duas versões e decide.
- A decisão: dentro dos limites, avança para a próxima etapa; fora deles, aborta e devolve todo o tráfego para a v1.
- O bloco Markdown lista as etapas e a regra de aborto, que devem fazer parte da revisão da configuração de rollout de cada serviço.
Feature flags são a quarta estratégia
Uma estratégia de deploy controla quais servidores rodam o código novo. Uma feature flag controla quais usuários veem um comportamento novo, independentemente dos deploys. Times que entregam com frequência combinam os dois: fazem deploy com rolling update ou canary, mantêm as funcionalidades arriscadas atrás de uma flag e a ativam aos poucos. A flag é o rollback mais rápido, porque nada precisa ser reimplantado.
O que colocar num diagrama de deploy
- Porcentagens de tráfego nas arestas. Elas mudam durante o rollout; mostre a primeira etapa.
- Quem muda os pesos. Um controlador, um pipeline ou uma pessoa.
- Os critérios de aborto. Números, não "se parecer ruim".
- O banco de dados, com uma nota de que as mudanças de schema seguem expand-and-contract.
O diagrama de pipeline de CI/CD mostra as etapas de build e teste que vêm antes, o diagrama de arquitetura do Kubernetes cobre o cluster, e o diagrama de arquitetura de observabilidade mostra de onde vêm as métricas.
Monte no Archboard
- Entre com Google ou GitHub e crie um diagrama.
- Adicione uma Pessoa para os usuários, além de um Ingress e dois nós ReplicaSet do pack Kubernetes para a versão estável e o canary.
- Adicione Métricas e um Pipeline de CI/CD do pack DevOps, e um Contêiner do pack Modelo C4 para o controlador de rollout.
- Adicione uma Decisão, um Processo e um Início / Fim do pack Fluxograma para promover e abortar.
- Rotule as arestas do ingress com os pesos do tráfego, desenhe as mudanças de peso como uma aresta tracejada e adicione um bloco Markdown do pack Básico com as etapas.
O exemplo usa 11 nós de diagrama e fica dentro do plano Free.
Perguntas frequentes
Qual é a melhor estratégia de deploy? Depende do risco e das ferramentas. Rolling update serve para a maioria das mudanças de baixo risco; canary, para serviços voltados ao usuário em que uma versão ruim sai cara; blue-green, para sistemas que precisam de trocas instantâneas e completas e podem pagar pelo dobro de capacidade.
Qual a diferença entre blue-green e canary? Blue-green muda todo o tráfego de uma vez e mantém o ambiente antigo para um rollback instantâneo. Um canary move primeiro uma pequena parte do tráfego e só a amplia quando a nova versão se prova.
Como lidar com migrations de banco de dados durante um deploy? Torne cada mudança de schema retrocompatível: primeiro expanda, faça deploy de um código que funcione com os dois formatos e depois contraia numa versão posterior.
Que métricas uma análise de canary deve usar? Taxa de erros e latência em percentis altos comparadas com a versão estável, mais uma métrica de negócio se você conseguir medi-la rapidamente.
Feature flags são uma estratégia de deploy? São uma estratégia de release. Elas desacoplam ligar uma funcionalidade de fazer deploy do código, e combinam bem com qualquer uma das três estratégias de deploy.