Runbook — Primeira instalação real do TLSStress.Art¶
Leia no seu idioma: English · Português · Español
Status do escopo (pós-congelamento de escopo 2026-05-10) — Ver ARCHITECTURE.md para os 37 MÓDULOs canônicos + 7 Test Kinds + arquitetura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cobrem adições pós-Freeze.
Sequência de onboarding: Acesso → Clone → Instalar ← você está aqui · alternativa: Instalação air-gap · setup do mantenedor: Private Repo Setup> Audiência: Operador que recebeu acesso via Access Broker e está prestes a instalar o TLSStress.Art em hardware real pela primeira vez.
Tempo estimado: ~2 horas no total. Cada passo tem tempo cronometrado.
Por que este runbook existe¶
A base de código do TLSStress.Art tem CI verde, testes unitários passando e linting limpo — mas nenhuma instalação individual foi validada end-to-end contra um Cisco Nexus 9000 + NGFW DUT real antes do operador executar isso. Este runbook é o protocolo que leva você de "UCS + Nexus zerados" até "primeiro p99 medido num painel Grafana", de forma controlada e reproduzível.
Se algum passo falhar, pare e investigue em vez de pular adiante. Falhas em cada passo têm procedimentos de recuperação específicos linkados ao final.
Pré-requisitos — antes do passo 1¶
- Acesso ao repositório concedido via Access Broker (ver ACCESS_REQUEST.pt-BR.md)
- Licença aceita através do License Acceptance Modal do Dashboard (aparece no primeiro login)
- Um host Ubuntu 22.04+ UCS com pelo menos 32 GB RAM, 16 vCPU, 200 GB disco
- Um Cisco Nexus 9000 com acesso de gerência via SSH e porta de trunk disponível
- Um NGFW DUT (Cisco FTD/ASA/Firepower, Palo Alto, Fortinet ou similar) com IP de gerência alcançável do UCS, e trunk-conectado ao Nexus
- IPs de rede reservados:
- UCS OOBI (eth0): sua rede de gerência (ex.:
192.168.90.10/24) - IP de gerência do Nexus para scrape SNMP: ex.:
192.168.90.2 - IP de gerência do NGFW: ex.:
192.168.90.3 - VLAN 20 (agentes browser engine):
172.16.0.0/16 - VLAN 30 (agentes synthetic-load engine):
172.17.0.0/16 - VLANs 101–120 (Synthetic personas):
10.1.{1..20}.0/27, gateway = NGFW - VLANs 200–209 (Cloned personas):
10.2.{1..10}.0/27, gateway = NGFW - Certificado CA do NGFW em formato PEM, disponível localmente (você vai injetá-lo como ConfigMap)
- Arquivo
.envna raiz do repo comSNMP_NEXUS_HOST,SNMP_NGFW_HOST,SNMP_COMMUNITY,SNMP_DUT_MODULE(um decisco_asa,cisco_firepower,palo_alto,fortinet,generic)
Se algum desses estiver faltando, não prossiga. O runbook depende de todos eles.
Passo 1 — Pré-flight de laboratório (60–90 minutos)¶
Objetivo: confirmar que o cluster sobe saudável com todas as 30 personas rodando, antes de qualquer envolvimento do DUT.
1.1 Clone o repositório no UCS¶
Clone autenticado — ver docs/CLONE_FOR_INSTALL.pt-BR.md para as quatro opções de autenticação. Recomendado para installs permanentes: deploy key SSH (opção B).
ssh ucs-1.example.com
mkdir -p ~/tlsstress && cd ~/tlsstress
# Opção A — gh CLI (recomendado para primeira instalação)
sudo apt update && sudo apt install -y gh
gh auth login # siga os prompts
gh repo clone nollagluiz/AI_forSE .
Esperado: diretório contém dashboard/, agent/, personas/, k8s/, platform/, docs/, etc. Tamanho total do clone em torno de 80 MB.
1.2 Instale K3s + Multus + cert-manager¶
sudo bash scripts/k8s-install.sh single-node
O script:
- Instala K3s
- Adiciona Multus CNI
- Adiciona cert-manager
- Aplica labels role=ngfw-dut e dut-data-plane=true no nó
- Configura PV hostpath se necessário
Esperado (últimas linhas):
✅ K3s up
✅ Multus instalado
✅ cert-manager pronto
✅ labels do nó aplicadas
Verificar:
kubectl get nodes
# esperado: 1 nó, status Ready, com labels visíveis via:
kubectl get nodes -o wide --show-labels | grep dut-data-plane
1.3 Aplique a stack base¶
kubectl apply -f k8s/
kubectl apply -k platform/ # Issuers cert-manager + persona-ca-issuer
kubectl apply -k personas/ # 20 Synthetic personas
Aguarde personas ficarem Ready (leva 2–5 minutos na primeira vez enquanto o seeder gera conteúdo):
watch -n 5 'kubectl get pods -A | grep persona-'
# prossiga quando 20 pods estiverem 1/1 Running com status Ready
Se uma persona ficar em Init:0/1 por mais de 5 minutos, ver Troubleshooting do Passo 1 abaixo.
1.4 Confirme que o Dashboard está alcançável¶
kubectl get svc -n web-agents dashboard
# anote o ClusterIP ou NodePort
# do UCS:
curl -sI http://<dashboard-ip>:3000 | head -5
# esperado: HTTP/1.1 302 Found (redirect para /login)
# ou via NodePort se você expôs um:
curl -sI http://<UCS-IP>:<NodePort>/login
Abra o dashboard em um browser. Esperado no primeiro carregamento: - License Acceptance Modal aparece (intercept). Preencha role + e-mail Cisco + reconhecimentos. Aceite. - Dashboard renderiza com estado vazio — sem agentes ainda. - Wordmark TLSStress.Art no canto superior esquerdo, footer de licença na parte inferior de toda página.
1.5 Confirme stack Prometheus + Grafana¶
kubectl get pods -n observability
# esperado: prometheus-0, grafana-XXX, loki-XXX, alertmanager-XXX todos Running
Abra o Grafana (default :3001). Login com admin / admin.
Esperado: - Tela de boas-vindas diz "TLSStress.Art" (após PR #190 mergear) - Lista de dashboards mostra todos os 10 dashboards prefixados com "TLSStress.Art —" - "TLSStress.Art — Personas — Overview" mostra até 30 personas vivas (20 Synthetic sempre; 10 slots Cloned quando ativos)
1.6 Checklist do Passo 1 antes de prosseguir¶
- Todas as 20 Synthetic personas em
1/1 Running - Dashboard alcançável, License Acceptance aceito, locale renderizando corretamente
- Grafana mostra 10 dashboards, nenhum "No data"
- Prometheus está fazendo scrape de todos os targets (Status → Targets, todos UP)
- Nenhum CrashLoopBackOff em
kubectl get pods -A
Se algum item falhar — não prossiga.
Passo 2 — Conexão do DUT (30 minutos)¶
Objetivo: rotear tráfego do data-plane através do NGFW, com TLS decrypt ativo.
2.1 Aplique o tuning do Nexus 9000¶
# De uma máquina com alcance ao IP de gerência do Nexus:
ssh admin@<nexus-mgmt-ip>
# No modo exec do NX-OS:
configure terminal
# Cole o conteúdo de scripts/nexus/01-apply-tuning.nxos
# Outputs esperados variam; o script desabilita EEE, define MTU 9216, aplica QoS DSCP AF41,
# e configura ECMP hash com porta UDP. Confirme com:
show running-config interface Eth1/1
# (Eth1/1 é a porta de trunk para o UCS — substitua pela sua interface)
Esperado: interface trunk mostra mtu 9216, flowcontrol receive off, flowcontrol send off.
Verifique VLANs trunked:
show vlan brief
# esperado VLANs 20, 30, 99, 101–120, 200–209 em estado active
2.2 Injete a CA do NGFW no cluster¶
# No UCS (onde você clonou o repo):
kubectl create configmap ngfw-ca \
--from-file=ca.crt=/path/to/ngfw-ca.pem \
-n web-agents \
--dry-run=client -o yaml | kubectl apply -f -
Esperado: configmap/ngfw-ca created (ou configured).
2.3 Aplique o overlay DUT¶
kubectl apply -k k8s/dut/
Isso aplica:
- 10-ngfw-ca.yaml — confirma que o ConfigMap está em vigor
- 20-network-attachments.yaml — definições NAD Multus (VLANs 20, 30, 99) com rotas apontando para o NGFW
- 60-snmp-exporter.yaml — job de scrape SNMP para o NGFW
- 70-network-policy-dut.yaml — NetworkPolicy modo DUT
- 85-node-tuning.yaml — sysctls do host (buffers UDP/TCP, BBR, FQ)
- 15-tls-decrypt-probe.yaml — probe independente de verificação de TLS decrypt (PR #180)
- 95-deployment-mode.yaml — ConfigMap deployment-mode (definido como single-node)
- 97-deployment-mode-rules.yaml + 98-topology-correlation.yaml + 99-slo-and-anomaly-rules.yaml — recording rules + alertas
2.4 Aplique os patches dos deployments de agentes¶
kubectl patch deployment web-agent -n web-agents \
--type=strategic-merge-patch \
--patch-file=k8s/dut/40-playwright-patch.yaml
kubectl patch deployment k6-agent -n web-agents \
--type=strategic-merge-patch \
--patch-file=k8s/dut/50-k6-patch.yaml
Esses patches adicionam interface macvlan net1, trust da CA do NGFW e REJECT_INVALID_CERTS=true. Pods reiniciam após o patch.
Aguarde ambos os deployments ficarem Ready:
kubectl rollout status deployment web-agent -n web-agents
kubectl rollout status deployment k6-agent -n web-agents
2.5 Verifique que o TLS Decrypt Probe concorda¶
kubectl logs -n web-agents -l app=tls-decrypt-probe --tail=20
# esperado: "decrypt mode: on" ou "decrypt mode: off" — nunca "unknown"
Abra Grafana → "TLSStress.Art — TLS Decrypt Mode — NGFW Inspection Verification". A métrica web_agent_tls_decrypt_active deve ser 1 (ativo) — significando que o NGFW está decriptando TLS com sucesso.
Se o probe disser 0 ou "unknown", não prossiga — seu NGFW não está decriptando (ou a CA está errada, ou a rota está faltando). Ver Troubleshooting do Passo 2.
2.6 Checklist do Passo 2¶
- Nexus mostra VLANs trunked, MTU 9216, flow-control off
- ConfigMap CA do NGFW aplicado
- Overlay DUT aplicado — todos os recursos em
k8s/dut/Created - Ambos patches de agente aplicados, deployments com rollout completo
- TLS Decrypt Probe reporta
active(Grafana mostra1) - Nenhum CrashLoopBackOff após o overlay DUT
Passo 3 — Smoke test (15 minutos)¶
Objetivo: rodar o plano mais leve (BASELINE-SMOKE-5M) e confirmar que os dados fluem por todo o pipeline.
3.1 Identifique planos disponíveis¶
curl -sS http://<dashboard-ip>:3000/api/test-plans/catalog | jq -r '.plans[]|.identifier'
Output esperado: 15 linhas começando com BASELINE-SMOKE-5M, BASELINE-SLO-30M, etc.
3.2 Dispare o smoke test¶
Para Fase 1 (estado atual), o trigger é via Dashboard UI. Para automação, ver a API documentada em TEST_PLANS.pt-BR.md.
Navegue para Dashboard → Test Plans → BASELINE-SMOKE-5M → Run. Confirme que o run inicia.
3.3 Acompanhe o run ao vivo¶
No Grafana, abra "TLSStress.Art — Test Plan Execution — Current Run" (após PR #190 mergear) ou "Test Plan Execution — Current Run". Observe:
- Contador de fase ativa avança pelas fases do plano
- Target da frota vs real bate com o plano
- Latência p99 começa a popular
No Dashboard, página Runs deve mostrar entradas aparecendo.
3.4 Verifique a tabela runs populando¶
kubectl exec -n web-agents <postgres-pod> -- psql -U postgres -d dashboard \
-c "SELECT COUNT(*) FROM runs WHERE started_at > now() - interval '5 minutes';"
# esperado: > 0 (depende do cycle interval; espere ~50–500 para um smoke de 5min)
3.5 Aguarde a conclusão do plano¶
BASELINE-SMOKE-5M roda por 5 minutos. Após conclusão, linha test_run_executions recebe endedAt e outcome.
3.6 Checklist do Passo 3¶
- Plano iniciou sem erros
- Painéis Grafana mostram dados live durante o run
- Tabela
runspopulou com > 50 linhas - Nenhum agente em CrashLoopBackOff durante o run
- Plano completa (status
completedna tabela executions) - TLS Decrypt Probe permaneceu
activedurante todo o run
Passo 4 — Primeira medida real (35 minutos)¶
Objetivo: um run de 30 minutos com SLO target que produza um resultado utilizável.
4.1 Rode BASELINE-SLO-30M¶
Mesmo padrão de trigger que o smoke test. Plano: BASELINE-SLO-30M. Duração: 30 minutos. Target SLO: p99 ≤ 500 ms.
4.2 Durante o run — monitore¶
Abra Grafana lado a lado: - "TLSStress.Art — Fleet Status — Deployment Aware" — confirme frota no target - "TLSStress.Art — SLO + Burn-Rate + Anomaly Detection" — confirme nenhum alerta de fast-burn disparando - "TLSStress.Art — Test-Bed Infrastructure Health" — confirme UCS não é o gargalo (CPU < 70%, mem estável) - "TLSStress.Art — Topology Correlation — Where Is the Bottleneck" — deve mostrar o NGFW (DUT) como o componente restrito, não seus agentes ou personas
Se seus agentes ou personas saturam antes do NGFW, o test bed em si é o gargalo e o resultado é sem significado. Pare e revisite o Passo 1 (aumente o UCS ou divida topologia para dual/tri/multi-node).
4.3 Após o run — colete¶
A linha test_run_executions agora tem endedAt e outcome. Faça GET /api/test-runs/<exec-id>/report.json e você tem os dados estruturados do report (após PR #185 mergear). Para Fase 1 você pode também navegar /runs/<exec-id>/report para uma página HTML print-styled.
4.4 Compare com expectativa do vendor¶
Pegue o p99 observado e compare com:
- Specs publicadas de throughput do vendor para o modelo NGFW
- Quaisquer benchmarks anteriores que o cliente tenha em arquivo
- O slo_target_p99_seconds do plano (o catálogo declara o target)
Um bom primeiro run cai dentro de ±30% da spec do vendor para shape de tráfego correspondente. Drift maior significa: problema de config do NGFW, gargalo de rede, ou um gap real de performance que vale investigar.
4.5 Checklist do Passo 4¶
- Plano completou com sucesso (
outcome: completed, nãoaborted) - Resultado p99 disponível e razoável (sem valores absurdos)
- Nenhum alerta disparou indicando self-bottleneck do test bed
- TLS Decrypt Probe permaneceu ativo durante todo o run
- Dados do report acessíveis via API + UI
- Primeira medida: documentada — capture run-id, plan-snapshot SHA-256, e p99 observado em suas notas de engagement
Troubleshooting do Passo 1¶
| Sintoma | Causa provável | Correção |
|---|---|---|
Personas presas em Init:0/1 por > 5 min |
imagem persona-seeder não baixada ou seeder crasha | kubectl describe pod <persona-pod> — verifique logs do init-container |
| Personas Pending para sempre | NAD Multus não pronto ou PV não bound | kubectl get networkattachmentdefinitions -A — verifique NADs criadas |
| Timeouts de cert-manager-webhook | webhook lento na primeira instalação | Aguarde 90 s, retry. Se persistir: kubectl rollout restart deployment cert-manager-webhook -n cert-manager |
Dashboard 502 de ingress |
Postgres não pronto | kubectl logs -n web-agents postgres-0 — aguarde "database system is ready to accept connections" |
Troubleshooting do Passo 2¶
| Sintoma | Causa provável | Correção |
|---|---|---|
TLS Decrypt Probe diz unknown |
NGFW inalcançável no data plane, ou CA errada | Verifique kubectl logs -l app=tls-decrypt-probe, valide rotas via kubectl exec numa persona e ip route, confirme gerência do NGFW está up |
TLS Decrypt Probe diz 0 (off) |
NGFW presente mas não decriptando | Verifique policy de decrypt do NGFW está habilitada, aponta para o cert certo, aplica nas interfaces relevantes |
| Macvlan não sobe | MTU de rede do host incompatível ou VLAN não trunked | nmcli / ip a no host + show interface no Nexus — MTU 9216 dos dois lados |
connection refused persistente do agente |
DNS de persona resolve para IP do NGFW mas rota não via macvlan | Verifique rota no agente: kubectl exec <agent> -- ip route get 10.1.5.10 deve mostrar net1 |
Troubleshooting dos Passos 3 / 4¶
| Sintoma | Causa provável | Correção |
|---|---|---|
Tabela runs vazia durante um run |
Agentes não estão rodando ciclos | kubectl logs -l app=web-agent — procure falhas de register ou mismatch de controller-token |
| Painel Grafana "No data" no meio do run | scrape interval > query window OU erro na query | Aguarde 30 s; se persistir, reimporte JSON do dashboard |
| Pico p99 para valor absurdo (ex.: 30s) | Algum DNS de persona inalcançável, agente time out | Verifique kubectl logs <persona-pod> e o DNS de Service da persona |
Status do plano aborted |
Operador parou o run, ou alerta de fleet readiness disparou | Leia campo outcome da linha de execução; verifique Alertmanager |
Após seu primeiro run bem-sucedido¶
- Salve as notas do engagement — run-id, plan-snapshot SHA-256, p99 observado, modelo + versão do NGFW, throughput observado.
- Tagueie o cluster se isso foi um baseline significativo:
kubectl annotate cluster <cluster> \ tlsstress.art/baseline-run="<run-id>" \ tlsstress.art/baseline-plan="BASELINE-SLO-30M" \ tlsstress.art/baseline-p99-ms="<value>" - Escolha o próximo plano baseado em objetivos do engagement:
- Encontrar capacidade →
CAP-FIND-KNEE-30M - Sustentado a 90% →
CAP-MAX-1H - Endurance →
SOAK-ENDURANCE-24H - Modos de falha →
STR-OVERLOAD-15M
Ver TEST_PLANS.pt-BR.md para guia de seleção de plano.
Relacionados¶
PRIVATE_REPO_SETUP.pt-BR.md— visibilidade do repo + branch protectionACCESS_REQUEST.pt-BR.md— como operadores ganham acesso para clonarCLONE_FOR_INSTALL.pt-BR.md— quatro opções de autenticação paragit cloneTEST_PLANS.pt-BR.md— os 15 planos do catálogoMONITORING_TEST_VALIDITY.pt-BR.md— alertas que sinalizam quando o test bed em si é o gargaloTLS_DECRYPT_MODE_VERIFICATION.pt-BR.md— probe de issuer usado no passo 2.5USAGE_POLICY.pt-BR.md— o que conta como uso autorizado durante este run