The Helix Kubernetes integration ships as a single Helm chart. The part that actually takes effort is labeling workloads so the data means anything.

Installing the Helix agent on a cluster is a Helm install and a values file. The work that determines whether the resulting dashboards are useful happens afterward, in how consistently workloads are labeled.

1. Install the agent as a DaemonSet

The Helix Kubernetes agent runs one pod per node and collects node, pod, and container metrics alongside cluster events, then forwards application traces and logs it intercepts through the standard OTLP port.

helm repo add helix https://charts.helix.dev
helm install helix-agent helix/k8s-agent \
  --namespace helix-system --create-namespace \
  --set apiKey=$HELIX_API_KEY \
  --set cluster.name=prod-us-east-1

2. Label workloads with the four attributes Helix expects

The agent picks up resource attributes from pod labels automatically, but only for a specific set of keys. Without them, every pod shows up in Helix as an anonymous container instead of a named service.

# deployment.yaml
metadata:
  labels:
    helix.dev/service: checkout-api
    helix.dev/team: payments
    helix.dev/environment: production
    helix.dev/version: "{{ .Values.image.tag }}"

3. Confirm cluster metrics are flowing

Node-level metrics land within about a minute of the agent starting. Check for them directly rather than waiting on a dashboard to populate.

from metrics
| where metric.name == "k8s.node.cpu.utilization"
| where cluster.name == "prod-us-east-1"
| summarize avg(value) by node.name

4. Watch cardinality from the start

Kubernetes environments are the single most common source of a runaway cardinality bill, because pod names change on every restart. Make sure the agent is configured to use workload.name rather than the ephemeral pod.name as the primary grouping label for dashboards and alerts, and reserve pod.name for ad hoc debugging queries only.

The difference shows up fast on a cluster with autoscaling turned on. A deployment that cycles through forty pod identities in a single busy afternoon will, if grouped by pod.name, produce forty separate time series for what is really one workload, inflating both the metrics bill and the number of lines on a chart nobody can read. Grouped by workload.name instead, it stays one clean line regardless of how many times the scheduler churns pods underneath it.

  • Install the agent as a DaemonSet with the cluster name set explicitly.
  • Label every workload with service, team, environment, and version, or it shows up unnamed.
  • Verify node and pod metrics with a direct query before building dashboards on top.
  • Group by workload name, not pod name, to avoid a cardinality blowup from pod churn.