Blue-green deployments no Kubernetes: estratégias sem downtime
1. Fundamentos do Blue-green deployment
O conceito de blue-green deployment é uma estratégia de implantação que mantém dois ambientes de produção idênticos, chamados de "blue" e "green". Em qualquer momento, apenas um deles está recebendo tráfego real de produção. Quando uma nova versão precisa ser implantada, ela é deployada no ambiente inativo, e após validação, o tráfego é instantaneamente redirecionado para ele.
Os objetivos principais são:
- Zero downtime: a troca de tráfego é instantânea, sem janelas de indisponibilidade
- Rollback imediato: basta reverter o tráfego para o ambiente anterior
- Isolamento de versões: cada versão roda em seu próprio conjunto de pods, sem interferência
Diferentemente do Rolling update (que substitui pods gradualmente) e do Canary release (que envia uma fração do tráfego para a nova versão), o blue-green oferece uma troca binária e completa. É ideal para cenários onde a consistência da experiência do usuário é crítica.
2. Arquitetura no Kubernetes: Services, Ingress e Labels
No Kubernetes, a implementação blue-green se apoia em três pilares:
Service com seletor de labels: o Service é configurado para apontar para um conjunto de pods através de labels. Alternar entre blue e green significa simplesmente mudar o selector do Service.
Ingress e Gateway API: para roteamento mais sofisticado, o Ingress pode direcionar tráfego para diferentes Services baseados em pesos ou cabeçalhos HTTP.
Labels e annotations: usamos labels como version: blue e version: green para identificar cada deployment. Annotations podem armazenar metadados como hash da imagem ou data do deploy.
3. Implementação prática com Deployments e Services
Vamos criar dois Deployments e um Service que alterna entre eles. Primeiro, o Deployment blue (versão atual):
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
labels:
app: minha-app
version: blue
spec:
replicas: 3
selector:
matchLabels:
app: minha-app
version: blue
template:
metadata:
labels:
app: minha-app
version: blue
spec:
containers:
- name: app
image: minha-app:1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
Agora o Deployment green (nova versão):
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
labels:
app: minha-app
version: green
spec:
replicas: 3
selector:
matchLabels:
app: minha-app
version: green
template:
metadata:
labels:
app: minha-app
version: green
spec:
containers:
- name: app
image: minha-app:2.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
E o Service que inicialmente aponta para o blue:
apiVersion: v1
kind: Service
metadata:
name: minha-app-service
spec:
selector:
app: minha-app
version: blue
ports:
- protocol: TCP
port: 80
targetPort: 8080
4. Estratégias de troca de tráfego (switch)
Troca manual com kubectl patch:
kubectl patch service minha-app-service -p '{"spec":{"selector":{"version":"green"}}}'
Este comando altera o seletor do Service instantaneamente. Todos os novos requests passam a ser roteados para os pods green.
Troca automatizada com script e validação:
#!/bin/bash
# Valida se o deployment green está saudável
kubectl rollout status deployment/app-green --timeout=120s
if [ $? -eq 0 ]; then
# Troca o tráfego
kubectl patch service minha-app-service -p '{"spec":{"selector":{"version":"green"}}}'
echo "Tráfego redirecionado para green"
else
echo "Deployment green não está saudável. Abortando."
exit 1
fi
Uso de probes: o readinessProbe garante que apenas pods prontos recebam tráfego. Durante a troca, o Kubernetes só considera pods com status Ready. Isso evita que requests sejam enviados para pods que ainda estão inicializando.
5. Blue-green com Ingress Controller (NGINX, Traefik)
Com o Ingress NGINX, podemos usar annotations para canary releases:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minha-app-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "0"
spec:
rules:
- host: app.exemplo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: minha-app-service-green
port:
number: 80
Para alternar totalmente, removemos a annotation canary do ingress green e a adicionamos no ingress blue, invertendo os pesos.
Roteamento por cabeçalhos HTTP para testes controlados:
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "green-test"
Isso permite que apenas requests com o header X-Canary: green-test sejam roteados para o ambiente green.
6. Rollback e gerenciamento de estado
Rollback imediato é tão simples quanto reverter o seletor:
kubectl patch service minha-app-service -p '{"spec":{"selector":{"version":"blue"}}}'
Para aplicações stateful (bancos, filas), o blue-green exige cuidado extra:
- Use bancos de dados separados para cada ambiente, com replicação assíncrona
- Ou utilize volumes compartilhados com locks distribuídos (ex: ZooKeeper, etcd)
- Ferramentas como Helm facilitam o gerenciamento: cada release helm pode representar um ambiente
ArgoCD pode gerenciar blue-green automaticamente com syncPolicy e automated:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: minha-app
spec:
destination:
namespace: production
source:
repoURL: https://git.exemplo.com/repo
path: k8s/blue-green
syncPolicy:
automated:
prune: true
selfHeal: true
7. Monitoramento e validação pós-deploy
Métricas chave com Prometheus + Grafana:
- Latência (p50, p95, p99)
- Taxa de erro HTTP (5xx, 4xx)
- CPU e memória dos pods
- Número de pods Ready vs Total
Testes automatizados com k6 durante a troca:
import http from 'k6/http';
import { check, sleep } from 'k6';
export default function () {
const res = http.get('http://app.exemplo.com/api/health');
check(res, {
'status é 200': (r) => r.status === 200,
'tempo de resposta < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
Alertas para rollback automático: integre Prometheus Alertmanager com um webhook que executa kubectl patch para reverter o tráfego se a taxa de erro exceder 1% nos primeiros 5 minutos após o deploy.
8. Integração com temas vizinhos da série
Compliance as code: use OPA/Gatekeeper para garantir que todo deployment blue-green tenha probes configuradas:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredProbes
metadata:
name: require-readiness-probe
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
namespaces: ["production"]
parameters:
probes: ["readinessProbe", "livenessProbe"]
Chaos engineering: LitmusChaos pode injetar falhas durante a troca para testar a resiliência:
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
name: pod-delete-during-switch
spec:
appinfo:
appns: production
applabel: "app=minha-app"
appkind: deployment
experiments:
- name: pod-delete
spec:
components:
env:
- name: TOTAL_CHAOS_DURATION
value: "60"
- name: CHAOS_INTERVAL
value: "10"
Canary releases: o blue-green é pré-requisito natural para canary. Primeiro estabelecemos o ambiente green, depois direcionamos gradualmente o tráfego usando pesos no Ingress.
Feature flags: com LaunchDarkly, podemos ativar funcionalidades específicas no ambiente green sem afetar o blue:
if (ldclient.variation("nova-funcionalidade", user, false)) {
// Código da nova funcionalidade
}
Isso permite testar funcionalidades em produção com usuários reais, mesmo antes do switch completo.
Referências
- Kubernetes Official Documentation: Deployments — Documentação oficial sobre Deployments, incluindo estratégias de atualização e probes.
- NGINX Ingress Controller: Canary Deployments — Guia completo de annotations para canary releases com NGINX Ingress.
- ArgoCD: Blue-Green Deployments — Documentação oficial do ArgoCD para implementação de blue-green deployments.
- LitmusChaos: Chaos Engineering for Kubernetes — Tutorial sobre injeção de falhas controladas em clusters Kubernetes.
- LaunchDarkly: Feature Flags in Kubernetes — Guia prático de integração de feature flags com deployments Kubernetes.
- k6: Load Testing Tool — Documentação oficial para testes de carga e validação pós-deploy.
- Prometheus + Grafana: Monitoring Kubernetes — Guia de monitoramento de clusters Kubernetes com Prometheus e Grafana.