diff --git a/aula-05/scaledobject.yaml b/aula-05/scaledobject.yaml index d8dfc88..60a28da 100644 --- a/aula-05/scaledobject.yaml +++ b/aula-05/scaledobject.yaml @@ -57,12 +57,12 @@ spec: # SCALE DOWN - Quando pode reduzir pods scaleDown: - stabilizationWindowSeconds: 10 # Aguarda 10s de métricas estáveis + stabilizationWindowSeconds: 0 # Sem espera - escala imediatamente policies: - - type: Percent - value: 50 # Remove 50% dos pods por vez - periodSeconds: 5 # A cada 5 segundos - # Exemplo: 30 -> 15 -> 8 -> 5 (em 10 segundos) + - type: Pods + value: 10 # Remove 10 pods por vez + periodSeconds: 1 # A cada 1 segundo + # Exemplo: 30 -> 20 -> 10 -> 5 (em 3 segundos) # --------------------------------------------------------------------------- # TRIGGERS - Métricas que disparam o scaling @@ -76,43 +76,25 @@ spec: # Comportamento: Escala quando há pods que não estão prontos para receber tráfego # - type: prometheus + metricType: AverageValue # desiredReplicas = ceil(metricValue / threshold) metadata: # Endereço do Victoria Metrics (compatível com API do Prometheus) serverAddress: http://vmsingle-vm-victoria-metrics-k8s-stack.monitoring:8428 - # Query PromQL - conta pods indisponíveis do deployment node-bugado + # Query PromQL - calcula réplicas desejadas diretamente + # Fórmula: 5 (base) + (pods_unavailable * 2) + # Exemplos: + # 0 unavailable → 5 réplicas (mínimo) + # 3 unavailable → 5 + 6 = 11 réplicas + # 5 unavailable → 5 + 10 = 15 réplicas query: | - kube_deployment_status_replicas_unavailable{deployment="node-bugado", namespace="default"} + 5 + (kube_deployment_status_replicas_unavailable{deployment="node-bugado", namespace="default"} * 2) - # threshold: valor da métrica que dispara o scaling - # Se unavailable >= 1, adiciona pods + # threshold: cada 1 unidade da query = 1 réplica desejada + # Com query=5 (0 unavailable): desiredReplicas = 5 (mínimo) + # Com query=15 (5 unavailable): desiredReplicas = 15 threshold: '1' - # activationThreshold: valor mínimo para ativar o scaler - # Só começa a escalar se unavailable >= 1 - activationThreshold: '1' - - # ------------------------------------------------------------------------- - # TRIGGER 2: Restarts Frequentes - # ------------------------------------------------------------------------- - # Métrica: kube_pod_container_status_restarts_total - # Origem: kube-state-metrics (coletado pelo Victoria Metrics) - # Comportamento: Escala quando pods estão reiniciando muito (indica problemas) - # - - type: prometheus - metadata: - serverAddress: http://vmsingle-vm-victoria-metrics-k8s-stack.monitoring:8428 - - # Query PromQL - soma de restarts nos últimos 2 minutos - # increase() calcula o incremento no período - # sum() agrega todos os pods do deployment - query: | - sum(increase(kube_pod_container_status_restarts_total{namespace="default", pod=~"node-bugado.*"}[2m])) - - # Se houve 1 ou mais restarts nos últimos 2 min, escala - threshold: '1' - activationThreshold: '1' - # ============================================================================= # COMANDOS ÚTEIS PARA DEBUG # ============================================================================= diff --git a/aula-05/setup.sh b/aula-05/setup.sh index 7eb6c1c..b1402bf 100755 --- a/aula-05/setup.sh +++ b/aula-05/setup.sh @@ -34,6 +34,9 @@ log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERRO]${NC} $1"; } +# Diretório do script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + # ============================================================================= # VERIFICAÇÕES INICIAIS # ============================================================================= @@ -96,6 +99,11 @@ kubectl wait --for=condition=ready pod \ --timeout=120s 2>/dev/null || true log_success "Victoria Metrics está rodando" + +# Configurar scrape rápido (5s) para detecção rápida de crashes +log_info "Configurando scrape interval de 5s para kube-state-metrics..." +kubectl apply -f "$SCRIPT_DIR/vmservicescrape-kube-state-metrics.yaml" +log_success "Scrape interval configurado para 5s" echo "" # ============================================================================= @@ -147,6 +155,8 @@ else helm install nginx-ingress ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ + --set controller.allowSnippetAnnotations=true \ + --set controller.config.annotations-risk-level=Critical \ --wait log_success "NGINX Ingress instalado" @@ -159,9 +169,6 @@ echo "" log_info "=== Aplicando manifestos da aplicação ===" -# Diretório do script -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - log_info "Aplicando ConfigMap..." kubectl apply -f "$SCRIPT_DIR/configmap.yaml" diff --git a/aula-05/teste-stress.sh b/aula-05/teste-stress.sh index 1ebc788..d825e97 100755 --- a/aula-05/teste-stress.sh +++ b/aula-05/teste-stress.sh @@ -3,10 +3,35 @@ # Teste de Stress para verificar resiliência do Ingress + Auto-Scaling # Uso: ./teste-stress.sh [URL] [NUM_REQUESTS] +# Cores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + URL="${1:-http://localhost}" TOTAL="${2:-100}" TIMEOUT=120 +# ============================================================================= +# VERIFICACAO DO NGINX INGRESS CONTROLLER +# ============================================================================= + +echo -e "${YELLOW}[INFO]${NC} Verificando NGINX Ingress Controller..." + +if ! kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx 2>/dev/null | grep -q "Running"; then + echo -e "${RED}[ERRO]${NC} NGINX Ingress Controller NAO esta rodando!" + echo "" + echo "Para resolver, execute:" + echo "" + echo " ./setup.sh" + echo "" + exit 1 +fi + +echo -e "${GREEN}[OK]${NC} NGINX Ingress Controller esta rodando" +echo "" + echo "============================================" echo " Teste de Stress - Auto-Scaling com KEDA" echo "============================================" @@ -24,7 +49,7 @@ for i in $(seq 1 $TOTAL); do if echo "$RESULT" | grep -q "Req ->"; then SUCCESS=$((SUCCESS + 1)) - echo -e "[$i/$TOTAL] \033[32mOK\033[0m - $RESULT" + echo -e "[$i/$TOTAL] ${GREEN}OK${NC} - $RESULT" else FAIL=$((FAIL + 1)) # Extrai apenas o título do erro se for HTML @@ -33,7 +58,7 @@ for i in $(seq 1 $TOTAL); do else ERROR="$RESULT" fi - echo -e "[$i/$TOTAL] \033[31mFALHA\033[0m - $ERROR" + echo -e "[$i/$TOTAL] ${RED}FALHA${NC} - $ERROR" fi sleep 0.2 @@ -44,14 +69,14 @@ echo "============================================" echo " Resultado Final" echo "============================================" PERCENT=$((SUCCESS * 100 / TOTAL)) -echo -e "Sucesso: \033[32m$SUCCESS\033[0m / $TOTAL ($PERCENT%)" -echo -e "Falhas: \033[31m$FAIL\033[0m / $TOTAL" +echo -e "Sucesso: ${GREEN}$SUCCESS${NC} / $TOTAL ($PERCENT%)" +echo -e "Falhas: ${RED}$FAIL${NC} / $TOTAL" echo "============================================" if [ $FAIL -eq 0 ]; then - echo -e "\033[32m*** ZERO FALHAS! ***\033[0m" + echo -e "${GREEN}*** ZERO FALHAS! ***${NC}" elif [ $PERCENT -ge 95 ]; then - echo -e "\033[33mBom resultado (>= 95%)\033[0m" + echo -e "${YELLOW}Bom resultado (>= 95%)${NC}" else - echo -e "\033[31mResultado abaixo do esperado\033[0m" + echo -e "${RED}Resultado abaixo do esperado${NC}" fi diff --git a/aula-05/vmservicescrape-kube-state-metrics.yaml b/aula-05/vmservicescrape-kube-state-metrics.yaml new file mode 100644 index 0000000..d6d4ab6 --- /dev/null +++ b/aula-05/vmservicescrape-kube-state-metrics.yaml @@ -0,0 +1,40 @@ +# ============================================================================= +# VMServiceScrape - Scrape rápido do kube-state-metrics (5s) +# ============================================================================= +# +# Por que 5s? +# O scrape interval padrão do Victoria Metrics é 30s. +# Para o KEDA reagir rapidamente a pods crashados, precisamos +# que as métricas sejam atualizadas com mais frequência. +# +# Fluxo de detecção: +# 1. Pod crasha +# 2. kube-state-metrics atualiza (imediato) +# 3. Victoria Metrics coleta (5s) ← Este arquivo configura isso +# 4. KEDA consulta (1s) +# 5. HPA escala (imediato) +# Total: ~6-7s de reação +# +# ============================================================================= + +apiVersion: operator.victoriametrics.com/v1beta1 +kind: VMServiceScrape +metadata: + name: vm-victoria-metrics-k8s-stack-kube-state-metrics + namespace: monitoring + labels: + app.kubernetes.io/instance: vm + app.kubernetes.io/name: victoria-metrics-k8s-stack +spec: + endpoints: + - honorLabels: true + port: http + interval: 5s # Scrape a cada 5 segundos (default: 30s) + metricRelabelConfigs: + - action: labeldrop + regex: (uid|container_id|image_id) + jobLabel: app.kubernetes.io/name + selector: + matchLabels: + app.kubernetes.io/instance: vm + app.kubernetes.io/name: kube-state-metrics