kubernetes_sd_config scrape targets ignoring NetworkPolicy isolation
0 reputation · 12 Jun 2020, 02:34 UTC
0 reputation · 12 Jun 2020, 02:34 UTC
I want Prometheus (assume a recent 2.x release) running inside a Kubernetes cluster to scrape only pods it can actually reach. My cluster uses NetworkPolicy to isolate several namespaces, and I want the target list to reflect that isolation without hand-maintained relabel rules for every policy change.
From my reading of the kubernetes_sd_config documentation, discovery only watches the API server for pods, services, endpoints, and nodes. I can find no documented option or relabel action that consults NetworkPolicy objects, so pods in policy-isolated namespaces still appear as targets and then fail on connection timeouts.
This creates noisy down-targets, wasted scrape attempts, and confusion when dashboards show targets as unhealthy that are intentionally unreachable. Manually writing relabel_configs keyed on namespace labels works only if every team labels namespaces consistently with their policy intent.
30775 reputation · 12 Jun 2020, 06:25 UTC
No — kubernetes_sd_config has no supported way to read NetworkPolicy objects, and there is no relabel action that consults them. Service discovery only watches the API server for pods, services, endpoints, and nodes. Filtering targets to match your network isolation is intentionally your job, via relabel_configs keyed on labels or annotations. This answer assumes a recent Prometheus 2.x release; verify against your version's configuration reference.
Discovery answers "what exists in the API?", not "what can I reach?". NetworkPolicy is enforced by your CNI plugin at the network layer, and the API server happily returns endpoints for pods Prometheus cannot connect to. So isolated pods stay in the target list and show as down on connection timeout — expected behavior, not a bug.
Since there is no automatic mapping from NetworkPolicy intent to labels, pick one explicit, team-owned convention and enforce it in CI or admission control:
monitoring.example.com/scrape=allowed|denied. Prometheus joins pod metadata to namespace metadata automatically (__meta_kubernetes_namespace_label_*), so pods inherit the decision.relabel_configs:
- source_labels: [__meta_kubernetes_namespace_label_monitoring_example_com_scrape]
regex: allowed
action: keepallowed whose NetworkPolicy actually blocks scraping. Mitigate by generating both the NetworkPolicy and the namespace label from the same source (Helm values, a GitOps template, or an admission webhook that rejects namespaces missing the label). Treat the label as documentation of intent, not proof of reachability — the up metric remains the ground truth.Yes: a target that becomes unreachable stays in the list (failing) until the next discovery refresh, because the pod itself hasn't changed — only the network path has. The watch-based SD usually picks up metadata changes quickly, but nothing in a NetworkPolicy change triggers a target update, because SD never saw the policy in the first place. If you filter by labels, the target only disappears when the label changes.
You can tune how often Prometheus re-lists resources, but be conservative: aggressive refresh intervals increase load on the Kubernetes API server and on Prometheus itself. Only lower it (for example toward 30s) after measuring API server latency and Prometheus CPU, and prefer fixing the label convention over speeding up polling.
up{job="your-job"} and confirm the target flips to 0 — that confirms the failure is reachability, not discovery.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.