cozystack/hack
Aleksei Sviridkin 3977aef509
feat(monitoring): add GPU observability dashboards and recording rules (#2418)
## What this PR does

Adds GPU observability to Cozystack: five Grafana dashboards, a set of
VictoriaMetrics recording rules with a throttle-regression alert, and
reference manifests for wiring the NVIDIA GPU Operator and DCGM Exporter
on Talos when running GPU workloads directly in pods.

### Components

1. **Dashboards** — `dashboards/gpu/*.json`, registered in
`packages/system/monitoring/dashboards-infra.list`. All follow the
project convention: the Prometheus data source is selected through the
`$ds_prometheus` template variable.

- `gpu-performance` — per-GPU utilization (NVML, tensor pipe, graphics
engine, memory copy), VRAM, power, temperature, and health (XID errors,
power/thermal throttling). All metrics are shown per-GPU, filterable by
the `$Hostname` selector.
- `gpu-fleet` — cluster-wide inventory, capacity, utilization, and
per-node power draw as percentage of TDP.
- `gpu-tenants` — per-namespace allocation and 24-hour GPU-hour/kWh
accounting; utilization and power are shown per-node (DCGM cannot
attribute hardware metrics to namespaces).
- `gpu-quotas` — allocated vs. requested GPUs, pending pods, and a
per-namespace requests/limits table. All counts derive from the
`namespace:gpu_count:allocated` recording rule, which excludes
`Failed`/`Succeeded` pod carryover.
- `gpu-efficiency` — cluster and per-GPU efficiency: tensor saturation,
util-per-watt, and per-GPU power/thermal throttle fractions.

2. **Recording rules and alert** —
`packages/system/monitoring-agents/alerts/gpu-recording.rules.yaml`.
Four rule groups:

- `gpu.recording.cluster.1m` — cluster-wide totals consumed by overview
panels.
- `gpu.recording.node.1m` — per-node hardware aggregates (grouped by
`Hostname`) plus per-namespace allocation counts from kube resource
requests; filters `cozy-*`/`kube-*`.
- `gpu.recording.efficiency.1m` — per-GPU tensor saturation and
util-per-watt, plus per-GPU power/thermal throttle fractions bounded via
`clamp_max(..., 1)`.
- `gpu.recording.throttle.validation.5m` — houses the
`GPUThrottleFractionOverOne` warning alert that fires if the pre-clamp
throttle fraction exceeds 1.0. This guards against DCGM counter-unit
drift between GPU families; the `/1e9` divisor is verified on NVIDIA A10
with DCGM 3.x.

Rules are safe on clusters without DCGM — they evaluate to empty series
when no matching metrics are scraped.

3. **Reference manifests** under
`packages/system/gpu-operator/examples/`. These are **not** templates;
they document one working configuration:

- `values-native-talos.yaml` — Cozystack Package values for the
native-pod scenario.
- `dcgm-custom-metrics.yaml` — ConfigMap extending the DCGM CSV with
profiling, ECC, throttling, and energy counters used by the dashboards
and recording rules.
- `nvidia-driver-compat.yaml` — DaemonSet that stages
`libnvidia-ml.so.1` and `nvidia-smi` from the Talos glibc tree into a
location the GPU Operator validator inspects. Workaround for
[NVIDIA/gpu-operator#1687](https://github.com/NVIDIA/gpu-operator/issues/1687).
Requires `pod-security.kubernetes.io/enforce: privileged` on the target
namespace when the cluster enforces baseline/restricted
PodSecurityStandards.
- `README.md` — explains the two deployment paths (sandbox vs. native),
which DCGM metrics each dashboard depends on, and how the pieces fit
together.

4. **Cross-validation test** — `hack/check-gpu-recording-rules.bats`
enforces that every recording-rule reference in tracked dashboards
resolves, and that every DCGM metric referenced by the rules is declared
in either the upstream default CSV snapshot
(`hack/dcgm-default-counters.csv`) or the custom CSV shipped under
`examples/`.

### Why reference manifests, not templates

The out-of-the-box `packages/system/gpu-operator/values-talos.yaml`
targets **sandbox workloads** — GPUs passed through to KubeVirt VMs via
VFIO, driver disabled on the host, device plugin disabled. That is the
sensible default for Cozystack today.

Running GPU workloads directly in pods on Talos is also possible but
requires a different configuration that makes assumptions not every user
shares:

- the NVIDIA Talos system extension must be installed on GPU nodes,
- the operator's own driver and toolkit components must be disabled
because the extension provides them,
- the validator's hardcoded paths need a workaround until
NVIDIA/gpu-operator#1687 lands upstream.

Shipping those as active templates would silently impose those
assumptions. Shipping them as reference files next to the package lets
operators opt in with eyes open and understand the moving parts before
applying them.

### Scope note

The dashboards and recording rules are useful independently of the
reference manifests — any cluster that scrapes DCGM Exporter (however it
is installed) will populate them. The reference manifests are
self-contained and do not change any default behavior of the
`gpu-operator` package.

### Screenshots

<img width="2824" height="1055" alt="2026-04-27_12-36-52"
src="https://github.com/user-attachments/assets/71f85de7-1c80-4817-b36c-aeb1c2bdd39a"
/>
<img width="2913" height="1255" alt="2026-04-27_12-36-39"
src="https://github.com/user-attachments/assets/7a54daca-0727-4510-938c-080d31bdc229"
/>
<img width="2932" height="1251" alt="2026-04-27_12-36-30"
src="https://github.com/user-attachments/assets/f6c6c215-3d05-400c-b21c-29f267c93f23"
/>
<img width="2864" height="1222" alt="2026-04-27_12-36-00"
src="https://github.com/user-attachments/assets/e9d34bab-ade5-434b-92c3-f36712cf68d9"
/>
<img width="2958" height="1226" alt="image"
src="https://github.com/user-attachments/assets/0047a5f8-12a5-4cda-8676-041de139cb76"
/>


### Release note

```release-note
feat(monitoring): add GPU observability — five Grafana dashboards (performance, fleet, tenants, quotas, efficiency), VictoriaMetrics recording rules with a throttle-regression alert, and reference manifests under packages/system/gpu-operator/examples/ for running GPU workloads natively in pods on Talos.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added five GPU dashboards for performance, efficiency, fleet overview,
quotas/allocation, and tenant usage (utilization, power, throttling,
allocation, billing).
* Added cluster recording rules and a throttling validation alert; new
Prometheus-derived metrics and per-GPU rankings/timeseries.

* **Documentation**
* Added GPU Operator examples and README documenting native Talos setup
and required DCGM counters.

* **Tests**
* Added validation tests ensuring dashboard ↔ recording-rule and DCGM
metric consistency.

* **Chores**
  * Registered new GPU dashboards in infra listings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-28 22:42:01 +03:00
..
e2e-apps fix(kubernetes): history guard non-empty check + nits from review 2026-04-16 21:50:10 +03:00
admin-kubeconfig-invariant.bats fix(kubernetes): history guard non-empty check + nits from review 2026-04-16 21:50:10 +03:00
boilerplate.go.txt Introduce cozystack-controller (#560) 2025-01-09 12:24:51 +01:00
cdi_golden_image_create.sh [vm-default-images] Added new optional package 2026-04-14 19:59:19 +05:00
check-gpu-recording-rules.bats docs(monitoring): comment bats regex rule-name convention 2026-04-19 11:10:43 +03:00
check-host-runtime.bats test(hack): assert sudo prefix in single-service HINTs, explicit exit code, and glob regression 2026-04-11 14:36:58 +03:00
check-host-runtime.sh fix(hack): wrap du in 'timeout 5s' to prevent preflight stall 2026-04-11 17:07:35 +03:00
check-optional-repos.sh Rename cozypkg to cozyhr 2025-12-25 16:54:22 +01:00
check-readiness.sh Added check-readiness.sh script 2026-03-29 13:16:35 +05:00
collect-images.sh [dx] Refactor collect-images functionality 2025-07-03 14:26:56 +03:00
common-envs.mk fix(build): filter git describe to match only v* tags 2026-04-13 14:25:25 +02:00
cozyreport.sh [ci] Cozyreport improvements 2026-02-11 17:09:47 +03:00
cozytest.sh [tests] Add pre-cleanup, fix port-forward race, fix temp leak 2026-03-23 17:25:01 +03:00
dcgm-default-counters.csv fix(monitoring): close DCGM coverage gap for gpu-fleet TDP panel 2026-04-18 06:55:17 +03:00
download-dashboards.sh Add monitoring for NATs 2026-02-17 22:54:12 +01:00
e2e-install-cozystack.bats test(api): address review round 4 findings 2026-04-12 14:17:12 +03:00
e2e-prepare-cluster.bats [ci] Run e2e tests on shared runners 2026-01-20 22:13:16 +01:00
e2e-test-openapi.bats [apps] Refactor apiserver to use typed objects and fix UnstructuredList GVK 2025-12-01 22:06:23 +01:00
helm-unit-tests.sh [ci,dx] Add unit tests for cozy-lib 2025-11-19 17:56:17 +03:00
migrate-to-version-1.0.sh Fixed packages name conversion in migration script 2026-03-03 19:10:39 +05:00
package.mk refactor: move scripts to hack directory 2026-01-15 16:06:56 +01:00
pre-checks.sh Fix osx grep have no -P flag (#438) 2024-10-21 11:59:56 +02:00
remediation-guard.bats test(hack): rename remediation-guard bats test to match what it pins 2026-04-16 22:32:24 +03:00
update-codegen.sh [docs] Fixed controller-gen markers 2026-03-25 15:57:25 +05:00
update-crd.sh refactor(labels): remove cozystack.io/ui label 2026-01-19 13:59:29 +01:00
upload-assets.sh [docs] Added openapi generation tool 2026-03-25 15:57:25 +05:00
upload-releasenotes.sh Add AI-agent for changelogs generation 2025-11-26 20:18:43 +01:00