Zone Transfers
Configure and optimize DNS zone transfers between primary and secondary instances.
Overview
Zone transfers replicate DNS zone data from primary to secondary servers using AXFR (full transfer) or IXFR (incremental transfer).
Configuring Zone Transfers
Primary Instance Setup
Allow zone transfers to secondary servers:
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
name: primary-dns
spec:
config:
allowTransfer:
- "10.0.0.0/8" # Secondary network
- "192.168.100.0/24" # Specific secondary subnet
Secondary Instance Setup
Configure secondary zones to transfer from primary:
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: example-com-secondary
spec:
zoneName: example.com
type: secondary
instanceSelector:
matchLabels:
dns-role: secondary
secondaryConfig:
primaryServers:
- "10.0.1.10" # Primary DNS server IP
- "10.0.1.11" # Backup primary IP
Transfer Types
Full Transfer (AXFR)
Transfers entire zone:
- Used for initial zone load
- Triggered manually or when IXFR unavailable
- More bandwidth intensive
Incremental Transfer (IXFR)
Transfers only changes since last serial:
- More efficient for large zones
- Requires serial number tracking
- Automatically used when available
Transfer Triggers
NOTIFY Messages
Primary sends NOTIFY when zone changes:
graph TB
primary["Primary Updates Zone"]
sec1["Secondary 1"]
sec2["Secondary 2"]
sec3["Secondary 3"]
transfer["Secondaries initiate IXFR/AXFR"]
primary -->|NOTIFY| sec1
primary -->|NOTIFY| sec2
primary -->|NOTIFY| sec3
sec1 --> transfer
sec2 --> transfer
sec3 --> transfer
style primary fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style sec1 fill:#e1f5ff,stroke:#01579b,stroke-width:2px
style sec2 fill:#e1f5ff,stroke:#01579b,stroke-width:2px
style sec3 fill:#e1f5ff,stroke:#01579b,stroke-width:2px
style transfer fill:#fff9c4,stroke:#f57f17,stroke-width:2px
Refresh Timer
Secondary checks for updates periodically:
soaRecord:
refresh: 3600 # Check every hour
retry: 600 # Retry after 10 minutes if failed
Manual Trigger
Force zone transfer:
# On secondary pod
kubectl exec -n dns-system deployment/secondary-dns -- \
rndc retransfer example.com
Monitoring Zone Transfers
Check Transfer Status
# View transfer logs
kubectl logs -n dns-system -l dns-role=secondary | grep "transfer of"
# Successful transfer
# transfer of 'example.com/IN' from 10.0.1.10#53: Transfer completed: 1 messages, 42 records
# Check zone status
kubectl exec -n dns-system deployment/secondary-dns -- \
rndc zonestatus example.com
Verify Serial Numbers
# Primary serial
kubectl exec -n dns-system deployment/primary-dns -- \
dig @localhost example.com SOA +short | awk '{print $3}'
# Secondary serial
kubectl exec -n dns-system deployment/secondary-dns -- \
dig @localhost example.com SOA +short | awk '{print $3}'
# Should match when in sync
Transfer Performance
Optimize Transfer Speed
- Use IXFR - Only transfer changes
- Increase Bandwidth - Adequate network resources
- Compress Transfers - Enable BIND9 compression
- Parallel Transfers - Multiple zones transfer concurrently
Transfer Limits
Configure maximum concurrent transfers:
# In BIND9 config (future enhancement)
options {
transfers-in 10; # Max incoming transfers
transfers-out 10; # Max outgoing transfers
};
Security
Access Control
Restrict transfers by IP:
spec:
config:
allowTransfer:
- "10.0.0.0/8" # Only this network
TSIG Authentication
Use TSIG keys for authenticated transfers:
# 1. Create a Kubernetes Secret with RNDC/TSIG credentials
apiVersion: v1
kind: Secret
metadata:
name: transfer-key-secret
namespace: dns-system
type: Opaque
stringData:
key-name: transfer-key
secret: K2xkajflkajsdf09asdfjlaksjdf== # base64-encoded HMAC key
---
# 2. Reference the secret in Bind9Cluster
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: production-dns
namespace: dns-system
spec:
rndcSecretRefs:
- name: transfer-key-secret
algorithm: hmac-sha256 # Algorithm for this key
The secret will be used for authenticated zone transfers between primary and secondary servers.
Troubleshooting
Transfer Failures
Check network connectivity:
kubectl exec -n dns-system deployment/secondary-dns -- \
nc -zv primary-dns-service 53
Test manual transfer:
kubectl exec -n dns-system deployment/secondary-dns -- \
dig @primary-dns-service example.com AXFR
Check ACLs:
kubectl get bind9instance primary-dns -o jsonpath='{.spec.config.allowTransfer}'
Slow Transfers
Check zone size:
kubectl exec -n dns-system deployment/primary-dns -- \
wc -l /var/lib/bind/zones/example.com.zone
Monitor transfer time:
kubectl logs -n dns-system -l dns-role=secondary | \
grep "transfer of" | grep "msecs"
Transfer Lag
Check refresh interval:
kubectl get dnszone example-com -o jsonpath='{.spec.soaRecord.refresh}'
Force immediate transfer:
kubectl exec -n dns-system deployment/secondary-dns -- \
rndc retransfer example.com
Best Practices
- Use IXFR - More efficient than full transfers
- Set Appropriate Refresh - Balance freshness vs load
- Monitor Serial Numbers - Detect sync issues
- Secure Transfers - Use ACLs and TSIG
- Test Failover - Verify secondaries work when primary fails
- Log Transfers - Monitor for failures
- Geographic Distribution - Secondaries in different regions
Example: Complete Setup
# Primary Instance
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
name: primary-dns
labels:
dns-role: primary
spec:
replicas: 2
config:
allowTransfer:
- "10.0.0.0/8"
---
# Primary Zone
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: example-com-primary
spec:
zoneName: example.com
type: primary
instanceSelector:
matchLabels:
dns-role: primary
soaRecord:
primaryNs: ns1.example.com.
adminEmail: admin@example.com
serial: 2024010101
refresh: 3600
retry: 600
expire: 604800
negativeTtl: 86400
---
# Secondary Instance
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
name: secondary-dns
labels:
dns-role: secondary
spec:
replicas: 2
---
# Secondary Zone
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: example-com-secondary
spec:
zoneName: example.com
type: secondary
instanceSelector:
matchLabels:
dns-role: secondary
secondaryConfig:
primaryServers:
- "primary-dns-service.dns-system.svc.cluster.local"
Next Steps
- Replication - Multi-region replication strategies
- High Availability - HA architecture
- Performance - Optimize zone transfer performance