fix(aula-05): otimizar KEDA para detecção instantânea de crashes
- Simplificar ScaledObject: usar apenas trigger de pods unavailable (instantâneo) em vez de restarts (requeria janela de tempo) - Adicionar VMServiceScrape com scrape interval de 5s para detecção rápida pelo Victoria Metrics (default era 30s) - Acelerar scale down: stabilizationWindow=0, remove 10 pods/s - Query intuitiva: 5 + (unavailable * 2) = réplicas desejadas - Usar metricType AverageValue para cálculo correto de réplicas - Limpar mensagem desnecessária do teste de stress
This commit is contained in:
@@ -57,12 +57,12 @@ spec:
|
|||||||
|
|
||||||
# SCALE DOWN - Quando pode reduzir pods
|
# SCALE DOWN - Quando pode reduzir pods
|
||||||
scaleDown:
|
scaleDown:
|
||||||
stabilizationWindowSeconds: 10 # Aguarda 10s de métricas estáveis
|
stabilizationWindowSeconds: 0 # Sem espera - escala imediatamente
|
||||||
policies:
|
policies:
|
||||||
- type: Percent
|
- type: Pods
|
||||||
value: 50 # Remove 50% dos pods por vez
|
value: 10 # Remove 10 pods por vez
|
||||||
periodSeconds: 5 # A cada 5 segundos
|
periodSeconds: 1 # A cada 1 segundo
|
||||||
# Exemplo: 30 -> 15 -> 8 -> 5 (em 10 segundos)
|
# Exemplo: 30 -> 20 -> 10 -> 5 (em 3 segundos)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# TRIGGERS - Métricas que disparam o scaling
|
# 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
|
# Comportamento: Escala quando há pods que não estão prontos para receber tráfego
|
||||||
#
|
#
|
||||||
- type: prometheus
|
- type: prometheus
|
||||||
|
metricType: AverageValue # desiredReplicas = ceil(metricValue / threshold)
|
||||||
metadata:
|
metadata:
|
||||||
# Endereço do Victoria Metrics (compatível com API do Prometheus)
|
# Endereço do Victoria Metrics (compatível com API do Prometheus)
|
||||||
serverAddress: http://vmsingle-vm-victoria-metrics-k8s-stack.monitoring:8428
|
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: |
|
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
|
# threshold: cada 1 unidade da query = 1 réplica desejada
|
||||||
# Se unavailable >= 1, adiciona pods
|
# Com query=5 (0 unavailable): desiredReplicas = 5 (mínimo)
|
||||||
|
# Com query=15 (5 unavailable): desiredReplicas = 15
|
||||||
threshold: '1'
|
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
|
# COMANDOS ÚTEIS PARA DEBUG
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
|
|||||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||||
log_error() { echo -e "${RED}[ERRO]${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
|
# VERIFICAÇÕES INICIAIS
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -96,6 +99,11 @@ kubectl wait --for=condition=ready pod \
|
|||||||
--timeout=120s 2>/dev/null || true
|
--timeout=120s 2>/dev/null || true
|
||||||
|
|
||||||
log_success "Victoria Metrics está rodando"
|
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 ""
|
echo ""
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -147,6 +155,8 @@ else
|
|||||||
helm install nginx-ingress ingress-nginx/ingress-nginx \
|
helm install nginx-ingress ingress-nginx/ingress-nginx \
|
||||||
--namespace ingress-nginx \
|
--namespace ingress-nginx \
|
||||||
--create-namespace \
|
--create-namespace \
|
||||||
|
--set controller.allowSnippetAnnotations=true \
|
||||||
|
--set controller.config.annotations-risk-level=Critical \
|
||||||
--wait
|
--wait
|
||||||
|
|
||||||
log_success "NGINX Ingress instalado"
|
log_success "NGINX Ingress instalado"
|
||||||
@@ -159,9 +169,6 @@ echo ""
|
|||||||
|
|
||||||
log_info "=== Aplicando manifestos da aplicação ==="
|
log_info "=== Aplicando manifestos da aplicação ==="
|
||||||
|
|
||||||
# Diretório do script
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
|
|
||||||
log_info "Aplicando ConfigMap..."
|
log_info "Aplicando ConfigMap..."
|
||||||
kubectl apply -f "$SCRIPT_DIR/configmap.yaml"
|
kubectl apply -f "$SCRIPT_DIR/configmap.yaml"
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,35 @@
|
|||||||
# Teste de Stress para verificar resiliência do Ingress + Auto-Scaling
|
# Teste de Stress para verificar resiliência do Ingress + Auto-Scaling
|
||||||
# Uso: ./teste-stress.sh [URL] [NUM_REQUESTS]
|
# 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}"
|
URL="${1:-http://localhost}"
|
||||||
TOTAL="${2:-100}"
|
TOTAL="${2:-100}"
|
||||||
TIMEOUT=120
|
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 "============================================"
|
||||||
echo " Teste de Stress - Auto-Scaling com KEDA"
|
echo " Teste de Stress - Auto-Scaling com KEDA"
|
||||||
echo "============================================"
|
echo "============================================"
|
||||||
@@ -24,7 +49,7 @@ for i in $(seq 1 $TOTAL); do
|
|||||||
|
|
||||||
if echo "$RESULT" | grep -q "Req ->"; then
|
if echo "$RESULT" | grep -q "Req ->"; then
|
||||||
SUCCESS=$((SUCCESS + 1))
|
SUCCESS=$((SUCCESS + 1))
|
||||||
echo -e "[$i/$TOTAL] \033[32mOK\033[0m - $RESULT"
|
echo -e "[$i/$TOTAL] ${GREEN}OK${NC} - $RESULT"
|
||||||
else
|
else
|
||||||
FAIL=$((FAIL + 1))
|
FAIL=$((FAIL + 1))
|
||||||
# Extrai apenas o título do erro se for HTML
|
# Extrai apenas o título do erro se for HTML
|
||||||
@@ -33,7 +58,7 @@ for i in $(seq 1 $TOTAL); do
|
|||||||
else
|
else
|
||||||
ERROR="$RESULT"
|
ERROR="$RESULT"
|
||||||
fi
|
fi
|
||||||
echo -e "[$i/$TOTAL] \033[31mFALHA\033[0m - $ERROR"
|
echo -e "[$i/$TOTAL] ${RED}FALHA${NC} - $ERROR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 0.2
|
sleep 0.2
|
||||||
@@ -44,14 +69,14 @@ echo "============================================"
|
|||||||
echo " Resultado Final"
|
echo " Resultado Final"
|
||||||
echo "============================================"
|
echo "============================================"
|
||||||
PERCENT=$((SUCCESS * 100 / TOTAL))
|
PERCENT=$((SUCCESS * 100 / TOTAL))
|
||||||
echo -e "Sucesso: \033[32m$SUCCESS\033[0m / $TOTAL ($PERCENT%)"
|
echo -e "Sucesso: ${GREEN}$SUCCESS${NC} / $TOTAL ($PERCENT%)"
|
||||||
echo -e "Falhas: \033[31m$FAIL\033[0m / $TOTAL"
|
echo -e "Falhas: ${RED}$FAIL${NC} / $TOTAL"
|
||||||
echo "============================================"
|
echo "============================================"
|
||||||
|
|
||||||
if [ $FAIL -eq 0 ]; then
|
if [ $FAIL -eq 0 ]; then
|
||||||
echo -e "\033[32m*** ZERO FALHAS! ***\033[0m"
|
echo -e "${GREEN}*** ZERO FALHAS! ***${NC}"
|
||||||
elif [ $PERCENT -ge 95 ]; then
|
elif [ $PERCENT -ge 95 ]; then
|
||||||
echo -e "\033[33mBom resultado (>= 95%)\033[0m"
|
echo -e "${YELLOW}Bom resultado (>= 95%)${NC}"
|
||||||
else
|
else
|
||||||
echo -e "\033[31mResultado abaixo do esperado\033[0m"
|
echo -e "${RED}Resultado abaixo do esperado${NC}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
40
aula-05/vmservicescrape-kube-state-metrics.yaml
Normal file
40
aula-05/vmservicescrape-kube-state-metrics.yaml
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user