- Extrair função ask_hostname para simplificar coleta de inputs - Remover variável DOMAIN do .env (usar hosts individuais) - Herdar domínio da aula-10 como default para hostnames - Adicionar label PodSecurity privileged no namespace istio-system - Usar ClusterIP no istio-ingressgateway e timeout de 10m no Helm - Permitir edição do email Let's Encrypt quando já configurado
Aula 14 - Istio Traffic Splitting
Demonstração de app-backend deployment 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 │ │ Jaeger │ │ 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)
└── istio/
├── kiali-values.yaml
├── jaeger-values.yaml
└── gateway.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)
- Instalar Kiali e Jaeger (métricas via Victoria Metrics)
- Configurar Ingress para dashboards
- 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. Verificar traces no Jaeger
Abra o Jaeger e observe os traces das requisições passando pelo mesh.
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
# Port-forward para Jaeger
kubectl port-forward svc/tracing -n istio-system 16686:80
Cleanup
./cleanup.sh
Remove Istio, addons 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