Operator monitors DCA and CLC health - #3348
Conversation
6577d05 to
ed9a81e
Compare
|
ed9a81e to
2871f6a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee1ee78c3e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| } | ||
|
|
||
| func (r *ComponentHealthReconciler) setActiveGauge(key componentIssueKey, affectedPods int) { | ||
| metrics.ComponentHealthIssuesActive.WithLabelValues(key.component, key.issueType).Set(float64(affectedPods)) |
There was a problem hiding this comment.
Sum active gauge across watched namespaces
With multi-namespace or cluster-wide watches, reported is keyed by namespace but the Prometheus series is not, so this setter writes only the affected-pod count for the single namespace being reconciled. If two namespaces both have cluster-agent/component_crash_looping, the later reconcile overwrites the earlier count, and resolving one namespace can set the shared gauge to 0 while the other namespace is still affected; either include namespace in the labels or set the gauge from the aggregate across all matching keys.
Useful? React with 👍 / 👎.
| // waiting reasons like ImagePullBackOff), scheduling conditions, phase, and | ||
| // termination context. Retaining these fields is what increases cache memory, | ||
| // which is why this is gated behind ComponentHealthEnabled. | ||
| if opts.ComponentHealthEnabled { |
There was a problem hiding this comment.
Keep full pod status limited to component pods
When ComponentHealthEnabled is combined with UntaintControllerWaitForCSIDriver, the earlier branch leaves podLabel nil so CSI node-server pods can be cached, which means this unconditional copy retains full phase/conditions/container statuses for every Pod in the agent and CSI namespaces. In namespaces such as kube-system that can include many unrelated pods and defeats the memory-saving transform; gate the full status copy on the DCA/CLC component label and leave only the untaint fields for the broader cache.
Useful? React with 👍 / 👎.
Bits has a CI fix ready🟢 Investigated · 🟢 Fix prepared · ⚪ Validation skipped · 🟠 Ready
View in Datadog | Reviewed commit ee1ee78 · Any feedback? Reach out in #deveng-pr-agent |
What does this PR do?
Adds a ComponentHealth controller (beta, off by default) that watches the Datadog
Cluster Agent and Cluster Check Runner pods and reports Kubernetes-level health issues
derived from their pod status:
component_oomkilled— a container was OOMKilledcomponent_crash_looping—CrashLoopBackOff, or restarts past a threshold (default 5)component_unschedulable— podPending+ scheduler reportedUnschedulableimage_pull_failure—ImagePullBackOff/ErrImagePullDetection is per-pod but reporting is per-component: the same issue type across several
pods is a single issue instance keyed by
(namespace, component, issue_type). Issues arelogged and exposed as Prometheus metrics (
..._issues_detected_totalcounter,..._issues_activegauge). Node Agent pods are intentionally excluded. Gated behind--componentHealthEnabled/DD_COMPONENT_HEALTH_ENABLED.Motivation
Cluster-level components have no platform-level health surface today: the operator mirrors
Deploymentreplica counts but never sees pod restarts, OOMKills, scheduling failures, orimage-pull problems. This is the operator-side collection layer from the CONTP-1865 brief,
a foundation for surfacing DCA/CLC health (a backend
HealthReportemitter follows behindthe same interface).
Additional Notes
rolling restart stays one active issue instead of emit/resolve churn. Metric labels are
limited to
component+issue_typeto bound cardinality.minimalist pod-cache transform is extended only when the flag is on). Node-agent-only
deployments are unaffected.
crash_loopingcan briefly flap (emit→resolve→emit) untilrestarts cross the threshold, since
CrashLoopBackOffis only intermittently presentbetween restarts. This shows up as extra
..._detected_totalincrements; the..._activegauge reflects true current state.Minimum Agent Versions
No minimum agent versions required — the controller reads Kubernetes pod status only.
Describe your test plan
Unit:
Manual (kind) — no image build or credentials needed. Run the operator locally with
only this controller, then feed it component-labeled pods that deliberately fail:
Apply pods labeled
agent.datadoghq.com/component: cluster-agent/cluster-checks-runnerthat crash-loop (
sh -c 'sleep 2; exit 1'), OOM (tail /dev/zero,memory: 16Mi), gounschedulable (
memory: 10000Girequest), and pull a bad image — plus onecomponent: agentpod to confirm exclusion. Check the log and
curl -s localhost:8085/metrics | grep component_health.Verified on kind (k8s v1.33.1):
33 → 2, no resolve→ 0Checklist
bug,enhancement,refactoring,documentation,tooling, and/ordependenciesqa/skip-qalabel