- aula-16: nova aula de canary deployment automatizado com Flagger - aula-14: removido Jaeger (tracing movido para aula-15), corrigido nome do serviço Victoria Metrics, adicionado rate limiting no Kiali - aula-15: adicionado receiver Zipkin no OTel Collector para receber traces do Istio, corrigida porta do Tempo (3100→3200), integração automática com Istio quando detectado - aula-03: corrigido MAX_REQUESTS de 10 para 3 (valor padrão) - CLAUDE.md: adicionada aula-16 na documentação
Aula 14 - Istio Traffic Splitting
Demonstração de canary deployment manual usando Istio para dividir tráfego entre duas versões da aplicação.
Motivação
Em produção, lançar uma nova versão diretamente para 100% dos usuários é arriscado. Com traffic splitting podemos:
- Enviar apenas 10% do tráfego para a nova versão inicialmente
- Monitorar erros e latência antes de aumentar o percentual
- Fazer rollback instantâneo sem redeploy
- Visualizar o fluxo de tráfego em tempo real com Kiali
Arquitetura
┌─────────────────────────────────────────────┐
│ Istio Service Mesh │
│ │
Requisições │ ┌─────────────────┐ │
──────────────► │ │ VirtualService │ │
│ │ (90/10 split) │ │
│ └────────┬────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ ▼ ▼ │
│ ┌──────┐ ┌──────┐ │
│ │ v1 │ │ v2 │ │
│ │ bug │ │ ok │ │
│ └──────┘ └──────┘ │
│ │
│ ┌─────────┐ ┌─────────────────┐ │
│ │ Kiali │ │ Victoria Metrics │ │
│ └─────────┘ └─────────────────┘ │
└─────────────────────────────────────────────┘
Conceitos
| Conceito | Descrição |
|---|---|
| Service Mesh | Camada de infraestrutura que gerencia comunicação entre serviços |
| Sidecar Injection | Proxy Envoy injetado automaticamente em cada pod |
| VirtualService | Define regras de roteamento de tráfego |
| DestinationRule | Define subsets (versões) do serviço |
| Traffic Splitting | Divisão percentual do tráfego entre versões |
Pré-requisitos
- Cluster Kubernetes na Hetzner (aula-08)
- Gitea com Registry (aula-10)
- Victoria Metrics (aula-12) para métricas
- kubectl, helm e docker instalados
Estrutura
aula-14/
├── README.md
├── setup.sh
├── cleanup.sh
├── app-backend/
│ ├── v1/
│ │ ├── app.js # Versão com bug (trava após N requests)
│ │ └── Dockerfile
│ └── v2/
│ ├── app.js # Versão corrigida (estável)
│ └── Dockerfile
├── k8s/
│ ├── namespace.yaml # Namespace com istio-injection
│ ├── deployment-v1.yaml
│ ├── deployment-v2.yaml
│ ├── service.yaml
│ ├── destination-rule.yaml # Define subsets v1, v2
│ ├── virtual-service.yaml # Traffic splitting (90/10)
│ └── ingress-kiali.yaml
└── istio/
└── kiali-values.yaml
Instalação
cd aula-14
./setup.sh
O script irá:
- Verificar pré-requisitos (incluindo Victoria Metrics da aula-12)
- Coletar configuração (domínio, registry, TLS)
- Instalar Istio (istio-base + istiod + ingressgateway)
- Instalar Kiali (dashboard do service mesh, métricas via Victoria Metrics)
- Configurar Ingress com Basic Auth e rate limiting
- Build e push das imagens v1 e v2
- Deploy da aplicação com traffic splitting 90/10
Verificação
Verificar pods
kubectl get pods -n istio
kubectl get pods -n istio-system
Verificar sidecar injection
Cada pod deve ter 2 containers (app + istio-proxy):
kubectl get pods -n istio -o jsonpath='{range .items[*]}{.metadata.name}{": "}{range .spec.containers[*]}{.name}{" "}{end}{"\n"}{end}'
Testar distribuição de tráfego
kubectl exec -n istio curl-test -- sh -c \
'for i in $(seq 1 100); do curl -s http://app-backend/; done' | sort | uniq -c
Resultado esperado (aproximado):
90 v1 - Request X
10 v2 - Request Y
Exercício Prático
1. Observar distribuição inicial (90/10)
kubectl exec -n istio curl-test -- sh -c \
'for i in $(seq 1 100); do curl -s http://app-backend/; done' | sort | uniq -c
2. Acessar Kiali e visualizar tráfego
Abra o Kiali no navegador e observe o gráfico de tráfego em tempo real. Gere tráfego contínuo em outro terminal:
kubectl exec -n istio curl-test -- sh -c \
'while true; do curl -s http://app-backend/ > /dev/null; sleep 0.1; done'
3. Alterar para 50/50
kubectl patch virtualservice app-backend -n istio --type='json' \
-p='[{"op":"replace","path":"/spec/http/0/route/0/weight","value":50},
{"op":"replace","path":"/spec/http/0/route/1/weight","value":50}]'
4. Observar no Kiali
Volte ao Kiali e veja o tráfego redistribuído igualmente entre v1 e v2.
5. Rollout completo para v2
kubectl patch virtualservice app-backend -n istio --type='json' \
-p='[{"op":"replace","path":"/spec/http/0/route/0/weight","value":0},
{"op":"replace","path":"/spec/http/0/route/1/weight","value":100}]'
6. Confirmar que app não trava mais
Com 100% do tráfego na v2, a aplicação permanece estável independente da quantidade de requests.
Comandos Úteis
# Ver distribuição atual
kubectl get virtualservice app-backend -n istio -o yaml
# Ver pods com labels de versão
kubectl get pods -n istio --show-labels
# Logs da v1
kubectl logs -n istio -l app=app-backend,version=v1 -f
# Logs da v2
kubectl logs -n istio -l app=app-backend,version=v2 -f
# Port-forward para Kiali (alternativa ao Ingress)
kubectl port-forward svc/kiali -n istio-system 20001:20001
Cleanup
./cleanup.sh
Remove Istio, Kiali e namespace da aplicação.
Troubleshooting
Pod não tem sidecar
Verificar se o namespace tem o label correto:
kubectl get ns istio --show-labels
Deve ter istio-injection=enabled. Se não tiver:
kubectl label ns istio istio-injection=enabled
kubectl rollout restart deployment -n istio
Kiali não mostra tráfego
- Verificar se Victoria Metrics está coletando métricas (aula-12)
- Gerar tráfego suficiente (pelo menos 10 requests)
- Aguardar 30 segundos para métricas aparecerem
VirtualService não aplicando weights
Verificar se DestinationRule existe:
kubectl get destinationrule app-backend -n istio -o yaml
E o tracing?
O tracing distribuído (ver o caminho de um request individual) é configurado na aula-15 com Grafana Tempo + OpenTelemetry. O Istio envia traces automaticamente para o Tempo após a aula-15 ser instalada.