Troubleshooting Workflows
Workflow 1: Service Latency Spike
Section titled “Workflow 1: Service Latency Spike”Input:
clusternamespaceservicetime windowFlow:
service/time -> historical Pods -> owner Deployment/ReplicaSet -> Nodes -> Pod facts -> workload changes -> Node pressure -> same-node Pods -> ranked evidence bundle -> exact JSON/diff for evidenceExpected output:
10:02:45 Deployment memory limit changed 512Mi -> 384Mi10:04:11 Node ip-10-0-4-91 MemoryPressure=True10:06:12 Pod checkout-api-... Ready=False10:06:20 Container app lastState.reason=OOMKilled10:06:23 Pod restarted on ip-10-0-4-91Workflow 2: OOMKilled After Events Expired
Section titled “Workflow 2: OOMKilled After Events Expired”Question:
Which historical Pods for this service had OOMKilled around this time?Primary tables:
object_edgesobject_factsversions
Query route:
service -> Pods in time window -> object_facts(reason=OOMKilled)Then reconstruct the Pod version before and after the termination.
Workflow 3: Pod Evicted Or Rescheduled
Section titled “Workflow 3: Pod Evicted Or Rescheduled”Question:
Did an affected Pod move Nodes or get evicted?Signals:
object_edges(edge_type=pod_on_node)object_facts(reason=Evicted)- Pod deletion and recreation with new UID
Output should distinguish:
- same Pod assigned to a Node,
- deleted and recreated Pod with same name pattern,
- ReplicaSet created replacement Pod,
- eviction event mirrored before expiration.
Workflow 4: Brief Deployment Misconfiguration
Section titled “Workflow 4: Brief Deployment Misconfiguration”Question:
Was the Deployment briefly configured incorrectly and then fixed?Signals:
object_changes(change_family=spec)- rollout facts
- ReplicaSet hash changes
- Pod template image/resource/probe changes
Display:
Deployment checkout-api changed at 10:02:45spec.template.spec.containers[name=app].resources.limits.memory 512Mi -> 384MiThen show the rollback or later correction.
Workflow 5: Same-Node Noisy Neighbor
Section titled “Workflow 5: Same-Node Noisy Neighbor”Question:
Were affected Pods colocated with high-resource or unstable Pods?Flow:
affected Pods -> Nodes during time window -> other Pods on same Nodes -> resource request/limit facts -> restart/readiness/churn factsEvidence examples:
- batch Pod scheduled shortly before spike,
- high memory limit on same Node,
- multiple same-node Pods restarted,
- Node pressure transitioned near the spike.
Workflow 6: Current State Is Healthy
Section titled “Workflow 6: Current State Is Healthy”Question:
Everything is normal now. What was different then?Flow:
topology at incident time vs latest topologyfacts around incident time vs recent baseline factsresource version diff incident version vs latest versionThe product should explicitly show “then vs now”.
Workflow 7: Webhook Broke Deployments Briefly
Section titled “Workflow 7: Webhook Broke Deployments Briefly”Question:
Why did creates/updates fail for several minutes even though the webhook ishealthy now?Traditional investigation pain:
- admission webhook Events may be gone,
- webhook configuration may already be rolled back,
- cert-manager Certificate and Secret may have changed since the incident,
- APIService or ValidatingWebhookConfiguration status must be correlated by hand.
Kube-insight route:
failed workload event -> ValidatingWebhookConfiguration / MutatingWebhookConfiguration -> webhook service -> EndpointSlice -> webhook Pods -> Certificate / CertificateRequest / Order / Challenge -> Secret metadata and keys -> exact config/certificate version diffsExpected evidence:
10:01:03 ValidatingWebhookConfiguration webhook.cert-manager.io caBundle changed10:01:08 Certificate api-cert Ready=False reason=DoesNotExist10:01:09 Secret api-tls had keys [tls.crt,tls.key] regenerated10:02:12 Webhook Pod Ready=False10:05:44 Certificate Ready=True and webhook Pod Ready=TrueAdvantage:
- Finds webhook service and cert-manager chain from stored edges.
- Shows exact before/after webhook and Certificate versions.
- Does not need expired Events to still exist in the cluster.
Workflow 8: RBAC Change Caused Permission Loss
Section titled “Workflow 8: RBAC Change Caused Permission Loss”Question:
Which RBAC change caused the controller to lose access?Traditional investigation pain:
kubectl auth can-ionly answers current state,- RoleBinding may have been fixed before investigation,
- ClusterRole aggregation and subject references are easy to miss.
Kube-insight route:
controller Pod -> ServiceAccount -> RoleBinding / ClusterRoleBinding -> Role / ClusterRole -> rules diff -> Events and failed reconciliationsExpected evidence:
09:58:20 Role api-reader removed verb=list from pods09:58:24 RoleBinding api-reader-binding still points to Role api-reader09:59:01 Controller Event Forbidden: cannot list pods10:07:45 Role api-reader restored verb=listAdvantage:
- Shows historical permissions instead of only current permissions.
- Uses RoleBinding edges rather than scanning every RBAC object.
- Returns exact Role version diffs as proof.
Workflow 9: CRD Or Controller Upgrade Regressed Custom Resources
Section titled “Workflow 9: CRD Or Controller Upgrade Regressed Custom Resources”Question:
Did a CRD/schema/controller change break custom resources?Traditional investigation pain:
- CRD status and schema are large,
- controller Events may be noisy or expired,
- custom resources vary by group and are often missed by hardcoded collectors.
Kube-insight route:
CustomResourceDefinition -> discovered API resource -> custom resource versions -> controller Deployment / Pods -> Events and status facts -> CRD schema diffExpected evidence:
13:10:02 CRD widgets.example.com stored version changed v1beta1 -> v113:10:04 schema removed spec.endpoint13:11:31 Widget api-widget status Ready=False reason=ValidationFailed13:12:10 Controller Deployment image changed controller:v1.8.1 -> v1.9.0Advantage:
- Discovery-backed collection can watch CRDs and custom resources.
- CRD definitions are mostly preserved; only truly sensitive fields are redacted.
- Dynamic resolver maps custom GVRs without adding code for every CRD.
Workflow 10: Namespace-Scoped Collector Lost Visibility
Section titled “Workflow 10: Namespace-Scoped Collector Lost Visibility”Question:
Were objects deleted, or did our collector lose namespace/RBAC visibility?Traditional investigation pain:
- relist output cannot distinguish deletion from scope loss unless previous visibility is tracked,
- incorrect delete tombstones corrupt later history.
Kube-insight route:
latest refs before relist -> relist namespace/resource scope -> missing in-scope objects => delete tombstone -> missing out-of-scope objects => unknown visibilityExpected evidence:
pods/default/api-0 missing from default relist -> confirmed deletedpods/other/api-1 outside current namespace scope -> unknown_visibilityAdvantage:
- Avoids false delete history when permissions or namespace scope changes.
- Reports
reconciledDeletedandunknownVisibilityseparately. - Exposes per-GVR queue/backpressure to diagnose collector lag.
Evidence Ranking
Section titled “Evidence Ranking”Initial scoring inputs:
- severity,
- time proximity to incident,
- object relationship distance from service,
- number of affected Pods,
- whether change happened before symptom,
- whether a rollback happened after symptom,
- whether multiple signals agree.
Example severity:
100 OOMKilled / Evicted / Node NotReady80 Node MemoryPressure / DiskPressure70 Ready=False / CrashLoopBackOff60 Deployment resource/image/probe change40 restart count increase20 colocated high-resource PodInvestigation Result Shape
Section titled “Investigation Result Shape”{ "input": { "cluster": "staging", "namespace": "production", "service": "checkout-api", "from": "2026-05-11T10:05:00Z", "to": "2026-05-11T10:20:00Z" }, "summary": "1 affected pod had OOMKilled after a deployment memory limit change.", "evidence": [ { "ts": "2026-05-11T10:02:45Z", "severity": 60, "kind": "Deployment", "reason": "memory_limit_changed", "object_id": "..." } ], "topology": { "pods": [], "nodes": [], "workloads": [] }}The API should return structured evidence. The UI can render timelines and graphs from the same response.
Agent Query Pattern
Section titled “Agent Query Pattern”The scenario workflows above are product acceptance cases. Agents should not call scenario-specific commands. The preferred primitive is schema-guided read-only SQL:
1. call query schema to understand tables, joins, timestamps, and indexes2. use query sql to find candidate facts, changes, edges, versions, and latest docs3. fetch exact retained JSON rows only when proof is needed4. summarize the answer with object IDs, facts, changes, edges, and version IDs5. check db resources health or query search coverage before stating confidenceThe wrapper commands remain useful shortcuts:
1. search evidence by symptom text, object kind, namespace, and time window2. inspect the highest scoring object bundle3. expand topology from the object that explains the symptom4. fetch historical versions and diffs only for proof5. summarize the answer with object IDs, facts, changes, edges, and version IDsExample:
query schemaquery sql "select fact_key, fact_value, severity from object_facts order by ts desc limit 20"query search "failed calling webhook no endpoints" --from 10:00 --to 10:10query topology --kind Event --namespace flux-system --name webapp-admission-failedquery topology --kind ValidatingWebhookConfiguration --name policy-guardquery object --kind ValidatingWebhookConfiguration --name policy-guard \ --max-versions-per-object 3This is the intended advantage over kubectl: the first step can find expired
or rolled-back evidence from retained history, and later steps use indexed
relationships and exact versions instead of live cluster state only.
query search includes a lightweight coverage summary by default. Agents
should treat coverage.summary.complete=false or non-empty
coverage.summary.warnings as a confidence signal: the evidence may still be
useful, but the answer should mention stale, failed, or not-yet-started resource
streams before drawing conclusions.