Componentes da Plataforma v2
Notificações
SLO e SLA
Aprovações
Multi-Cluster
Auditoria
Chaos Engineering
Motor de Decisão
Capacity e Custos
Web Dashboard
REST API e Dashboard
O operator expõe uma API REST HTTP na porta8090 (valor api.port do chart, env CHATCLI_AIOPS_PORT), acessada pelo Service chatcli-operator no namespace do operator (não pelo Service da Instance). São mais de 40 endpoints cobrindo incidents, AI insights, remediações, runbooks, aprovações, SLOs, post-mortems, analytics (incluindo custo de LLM), clusters, federação, políticas e auditoria. Um Web Dashboard embutido é servido em / na mesma porta.
- Autenticação: header
X-API-Key. As chaves vêm do Secretchatcli-operator-secrets, chaveapi-keys(fallback: ConfigMapchatcli-operator-config), no namespace do operator, como uma lista YAML de{key, role, description}. Os papéis sãoviewer<operator<admin; qualquer outro valor de role é negado. Alterações são aplicadas em cerca de 30 segundos; uma entradaapi-keysque não é YAML válido mantém em vigor o último conjunto de chaves válido, e um Secret sem a entrada cai para o ConfigMap. Crie-o você mesmo, ou deixe o chart do operator renderizá-lo (apiKeys.create: truecomapiKeys.entries). Sem chaves configuradas, toda chamada em/api/retorna401, a menos queCHATCLI_OPERATOR_DEV_MODE=true(admin sem chave, só para desenvolvimento). - Rate limit: 30 requisições por minuto por host de cliente sem API key válida, 600 por minuto por chave válida (
429comRetry-After). - CORS: deny-all, a menos que
CHATCLI_CORS_ALLOWED_ORIGINS/CHATCLI_CORS_ORIGINestejam definidos. TLS: definaCHATCLI_AIOPS_TLS_CERTeCHATCLI_AIOPS_TLS_KEYpara servir HTTPS (TLS 1.3). - Preview local:
make dash-previewemoperator/serve o dashboard com dados sintéticos, sem cluster, emhttp://127.0.0.1:8085com a API keypreview.
replicaCount > 1 funciona atrás do Service sem fixar as requisições na líder.deploy/grafana/. O dashboards-configmap.yaml de lá traz só os dois ServiceMonitors (operator e servidor, este selecionando app.kubernetes.io/name: chatcli), não os dashboards: crie o ConfigMap nomeando cada arquivo JSON (veja Web Dashboard) ou importe os JSONs manualmente.
Visão Geral do Pipeline
Componentes Internos
1. WatcherBridge (watcher_bridge.go)
O WatcherBridge é o ponto de entrada do pipeline. Implementa a interface manager.Runnable do controller-runtime e roda como goroutine gerenciada pelo manager.
Responsabilidades:
- Sem componente temporal: Um problema contínuo (e.g. CrashLoopBackOff) gera apenas uma Anomaly
- UID do recurso: um workload apagado e recriado ganha outro UID, então seus alertas não são engolidos pela entrada antiga
- TTL: 30 minutos por padrão (Instance
spec.aiops.dedupTTLMinutes, 5–1440) — hashes expirados são podados automaticamente - Invalidação: Quando um Issue é resolvido, contido ou escalado, as entradas de dedup para o recurso afetado são invalidadas, permitindo detecção imediata de recorrências
- Resultado: Evita duplicatas durante problema ativo; detecta recorrência após resolução
Lista Instance CRs no cluster inteiro
Seleciona o primeiro Instance com Status.Ready=true
Conecta via gRPC com TLS 1.3
dns:///<nome>.<namespace>.svc.cluster.local:<porta>, com credencial e CA tirados do spec da Instance. O TLS é obrigatório: a Instance precisa de spec.server.tls.enabled: true e de um certificado válido para esse nome.Retry
2. AnomalyReconciler (anomaly_controller.go)
Observa Anomaly CRs e os correlaciona em Issues.
Fluxo:
Recebe Anomaly CR
Status.Correlated = false.Anexa a um Issue ativo
Verificações de supressão
spec.aiops.resolutionCooldownMinutes, padrão 10; 0 desliga o cooldown) ou quando o noise reducer a marca (repetitiva, flapping, sazonal).Agrupa anomalias e calcula risk score e severidade
CorrelationEngine.FindRelatedAnomalies() para as anomalias não correlacionadas do mesmo recurso nos últimos 10 minutos.Cria o Issue CR
<recurso>-<sinal>-<unix time>, com os labels platform.chatcli.io/inc-id (INC-YYYYMMDD-NNN), platform.chatcli.io/resource e platform.chatcli.io/signal.Marca Anomaly como correlacionada
Correlated = true com referência ao Issue.3. CorrelationEngine (correlation.go)
Motor de correlação que agrupa anomalias em incidentes.
Algoritmo de Correlação:
pod_restart (25) + memory_high (15) = risk 40 → Medium. Somando error_rate (30) = risk 70 → High. Um Issue aberto por uma anomalia oom_kill é Critical qualquer que seja o score.
Mapeamento de Fonte: a source do Issue espelha a da Anomaly (watcher, prometheus, events, logs, webhook); uma source desconhecida vira prometheus.
4. IssueReconciler (issue_controller.go)
Gerencia o ciclo de vida completo de um Issue através de uma máquina de estados.
Estados e Transições:
Contained significa que o plano silenciou o workload (por exemplo ScaleDeployment para 0 com containment=true) sem corrigi-lo: o Issue carrega status.requiresHumanAction: true e status.requiredAction, e só vai para Resolved quando o workload é restaurado. Issues Escalated são reavaliados a cada 30 segundos e se auto-resolvem quando o recurso volta a ficar saudável, a menos que a Instance defina spec.aiops.enableAutoResolve: false. A checagem de saúde entende Deployments, StatefulSets, DaemonSets, Jobs (saudáveis quando Complete) e Nodes (saudáveis quando Ready); um Issue em qualquer outro kind não é auto-resolvido. Failed é terminal.
As configurações de AIOps (spec.aiops) vêm da Instance que o WatcherBridge usa: o WatcherBridge marca cada Anomaly com platform.chatcli.io/instance e platform.chatcli.io/instance-namespace, o Issue herda esses labels e, sem eles, vale a primeira Instance pronta.
handleDetected()
handleDetected()
- Define
detectedAtemaxRemediationAttempts(padrão: 5, configurável via Instanceaiops.maxRemediationAttempts; lido da Instance que o WatcherBridge usa) - Cria AIInsight CR
<issue>-insightcom owner reference (Issue → AIInsight), anotado com os Runbooks candidatos - Transiciona para
Analyzing - Roda as verificações de federação (detecção de cascata, correlação cross-cluster), em best effort
- Requeue após 10 segundos
handleAnalyzing()
handleAnalyzing()
- Verifica se AIInsight tem
Analysispreenchida - Busca Runbook manual correspondente (
findMatchingRunbook— tiered matching) - Se encontrou Runbook manual →
createRemediationPlan()(manual tem precedência) - Se não encontrou Runbook manual mas AIInsight tem
SuggestedActions→generateRunbookFromAI()→createRemediationPlan()usando o Runbook auto-gerado - Se nenhum →
createAgenticRemediationPlan()(AgenticMode=true, sem ações pré-definidas — a IA decide cada passo) - Transiciona para
Remediating
findMatchingRunbook() -- Matching em camadas
findMatchingRunbook() -- Matching em camadas
- Tier 1: SignalType + Severity + ResourceKind (match exato, preferido)
- Tier 2: Severity + ResourceKind (fallback quando signal não bate)
SignalTyperesolvido de:issue.Spec.SignalType→ fallbackissue.Labels["platform.chatcli.io/signal"]- Os Runbooks são buscados em todos os namespaces, não só no do Issue: primeiro o namespace do Issue, depois os demais, cada Runbook uma vez
generateRunbookFromAI()
generateRunbookFromAI()
- Materializa
SuggestedActionsdo AI como Runbook CR reutilizável - Nome:
auto-{signal}-{severity}-{kind}-{hash}(sanitizado;hash= 6 primeiros caracteres hex do SHA256 da análise, então causas raiz diferentes geram Runbooks diferentes) - Labels:
platform.chatcli.io/auto-generated=true - Trigger: SignalType + Severity + ResourceKind (para reutilização futura)
- Usa
CreateOrUpdatepara idempotência
handleRemediating()
handleRemediating()
- Busca RemediationPlan mais recente (
findLatestRemediationPlan) - Se
Completed→ IssueResolved(ouContainedquando o plano aplicou uma ação de contenção) + PostMortem CR (timeline, causa raiz, impacto, lições) + invalida dedup do recurso- Se plano agêntico: também gera um Runbook reutilizável dos passos bem-sucedidos
- Se
Failede tentativas restantes → re-análise: coleta evidência de falha (collectFailureEvidence), limpa análise do AIInsight, volta para estadoAnalyzingcom failure context - Se
Failede max tentativas →Escalated+ invalida dedup do recurso
- Cada retry dispara re-análise do AI com contexto de falhas anteriores
- O AI recebe
previous_failure_contextcom evidência das tentativas que falharam - O prompt instrui: “Não repita as mesmas ações. Analise por que falharam e sugira uma abordagem fundamentalmente diferente”
- Gera um novo Runbook auto-gerado quando a nova análise é diferente (o nome carrega um hash da análise)
5. AIInsightReconciler (aiinsight_controller.go)
Observa AIInsight CRs e chama o AnalyzeIssue RPC para preencher a análise.
Fluxo:
Verifica análise existente
Status.Analysis já está preenchida (skip se sim).Verifica conectividade
Busca contexto
Coleta contexto K8s
KubernetesContextBuilder (deployment, pods, eventos, revisões).Lê failure context
platform.chatcli.io/failure-context (se re-análise).Monta request
AnalyzeIssueRequest com dados do Issue + contexto K8s + failure context.Chama AnalyzeIssue RPC
AnalyzeIssue RPC via ServerClient.Preenche status
Status.Analysis, Confidence, Recommendations, SuggestedActions. Limpa annotation failure-context após re-análise concluída.k8s_context.go):
Coleta contexto real do cluster para Deployments, StatefulSets, DaemonSets, Jobs, CronJobs e HPAs (max 15000 chars):
- Resource Status: replicas, conditions, containers, images + resources (cada tipo tem context builder dedicado)
- StatefulSet: replicas, update strategy, partition, PodManagementPolicy, VolumeClaimTemplates
- DaemonSet: desired/current/ready/available/unavailable, nodeSelector, tolerations
- Job/CronJob: active/succeeded/failed, completions, parallelism, schedule, lastSuccessful
- HPA: min/max replicas, current/desired, target utilization, current metrics, maxed-out detection
- Pod Details (até 5 pods, unhealthy primeiro): phase, restart count, container states
- Recent Events (últimos 15): tipo, reason, message, count
- Revision History: Últimas 5 revisões (ReplicaSets) com diff de imagens
log_analyzer.go):
Análise avançada de logs de aplicação (além do tail básico de 50 linhas):
- Stack Trace Extraction: detecta e extrai stack traces de Java (Exception/Caused by), Go (panic/goroutine), Python (Traceback), Node.js (Error at)
- Error Pattern Detection: 24+ padrões críticos categorizados (crash, connectivity, dns, auth, storage, tls, database, cache, messaging)
- Structured Log Parsing: extrai error/warn entries de logs JSON (campos level, msg, error, timestamp, logger)
- Init Container Logs: analisa logs de init containers (revela falhas de startup)
- Sidecar Logs: analisa logs de sidecars (istio-proxy, envoy, datadog-agent, etc.)
- Critical Lines: extrai linhas FATAL/PANIC com 3 linhas de contexto antes/depois
- Temporal Window: busca logs por janela temporal (10min antes do incidente), não apenas tail
metrics_collector.go):
Queries ao Prometheus para dados quantitativos durante análise:
- CPU/Memory: usage trends 30min antes → durante → 15min depois do incidente
- Request/Error Rate: HTTP requests e 5xx por segundo
- Latency: P50, P95, P99 histogram percentiles
- HPA Metrics: current vs desired replicas, CPU target
- Network: receive/transmit bytes/s
- Trend Analysis: detecta spikes, drops, sustained_high/low com cálculo de % de mudança
- Habilitado via:
PROMETHEUS_URLenv var no operator
gitops_detector.go):
Detecta e integra com ferramentas GitOps:
- Helm Releases: detecta via Secrets type
helm.sh/release.v1, status (deployed/failed/pending-upgrade), chart version, revisão anterior para rollback - ArgoCD Applications: sync status (Synced/OutOfSync), health (Healthy/Degraded), conditions, last sync result
- Flux Kustomizations: ready status, source ref, conditions, last applied
source_controller.go):
Diagnóstico code-aware quando SourceRepository CRD está configurado:
- Git Correlation: encontra commits nos 30min antes do incidente
- Suspected Commit: identifica o commit mais provável (score por proximidade temporal + volume de mudanças)
- Code Extraction: extrai trechos de código referenciados em stack traces (file path + line number → código fonte)
- Config Analysis: lê Dockerfile, values.yaml, Chart.yaml para contexto de deploy
- Credenciais: chaves do Secret
token,username+password, oussh-key+known_hosts; as credenciais HTTPS passam por um helperGIT_ASKPASSe nunca são gravadas no.git/config; o SSH confere as chaves do host contra oknown_hosts(spec.sshHostKeyPolicy: acceptNewconfia na primeira chave quando o Secret não tem nenhuma). Veja Repositórios de código
cascade_analyzer.go):
Análise de cascade failures cross-service:
- Dependency Graph: descobre dependências via Services + EndpointSlices
- Temporal Correlation: encontra issues ativos no mesmo namespace e cross-namespace em janela de 15-20min
- Cascade Chain: ordena serviços por tempo de detecção (primeiro = root cause)
- Root Cause Service: identifica o serviço origem do cascade
blast_radius.go):
Predição de impacto antes da execução de ações:
- PDB Check: verifica se a ação violaria PodDisruptionBudgets
- Quota Check: verifica ResourceQuotas (>90% usado = warning)
- Node Capacity: conta pods no node para ações de cordon/drain
- Affected Services: descobre quais Services seriam impactados
- Risk Level: classifica como low/medium/high/critical
6. RemediationReconciler (remediation_controller.go)
Executa as ações definidas em um RemediationPlan.
Ações Suportadas (54 tipos, mais Custom, que é sempre rejeitado):
Deployment / Genérico (19 ações + Custom):
7. ServerClient (grpc_client.go)
Cliente gRPC compartilhado entre o WatcherBridge, o AIInsightReconciler e o RemediationReconciler.
Interação Server e Operator
RPCs StreamAlerts e GetAlerts
O servidor empurra os alertas do K8s Watcher porStreamAlerts (streaming do servidor com heartbeats; veja Modo Servidor) e continua expondo-os para leituras pontuais via gRPC:
ObservabilityStore de cada target do MultiWatcher, filtra por namespace se especificado, e retorna alertas ativos.
AnalyzeIssue RPC
O servidor recebe o contexto do Issue e chama o LLM para análise:- Contexto do Issue (nome, namespace, recurso, severidade, risk score, descrição)
- O catálogo de ações (os 54 tipos de ação, com parâmetros e regras por tipo de recurso)
- Instruções para retornar JSON estruturado com campos
analysis,confidence,recommendationseactions
- Remove markdown codeblocks (
```json ... ```) - Parseia JSON em
analysisResult - Clamp confidence entre 0.0 e 1.0
- Se parsing falhar → usa resposta raw como analysis com confidence 0.5
AgenticStep RPC
O servidor recebe o contexto do Issue, histórico de passos anteriores e contexto K8s atualizado, e decide a próxima ação:- Role + Issue details: contexto do incidente (tipo, severidade, recurso)
- Kubernetes context: estado real do cluster (refreshado a cada step via KubernetesContextBuilder)
- Tool definitions: o catálogo de ações + “Observe” (sem ação, espera próximo contexto)
- Conversation history: cada step anterior formatado com reasoning → action → observation
- Instructions: respond JSON, budget (step N of M), regras de segurança
resolved=true, a resposta inclui dados para geração do PostMortem (summary, root_cause, impact, lessons_learned, prevention_actions). Quando diverges_from_insight é true e divergence_reason está vazio, o operator registra o passo como rejeitado e não executa a ação proposta.
PostMortem Generation
Quando qualquer plano de remediação é concluído (standard ou agêntico, incluindo uma contenção que deixa o IssueContained), o IssueReconciler gera automaticamente:
PostMortem CR
Criado viageneratePostMortem(), com o nome pm-<issue> no namespace do Issue:
- Trending: detecção de incidentes recorrentes (contagem nos últimos 30 dias, PostMortems relacionados)
- Cascade Chain: cadeia de cascade failure se houver issues correlacionados cross-service
- Git Correlation: commit suspeito (SHA, autor, arquivos alterados, confiança)
- GitOps Context: estado do Helm/ArgoCD/Flux no momento do incidente
Runbook Auto-gerado (Agentic)
Criado viagenerateAgenticRunbook():
- Nome:
agentic-{signal}-{severity}-{kind}(sanitizado) - Steps: apenas os passos com ação bem-sucedida
- Labels:
auto-generated=true,source=agentic - Usa
CreateOrUpdate(reutilizado para incidentes futuros do mesmo tipo)
Prometheus Metrics do Operator
O operator expõe métricas Prometheus na porta de métricas (8080, HTTP sem TLS, path /metrics; serviceMonitor.enabled no chart cria um ServiceMonitor). As métricas do pipeline:
chatcli_operator_*, listadas nas respectivas páginas; o controller-runtime adiciona as métricas padrão de reconcile.
Testes
Os testes unitários do operator rodam sobre o client fake do controller-runtime e cobrem todos os componentes desta página:Executar Testes
operator/integration) prova o que o client fake não consegue: schemas e campos obrigatórios dos CRDs, subresource de status, owner references e controllers reagindo às escritas uns dos outros. Os cenários são uma Instance provisionando seu workload só quando há credencial configurada, uma anomalia percorrendo Anomaly → Issue → AIInsight → RemediationPlan → Deployment escalado → plano concluído → Issue resolvido → PostMortem, uma ApprovalPolicy segurando o plano até um humano aprovar, e um IncidentSLA registrando uma violação de resolução. O CI roda a suíte com KUBEBUILDER_ASSETS exportado e a conta na cobertura.
Diagrama de Ownership (Garbage Collection)
- Instance é owner dos recursos namespaced que cria (Deployment, Service, ConfigMaps, SA, PVC, Role/RoleBinding do watcher); um ClusterRoleBinding de watcher entre namespaces é removido pelo finalizer da Instance
- Issue é owner de AIInsight, RemediationPlan e PostMortem (cascade delete)
- Anomalies são independentes (não têm owner) para preservar histórico
Checklist de Implantação AIOps
Instalar Operator via Helm (CRDs + RBAC + Deployment + Dashboard)
Criar os Secrets de que a Instance precisa
- as chaves do provedor LLM (por exemplo
ANTHROPIC_API_KEY), referenciadas porspec.apiKeys.name - um token do servidor (ou material JWT): um servidor dentro do cluster escuta em
0.0.0.0e se recusa a rodar sem credencial, e o operator não cria o Deployment sem ela (AuthenticationConfigured=False) - um Secret TLS (
tls.crt,tls.key, opcionalmenteca.crt) válido para<instance>.<namespace>.svc.cluster.local: o operator sempre fala com o servidor via TLS 1.3
Criar Instance CR
chatcli-watcher (criada pelo chart).Crie uma Instance para o AIOps por cluster: o pipeline se conecta à primeira Instance pronta que encontrar, no cluster inteiro.Verificar servidor
kubectl get instances -A — READY precisa estar true; confira as conditions AuthenticationConfigured e ServerReachable com kubectl describe instance chatcli -n chatcli.Verificar pipeline AIOps
kubectl get anomalies -A— anomalias sendo detectadaskubectl get issues -A— issues sendo criadoskubectl get aiinsights -A— IA analisando
(Opcional) Habilitar o dashboard e a API REST
chatcli-operator-secrets (chave api-keys) em chatcli-system, depois rode kubectl -n chatcli-system port-forward svc/chatcli-operator 8090:8090 e abra http://localhost:8090.(Opcional) Criar Runbooks manuais
Monitorar métricas
serviceMonitor.enabled=true no chart).