A production-ready Kubernetes operator for ESDDNS using Kopf framework with LoadBalancer service integration. Complete with monitoring, automated deployment, and comprehensive documentation.
Status: Ready for immediate deployment
Choose your entry point based on what you need:
β QUICKSTART.md
β k8s/README.md
β FILES_CREATED.md
# 1. Set your Gandi API key
export GANDI_API_KEY="your-gandi-api-key"
# 2. Deploy
cd k8s
./deploy.sh production
# 3. Verify
kubectl get all -n esddns
# 4. Get external IP (takes 2-5 minutes)
kubectl get svc -n esddns esddns-service
# 5. Access the service
curl http://$EXTERNAL_IP/
See QUICKSTART.md for more details
esddns/
βββ k8s/ # Main Kubernetes operator directory
β βββ esddns_operator.py # Kopf operator implementation
β βββ Dockerfile # Container image
β βββ deploy.sh # Automated deployment script
β βββ DEPLOYMENT.md # Complete installation guide
β βββ README.md # Architecture & features
β β
β βββ base/ # Base Kubernetes manifests
β β βββ kustomization.yaml
β β βββ namespace.yaml
β β βββ serviceaccount.yaml
β β βββ clusterrole.yaml
β β βββ clusterrolebinding.yaml
β β βββ daemon-deployment.yaml # DaemonSet (operator)
β β βββ service-deployment.yaml # Deployment (Flask)
β β βββ service.yaml # LoadBalancer
β β βββ configmap.yaml # Configuration
β β βββ secrets.yaml # API credentials
β β
β βββ overlays/ # Environment-specific configs
β β βββ development/ # Dev environment
β β β βββ kustomization.yaml
β β β βββ daemon-dev-patch.yaml
β β β βββ service-dev-patch.yaml
β β β
β β βββ production/ # Production environment
β β βββ kustomization.yaml
β β βββ daemon-prod-patch.yaml
β β βββ service-prod-patch.yaml
β β
β βββ monitoring/ # Prometheus monitoring
β βββ prometheus-servicemonitor.yaml
β βββ prometheus-rules.yaml
β
βββ esddns_service/
β βββ metrics.py # Prometheus metrics
β
βββ requirements-k8s.txt # Kubernetes dependencies
βββ QUICKSTART.md # Quick start guide (READ THIS FIRST)
βββ OPERATOR_SUMMARY.md # Implementation details
βββ FILES_CREATED.md # Complete file listing
βββ README_OPERATOR.md # This file
βββ IMPLEMENTATION_COMPLETE.txt # Visual summary
./k8s/deploy.sh production # Deploy to production
./k8s/deploy.sh development # Deploy to development
# View operator logs
kubectl logs -n esddns -l app=esddns-operator -f
# View service logs
kubectl logs -n esddns -l app=esddns-service -f
# Get current status
kubectl get all -n esddns
# View metrics
kubectl port-forward -n esddns daemonset/esddns-operator-daemon 8080:8080
curl http://localhost:8080/metrics
# Update domain
kubectl patch configmap esddns-config -n esddns \
-p '{"data":{"target-domain":"yourdomain.com"}}'
# Update API key
kubectl delete secret esddns-gandi-credentials -n esddns
kubectl create secret generic esddns-gandi-credentials \
--from-literal=api-key=$NEW_KEY -n esddns
# Restart pods to pick up changes
kubectl rollout restart daemonset/esddns-operator-daemon -n esddns
kubectl rollout restart deployment/esddns-service -n esddns
# Get external IP
kubectl get svc -n esddns esddns-service
# Test endpoint
EXTERNAL_IP=$(kubectl get svc -n esddns esddns-service \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://$EXTERNAL_IP/
curl http://$EXTERNAL_IP/raw
See QUICKSTART.md for more commands
β Centralized IP Detection
β Distributed DNS Updates
β High Availability
β LoadBalancer Service
β Prometheus Metrics
β Alert Rules
β Multi-Environment Support
β Complete Documentation
β Read QUICKSTART.md (5 min) β Run ./k8s/deploy.sh production
β Read OPERATOR_SUMMARY.md (20 min) for architecture and design
β Read k8s/DEPLOYMENT.md (30 min) for complete walkthrough
β Read k8s/README.md (15 min) for feature overview
β Check QUICKSTART.md troubleshooting section first β Then k8s/DEPLOYMENT.md for detailed debugging
β Check FILES_CREATED.md for complete listing
β See IMPLEMENTATION_COMPLETE.txt
Kubernetes Cluster
CENTRALIZED IP DETECTION (Leader via Kopf lock)
βββ Kopf Operator (Single Instance)
β β’ Detects WAN IP every 5 minutes
β β’ Stores in ConfigMap: esddns-wan-ip
β β’ Leader election via Kopf timer lock
β
βββ ConfigMap: esddns-wan-ip
β’ current_ip: X.X.X.X
β’ detected_at: timestamp
β Read by all nodes
DISTRIBUTED DNS UPDATES (All DaemonSet pods)
βββ Node 1
β βββ DaemonSet Pod (NodeDNSUpdater)
β β’ Read cached IP from ConfigMap
β β’ Update DNS if IP changed
β β’ Fallback to direct detection if stale/missing
β
βββ Node 2
β βββ DaemonSet Pod (NodeDNSUpdater)
β β’ Read cached IP from ConfigMap
β β’ Update DNS if IP changed
β β’ Fallback to direct detection if stale/missing
β
βββ ... (All nodes)
β
βββ Single Replica Deployment (Flask Service)
β β’ REST API endpoints
β β’ Exposes DNS state
β β’ Health checks
β
βββ LoadBalancer Service
β’ Cloud provider integration
β’ External IP assignment
β’ Automatic failover
β Updates via
Gandi.net API
β’ A Record Updates
β’ LiveDNS API
BENEFITS
β’ 1 IP detection instead of N β 90-95% fewer API calls
β’ All nodes use same IP source β zero drift
β’ Works with network isolation β no per-node external calls
β’ Fallback to direct detection β high availability
Prometheus Integration
Key Metrics
Alerts Configured
Reuses Existing Code
New Components
./k8s/deploy.sh production
# LoadBalancer creates AWS ELB automatically
./k8s/deploy.sh production
# LoadBalancer creates Google Cloud LB automatically
./k8s/deploy.sh production
# LoadBalancer creates Azure LB automatically
kubectl patch svc esddns-service -n esddns \
-p '{"spec":{"type":"NodePort"}}'
# Access via NodePort instead
Q: Whatβs the difference between operator and service? A: Operator (DaemonSet) runs on every node and updates DNS. Service (Deployment) exposes the DNS state via HTTP API.
Q: Do I need to configure anything before deploying? A: Set your Gandi API key and optionally update the domain in ConfigMap.
Q: How often does it check for IP changes? A: Default is every 300 seconds (5 minutes). Adjustable in ConfigMap.
Q: Can I run this on-premises? A: Yes, just use NodePort instead of LoadBalancer.
Q: How do I update the API key? A: Delete the secret and create a new one, then restart the pods.
Q: Does it support IPv6? A: Currently supports IPv4 only (A records). IPv6 (AAAA) support can be added.
Q: What if the LoadBalancer IP doesnβt get assigned? A: Check your cloud providerβs load balancer quota. Can take 2-5 minutes.
β Check QUICKSTART.md troubleshooting
β See k8s/DEPLOYMENT.md configuration section
kubectl logs -n esddns -l app=esddns-operator -f
kubectl logs -n esddns -l app=esddns-service -f
https://github.com/sqe/esddns/issues
| Component | Type | Replicas | Resources | Port |
|---|---|---|---|---|
| Operator | DaemonSet | 1 per node | 512Mi/500m | 8080 |
| Service | Deployment | 1 | 512Mi/500m | 51339 |
| LoadBalancer | Service | 1 | - | 80/443 |
Total Implementation: 24 files, 2,000+ lines, production-ready β
Next Step: Read QUICKSTART.md and deploy!