mirror of
https://github.com/eznix86/kubernetes-dns-healthcheck-cloudflare.git
synced 2026-07-25 21:09:17 +00:00
In case you've got cool friends who share their nodes with you
- Python 100%
| app | ||
| manifests | ||
| tests | ||
| .gitignore | ||
| kustomization.yaml | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
DNS Healthcheck + Cloudflare
This setup runs a Kubernetes deployment that:
- checks DDNS nodes for health on ports 80/443,
- collects managed hostnames from Ingress/Gateway resources,
- keeps Cloudflare A records in sync with healthy node IPs,
- stores cooldown state in a PVC.
Files
app/main.py: bootstrap + runtime loopapp/reconcilers/domain.py: per-domain reconcile logicapp/reconcilers/once.py: one reconcile cycle across domainsapp/services/*.py: Cloudflare/Kubernetes/nodes/state implementationsapp/facades.py: Laravel-style facades (Cloudflare,Kubernetes,Nodes)app/di.py: dependency-injector container and bindingspyproject.toml: Python dependency definitions for uvuv.lock: locked dependency graph used by uv (--frozen)manifests/*.yaml: Kubernetes resourceskustomization.yaml: assembles resources and script ConfigMap
Configure
- Edit node list and timings in
manifests/20-config.yaml. - Create the Cloudflare token secret:
kubectl apply -f manifests/00-namespace.yaml
kubectl -n dns-healthcheck create secret generic cloudflare --from-literal=token='your-cloudflare-api-token'
The token needs Zone:DNS:Edit for your zones.
Local dev with uv
Prerequisite: install uv (https://docs.astral.sh/uv/getting-started/installation/).
Install and sync local environment:
uv sync --dev
Run tests:
uv run pytest
Facade fakes are available for tests and local experimentation:
Cloudflare.fake(records={...})Kubernetes.fake(hosts={...})Nodes.fake(healthy_ips={...})
Run the checker locally (with env values):
CF_TOKEN=... NODES='friend1: friend1.ddns.net' INTERVAL=30 COOLDOWN=60 uv run python -m app.main
Upgrade dependencies and refresh lock file:
uv lock --upgrade
uv sync --dev --upgrade
Deploy
The deployment runs with uv and installs from pyproject.toml + uv.lock using --frozen, so cluster installs are lockfile-based and reproducible.
kubectl apply -k .
Tail logs:
kubectl -n dns-healthcheck logs -f deploy/dns-healthcheck
Troubleshooting
- No domains detected: ensure resources have
dns-healthcheck/managed: "true". - Gateway API route without hostnames (TCP/UDP): set
dns-healthcheck/hostsannotation. - Cloudflare auth errors: verify the token secret exists in
dns-healthchecknamespace and hasZone:DNS:Editpermission. - No healthy IPs: verify DDNS names in
manifests/20-config.yamlresolve publicly and ports80or443are reachable. - Runtime dependency mismatch in cluster: make sure
uv.lockis committed andkubectl apply -k .is re-run after lock changes.
Managed hosts annotations
Mark resources that should be managed by the checker:
dns-healthcheck/managed: "true"
Optional explicit host list annotation:
dns-healthcheck/hosts: "example.com,api.example.com"
If dns-healthcheck/hosts is not set:
- Ingress hosts are read from
spec.rules[].host - HTTPRoute/GRPCRoute/TLSRoute hosts are read from
spec.hostnames