Skip to main content

Visão Geral

A plataforma AIOps do ChatCLI gerencia incidentes (CRs Issue, nome curto iss) através de uma máquina de estados com 7 estados, e planos de remediação (CRs RemediationPlan, nome curto rp) através de uma máquina de estados com 7 estados. Entender este ciclo de vida é essencial para operadores que precisam intervir quando a remediação automática falha.

Estados do Incidente

Estado Contained — Um plano que termina depois de executar uma ação com containment: "true" (por exemplo ScaleDeployment replicas=0 containment=true) não marca o Issue como Resolved. Ele transita para Contained, que:
  • Não é terminal: só se auto-resolve quando o workload volta com réplicas desejadas > 0 e todas as réplicas prontas (verificado a cada 60 segundos). Para DaemonSet, Job ou Node, a verificação é a mesma do auto-resolve de Escalated; outros tipos ficam em Contained até serem resolvidos manualmente
  • Define status.requiresHumanAction: true e status.requiredAction no Issue, além das conditions Contained e RequiresHumanAction
  • Gera um PostMortem com requiresHumanAction: true que não pode permanecer Closed até um humano reconhecer a ação (veja abaixo)
  • É contado em analytics/summary como containedIssues e como aberto
Configure uma regra de NotificationPolicy com states: [Contained] para garantir que humanos sejam paginados quando isso acontecer.

Fluxo da Máquina de Estados

Fase de Detecção (Detected)

Quando o watcher bridge transforma um alerta do servidor em um CR Anomaly, o controller de Anomaly faz a correlação:
  1. Incidente existente — se já existe um Issue não terminal (qualquer estado exceto Resolved, Escalated, Failed) para o mesmo recurso (kind + nome + namespace), a anomalia é anexada a ele e o risk score sobe se o novo score (que conta a anomalia recém-anexada) for maior
  2. Cooldown de resolução — se um Issue do mesmo recurso foi Resolved dentro de resolutionCooldownMinutes, a anomalia é suprimida
  3. Redução de ruído — anomalias repetitivas, sazonais, intermitentes (flapping) ou com alta fadiga de alertas (score > 80) são suprimidas
  4. Pontuação de sinal — cada tipo de sinal tem um peso (oom_kill=40, error_rate=30, pod_restart=25, deploy_failing=25, latency=20, pod_not_ready=20, cpu_high=15, memory_high=15, qualquer outro sinal=10); o risk score soma todas as anomalias não correlacionadas do recurso nos últimos 10 minutos, com teto de 100
  5. Determinação da severidade — oom_kill é sempre critical; nos demais casos Critical (risk ≥ 80), High (≥ 60), Medium (≥ 30), Low (abaixo de 30)
  6. ID do incidente — formato INC-AAAAMMDD-NNN, guardado no label platform.chatcli.io/inc-id. O nome do Issue é <recurso>-<sinal>-<timestamp-unix> (ex.: payment-api-oom-kill-1773900000); a API REST e o kubectl endereçam Issues por esse nome, não pelo ID INC
  7. Máximo de tentativas de remediação — definido no primeiro reconcile a partir de aiops.maxRemediationAttempts (padrão 5). Se um runbook for selecionado depois, o maxAttempts dele substitui esse valor (veja a dica abaixo)
Escalated conta como encerrado para a correlação: enquanto um Issue está Escalated, novas anomalias do mesmo recurso abrem um novo Issue em vez de se anexarem ao escalado.
Para encontrar um Issue pelo ID do incidente:

Fase de Análise (Analyzing)

O sistema cria um CR AIInsight (<issue>-insight) para análise via IA. Na detecção, TODOS os runbooks candidatos são injetados no AIInsight (anotações platform.chatcli.io/candidate-runbooks e platform.chatcli.io/runbook-context) para validação.
  1. Descoberta de runbooks candidatos (em camadas):
    • Camada 1: runbooks com SignalType + Severity + ResourceKind
    • Camada 2: runbooks com Severity + ResourceKind e sinal diferente
    • Múltiplos runbooks podem existir por trigger (causas raiz diferentes geram runbooks diferentes)
  2. IA valida os candidatos: o LLM recebe todos os runbooks candidatos e avalia cada um contra a análise de causa raiz atual:
    • RUNBOOK_APPROVED: &lt;nome&gt; → usa aquele runbook (caminho rápido); se o nome não corresponder a nenhum candidato, usa o primeiro
    • RUNBOOK_REJECTED → ignora todos os candidatos, usa as sugestões da IA ou o modo agêntico
    • Nenhum dos dois → usa o primeiro candidato como padrão (compatibilidade)
  3. Se nenhum runbook foi selecionado e a IA sugeriu ações → gera um novo runbook a partir dessas ações e o usa
  4. Se não há runbook nem ações da IA → entra no Modo Agêntico (IA passo a passo)
  5. Cria o RemediationPlan <issue>-plan-<tentativa> e transita para Remediating

Fase de Remediação (Remediating)

Antes de executar, o controller de remediação verifica os gates de aprovação nesta ordem: uma ApprovalPolicy correspondente, depois o tier do cluster local (quando CHATCLI_OPERATOR_CLUSTER_NAME está definido) e depois o decision engine (quando CHATCLI_OPERATOR_DECISION_ENGINE=true). Um plano retido espera em WaitingApproval (veja Fluxo de Aprovação). Os gates falham fechados: se o Issue, o AIInsight ou as policies não puderem ser lidos, ou o decision engine der erro, o plano fica Pending com um Event de Warning ApprovalGateUnavailable e é tentado de novo; um plano cujo Issue sumiu falha. Em seguida o plano é executado com um loop ReAct (Reason-Act-Observe):
  1. Snapshot pré-voo do workload alvo capturado para rollback
  2. Para cada ação do plano:
    • OBSERVE — a partir da segunda ação, verifica se o recurso já está saudável. Se sim, para imediatamente sem executar as ações restantes (early exit)
    • ACT — executa a ação e registra um checkpoint
    • Se a ação falha → rollback automático para o snapshot pré-voo
  3. Verificação final de saúde (polling a cada 10 segundos, por até 90 segundos; no timeout, rollback para o snapshot pré-voo)
  4. Em caso de sucesso → Resolved (ou Contained, se uma ação de contenção rodou) + PostMortem gerado
  5. Em caso de falha → re-análise com o contexto da falha (próxima tentativa) ou escalação
Isso evita que ações contraditórias sejam executadas (ex.: AdjustResources seguido de RollbackDeployment, que desfaria o ajuste) e reduz o impacto operacional ao mínimo necessário.

Mecanismo de Retry

Quando o plano mais recente termina Failed ou RolledBack:
  • Tentativa < máximo de tentativas: a evidência de falha de todos os planos que falharam é gravada no AIInsight (anotação platform.chatcli.io/failure-context), a análise é limpa e o Issue volta para Analyzing — podendo selecionar outro runbook ou estratégia
  • Todas as tentativas esgotadas: transita para Escalated
Toda forma de um plano terminar Failed conta como tentativa falha — inclusive uma aprovação rejeitada ou expirada. Rejeitar uma aprovação, portanto, dispara uma re-análise e um novo plano (e, no fim, a escalação); não encerra o incidente.

Estado Escalated — O Que os Operadores Devem Fazer

Quando um incidente atinge Escalated, o sistema esgotou todas as opções automáticas. Veja o que acontece e o que você precisa fazer: O que o sistema faz automaticamente:
  1. Inicia a primeira EscalationPolicy habilitada que corresponde (por severities; uma política com defaultPolicy: true é o fallback) e notifica o nível 0 — ignorado para Issues induzidos por chaos
  2. Envia as notificações de qualquer regra de NotificationPolicy que corresponda ao estado Escalated
  3. Avança para o próximo nível quando o timeoutMinutes do nível atual expira, até o último nível (veja Notificações)
  4. Registra um evento de auditoria issue_escalated
  5. Continua verificando o recurso a cada 30 segundos para o auto-resolve (abaixo)
O que os operadores devem fazer:
  1. Reconhecer o incidente (registra quem está cuidando e para a escalação):
    O reconhecimento grava as anotações aiops.chatcli.io/acknowledged, -at e -by (o valor de -by é o role da API key usada, não uma pessoa; o corpo da requisição é ignorado). A escalação para no nível atual: nenhum nível a mais e nenhuma repetição, e o reconhecimento fica registrado na entrada de status.activeEscalations da EscalationPolicy. O snooze (/snooze, corpo {"duration": "1h"}, uma duração positiva) segura toda notificação exceto Resolved, e a escalação, até aiops.chatcli.io/snoozed-until; um page de escalação retido sai quando o snooze termina e o timer do nível recomeça. Veja Notificações.
  2. Investigar e corrigir o problema manualmente
  3. Resolver o incidente por um dos três métodos: Método 1: API REST (recomendado para automação/scripts; role operator)
    Sem ?namespace=, é usado o primeiro Issue com esse nome em qualquer namespace. A chamada retorna 409 se o Issue já estiver Resolved. Ela define o status e as anotações aiops.chatcli.io/resolved-by (o role), resolved-at e manual-resolution: "true". Método 2: Web Dashboard Navegue até a página de detalhes do incidente e clique no botão “Resolve”. Informe a nota de resolução no prompt (opcional). Método 3: Kubernetes Direto (avançado) — status é um subresource, então o patch precisa apontar para ele:
Uma resolução manual (REST, dashboard ou kubectl) não gera PostMortem e não limpa o cache de dedup do watcher bridge — alertas idênticos continuam deduplicados até dedupTTLMinutes expirar. PostMortems só são gerados quando um plano de remediação é concluído.

Auto-Resolve para Issues Escalados

Quando um incidente atinge Escalated, o sistema continua verificando o recurso a cada 30 segundos. Se o recurso se recuperar, o incidente é resolvido automaticamente com a mensagem:
“Auto-resolved: resource recovered while awaiting human intervention”
e as anotações aiops.chatcli.io/resolved-by: auto-resolve e aiops.chatcli.io/auto-resolution: "true". “Recuperado” depende do tipo: Issues escalados de qualquer outro tipo (CronJob, Pod, …) nunca se auto-resolvem e precisam ser resolvidos manualmente. Isso cobre os casos em que:
  • Um operador corrige o problema manualmente (kubectl rollout undo etc.) sem usar a API
  • O recurso se auto-corrige (ex.: um problema de rede transitório se resolve)
  • Um pipeline de CI/CD implanta uma correção enquanto o incidente ainda está aberto
O auto-resolve (tanto de Escalated quanto de Contained) pode ser desabilitado no Instance CRD: spec.aiops.enableAutoResolve: false. O Issue então permanece nesse estado até ser resolvido manualmente.

Parâmetros AIOps Configuráveis

Todos os parâmetros de tempo e retry são configuráveis na seção aiops do Instance CRD:
Essas configurações são lidas da Instance que o watcher bridge usa. O bridge carimba a Instance dele em toda Anomaly (labels platform.chatcli.io/instance e platform.chatcli.io/instance-namespace) e o Issue as herda, então o cooldown segue a Instance de onde veio o alerta; as demais configurações vêm da primeira Instance Ready (aquela à qual o bridge se conecta), ou da primeira Instance quando nenhuma está Ready.
Runbooks gerados pela IA (tanto padrão quanto agênticos) recebem maxAttempts = o maxRemediationAttempts da Instance. Runbooks criados manualmente via YAML ou API usam o padrão do CRD (maxAttempts: 3), a menos que especificado. Quando um runbook candidato é selecionado, o maxAttempts dele substitui o máximo de tentativas do Issue — um incidente associado a um runbook manual sem maxAttempts escala após 3 tentativas, não 5.

Estados do Plano de Remediação

Cada incidente pode ter múltiplos planos de remediação (um por tentativa, com nome <issue>-plan-<tentativa>):

Modo de Remediação Agêntico

Quando nenhum runbook corresponde e a IA não sugeriu ações, o sistema usa remediação agêntica dirigida por IA:
  1. IA propõe uma ação via RPC AgenticStep
  2. A ação é executada e o resultado é observado
  3. IA analisa a observação e propõe a próxima ação
  4. O loop continua até resolver ou até um guardrail interrompê-lo
Guardrails de segurança (qualquer um deles falha o plano):
  • Máximo de passos: 10 (configurável via aiops.agenticMaxSteps)
  • Tempo máximo: 10 minutos por plano agêntico (o detector de convergência já o interrompe aos 8 minutos)
  • Detecção de convergência (contabilizada em chatcli_operator_agentic_convergence_stops_total):
    • Últimas 3 observações idênticas → parada forçada
    • Padrão alternado de ações A→B→A→B → parada forçada
    • Últimas 5 ações falharam → parada forçada

Limiares de Confiança do Decision Engine

O decision engine vem desligado por padrão (decisionEngine.enabled: true no chart do operator, ou seja, CHATCLI_OPERATOR_DECISION_ENGINE=true). Ele só avalia planos que nenhuma ApprovalPolicy ou tier de cluster já reteve. Quando ligado, decide se um plano pode rodar automaticamente com base na confiança ajustada: Ajustes sobre a confiança do AIInsight: taxa histórica de sucesso do primeiro tipo de ação (+0.1 / +0.05 / −0.1, com pelo menos 3 planos em 30 dias), bônus por padrão aprendido, −0.05 fora de 09:00–18:00 UTC, −0.02 por Issue ativo acima de 3 (máx. −0.1) e severidade (critical −0.1, high −0.05, low +0.05). Circuit breaker: se 3+ remediações falharam ou sofreram rollback no mesmo namespace na última hora, o plano é bloqueado e espera um humano. Planos que esperam ficam retidos em um ApprovalRequest sob a política sintética decision-engine: um aprovador, 30 minutos, depois o plano falha como expirado.

Rollback Engine

O rollback engine oferece redes de segurança em dois níveis:
  1. Snapshot pré-voo — capturado antes de QUALQUER ação. Os rollbacks automáticos sempre restauram este snapshot do workload alvo.
  2. Checkpoints por ação — um snapshot registrado antes de CADA ação (para ações de node, um snapshot do node). Ficam em status.actionCheckpoints para auditoria e para a timeline do PostMortem; não são reaplicados automaticamente (não existe rollback parcial automático).
Gatilhos de rollback automático:
  • A execução da ação falha
  • A verificação de saúde expira (90 segundos)
O que um snapshot restaura:
  • Deployment: réplicas, imagens de container, recursos dos containers (e min/max do HPA)
  • StatefulSet: réplicas, imagens, recursos, partition
  • DaemonSet: imagens, recursos, max unavailable
  • Job/CronJob: suspend, deadline, backoff limit, parallelism
  • Node: estado de agendamento — suportado pelo engine, mas como o rollback automático restaura o snapshot do workload, um CordonNode/DrainNode não é desfeito automaticamente (use UncordonNode)

Tipos de Ação de Remediação

A plataforma suporta 54 ações de remediação tipadas (mais Custom, tratada como no-op que exige intervenção manual) entre os tipos de recurso:

Deployment e nível de cluster (19 ações)

ScaleDeployment, RollbackDeployment, RestartDeployment, PatchConfig, AdjustResources, DeletePod, HelmRollback, ArgoSyncApp, AdjustHPA, RestartStatefulSetPod, CordonNode, UncordonNode, DrainNode, ResizePVC, RotateSecret, ExecDiagnostic, UpdateIngress, PatchNetworkPolicy, ApplyManifest

StatefulSet (9 ações)

ScaleStatefulSet, RestartStatefulSet, RollbackStatefulSet, AdjustStatefulSetResources, DeleteStatefulSetPod, ForceDeleteStatefulSetPod, UpdateStatefulSetStrategy, RecreateStatefulSetPVC, PartitionStatefulSetUpdate

DaemonSet (7 ações)

RestartDaemonSet, RollbackDaemonSet, AdjustDaemonSetResources, DeleteDaemonSetPod, UpdateDaemonSetStrategy, PauseDaemonSetRollout, CordonAndDeleteDaemonSetPod

Job (9 ações)

RetryJob, AdjustJobResources, DeleteFailedJob, SuspendJob, ResumeJob, AdjustJobParallelism, AdjustJobDeadline, AdjustJobBackoffLimit, ForceDeleteJobPods

CronJob (10 ações)

SuspendCronJob, ResumeCronJob, TriggerCronJob, AdjustCronJobResources, AdjustCronJobSchedule, AdjustCronJobDeadline, AdjustCronJobHistory, AdjustCronJobConcurrency, DeleteCronJobActiveJobs, ReplaceCronJobTemplate

Sistema de Aprendizado de Runbooks

Falha de Node — Fluxo de Remediação

Quando um node apresenta problemas, o watcher detecta a condição e o bridge emite uma Anomaly cujo resource kind é Node:
O DrainNode faz cordon no node e então despeja os pods dele pela Eviction API policy/v1 com grace period de 30 segundos (pods de DaemonSet e mirror pods são ignorados), portanto PodDisruptionBudgets são respeitados. Um despejo recusado com 429 (um PDB) ou erro de servidor é refeito a cada 5 segundos até o param opcional timeout (uma duração Go, padrão 2m, no máximo 10m); depois disso a ação falha, citando os pods que não conseguiu despejar. Mesmo assim, exija aprovação para ações de node. O contexto do node (CPU, memória, contagem de pods, condições) é incluído na análise da IA.
A verificação de saúde e o auto-resolve entendem um alvo Node: ele está saudável quando a condition Ready está True (um cordon a mantém assim). Os snapshots de rollback só cobrem tipos de workload (Deployment, StatefulSet, DaemonSet, Job, CronJob), então um plano de node que falhou não pode ser revertido automaticamente.
A plataforma constrói uma biblioteca de estratégias aprendidas ao longo do tempo, reutilizáveis em incidentes futuros com o mesmo trigger.

Como os Runbooks São Nomeados

Runbooks gerados a partir das ações sugeridas pela IA incluem um hash (os 6 primeiros caracteres hexadecimais do SHA-256 da análise), garantindo que causas diferentes produzam runbooks diferentes:
Runbooks aprendidos com um plano agêntico bem-sucedido se chamam agentic-{sinal}-{severidade}-{tipo} (sem hash — um sucesso agêntico posterior para o mesmo trigger o sobrescreve) e mantêm só os passos que não falharam. Ambos levam o label platform.chatcli.io/auto-generated: "true".

Seleção Multi-Runbook

Quando múltiplos runbooks correspondem ao mesmo trigger (sinal + severidade + tipo), a IA recebe TODOS os candidatos e seleciona o mais apropriado:
Se nenhum dos candidatos corresponde à causa raiz atual, a IA responde com RUNBOOK_REJECTED; se ela sugerir ações, um novo runbook é criado com hash único — expandindo a biblioteca para incidentes futuros.

Ciclo de Vida do Runbook

Como os runbooks auto-* são criados antes de serem comprovados, revise a biblioteca (kubectl get rb -A -l platform.chatcli.io/auto-generated=true) e apague runbooks que levaram a tentativas falhas. Com o tempo, falhas comuns passam a ser resolvidas via runbooks (segundos) em vez de análise completa da IA (minutos).

Geração de PostMortem

Quando um plano de remediação é concluído — o Issue vira Resolved ou Contained — um CR PostMortem (pm-<issue>, nome curto pm, estado Open) é gerado contendo:
  • Timeline — eventos cronológicos da detecção à resolução
  • Causa raiz, resumo e impacto — a partir da análise da IA
  • Ações executadas — histórico completo de remediação
  • Lições aprendidas e ações de prevenção — recomendações da IA
  • Correlação com Git e contexto GitOps — mudanças recentes que podem ter causado o problema
  • Cadeia de cascata — incidentes relacionados entre serviços
  • Tendência — recorrência de incidentes semelhantes
Issues resolvidos manualmente ou por auto-resolve não ganham PostMortem. PostMortems podem ser revisados e fechados pelos endpoints Review PostMortem e Close PostMortem.

PostMortems com requiresHumanAction

Quando o Issue pai está Contained, tanto o Issue quanto o PostMortem carregam campos tipados em status:
Comportamentos garantidos:
  • Se um PostMortem com requiresHumanAction: true for colocado em Closed sem a anotação aiops.chatcli.io/human-action-acknowledged com valor verdadeiro (true, True, yes, ack, acknowledged), o PostMortemReconciler o reverte para Open (mesmo após um kubectl patch forçado)
  • Quando o auto-resolve dispara (um humano restaurou as réplicas), o controller limpa os dois campos no Issue e define a condition RequiresHumanAction: False. O PostMortem mantém a flag até a ação humana ser reconhecida
  • A API REST expõe os campos como campos de primeiro nível do item de incidente (requiresHumanAction, requiredAction, retornados tanto em spec quanto em status da resposta), para dashboards renderizarem direto sem buscar o PostMortem
Histórico do schema (v1alpha1) — Na 1.122.x esses campos ficavam em PostMortemSpec e eram null em runtime. Hoje ficam em PostMortemStatus e IssueStatus. Instalações via Helm reaplicam os CRDs automaticamente (hook de pre-install/pre-upgrade, crdUpgrade.enabled: true); com manifests crus, reaplique config/crd/bases/.
Para reconhecer a ação e desbloquear o fechamento (role operator):
A chamada REST retorna 400 se o PostMortem não exige ação humana; em caso de sucesso também limpa status.requiresHumanAction na hora. No web dashboard isso aparece como o botão “Ack Human Action” na linha do PostMortem quando requiresHumanAction=true.

Correlação com Chaos Engineering

Um Issue criado enquanto uma ChaosExperiment tem como alvo o mesmo recurso (kind, nome e namespace) — com o experimento em Running, ou até 2 minutos depois de ele ficar Completed ou Aborted — recebe automaticamente os labels:
  • platform.chatcli.io/source=chaos-experiment
  • platform.chatcli.io/chaos-experiment=<nome-do-experimento>
Esses labels alteram o comportamento da plataforma: Veja Chaos Engineering para detalhes do CR e do controller.

Integração com SLA

Cada severidade de incidente pode ter um IncidentSLA:
  • Tempo de resposta — tempo máximo da detecção até o Issue ser visto em Analyzing ou Remediating
  • Tempo de resolução — tempo máximo da detecção até a resolução (um Issue que chega a Escalated também é verificado contra ele)
  • Horário comercial — opcionalmente conta só o tempo dentro do horário comercial
  • escalationPolicyRef / notificationPolicyRef — aceitos pelo CRD, mas não lidos por nenhum controller: uma violação de SLA é registrada (status, métricas, auditoria), mas não dispara escalação nem notificações por si só
Veja SLOs e SLAs para detalhes.