Pular para o conteúdo
10 min de leitura

Deploy Sem Downtime: Rolling, Blue-Green e Canary Explicados

Por Equipe Nebular ·

Rolling update, blue-green e canary não são sinônimos. Entenda o que cada estratégia troca em risco, custo e velocidade de rollback, e quando usar qual.

Neste artigo

Existe uma época, felizmente cada vez mais distante, em que colocar uma nova versão no ar significava avisar os usuários, colocar uma página de "estamos em manutenção", derrubar o sistema, subir a versão nova e torcer. Downtime planejado era normal, e downtime não planejado, quando o deploy dava errado, era pânico. Reverter significava restaurar backups às pressas enquanto o telefone tocava.

Nada disso é aceitável hoje. Usuários esperam que o serviço esteja sempre disponível, e implantar versões novas várias vezes ao dia sem que ninguém perceba virou o padrão de qualquer operação séria. O que tornou isso possível não foi uma ferramenta mágica, e sim um conjunto de estratégias de implantação que trocam risco por controle de formas diferentes. As três mais importantes são o rolling update, o blue-green e o canary. Elas não são intercambiáveis, e escolher a certa depende de entender o que cada uma troca. Este artigo destrincha essas trocas.

O problema que todas resolvem#

Antes das estratégias, o problema. Você tem a versão 1 rodando e atendendo usuários. Quer colocar a versão 2 no ar. Entre os dois estados há um intervalo perigoso: durante a transição, você precisa garantir que ninguém fique sem resposta, que uma versão com bug não atinja todos os usuários de uma vez, e que, se algo der errado, você consiga voltar rápido.

Toda estratégia de deploy sem downtime ataca três variáveis. O risco de exposição: quantos usuários uma versão ruim atinge antes de você perceber. A velocidade de rollback: quão rápido você volta ao estado bom. E o custo de infraestrutura: quantos recursos a mais a estratégia consome durante a transição. Cada abordagem faz um trade-off diferente entre essas três, e não existe a melhor em abstrato, só a mais adequada ao contexto.

Um pré-requisito atravessa todas elas: o health check. Nenhuma estratégia funciona se o sistema não souber distinguir uma instância que subiu de uma instância saudável e pronta para receber tráfego. Um health check bem-feito, que só reporta saúde quando a aplicação está de fato pronta para atender, é a fundação sobre a qual as três estratégias operam. Sem ele, o orquestrador manda tráfego para instâncias que ainda estão inicializando, e o "sem downtime" vira uma promessa quebrada.

Rolling update: a substituição gradual#

O rolling update é a estratégia padrão da maioria dos orquestradores, incluindo o Kubernetes, e a mais econômica em recursos. A ideia é substituir as instâncias antigas pelas novas aos poucos, algumas de cada vez, até trocar todas.

Imagine dez réplicas da versão 1 rodando. O rolling update sobe algumas réplicas da versão 2, espera elas ficarem saudáveis, direciona tráfego para elas, e então remove um número equivalente de réplicas da versão 1. Repete esse passo em ondas até que as dez réplicas sejam da versão 2. Em nenhum momento o serviço fica indisponível, porque sempre há réplicas saudáveis atendendo, e o número total de réplicas se mantém aproximadamente constante, o que torna a estratégia barata: você não precisa dobrar a infraestrutura.

Dois parâmetros controlam o comportamento e valem entender. O max unavailable define quantas réplicas podem estar fora ao mesmo tempo durante a troca, controlando quanta capacidade você aceita perder momentaneamente. O max surge define quantas réplicas a mais do total normal podem existir durante a transição, controlando quanto de recurso extra você tolera. Ajustar esses dois é ajustar o equilíbrio entre a velocidade da troca e a capacidade preservada.

O rolling update tem duas fraquezas importantes. Durante a transição, as duas versões coexistem atendendo tráfego, o que exige que elas sejam compatíveis entre si, especialmente no banco de dados. E o rollback é relativamente lento: reverter significa fazer outro rolling update de volta à versão anterior, réplica por réplica, o que leva o mesmo tempo que a ida. Para a maioria dos serviços, essas limitações são aceitáveis, e é por isso que o rolling update é o padrão. Ele merece esse posto pelo equilíbrio, não por ser o melhor em nenhuma das três variáveis.

Blue-green: dois ambientes, uma chave#

O blue-green deployment troca economia por velocidade de rollback. A ideia é manter dois ambientes completos e idênticos: o blue, que está atendendo produção, e o green, ocioso ou rodando a versão nova.

O fluxo é limpo. A versão 1 roda no ambiente blue, recebendo todo o tráfego. Você implanta a versão 2 no ambiente green, completamente separado, e o testa à vontade sem afetar ninguém, porque o green ainda não recebe tráfego real. Quando está satisfeito, você vira a chave: o roteador de tráfego, um balanceador ou um serviço, passa a apontar para o green de uma vez. Agora o green é produção e o blue fica ocioso, guardado.

A grande vantagem é o rollback instantâneo. Se a versão 2 no green apresentar problema, você vira a chave de volta para o blue, que ainda está intacto com a versão 1. O rollback é uma mudança de roteamento, quase imediato, sem esperar réplicas subirem. Essa é a razão de escolher blue-green: quando o custo de um rollback lento é alto demais, você paga por poder voltar num instante.

O preço é literal: você precisa de capacidade para dois ambientes completos, o que na prática pode dobrar o custo de infraestrutura durante o período em que ambos existem. Há também um cuidado sério com o banco de dados, que geralmente é compartilhado entre os dois ambientes e não pode simplesmente ser "virado". Mudanças de schema precisam ser compatíveis com as duas versões durante a transição, um problema que exige disciplina de migrações incrementais e retrocompatíveis. O blue-green resolve o rollback da aplicação, mas não isenta ninguém de pensar com cuidado no dado.

Canary: testar na produção, com poucos#

O canary deployment é a estratégia mais sofisticada e a que melhor controla o risco de exposição. O nome vem dos canários que mineiros levavam para dentro das minas: se o pássaro passava mal, era sinal de gás perigoso antes que atingisse as pessoas. A versão nova é o canário.

A ideia é liberar a versão 2 para uma pequena fração dos usuários primeiro, digamos 5%, enquanto os outros 95% continuam na versão 1. Você então observa de perto essa fração: as métricas de erro, latência e comportamento da versão 2 estão saudáveis comparadas à versão 1? Se sim, você aumenta gradualmente a fração, para 25%, 50%, até 100%, ganhando confiança a cada passo. Se as métricas do canário degradam, você reverte antes que o problema atinja a maioria, tendo exposto apenas uma minoria a uma versão ruim.

O canary é imbatível em uma coisa: minimizar o raio de dano de uma versão problemática. Enquanto rolling e blue-green, no momento da virada, expõem todos ou quase todos os usuários à versão nova, o canary expõe pouquíssimos e só cresce a exposição depois de a versão provar que se comporta bem. Isso o torna a escolha natural para mudanças de alto risco, onde um bug atingindo todos de uma vez seria caro demais.

O custo do canary é a complexidade. Ele exige um roteamento de tráfego capaz de dividir requisições por porcentagem, e, sobretudo, exige observabilidade excelente. Todo o valor do canary depende de você conseguir comparar, em tempo real e com confiança, a saúde da versão nova contra a antiga; sem métricas boas, você está liberando às cegas e o canário não avisa nada. Formas mais avançadas automatizam essa análise, promovendo ou revertendo a liberação com base em métricas sem intervenção humana, mas isso só funciona sobre uma base sólida de sinais confiáveis.

O elo mais frágil: o banco de dados#

Todas as três estratégias tratam de trocar a versão da aplicação sem downtime, e todas escondem o mesmo calcanhar de Aquiles: o banco de dados. Aplicações são efêmeras e descartáveis, você as sobe e derruba à vontade. O banco é estado persistente, único, compartilhado, e não pode ser simplesmente duplicado ou revertido junto com a aplicação. É aqui que deploys aparentemente seguros dão errado.

O ponto crítico é que, durante qualquer uma dessas transições, duas versões da aplicação coexistem falando com o mesmo banco. Se a versão 2 exige uma mudança de schema incompatível com a versão 1, você tem um conflito: a migração que agrada a versão 2 quebra a versão 1 que ainda está no ar, e vice-versa. Pior, se você reverte a aplicação mas a migração já rodou, a versão antiga encontra um schema que não entende.

A disciplina que resolve isso são as migrações compatíveis para trás, aplicadas em passos que nunca quebram a versão anterior. Adicionar uma coluna nova é seguro, porque a versão antiga a ignora; remover ou renomear uma coluna não é, porque a versão antiga ainda a usa. A técnica é decompor mudanças destrutivas em etapas seguras espalhadas por vários deploys: primeiro adiciona-se o novo sem remover o velho, depois migra-se o código para usar o novo, e só num deploy posterior, quando nenhuma versão viva usa mais o velho, ele é removido. É mais trabalhoso, mas é o que torna o rollback da aplicação realmente seguro. De nada adianta um blue-green com rollback instantâneo se a migração de schema tornou o retorno impossível. O deploy sem downtime da aplicação exige, como par inseparável, uma disciplina de evolução de schema que nunca queime a ponte de volta.

Escolhendo a estratégia certa#

Não existe vencedora universal; existe a adequada. O rolling update é o padrão sensato para a maioria dos serviços: barato, sem downtime, com rollback aceitável, bom quando as versões coexistem sem atrito. O blue-green vale quando o rollback precisa ser instantâneo e você pode pagar por dois ambientes, comum em sistemas onde um período ruim é intolerável. O canary brilha em mudanças arriscadas onde limitar o número de usuários afetados é a prioridade máxima, e você tem a observabilidade para sustentá-lo.

Repare que todas as três estratégias assumem algo em comum sobre a aplicação: que ela lida bem com múltiplas versões rodando ao mesmo tempo, que seus health checks são honestos, e que suas mudanças de banco são compatíveis para trás. Essas propriedades não vêm de graça; são fruto de como você desenha e empacota a aplicação. Um serviço bem comportado, que inicia rápido, responde a sinais de encerramento e não quebra o schema, é o que torna qualquer uma dessas estratégias suave. Vale entender como esse serviço nasce a partir da própria arquitetura do Kubernetes, que oferece rolling update nativo e primitivas sobre as quais canary e blue-green são construídos.

No fim, a evolução de "sistema em manutenção" para "deploy invisível várias vezes ao dia" resume o amadurecimento da operação moderna. As três estratégias são ferramentas diferentes para o mesmo objetivo: trocar de versão sem que o usuário sinta, e voltar atrás sem drama quando a versão nova decepciona. Dominar as três, e saber qual puxar em cada situação, é o que torna o deploy um não-evento, que é exatamente o que ele deveria ser.

Leituras relacionadas

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly