Bind9Cluster Specification
Complete specification for the Bind9Cluster Custom Resource Definition.
Resource Definition
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: string
namespace: string
spec:
version: string # Optional, BIND9 version
image: # Optional, container image config
image: string
imagePullPolicy: string
imagePullSecrets: [string]
configMapRefs: # Optional, custom config files
namedConf: string
namedConfOptions: string
global: # Optional, global BIND9 config for all instances
recursion: boolean
allowQuery: [string] # ⚠️ NO DEFAULT - must be explicitly set
allowTransfer: [string] # ⚠️ NO DEFAULT - must be explicitly set
dnssec:
enabled: boolean
validation: boolean
forwarders: [string]
listenOn: [string]
listenOnV6: [string]
rndcSecretRefs: [RndcSecretRef] # Optional, refs to Secrets with RNDC/TSIG keys
acls: # Optional, named ACLs
name: [string]
volumes: [Volume] # Optional, Kubernetes volumes
volumeMounts: [VolumeMount] # Optional, volume mount specifications
Overview
Bind9Cluster defines a logical grouping of BIND9 DNS server instances with shared configuration. It provides centralized management of BIND9 version, container images, and common settings across multiple instances.
Key Features:
- Shared version and image configuration
- Centralized BIND9 configuration
- TSIG key management for secure zone transfers
- Named ACLs for access control
- Cluster-wide status reporting
Spec Fields
version
Type: string Required: No Default: “9.18”
BIND9 version to deploy across all instances in the cluster unless overridden at the instance level.
spec:
version: "9.18"
Supported Versions:
- “9.16” - Older stable
- “9.18” - Current stable (recommended)
- “9.19” - Development
image
Type: object Required: No
Container image configuration shared by all instances in the cluster.
spec:
image:
image: "internetsystemsconsortium/bind9:9.18"
imagePullPolicy: "IfNotPresent"
imagePullSecrets:
- my-registry-secret
How It Works:
- Instances inherit image configuration from the cluster
- Instances can override with their own
imageconfig - Simplifies managing container images across multiple instances
image.image
Type: string Required: No Default: “internetsystemsconsortium/bind9:9.18”
Full container image reference including registry, repository, and tag.
spec:
image:
image: "my-registry.example.com/bind9:custom"
image.imagePullPolicy
Type: string Required: No Default: “IfNotPresent”
Kubernetes image pull policy.
Valid Values:
"Always"- Always pull the image"IfNotPresent"- Pull only if not present locally (recommended)"Never"- Never pull, use local image only
image.imagePullSecrets
Type: array of strings Required: No Default: []
List of Kubernetes secret names for authenticating with private container registries.
spec:
image:
imagePullSecrets:
- docker-registry-secret
configMapRefs
Type: object Required: No
References to custom ConfigMaps containing BIND9 configuration files shared across the cluster.
spec:
configMapRefs:
namedConf: "cluster-named-conf"
namedConfOptions: "cluster-options"
How It Works:
- Cluster-level ConfigMaps apply to all instances
- Instances can override with their own ConfigMap references
- Useful for sharing common configuration
configMapRefs.namedConf
Type: string Required: No
Name of ConfigMap containing the main named.conf file.
configMapRefs.namedConfOptions
Type: string Required: No
Name of ConfigMap containing the named.conf.options file.
global
Type: object Required: No
Global BIND9 configuration shared across all instances in the cluster.
⚠️ Warning: There are NO defaults for
allowQueryandallowTransfer. If not specified, BIND9’s default behavior applies (no queries or transfers allowed). Always explicitly configure these fields for your security requirements.
spec:
global:
recursion: false
allowQuery:
- "0.0.0.0/0"
allowTransfer:
- "10.0.2.0/24"
dnssec:
enabled: true
validation: auto
How It Works:
- All instances inherit global configuration
- Instances can override specific settings
- Role-specific configuration (primary/secondary) can override global settings
- Changes propagate to all instances using global config
global.recursion
Type: boolean Required: No Default: false
Enable recursive DNS queries.
global.allowQuery
Type: array of strings Required: No Default: None (BIND9 default: no queries allowed)
IP addresses or CIDR blocks allowed to query servers in this cluster.
⚠️ Warning: No default value is provided. You must explicitly configure this field or queries will be denied.
global.allowTransfer
Type: array of strings Required: No Default: None (BIND9 default: no transfers allowed)
IP addresses or CIDR blocks allowed to perform zone transfers.
⚠️ Warning: No default value is provided. You must explicitly configure this field or zone transfers will be denied.
global.dnssec
Type: object Required: No
DNSSEC configuration for the cluster.
global.dnssec.enabled
Type: boolean Required: No Default: false
Enable DNSSEC signing for zones.
global.dnssec.validation
Type: boolean Required: No Default: false
Enable DNSSEC validation for recursive queries.
global.forwarders
Type: array of strings Required: No Default: []
DNS servers to forward queries to (for recursive mode).
spec:
global:
recursion: true
forwarders:
- "8.8.8.8"
- "1.1.1.1"
global.listenOn
Type: array of strings Required: No Default: [“any”]
IPv4 addresses to listen on.
global.listenOnV6
Type: array of strings Required: No Default: [“any”]
IPv6 addresses to listen on.
rndcSecretRefs
Type: array of RndcSecretRef objects Required: No Default: []
References to Kubernetes Secrets containing RNDC/TSIG keys for authenticated zone transfers and RNDC communication.
# 1. Create Secret with credentials
apiVersion: v1
kind: Secret
metadata:
name: transfer-key-secret
type: Opaque
stringData:
key-name: transfer-key
secret: base64-encoded-hmac-key
---
# 2. Reference in Bind9Cluster
spec:
rndcSecretRefs:
- name: transfer-key-secret
algorithm: hmac-sha256 # Algorithm specified in CRD
How It Works:
- RNDC/TSIG keys authenticate zone transfers and RNDC commands
- Keys stored securely in Kubernetes Secrets
- Algorithm specified in CRD for type safety
- Keys are shared across all instances in the cluster
RndcSecretRef Fields:
name(string, required) - Name of the Kubernetes Secretalgorithm(RndcAlgorithm, optional) - HMAC algorithm (defaults to hmac-sha256)- Supported:
hmac-md5,hmac-sha1,hmac-sha224,hmac-sha256,hmac-sha384,hmac-sha512
- Supported:
keyNameKey(string, optional) - Key in secret for key name (defaults to “key-name”)secretKey(string, optional) - Key in secret for secret value (defaults to “secret”)
acls
Type: object (map of string arrays) Required: No Default: {}
Named Access Control Lists that can be referenced in instance configurations.
spec:
acls:
internal:
- "10.0.0.0/8"
- "172.16.0.0/12"
trusted:
- "192.168.1.0/24"
external:
- "0.0.0.0/0"
How It Works:
- Define ACLs once at cluster level
- Reference by name in instance configurations
- Simplifies managing access control across instances
Usage Example:
# In Bind9Instance
spec:
global:
allowQuery:
- "acl:internal"
allowTransfer:
- "acl:trusted"
volumes
Type: array of Kubernetes Volume objects Required: No Default: []
Kubernetes volumes that can be mounted by instances in this cluster.
spec:
volumes:
- name: zone-data
persistentVolumeClaim:
claimName: dns-zone-pvc
- name: config-override
configMap:
name: custom-bind-config
How It Works:
- Volumes defined at cluster level are inherited by all instances
- Instances can override with their own volumes
- Common use cases include:
- PersistentVolumeClaims for zone data persistence
- ConfigMaps for custom configuration files
- Secrets for sensitive data like TSIG keys
- EmptyDir for temporary storage
Volume Types: Supports all Kubernetes volume types including:
persistentVolumeClaim- Persistent storage for zone dataconfigMap- Configuration filessecret- Sensitive dataemptyDir- Temporary storagehostPath- Host directory (use with caution)nfs- Network file system
volumeMounts
Type: array of Kubernetes VolumeMount objects Required: No Default: []
Volume mount specifications that define where volumes should be mounted in containers.
spec:
volumes:
- name: zone-data
persistentVolumeClaim:
claimName: dns-zone-pvc
volumeMounts:
- name: zone-data
mountPath: /var/lib/bind
readOnly: false
How It Works:
- Volume mounts must reference volumes defined in the
volumesfield - Each mount specifies the volume name and where to mount it
- Instances inherit cluster-level volume mounts unless overridden
- Mounts are applied to the BIND9 container
VolumeMount Fields:
name(string, required) - Volume name to mount (must match a volume)mountPath(string, required) - Path in container where volume is mountedreadOnly(boolean, optional) - Mount as read-only (default: false)subPath(string, optional) - Sub-path within the volume
Status Fields
conditions
Type: array of objects
Standard Kubernetes conditions indicating cluster state.
status:
conditions:
- type: Ready
status: "True"
reason: AllInstancesReady
message: "All 3 instances are ready"
lastTransitionTime: "2024-01-15T10:30:00Z"
Condition Types:
- Ready - Cluster is ready (all instances operational)
- Degraded - Some instances are not ready
- Progressing - Cluster is being reconciled
observedGeneration
Type: integer
The generation of the resource that was last reconciled.
status:
observedGeneration: 5
instanceCount
Type: integer
Total number of Bind9Instance resources referencing this cluster.
status:
instanceCount: 3
readyInstances
Type: integer
Number of instances that are ready and serving traffic.
status:
readyInstances: 3
Complete Examples
Basic Production Cluster
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: production-dns
namespace: dns-system
spec:
version: "9.18"
global:
recursion: false
allowQuery:
- "0.0.0.0/0"
allowTransfer:
- "10.0.2.0/24"
dnssec:
enabled: true
validation: auto
rndcSecretRefs:
- name: transfer-key-secret
algorithm: hmac-sha256
Cluster with Custom Image
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: custom-dns
namespace: dns-system
spec:
version: "9.18"
image:
image: "my-registry.example.com/bind9:hardened"
imagePullPolicy: "Always"
imagePullSecrets:
- my-registry-secret
global:
recursion: false
allowQuery:
- "0.0.0.0/0"
Recursive Resolver Cluster
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: resolver-cluster
namespace: dns-system
spec:
version: "9.18"
global:
recursion: true
allowQuery:
- "10.0.0.0/8" # Internal network only
forwarders:
- "8.8.8.8"
- "8.8.4.4"
- "1.1.1.1"
dnssec:
enabled: false
validation: true
acls:
internal:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
Multi-Region Cluster with ACLs
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: global-dns
namespace: dns-system
spec:
version: "9.18"
global:
recursion: false
allowQuery:
- "0.0.0.0/0"
allowTransfer:
- "acl:secondary-servers"
dnssec:
enabled: true
rndcSecretRefs:
- name: us-east-transfer-secret
algorithm: hmac-sha256
- name: us-west-transfer-secret
algorithm: hmac-sha256
- name: eu-transfer-secret
algorithm: hmac-sha512 # Different algorithm for EU
acls:
secondary-servers:
- "10.1.0.0/24" # US East
- "10.2.0.0/24" # US West
- "10.3.0.0/24" # EU
monitoring:
- "10.0.10.0/24"
Cluster with Persistent Storage
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Cluster
metadata:
name: persistent-dns
namespace: dns-system
spec:
version: "9.18"
global:
recursion: false
allowQuery:
- "0.0.0.0/0"
dnssec:
enabled: true
# Define persistent volume for zone data
volumes:
- name: zone-data
persistentVolumeClaim:
claimName: bind-zone-storage
volumeMounts:
- name: zone-data
mountPath: /var/lib/bind
readOnly: false
Prerequisites: Create a PersistentVolumeClaim first:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: bind-zone-storage
namespace: dns-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: fast-ssd
Cluster Hierarchy
Bind9Cluster
├── Defines shared configuration
├── Manages TSIG keys
├── Defines ACLs
└── Referenced by one or more Bind9Instances
├── Instance inherits cluster config
├── Instance can override cluster settings
└── Instance uses cluster TSIG keys
Configuration Inheritance
When a Bind9Instance references a Bind9Cluster:
- Version - Instance inherits cluster version unless it specifies its own
- Image - Instance inherits cluster image config unless it specifies its own
- Config - Instance inherits cluster config unless it specifies its own
- TSIG Keys - Instance uses cluster TSIG keys for zone transfers
- ACLs - Instance can reference cluster ACLs by name
Override Priority: Instance-level config > Cluster-level config > Default values
Related Resources
- Bind9Instance Specification - Individual DNS server instances
- DNSZone Specification - DNS zones managed by instances
- Examples - Complete configuration examples