O que Todo Dev Deve Saber sobre Progressive Delivery com Argo Rollouts: Canary e Blue-Green Automatizados Já leu

O que é Progressive Delivery? Progressive Delivery é um modelo de implantação que permite liberar alterações de software para produção de forma gradual e controlada, minimizando riscos e permitindo validação em tempo real. Diferente da entrega contínua tradicional (onde você implanta tudo de uma vez), a progressive delivery segmenta o acesso a novas versões, observa comportamento, coleta métricas e decide automaticamente se continua a migração ou faz rollback. A principal vantagem é reduzir o impacto de bugs ou problemas de performance. Se você descobre que a versão nova consome mais memória ou tem latência mais alta, você não perdeu 100% dos seus usuários. Você pode parar a migração, investigar, corrigir e tentar novamente. Isso é especialmente crítico em sistemas de missão crítica onde indisponibilidade ou degradação custa dinheiro em tempo real. Argo Rollouts: Orquestração de Progressive Delivery no Kubernetes O que é Argo Rollouts? Argo Rollouts é uma extensão do Kubernetes mantida pela CNCF que traz estratégias sofisticadas de implantação

O que é Progressive Delivery?

Progressive Delivery é um modelo de implantação que permite liberar alterações de software para produção de forma gradual e controlada, minimizando riscos e permitindo validação em tempo real. Diferente da entrega contínua tradicional (onde você implanta tudo de uma vez), a progressive delivery segmenta o acesso a novas versões, observa comportamento, coleta métricas e decide automaticamente se continua a migração ou faz rollback.

A principal vantagem é reduzir o impacto de bugs ou problemas de performance. Se você descobre que a versão nova consome mais memória ou tem latência mais alta, você não perdeu 100% dos seus usuários. Você pode parar a migração, investigar, corrigir e tentar novamente. Isso é especialmente crítico em sistemas de missão crítica onde indisponibilidade ou degradação custa dinheiro em tempo real.

Argo Rollouts: Orquestração de Progressive Delivery no Kubernetes

O que é Argo Rollouts?

Argo Rollouts é uma extensão do Kubernetes mantida pela CNCF que traz estratégias sofisticadas de implantação além do Deployment padrão. Enquanto o Deployment do Kubernetes oferece apenas Rolling Updates ou Recreate, Argo Rollouts implementa nativamente Canary, Blue-Green, e A/B Testing com suporte automático a análise de métricas.

Argo Rollouts funciona através de um recurso customizado chamado Rollout. Você define seu aplicativo como um Rollout em vez de um Deployment, e o controller do Argo Rollouts gerencia a transição entre versões conforme regras de tráfego e critérios de análise que você especifica. Isso é poderoso porque toda a lógica de decisão (continuar ou reverter) é declarativa, versionável e repetível.

Instalando Argo Rollouts

Antes de criar seu primeiro Rollout, você precisa instalar o controller no cluster. Argo Rollouts roda como um deployment no namespace argo-rollouts:

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

Após a instalação, verifique se o controller está rodando:

kubectl get pods -n argo-rollouts

Você deve ver um pod com nome argo-rollouts-* em estado Running. Se estiver em CrashLoopBackOff, verifique os logs com kubectl logs -n argo-rollouts <pod-name>.

Estratégia Canary: Implantação Gradual com Validação Automática

Conceito e Fluxo

Canary é uma estratégia onde você envia a nova versão para um pequeno percentual de usuários (por exemplo, 5%) e observa métricas como taxa de erro, latência e uso de recursos. Se tudo estiver bem, você aumenta gradualmente o percentual até que todos os usuários estejam na nova versão. Se algo der errado, você reverte para a versão anterior automaticamente.

O nome "canary" vem da metáfora do canário na mina de carvão: os mineiros levavam canários porque eles morriam quando havia gás tóxico, servindo como alarme. Aqui, o canário é seu pequeno grupo de usuários que "avisa" se a nova versão tem problemas.

Exemplo Prático: Canary com Análise Automática

Vamos criar um Rollout que faz implantação canary automática. Suponha que você tem uma API simples em Go:

package main

import (
    "fmt"
    "net/http"
    "os"
)

func handler(w http.ResponseWriter, r *http.Request) {
    version := os.Getenv("APP_VERSION")
    if version == "" {
        version = "v1"
    }
    fmt.Fprintf(w, "Hello from %s\n", version)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Você conteirizará isso em uma imagem Docker chamada meu-app:v1 e depois meu-app:v2 com APP_VERSION=v2.

Agora crie um Rollout que faz canary automático:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: meu-app
spec:
  replicas: 4
  selector:
    matchLabels:
      app: meu-app
  template:
    metadata:
      labels:
        app: meu-app
    spec:
      containers:
      - name: meu-app
        image: meu-app:v1
        ports:
        - containerPort: 8080
        env:
        - name: APP_VERSION
          value: "v1"
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {duration: 5m}
      - setWeight: 50
      - pause: {duration: 5m}
      - setWeight: 100
  revisionHistoryLimit: 2

Neste exemplo, o Rollout começa com 20% do tráfego na nova versão, aguarda 5 minutos (tempo para coletar métricas), aumenta para 50%, aguarda novamente, e finalmente coloca 100%. Se nenhuma análise falhar nesse tempo, a versão nova é promovida.

Para atualizar para a versão v2, você muda a imagem:

kubectl patch rollout meu-app --type='json' \
  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"meu-app:v2"}]'

Ou edite o YAML diretamente com kubectl edit rollout meu-app.

Integração com Análise (Prometheus)

Para que o Rollout realmente interrompa a migração em caso de problemas, você precisa definir regras de análise. Isso requer um recurso chamado AnalysisTemplate. Vamos supor que você tem Prometheus rodando no cluster:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: meu-app-analysis
spec:
  metrics:
  - name: error-rate
    interval: 60s
    successCriteria: "{{ result <= 0.05 }}"
    provider:
      prometheus:
        address: http://prometheus:9090
        query: |
          sum(rate(http_requests_total{job="meu-app",status=~"5.."}[5m])) /
          sum(rate(http_requests_total{job="meu-app"}[5m]))
  - name: response-latency
    interval: 60s
    successCriteria: "{{ result < 500 }}"
    provider:
      prometheus:
        address: http://prometheus:9090
        query: |
          histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job="meu-app"}[5m])) by (le))

Agora modifique seu Rollout para usar essa análise:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: meu-app
spec:
  replicas: 4
  selector:
    matchLabels:
      app: meu-app
  template:
    metadata:
      labels:
        app: meu-app
    spec:
      containers:
      - name: meu-app
        image: meu-app:v1
        ports:
        - containerPort: 8080
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {duration: 5m}
      - analysis:
          templates:
          - name: meu-app-analysis
      - setWeight: 50
      - pause: {duration: 5m}
      - setWeight: 100

Agora, após 5 minutos na versão canary (20%), o Argo Rollouts executa a análise. Se a taxa de erro estiver acima de 5% ou a latência acima de 500ms, a análise falha e a migração é revertida automaticamente.

Estratégia Blue-Green: Troca Instantânea com Validação Offline

Conceito e Fluxo

Blue-Green é radicalmente diferente de Canary. Em vez de gradualmente migrar tráfego, você mantém dois ambientes completos: Blue (atual) e Green (nova versão). O Green é preparado completamente em paralelo, testado offline, e depois você faz uma mudança instantânea de tráfego de Blue para Green. Se algo der errado, você volta para Blue imediatamente.

Blue-Green é mais apropriado para aplicações onde você quer validação completa antes de qualquer usuário ver a nova versão, ou quando suas métricas levam tempo para estabilizar (você não quer esperar 30 minutos em Canary). A desvantagem é que você precisa do dobro de recursos durante a transição.

Exemplo Prático: Blue-Green com Validação Manual

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: meu-app-bg
spec:
  replicas: 3
  selector:
    matchLabels:
      app: meu-app-bg
  template:
    metadata:
      labels:
        app: meu-app-bg
    spec:
      containers:
      - name: meu-app
        image: meu-app:v1
        ports:
        - containerPort: 8080
  strategy:
    blueGreen:
      activeSlotSelector: blue
      prePromotionAnalysis:
        templates:
        - name: meu-app-analysis
      autoPromotionEnabled: false
      autoPromotionSeconds: 0

Neste Rollout Blue-Green:

  • activeSlotSelector: blue significa que atualmente o slot "blue" (v1) está recebendo tráfego.
  • Quando você atualiza a imagem para meu-app:v2, o Argo cria pods novos no slot "green" sem mudar tráfego.
  • prePromotionAnalysis roda testes antes de promover green para ativo. Você pode fazer chamadas HTTP, verificar logs, etc.
  • autoPromotionEnabled: false significa que você decide manualmente quando fazer a troca. Para promover, você executa:
kubectl argo rollouts promote meu-app-bg

Para reverter se algo der errado:

kubectl argo rollouts abort meu-app-bg

Blue-Green Totalmente Automatizado

Se você quer automação total, ative autoPromotionEnabled:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: meu-app-bg-auto
spec:
  replicas: 3
  selector:
    matchLabels:
      app: meu-app-bg-auto
  template:
    metadata:
      labels:
        app: meu-app-bg-auto
    spec:
      containers:
      - name: meu-app
        image: meu-app:v1
        ports:
        - containerPort: 8080
  strategy:
    blueGreen:
      activeSlotSelector: blue
      prePromotionAnalysis:
        templates:
        - name: meu-app-analysis
      autoPromotionEnabled: true
      autoPromotionSeconds: 300

Com isso:

  1. Você atualiza a imagem.
  2. Green é criado e testado com a análise.
  3. Se a análise passar, após 300 segundos (5 minutos) o tráfego é automaticamente movido para green.
  4. Blue permanece rodando e pode ser rapidamente reativado se necessário.

Monitoramento e Troubleshooting de Rollouts

Inspecionando o Status do Rollout

Para ver o progresso de um Rollout em tempo real:

kubectl get rollouts -w

Para detalhes completos sobre o status atual:

kubectl describe rollout meu-app

Para ver o histórico de análises executadas:

kubectl get analysisruns
kubectl describe analysisrun <nome-do-run>

Logs e Debugging

Se uma análise falhar ou um step pausar indefinidamente, verifique os logs do controller:

kubectl logs -n argo-rollouts -l app=argo-rollouts -f

Verifique também se o recurso de Rollout está bem formado:

kubectl get rollout meu-app -o yaml

Se você tem múltiplas versões de um aplicativo e quer comparar:

kubectl get rs -l app=meu-app

Isso mostra os ReplicaSets (versões antigas e novas) que o Rollout criou.

Revogando um Rollout em Andamento

Se você detectar um problema durante a migração canary:

kubectl argo rollouts abort meu-app

Isso para imediatamente o rollout e mantém a versão anterior. Para saber qual versão está ativa:

kubectl argo rollouts status meu-app

Conclusão

Você aprendeu que Progressive Delivery com Argo Rollouts elimina a falsa dicotomia entre velocidade e segurança: você pode liberar múltiplas vezes ao dia para produção sem arriscar seus usuários. Canary funciona melhor quando suas métricas estabilizam rápido e você quer medir impacto em tempo real; Blue-Green é superior quando você precisa de validação offline completa ou quando quer uma janela de rollback instantâneo. Ambas as estratégias, quando acopladas a análises automáticas com Prometheus, transformam o deployment de um processo nervoso em uma atividade rotineira e confiável, com capacidade de decisão totalmente codificada e observável.

Referências


Artigos relacionados