feat(aula-14): adicionar Istio Traffic Splitting com canary deployment
- Instala Istio (base + istiod + ingressgateway) - Configura Kiali e Jaeger para observabilidade - Deploy de app-backend v1 e v2 com traffic splitting 90/10 - Integra com Victoria Metrics da aula-12 - Inclui teste-stress.sh para validar distribuição de tráfego - Tráfego externo passa pelo Istio Gateway via NGINX Ingress
This commit is contained in:
198
aula-14/teste-stress.sh
Executable file
198
aula-14/teste-stress.sh
Executable file
@@ -0,0 +1,198 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# Teste de Stress - Demonstração de Traffic Splitting do Istio
|
||||
# ============================================================================
|
||||
# Script interativo para visualizar a distribuição de tráfego entre v1 e v2.
|
||||
#
|
||||
# Uso:
|
||||
# ./teste-stress.sh [URL] [NUM_REQUESTS]
|
||||
#
|
||||
# Exemplos:
|
||||
# ./teste-stress.sh # Usa APP_HOST do .env, 100 requests
|
||||
# ./teste-stress.sh https://app.kube.quest # URL específica, 100 requests
|
||||
# ./teste-stress.sh https://app.kube.quest 50 # 50 requests
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
MAGENTA='\033[0;35m'
|
||||
NC='\033[0m'
|
||||
BOLD='\033[1m'
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ENV_FILE="${SCRIPT_DIR}/.env"
|
||||
|
||||
# ============================================================================
|
||||
# Configuração
|
||||
# ============================================================================
|
||||
|
||||
# Carregar .env se existir
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
source "$ENV_FILE"
|
||||
fi
|
||||
|
||||
# Parâmetros
|
||||
URL="${1:-}"
|
||||
NUM_REQUESTS="${2:-100}"
|
||||
|
||||
# Se URL não foi passada, tentar construir do .env
|
||||
if [[ -z "$URL" ]]; then
|
||||
if [[ -n "$APP_HOST" ]]; then
|
||||
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
|
||||
URL="https://${APP_HOST}"
|
||||
else
|
||||
URL="http://${APP_HOST}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}[ERRO]${NC} URL não especificada e APP_HOST não encontrado no .env"
|
||||
echo ""
|
||||
echo "Uso: $0 [URL] [NUM_REQUESTS]"
|
||||
echo ""
|
||||
echo "Exemplos:"
|
||||
echo " $0 https://app.kube.quest"
|
||||
echo " $0 https://app.kube.quest 50"
|
||||
echo ""
|
||||
echo "Ou configure APP_HOST no .env executando setup.sh novamente."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Funções
|
||||
# ============================================================================
|
||||
|
||||
get_current_weights() {
|
||||
local weights
|
||||
weights=$(kubectl get virtualservice app-backend -n istio -o jsonpath='{.spec.http[0].route[*].weight}' 2>/dev/null || echo "90 10")
|
||||
echo "$weights"
|
||||
}
|
||||
|
||||
draw_bar() {
|
||||
local value=$1
|
||||
local max=$2
|
||||
local width=40
|
||||
local filled=$((value * width / max))
|
||||
local empty=$((width - filled))
|
||||
|
||||
printf "["
|
||||
for ((i=0; i<filled; i++)); do printf "${GREEN}#${NC}"; done
|
||||
for ((i=0; i<empty; i++)); do printf "."; done
|
||||
printf "]"
|
||||
}
|
||||
|
||||
show_header() {
|
||||
local weights
|
||||
weights=$(get_current_weights)
|
||||
local v1_weight=$(echo "$weights" | awk '{print $1}')
|
||||
local v2_weight=$(echo "$weights" | awk '{print $2}')
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}${BOLD}╔═══════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${CYAN}${BOLD}║ Teste de Traffic Splitting - Istio ║${NC}"
|
||||
echo -e "${CYAN}${BOLD}╚═══════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Distribuição configurada:${NC} v1=${v1_weight}% v2=${v2_weight}%"
|
||||
echo -e "${YELLOW}URL:${NC} ${URL}"
|
||||
echo -e "${YELLOW}Requests:${NC} ${NUM_REQUESTS}"
|
||||
echo ""
|
||||
echo -e "${CYAN}───────────────────────────────────────────────────────────${NC}"
|
||||
}
|
||||
|
||||
run_test() {
|
||||
local count_v1=0
|
||||
local count_v2=0
|
||||
local count_other=0
|
||||
|
||||
for ((i=1; i<=NUM_REQUESTS; i++)); do
|
||||
# Fazer request e capturar resposta
|
||||
local response
|
||||
response=$(curl -sk --connect-timeout 5 --max-time 10 "$URL" 2>/dev/null || echo "ERROR")
|
||||
|
||||
# Identificar versão baseado na resposta
|
||||
if echo "$response" | grep -q "v1\|node-bugado v1"; then
|
||||
((count_v1++))
|
||||
elif echo "$response" | grep -q "v2\|stable\|node-bugado v2"; then
|
||||
((count_v2++))
|
||||
else
|
||||
((count_other++))
|
||||
fi
|
||||
|
||||
# Exibir progresso
|
||||
printf "\r${NC}[%3d/%d] ${BLUE}v1:%-3d${NC} ${GREEN}v2:%-3d${NC}" "$i" "$NUM_REQUESTS" "$count_v1" "$count_v2"
|
||||
|
||||
# Pequena pausa para não sobrecarregar
|
||||
sleep 0.05
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
# Exibir resultados
|
||||
show_results "$count_v1" "$count_v2" "$count_other"
|
||||
}
|
||||
|
||||
show_results() {
|
||||
local count_v1=$1
|
||||
local count_v2=$2
|
||||
local count_other=$3
|
||||
local total=$((count_v1 + count_v2 + count_other))
|
||||
|
||||
local pct_v1=0
|
||||
local pct_v2=0
|
||||
[[ $total -gt 0 ]] && pct_v1=$((count_v1 * 100 / total))
|
||||
[[ $total -gt 0 ]] && pct_v2=$((count_v2 * 100 / total))
|
||||
|
||||
echo -e "${CYAN}═══════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${BOLD}Resultados:${NC}"
|
||||
echo ""
|
||||
printf " ${BLUE}v1${NC}: %3d (%2d%%) " "$count_v1" "$pct_v1"
|
||||
draw_bar "$count_v1" "$total"
|
||||
echo ""
|
||||
printf " ${GREEN}v2${NC}: %3d (%2d%%) " "$count_v2" "$pct_v2"
|
||||
draw_bar "$count_v2" "$total"
|
||||
echo ""
|
||||
|
||||
if [[ $count_other -gt 0 ]]; then
|
||||
echo -e " ${RED}Erros${NC}: $count_other"
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}═══════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
# Comandos para alterar distribuição
|
||||
show_commands
|
||||
}
|
||||
|
||||
show_commands() {
|
||||
echo -e "${BOLD}Comandos para alterar distribuição:${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}# Aumentar tráfego para v2 (50/50)${NC}"
|
||||
echo "kubectl patch virtualservice app-backend -n istio --type='json' \\"
|
||||
echo " -p='[{\"op\":\"replace\",\"path\":\"/spec/http/0/route/0/weight\",\"value\":50},"
|
||||
echo " {\"op\":\"replace\",\"path\":\"/spec/http/0/route/1/weight\",\"value\":50}]'"
|
||||
echo ""
|
||||
echo -e "${YELLOW}# Virada completa para v2 (0/100)${NC}"
|
||||
echo "kubectl patch virtualservice app-backend -n istio --type='json' \\"
|
||||
echo " -p='[{\"op\":\"replace\",\"path\":\"/spec/http/0/route/0/weight\",\"value\":0},"
|
||||
echo " {\"op\":\"replace\",\"path\":\"/spec/http/0/route/1/weight\",\"value\":100}]'"
|
||||
echo ""
|
||||
echo -e "${YELLOW}# Rollback para v1 se necessário (100/0)${NC}"
|
||||
echo "kubectl patch virtualservice app-backend -n istio --type='json' \\"
|
||||
echo " -p='[{\"op\":\"replace\",\"path\":\"/spec/http/0/route/0/weight\",\"value\":100},"
|
||||
echo " {\"op\":\"replace\",\"path\":\"/spec/http/0/route/1/weight\",\"value\":0}]'"
|
||||
echo ""
|
||||
echo -e "${CYAN}Após alterar, re-execute: ${NC}${BOLD}./teste-stress.sh${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Execução
|
||||
# ============================================================================
|
||||
|
||||
show_header
|
||||
run_test
|
||||
Reference in New Issue
Block a user