Skip to content

fix(alloy): cluster the pod and cAdvisor metrics scrapes - #94

Merged
jtslear merged 1 commit into
mainfrom
skarbek/alloy-scrape-clustering
Oct 16, 2026
Merged

jtslear merged 1 commit into
mainfrom
skarbek/alloy-scrape-clustering

Conversation

@jtslear

@jtslear jtslear commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Enable clustering on prometheus.scrape "pods" and prometheus.scrape "cadvisor" in the collector config.

Review of coder/dogfood#702 (v0.8.0 bump), Linear PLE-22 (metrics gaps and Prometheus out-of-order samples): https://github.com/coder/dogfood/pull/702#discussion_r4286742478 . The review noted the cause as likely, from reading the config: https://github.com/coder/dogfood/pull/702#pullrequestreview-5538197905

Why

Alloy runs as a DaemonSet with alloy.clustering.enabled: true, but only pyroscope.scrape has a clustering block. Each Alloy pod therefore scrapes every pod and every node. remote_write drops the instance label, so every pod writes the same series, and Prometheus rejects the copies with out of order sample. This is the same on main and on the previous grafana-agent config.

Test

Using Kind for testing, the cluster has one node, so a DaemonSet gives one peer. I simulated several nodes with --set alloy.controller.type=statefulset --set alloy.controller.replicas=2. Both pods join the cluster (cluster_node_peers = 2).

Totals for both Alloy pods, from prometheus_remote_storage_samples_total and ..._failed_total:

samples/s sent failed/s failed share
main, 2 peers about 1900 about 600 about 31%
this branch, 2 peers about 1000 44 to 130 4% to 12%

Target split on this branch (prometheus_target_scrape_pool_targets):

pool alloy-0 alloy-1
prometheus.scrape.pods 8 7
prometheus.scrape.cadvisor 1 0

Each target now belongs to one peer, and all targets are still scraped (10 pods with up == 1).

Limits

  • The failures do not go to zero. I did not find the remaining source. One likely cause is that several ports of one pod give targets with the same labels, because instance is dropped (CRF-18 in the review). I did not test that.
  • A single-node kind cluster cannot show a multi-node DaemonSet. The StatefulSet test shows the same clustering mechanism.
  • Behaviour change: when an Alloy pod leaves or joins, the targets are redistributed between peers.

Notes

  • compiled/resources.yaml regenerated with make build.

Alloy runs as a DaemonSet with clustering enabled. Only
pyroscope.scrape uses it. prometheus.scrape for pods and cAdvisor has no
clustering block, so every Alloy pod scrapes every target. The
remote_write config drops the instance label, so each pod writes the
same series to Prometheus. Prometheus rejects the duplicates as out of
order samples.

Enable clustering on both prometheus.scrape components so that the pods
share the targets.
@jtslear
jtslear force-pushed the skarbek/alloy-scrape-clustering branch from 6136bf1 to 7713be6 Compare October 16, 2026 15:04
@jtslear
jtslear marked this pull request as ready for review October 16, 2026 15:28
@jtslear
jtslear requested a review from dannykopping as a code owner October 16, 2026 15:28
@jtslear
jtslear merged commit cebc711 into main Oct 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants