DNSZone Specification
Complete specification for the DNSZone Custom Resource Definition.
Resource Definition
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: string
namespace: string
spec:
zoneName: string
clusterRef: string # References Bind9Cluster
soaRecord:
primaryNs: string
adminEmail: string
serial: integer
refresh: integer
retry: integer
expire: integer
negativeTtl: integer
ttl: integer
Spec Fields
zoneName
Type: string Required: Yes
The DNS zone name (domain name).
spec:
zoneName: "example.com"
Requirements:
- Must be a valid DNS domain name
- Maximum 253 characters
- Can be forward or reverse zone
Examples:
- “example.com”
- “subdomain.example.com”
- “1.0.10.in-addr.arpa” (reverse zone)
clusterRef
Type: string Required: Yes
Name of the Bind9Cluster that will manage this zone.
spec:
clusterRef: production-dns # References Bind9Cluster named "production-dns"
How It Works:
- Controller finds Bind9Cluster with this name
- Discovers all Bind9Instance resources referencing this cluster
- Identifies primary instances for zone hosting
- Loads RNDC keys from cluster configuration
- Creates zone on primary instances using
rndc addzonecommand - Configures zone transfers to secondary instances
Validation:
- Referenced Bind9Cluster must exist in same namespace
- Controller validates reference at admission time
soaRecord
Type: object Required: Yes
Start of Authority record defining zone parameters.
spec:
soaRecord:
primaryNs: "ns1.example.com."
adminEmail: "admin.example.com." # Note: @ replaced with .
serial: 2024010101
refresh: 3600
retry: 600
expire: 604800
negativeTtl: 86400
soaRecord.primaryNs
Type: string Required: Yes
Primary nameserver for the zone.
soaRecord:
primaryNs: "ns1.example.com."
Requirements:
- Must be a fully qualified domain name (FQDN)
- Must end with a dot (.)
- Pattern:
^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.$
soaRecord.adminEmail
Type: string Required: Yes
Email address of zone administrator in DNS format.
soaRecord:
adminEmail: "admin.example.com." # Represents admin@example.com
Format:
- Replace @ with . in email address
- Must end with a dot (.)
- Example: admin@example.com → admin.example.com.
- Pattern:
^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.$
soaRecord.serial
Type: integer (64-bit) Required: Yes Range: 0 to 4,294,967,295
Zone serial number for change tracking.
soaRecord:
serial: 2024010101
Best Practices:
- Use format: YYYYMMDDnn (year, month, day, revision)
- Increment on every change
- Secondaries use this to detect updates
Examples:
- 2024010101 - January 1, 2024, first revision
- 2024010102 - January 1, 2024, second revision
soaRecord.refresh
Type: integer (32-bit) Required: Yes Range: 1 to 2,147,483,647
How often (in seconds) secondary servers should check for updates.
soaRecord:
refresh: 3600 # 1 hour
Typical Values:
- 3600 (1 hour) - Standard
- 7200 (2 hours) - Less frequent updates
- 900 (15 minutes) - Frequent updates
soaRecord.retry
Type: integer (32-bit) Required: Yes Range: 1 to 2,147,483,647
How long (in seconds) to wait before retrying a failed refresh.
soaRecord:
retry: 600 # 10 minutes
Best Practice: Should be less than refresh value
soaRecord.expire
Type: integer (32-bit) Required: Yes Range: 1 to 2,147,483,647
How long (in seconds) secondary servers should keep serving zone data after primary becomes unreachable.
soaRecord:
expire: 604800 # 1 week
Typical Values:
- 604800 (1 week) - Standard
- 1209600 (2 weeks) - Extended
- 86400 (1 day) - Short-lived zones
soaRecord.negativeTtl
Type: integer (32-bit) Required: Yes Range: 0 to 2,147,483,647
How long (in seconds) to cache negative responses (NXDOMAIN).
soaRecord:
negativeTtl: 86400 # 24 hours
Typical Values:
- 86400 (24 hours) - Standard
- 3600 (1 hour) - Shorter caching
- 300 (5 minutes) - Very short for dynamic zones
ttl
Type: integer (32-bit) Required: No Default: 3600 Range: 0 to 2,147,483,647
Default Time To Live for records in this zone (in seconds).
spec:
ttl: 3600 # 1 hour
Common Values:
- 3600 (1 hour) - Standard
- 300 (5 minutes) - Frequently changing zones
- 86400 (24 hours) - Stable zones
Status Fields
conditions
Type: array of objects
Standard Kubernetes conditions.
status:
conditions:
- type: Ready
status: "True"
reason: Synchronized
message: "Zone created for cluster: primary-dns"
lastTransitionTime: "2024-01-15T10:30:00Z"
Condition Types:
- Ready - Zone is created and serving
- Synced - Zone is synchronized with BIND9
- Failed - Zone creation or update failed
observedGeneration
Type: integer
The generation last reconciled.
status:
observedGeneration: 3
recordCount
Type: integer
Number of DNS records in this zone.
status:
recordCount: 42
Complete Examples
Simple Primary Zone
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: example-com
namespace: dns-system
spec:
zoneName: example.com
clusterRef: primary-dns
soaRecord:
primaryNs: ns1.example.com.
adminEmail: admin.example.com.
serial: 2024010101
refresh: 3600
retry: 600
expire: 604800
negativeTtl: 86400
ttl: 3600
Production Zone with Custom TTL
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: api-example-com
namespace: dns-system
spec:
zoneName: api.example.com
clusterRef: production-dns
ttl: 300 # 5 minute default TTL for faster updates
soaRecord:
primaryNs: ns1.api.example.com.
adminEmail: ops.example.com.
serial: 2024010101
refresh: 1800 # Check every 30 minutes
retry: 300 # Retry after 5 minutes
expire: 604800
negativeTtl: 300 # Short negative cache
Reverse DNS Zone
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: reverse-zone
namespace: dns-system
spec:
zoneName: 1.0.10.in-addr.arpa
clusterRef: primary-dns
soaRecord:
primaryNs: ns1.example.com.
adminEmail: admin.example.com.
serial: 2024010101
refresh: 3600
retry: 600
expire: 604800
negativeTtl: 86400
ttl: 3600
Multi-Region Setup
# East Region Zone
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: example-com-east
namespace: dns-system
spec:
zoneName: example.com
clusterRef: dns-east # References east instance
soaRecord:
primaryNs: ns1.east.example.com.
adminEmail: admin.example.com.
serial: 2024010101
refresh: 3600
retry: 600
expire: 604800
negativeTtl: 86400
---
# West Region Zone
apiVersion: bindy.firestoned.io/v1alpha1
kind: DNSZone
metadata:
name: example-com-west
namespace: dns-system
spec:
zoneName: example.com
clusterRef: dns-west # References west instance
soaRecord:
primaryNs: ns1.west.example.com.
adminEmail: admin.example.com.
serial: 2024010101
refresh: 3600
retry: 600
expire: 604800
negativeTtl: 86400
Zone Creation Flow
When you create a DNSZone resource:
- Admission - Kubernetes validates the resource schema
- Controller watches - Bindy controller detects the new zone
- Cluster lookup - Finds Bind9Cluster referenced by
clusterRef - Instance discovery - Finds all Bind9Instance resources referencing the cluster
- Primary identification - Identifies primary instances (with
role: primary) - RNDC key load - Retrieves RNDC keys from cluster configuration
- RNDC connection - Connects to primary instance pods via RNDC
- Zone creation - Executes
rndc addzone {zoneName} ...on primary instances - Zone transfer setup - Configures zone transfers to secondary instances
- Status update - Updates DNSZone status to Ready