Nachzug zu #865. Der ServiceMonitor findet beide external-dns-Targets und läuft dann in einen Timeout — apps ist default-deny-ingress, der Scrape kommt nie an.
job: external-dns-unifi
scrapeUrl: http://10.244.2.218:7979/metrics
lastError: Get "http://10.244.2.218:7979/metrics": context deadline exceeded
health: down
Mein Fehler: ich habe die Namespace-Policies nicht geprüft, bevor ich den ServiceMonitor geschrieben habe. Für gitea existiert genau dieses Muster bereits (gitea-allow-metrics-scrape).
Eine Policy deckt beide Releases ab — der Chart vergibt beiden dasselbe app.kubernetes.io/name: external-dns und sie liegen im selben Namespace, auch wenn external-dns-unifi unter infrastructure/ deklariert ist.
Ohne das bleibt ExternalDNSMetricsMissing dauerhaft am Feuern und die vier Regeln darüber sind blind. Die DNS-Probes aus #865 laufen unabhängig davon und sind bereits grün.
Nachzug zu #865. Der ServiceMonitor findet beide external-dns-Targets und läuft dann in einen Timeout — `apps` ist `default-deny-ingress`, der Scrape kommt nie an.
```
job: external-dns-unifi
scrapeUrl: http://10.244.2.218:7979/metrics
lastError: Get "http://10.244.2.218:7979/metrics": context deadline exceeded
health: down
```
Mein Fehler: ich habe die Namespace-Policies nicht geprüft, bevor ich den ServiceMonitor geschrieben habe. Für gitea existiert genau dieses Muster bereits (`gitea-allow-metrics-scrape`).
Eine Policy deckt beide Releases ab — der Chart vergibt beiden dasselbe `app.kubernetes.io/name: external-dns` und sie liegen im selben Namespace, auch wenn `external-dns-unifi` unter `infrastructure/` deklariert ist.
Ohne das bleibt `ExternalDNSMetricsMissing` dauerhaft am Feuern und die vier Regeln darüber sind blind. Die DNS-Probes aus #865 laufen unabhängig davon und sind bereits grün.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The ServiceMonitor added in #865 discovers both external-dns targets and
then times out on them: the apps namespace is default-deny-ingress, so the
scrape never arrives.
lastError: Get "http://10.244.2.218:7979/metrics": context deadline exceeded
health: down
Same shape as gitea-allow-metrics-scrape, and one policy covers both
releases — the chart gives them the same app.kubernetes.io/name and they
share the namespace, even though external-dns-unifi is declared under
infrastructure/.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🤖Automated review — model CLI default (complexity: complex), commit 5f3aecb381b5906e0979ef9c6c0b0cfddc045f14.
Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.
Summary
Adds a CiliumNetworkPolicy allowing Prometheus (in the monitoring namespace) to reach port 7979 on external-dns pods in the apps namespace, which is default-deny-ingress. The fix is small, correctly scoped, and mirrors an already-proven pattern (gitea-allow-metrics-scrape) elsewhere in the repo. No blocking issues found.
🟡 Suggestions
kubernetes/apps/external-dns/networkpolicy.yaml:1-4: the header comment references monitoring-rules/external-dns-servicemonitor.yaml as already existing (from PR #865), but that file is not present anywhere in this checkout (kubernetes/apps/monitoring-rules/ has no external-dns-* ServiceMonitor, and a repo-wide grep for external-dns turns up nothing under monitoring-rules/). This is harmless either way — a CiliumNetworkPolicy doesn't depend on the ServiceMonitor existing, and Cilium policies for the same endpoint selector are additive — but it's worth confirming #865 lands (in either order) so the policy actually gets exercised; otherwise this PR is a no-op until then.
🟢 Nits
kubernetes/apps/external-dns/networkpolicy.yaml:33: the key k8s:io.kubernetes.pod.namespace: monitoring is unquoted here, while every other CiliumNetworkPolicy in the repo (gitea, paperless, woodpecker, all of infrastructure/network-policies/*, ~100+ occurrences) quotes it as "k8s:io.kubernetes.pod.namespace". It still parses fine as valid YAML (the colon isn't followed by a space), but it's inconsistent with the established convention this PR is explicitly modeled on.
Tests
No automated tests apply here — this is a declarative GitOps manifest, consistent with how the rest of the repo's CiliumNetworkPolicy resources are handled (no test suite, correctness relies on review + post-merge observation). I verified the logic statically instead of running it:
Confirmed apps namespace's default-deny-ingress (kubernetes/infrastructure/network-policies/default-deny.yaml) only allows same-namespace, home-assistant, and host/remote-node ingress — monitoring is indeed absent, matching the PR's claimed root cause.
Confirmed port 7979 matches the Prometheus target URL quoted in the PR body (http://10.244.2.218:7979/metrics) for the external-dns-unifi job.
Confirmed both HelmReleases (kubernetes/apps/external-dns/helmrelease.yaml and kubernetes/infrastructure/external-dns-unifi/helmrelease.yaml) use the same external-dns chart with no nameOverride, so both pods get app.kubernetes.io/name: external-dns regardless of the differing release names / fullnameOverride: external-dns-unifi — the single shared endpointSelector is correctly scoped to cover both releases as the author intends.
Confirmed this exactly mirrors the pre-existing gitea-allow-metrics-scrape policy in kubernetes/apps/gitea/networkpolicy.yaml, an already-working precedent for the same "Prometheus can't reach an apps-namespace pod's metrics port" problem.
The one thing I could not verify from the checkout (would need cluster/Prometheus access) is that this actually clears the ExternalDNSMetricsMissing alert post-merge — but that's an operational follow-up, not something the diff itself can prove.
Recommendation
Looks reasonable — no blocking issues; comments above are optional.
🤖 **Automated review** — model `CLI default` (complexity: complex), commit `5f3aecb381b5906e0979ef9c6c0b0cfddc045f14`.
> Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review.
---
## Summary
Adds a `CiliumNetworkPolicy` allowing Prometheus (in the `monitoring` namespace) to reach port `7979` on `external-dns` pods in the `apps` namespace, which is `default-deny-ingress`. The fix is small, correctly scoped, and mirrors an already-proven pattern (`gitea-allow-metrics-scrape`) elsewhere in the repo. No blocking issues found.
## 🟡 Suggestions
- `kubernetes/apps/external-dns/networkpolicy.yaml:1-4`: the header comment references `monitoring-rules/external-dns-servicemonitor.yaml` as already existing (from PR #865), but that file is not present anywhere in this checkout (`kubernetes/apps/monitoring-rules/` has no `external-dns-*` ServiceMonitor, and a repo-wide grep for `external-dns` turns up nothing under `monitoring-rules/`). This is harmless either way — a `CiliumNetworkPolicy` doesn't depend on the `ServiceMonitor` existing, and Cilium policies for the same endpoint selector are additive — but it's worth confirming #865 lands (in either order) so the policy actually gets exercised; otherwise this PR is a no-op until then.
## 🟢 Nits
- `kubernetes/apps/external-dns/networkpolicy.yaml:33`: the key `k8s:io.kubernetes.pod.namespace: monitoring` is unquoted here, while every other `CiliumNetworkPolicy` in the repo (gitea, paperless, woodpecker, all of `infrastructure/network-policies/*`, ~100+ occurrences) quotes it as `"k8s:io.kubernetes.pod.namespace"`. It still parses fine as valid YAML (the colon isn't followed by a space), but it's inconsistent with the established convention this PR is explicitly modeled on.
## Tests
No automated tests apply here — this is a declarative GitOps manifest, consistent with how the rest of the repo's `CiliumNetworkPolicy` resources are handled (no test suite, correctness relies on review + post-merge observation). I verified the logic statically instead of running it:
- Confirmed `apps` namespace's `default-deny-ingress` (`kubernetes/infrastructure/network-policies/default-deny.yaml`) only allows same-namespace, `home-assistant`, and host/remote-node ingress — `monitoring` is indeed absent, matching the PR's claimed root cause.
- Confirmed port `7979` matches the Prometheus target URL quoted in the PR body (`http://10.244.2.218:7979/metrics`) for the `external-dns-unifi` job.
- Confirmed both HelmReleases (`kubernetes/apps/external-dns/helmrelease.yaml` and `kubernetes/infrastructure/external-dns-unifi/helmrelease.yaml`) use the same `external-dns` chart with no `nameOverride`, so both pods get `app.kubernetes.io/name: external-dns` regardless of the differing release names / `fullnameOverride: external-dns-unifi` — the single shared `endpointSelector` is correctly scoped to cover both releases as the author intends.
- Confirmed this exactly mirrors the pre-existing `gitea-allow-metrics-scrape` policy in `kubernetes/apps/gitea/networkpolicy.yaml`, an already-working precedent for the same "Prometheus can't reach an `apps`-namespace pod's metrics port" problem.
The one thing I could not verify from the checkout (would need cluster/Prometheus access) is that this actually clears the `ExternalDNSMetricsMissing` alert post-merge — but that's an operational follow-up, not something the diff itself can prove.
## Recommendation
Looks reasonable — no blocking issues; comments above are optional.
<!-- pr-review:sha=5f3aecb381b5906e0979ef9c6c0b0cfddc045f14 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Nachzug zu #865. Der ServiceMonitor findet beide external-dns-Targets und läuft dann in einen Timeout —
appsistdefault-deny-ingress, der Scrape kommt nie an.Mein Fehler: ich habe die Namespace-Policies nicht geprüft, bevor ich den ServiceMonitor geschrieben habe. Für gitea existiert genau dieses Muster bereits (
gitea-allow-metrics-scrape).Eine Policy deckt beide Releases ab — der Chart vergibt beiden dasselbe
app.kubernetes.io/name: external-dnsund sie liegen im selben Namespace, auch wennexternal-dns-unifiunterinfrastructure/deklariert ist.Ohne das bleibt
ExternalDNSMetricsMissingdauerhaft am Feuern und die vier Regeln darüber sind blind. Die DNS-Probes aus #865 laufen unabhängig davon und sind bereits grün.🤖 Generated with Claude Code
🤖 Automated review — model
CLI default(complexity: complex), commit5f3aecb381b5906e0979ef9c6c0b0cfddc045f14.Summary
Adds a
CiliumNetworkPolicyallowing Prometheus (in themonitoringnamespace) to reach port7979onexternal-dnspods in theappsnamespace, which isdefault-deny-ingress. The fix is small, correctly scoped, and mirrors an already-proven pattern (gitea-allow-metrics-scrape) elsewhere in the repo. No blocking issues found.🟡 Suggestions
kubernetes/apps/external-dns/networkpolicy.yaml:1-4: the header comment referencesmonitoring-rules/external-dns-servicemonitor.yamlas already existing (from PR #865), but that file is not present anywhere in this checkout (kubernetes/apps/monitoring-rules/has noexternal-dns-*ServiceMonitor, and a repo-wide grep forexternal-dnsturns up nothing undermonitoring-rules/). This is harmless either way — aCiliumNetworkPolicydoesn't depend on theServiceMonitorexisting, and Cilium policies for the same endpoint selector are additive — but it's worth confirming #865 lands (in either order) so the policy actually gets exercised; otherwise this PR is a no-op until then.🟢 Nits
kubernetes/apps/external-dns/networkpolicy.yaml:33: the keyk8s:io.kubernetes.pod.namespace: monitoringis unquoted here, while every otherCiliumNetworkPolicyin the repo (gitea, paperless, woodpecker, all ofinfrastructure/network-policies/*, ~100+ occurrences) quotes it as"k8s:io.kubernetes.pod.namespace". It still parses fine as valid YAML (the colon isn't followed by a space), but it's inconsistent with the established convention this PR is explicitly modeled on.Tests
No automated tests apply here — this is a declarative GitOps manifest, consistent with how the rest of the repo's
CiliumNetworkPolicyresources are handled (no test suite, correctness relies on review + post-merge observation). I verified the logic statically instead of running it:appsnamespace'sdefault-deny-ingress(kubernetes/infrastructure/network-policies/default-deny.yaml) only allows same-namespace,home-assistant, and host/remote-node ingress —monitoringis indeed absent, matching the PR's claimed root cause.7979matches the Prometheus target URL quoted in the PR body (http://10.244.2.218:7979/metrics) for theexternal-dns-unifijob.kubernetes/apps/external-dns/helmrelease.yamlandkubernetes/infrastructure/external-dns-unifi/helmrelease.yaml) use the sameexternal-dnschart with nonameOverride, so both pods getapp.kubernetes.io/name: external-dnsregardless of the differing release names /fullnameOverride: external-dns-unifi— the single sharedendpointSelectoris correctly scoped to cover both releases as the author intends.gitea-allow-metrics-scrapepolicy inkubernetes/apps/gitea/networkpolicy.yaml, an already-working precedent for the same "Prometheus can't reach anapps-namespace pod's metrics port" problem.The one thing I could not verify from the checkout (would need cluster/Prometheus access) is that this actually clears the
ExternalDNSMetricsMissingalert post-merge — but that's an operational follow-up, not something the diff itself can prove.Recommendation
Looks reasonable — no blocking issues; comments above are optional.