Pular para conteúdo

5. Meça

O Kubernetes promete elasticidade e autocura. Coloque números nas duas. Como sempre, rode cada experimento duas vezes e reporte a segunda execução; os números nas caixas de "forma esperada" são ilustrativos (vêm de uma execução num laptop, e os seus vão ser outros).

# Experimento Botão O que registrar
A réplicas fixas vs HPA HPA apagado vs aplicado p95, p99, erros, máximo de réplicas, tempo para escalar
B rolling update sob carga com vs sem readiness probe + preStop requisições com falha durante o rollout
C autocura apagar um pod / parar um nó tempo até a capacidade voltar (MTTR)

A. Réplicas fixas vs HPA

# before: two fixed replicas
kubectl -n boxoffice delete hpa catalog
kubectl -n boxoffice scale deployment catalog --replicas=2
k6 run -e PEAK=1000 load/catalog-hpa.js

# after: the HPA
kubectl apply -k k8s/overlays/local
mkdir -p results && sh scripts/watch-hpa.sh > results/lab10-hpa.csv &
k6 run -e PEAK=1000 load/catalog-hpa.js
kubectl -n boxoffice get hpa catalog -w  # until REPLICAS is 2 again (minutes after k6 ends), then Ctrl+C
kill %1                                  # stop the watcher

Do results/lab10-hpa.csv, leia: o momento em que a CPU passou de 60% pela primeira vez, o momento em que o desired aumentou pela primeira vez (tempo de reação), o momento em que o ready chegou ao máximo (tempo até a capacidade), o número máximo de réplicas e o momento em que o desired voltou a 2 (scale-down). Faça um gráfico de cpu, desired e ready ao longo do tempo — uma planilha basta — e adicione-o aos seus resultados.

Forma esperada (ilustrativa)

Uma execução com PEAK=1000 num laptop (kind, 3 nós dividindo 8 CPUs), começando com pods aquecidos, amostrada do CSV:

t (min:s) CPU (% do request) desired current ready
0:00 3 2 2 2
1:48 63 2 2 2
2:03 79 3 2 2
2:34 123 5 3 3
3:33 247 8 6 4
4:05 109 8 8 3
5:37 131 8 8 5
7:31 220 8 8 8
10:26 13 7 8 7
13:00 4 2 3 2

Os dois pods aquecidos passaram de 60% 1:48 depois do início da rampa (cerca de 600 req/s); o HPA pediu um terceiro pod 15 s depois e oito em 3:33, mas o oitavo pod só ficou pronto em 7:31, quando o patamar já tinha acabado. Num laptop, as JVMs novas sobem nas mesmas CPUs que servem a carga e rodam o k6: cada uma levou mais de um minuto para iniciar e, ainda fria, falhou a readiness probe de vez em quando por um tempo (o ready desce além de subir). O k6 reportou p95 de 5–7 s, p99 ≈ 19 s, 0,3% de erros e descartou mais de 40% das chegadas. A mesma rampa com duas réplicas fixas deu p95 ≈ 34 ms, p99 ≈ 180 ms e nenhum erro: os dois pods aquecidos usaram cerca de 300m cada, muito abaixo do limite de 1 CPU, então neste laptop o scale-out custou mais CPU do que acrescentou. Depois que a carga caiu (8:00), os pods saíram um de cada vez, após a janela de estabilização de 2 minutos, e voltaram a 2 réplicas em 13:00. Num cluster real os nós não são compartilhados com o gerador de carga e nós novos trazem as próprias CPUs, mas a forma — um atraso entre a demanda e a capacidade pronta — é a mesma; esse atraso é o que o pré-escalonamento elimina.

B. Rolling update sob carga

Mantenha uma carga constante rodando (o script do k6 do lab 8 funciona como está) e reinicie o Deployment no meio:

k6 run -e RATE=100 -e DURATION=2m load/catalog-otel.js &
sleep 30 && kubectl -n boxoffice rollout restart deployment/catalog
wait                                     # until k6 ends; note http_req_failed

Agora remova a readiness probe e a pausa do preStop, espere essa mudança entrar e repita:

kubectl -n boxoffice patch deployment catalog --type=json -p '[
  {"op": "remove", "path": "/spec/template/spec/containers/0/readinessProbe"},
  {"op": "remove", "path": "/spec/template/spec/containers/0/lifecycle"}]'
kubectl -n boxoffice rollout status deployment/catalog
k6 run -e RATE=100 -e DURATION=2m load/catalog-otel.js &
sleep 30 && kubectl -n boxoffice rollout restart deployment/catalog
wait                                     # until k6 ends; note http_req_failed
kubectl apply -k k8s/overlays/local      # restore the probes and the preStop pause

A startup probe continua mantendo um pod novo fora do Service até a JVM responder; o que muda é a outra ponta: sem a pausa do preStop, os pods antigos param de aceitar conexões enquanto ainda estão nas listas de endpoints do Traefik. Conte as requisições com falha (http_req_failed) nas duas execuções. Numa execução de teste: 0 requisições com falha com as probes, cerca de 140 de 11.900 (1,2%, 502 e 504 do Traefik) sem elas.

C. Autocura

kubectl -n boxoffice delete pod -l app=catalog --wait=false; date +%T
kubectl -n boxoffice get pods -l app=catalog -w        # note the time both are 1/1 again

Repita com docker stop boxoffice-worker2 (uma falha de nó) e compare: o que domina cada tempo de recuperação — detecção, agendamento ou inicialização da JVM?

Resultados

Copie para results/lab10.md e preencha.

Métrica Antes Depois
A · Vazão no pico (req/s) — 2 fixas vs HPA
A · p50 (ms)
A · p95 (ms)
A · p99 (ms)
A · Taxa de erro (%)
A · Máximo de réplicas / tempo até o primeiro scale-up (s) / tempo até a capacidade total (s) —
A · Tempo do fim da carga até voltar a 2 réplicas (s) —
B · Requisições com falha durante um rollout — sem probes vs probes + preStop
C · Pod apagado → pronto de novo (s) —
C · Nó parado → pods prontos em outro lugar (s) —

Abaixo da tabela: para a venda relâmpago do BoxOffice às 10:00, você confiaria no HPA, faria pré-escalonamento ou os dois? Use os seus números de tempo de reação para justificar.

Voltar à visão geral Quiz