NextDNS Kubernetes Operator
A Kubernetes operator for managing NextDNS profiles declaratively using Custom Resources.
Features
- Declarative DNS Management: Define NextDNS profiles as Kubernetes resources
- Multi-CRD Architecture: Separate resources for allowlists, denylists, and TLD lists that can be shared across profiles
- Full NextDNS API Coverage: Security, privacy, parental control, and settings configuration
- Profile Lifecycle Management: Create new profiles or adopt existing ones; operator-created profiles are deleted on resource removal
- Drift Detection: Automatic periodic reconciliation (default: 1 hour) catches manual changes made outside the operator
- ConfigMap Export: Optionally create a ConfigMap with DNS connection details for easy integration with other applications
Custom Resources
| CRD |
Description |
NextDNSProfile |
Main profile configuration with security, privacy, and parental control settings |
NextDNSAllowlist |
Reusable list of allowed domains |
NextDNSDenylist |
Reusable list of blocked domains |
NextDNSTLDList |
Reusable list of blocked TLDs |
Installation
Helm (Recommended)
# Install from OCI registry
helm install nextdns-operator oci://ghcr.io/jacaudi/charts/nextdns-operator \
--version 0.1.0 \
--namespace nextdns-operator-system \
--create-namespace
Kubectl
# Install CRDs
kubectl apply -f https://github.com/jacaudi/nextdns-operator/releases/latest/download/install.yaml
# Deploy operator
kubectl apply -f https://github.com/jacaudi/nextdns-operator/releases/latest/download/operator.yaml
Local Development
# Install CRDs
make install
# Run locally
make run
Quick Start
Once the operator is installed:
- Create a Secret with your NextDNS API key:
apiVersion: v1
kind: Secret
metadata:
name: nextdns-credentials
namespace: default
type: Opaque
stringData:
api-key: "your-nextdns-api-key"
- Create a NextDNSProfile:
apiVersion: nextdns.io/v1alpha1
kind: NextDNSProfile
metadata:
name: my-profile
namespace: default
spec:
name: "My DNS Profile"
credentialsRef:
name: nextdns-credentials
security:
aiThreatDetection: true
googleSafeBrowsing: true
- Apply the resources:
kubectl apply -f secret.yaml
kubectl apply -f profile.yaml
- Check the status:
kubectl get nextdnsprofile my-profile -o yaml
Examples
See the config/samples directory for complete examples:
Configuration
ConfigMap Export
Optionally create a ConfigMap containing your profile's DNS connection details. This is useful for configuring DNS clients (CoreDNS, Blocky, etc.) or injecting connection details into pods.
apiVersion: nextdns.io/v1alpha1
kind: NextDNSProfile
metadata:
name: my-profile
spec:
name: "My Profile"
credentialsRef:
name: nextdns-credentials
configMapRef:
enabled: true
name: my-dns-config # optional, defaults to "<profile-name>-nextdns"
The created ConfigMap contains:
data:
NEXTDNS_PROFILE_ID: "abc123"
NEXTDNS_DOT: "abc123.dns.nextdns.io"
NEXTDNS_DOH: "https://dns.nextdns.io/abc123"
NEXTDNS_DOQ: "quic://abc123.dns.nextdns.io"
NEXTDNS_IPV4_1: "45.90.28.0"
NEXTDNS_IPV4_2: "45.90.30.0"
NEXTDNS_IPV6_1: "2a07:a8c0::"
NEXTDNS_IPV6_2: "2a07:a8c1::"
Use it in your pods with envFrom:
envFrom:
- configMapRef:
name: my-dns-config
Drift Detection
The operator periodically reconciles all resources to detect and correct drift from manual changes made outside Kubernetes.
Configure via environment variable:
SYNC_PERIOD=30m ./nextdns-operator
Configure via command-line flag:
./nextdns-operator --sync-period=30m
Disable periodic syncing:
SYNC_PERIOD=0 ./nextdns-operator
Default: 1h (60 minutes)
Behavior:
- Syncs include ±10% jitter to prevent all resources from hitting the API simultaneously
- Each profile makes ~1 API call per sync period
- List resources (allowlist, denylist, tldlist) sync status but don't call the NextDNS API directly
- Setting to
0 disables periodic syncing (event-driven only)
Development
# Run tests
make test
# Build
make build
License
Apache 2.0