Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bind9Instance Specification

Complete specification for the Bind9Instance Custom Resource Definition.

Resource Definition

apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
  name: string
  namespace: string
  labels:
    key: value
spec:
  clusterRef: string          # References Bind9Cluster
  role: primary|secondary     # Required: Server role
  replicas: integer
  version: string             # Optional, overrides cluster version
  image:                      # Optional, overrides cluster image
    image: string
    imagePullPolicy: string
    imagePullSecrets: [string]
  configMapRefs:              # Optional, custom config files
    namedConf: string
    namedConfOptions: string
  global:                     # Optional, overrides cluster global config
    recursion: boolean
    allowQuery: [string]
    allowTransfer: [string]
    dnssec:
      enabled: boolean
      validation: boolean
    forwarders: [string]
    listenOn: [string]
    listenOnV6: [string]
  primaryServers: [string]    # Required for secondary role

Spec Fields

clusterRef

Type: string Required: Yes

Name of the Bind9Cluster that this instance belongs to. The instance inherits cluster-level configuration (version, shared config, TSIG keys, ACLs) from the referenced cluster.

spec:
  clusterRef: production-dns  # References Bind9Cluster named "production-dns"

How It Works:

  • Instance inherits version from cluster unless overridden
  • Instance inherits global config from cluster unless overridden
  • Controller uses cluster TSIG keys for zone transfers
  • Instance can override cluster settings with its own spec

replicas

Type: integer Required: No Default: 1

Number of BIND9 pod replicas to run.

spec:
  replicas: 3

Best Practices:

  • Use 2+ replicas for high availability
  • Use odd numbers (3, 5) for consensus-based systems
  • Consider resource constraints when scaling

version

Type: string Required: No Default: “9.18”

BIND9 version to deploy. Must match available Docker image tags.

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 for the BIND9 instance. Overrides cluster-level image configuration.

spec:
  image:
    image: "my-registry.example.com/bind9:custom"
    imagePullPolicy: "Always"
    imagePullSecrets:
      - my-registry-secret

How It Works:

  • If not specified, inherits from Bind9Cluster.spec.image
  • If cluster doesn’t specify, uses default image internetsystemsconsortium/bind9:9.18
  • Instance-level configuration takes precedence over cluster configuration

image.image

Type: string Required: No Default: “internetsystemsconsortium/bind9:9.18”

Full container image reference including registry, repository, and tag.

spec:
  image:
    image: "docker.io/internetsystemsconsortium/bind9:9.18"

Examples:

  • Public registry: "internetsystemsconsortium/bind9:9.18"
  • Private registry: "my-registry.example.com/dns/bind9:custom"
  • With digest: "bind9@sha256:abc123..."

image.imagePullPolicy

Type: string Required: No Default: “IfNotPresent”

Kubernetes image pull policy.

spec:
  image:
    imagePullPolicy: "Always"

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
      - gcr-pull-secret

Setup:

  1. Create a docker-registry secret:
    kubectl create secret docker-registry my-registry-secret \
      --docker-server=my-registry.example.com \
      --docker-username=user \
      --docker-password=pass \
      --docker-email=email@example.com
    
  2. Reference the secret name in imagePullSecrets

configMapRefs

Type: object Required: No

References to custom ConfigMaps containing BIND9 configuration files. Overrides cluster-level ConfigMap references.

spec:
  configMapRefs:
    namedConf: "my-custom-named-conf"
    namedConfOptions: "my-custom-options"

How It Works:

  • If specified, Bindy uses your custom ConfigMaps instead of auto-generating configuration
  • If not specified, Bindy auto-generates ConfigMaps from the config block
  • Instance-level references override cluster-level references
  • You can specify one or both ConfigMaps

Default Behavior:

  • If configMapRefs is not set, Bindy creates a ConfigMap named <instance-name>-config
  • Auto-generated ConfigMap includes both named.conf and named.conf.options
  • Configuration is built from the config block in the spec

configMapRefs.namedConf

Type: string Required: No

Name of ConfigMap containing the main named.conf file.

spec:
  configMapRefs:
    namedConf: "my-named-conf"

ConfigMap Format:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-named-conf
  namespace: dns-system
data:
  named.conf: |
    // Custom BIND9 configuration
    include "/etc/bind/named.conf.options";
    include "/etc/bind/zones/named.conf.zones";

    logging {
      channel custom_log {
        file "/var/log/named/queries.log" versions 3 size 5m;
        severity info;
      };
      category queries { custom_log; };
    };

File Location: The ConfigMap data must have a key named.conf which will be mounted at /etc/bind/named.conf

configMapRefs.namedConfOptions

Type: string Required: No

Name of ConfigMap containing the named.conf.options file.

spec:
  configMapRefs:
    namedConfOptions: "my-options"

ConfigMap Format:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-options
  namespace: dns-system
data:
  named.conf.options: |
    options {
      directory "/var/cache/bind";
      recursion no;
      allow-query { any; };
      dnssec-validation auto;
    };

File Location: The ConfigMap data must have a key named.conf.options which will be mounted at /etc/bind/named.conf.options

Examples:

Using separate ConfigMaps for fine-grained control:

spec:
  configMapRefs:
    namedConf: "prod-named-conf"
    namedConfOptions: "prod-options"

Using only custom options, auto-generating main config:

spec:
  configMapRefs:
    namedConfOptions: "my-custom-options"
  # namedConf not specified - will be auto-generated

global

Type: object Required: No

BIND9 configuration options that override cluster-level global configuration.

global.recursion

Type: boolean Required: No Default: false

Enable recursive DNS queries. Should be false for authoritative servers.

spec:
  global:
    recursion: false

Warning: Enabling recursion on public-facing authoritative servers is a security risk.

global.allowQuery

Type: array of strings Required: No Default: [“0.0.0.0/0”]

IP addresses or CIDR blocks allowed to query this server.

spec:
  global:
    allowQuery:
      - "0.0.0.0/0"        # Allow all (public DNS)
      - "10.0.0.0/8"       # Private network
      - "192.168.1.0/24"   # Specific subnet

global.allowTransfer

Type: array of strings Required: No Default: []

IP addresses or CIDR blocks allowed to perform zone transfers (AXFR/IXFR).

spec:
  global:
    allowTransfer:
      - "10.0.1.10"        # Specific secondary server
      - "10.0.1.11"        # Another secondary

Security Note: Restrict zone transfers to trusted secondary servers only.

global.dnssec

Type: object Required: No

DNSSEC configuration for signing zones and validating responses.

global.dnssec.enabled

Type: boolean Required: No Default: false

Enable DNSSEC signing for zones.

spec:
  global:
    dnssec:
      enabled: true
global.dnssec.validation

Type: boolean Required: No Default: false

Enable DNSSEC validation for recursive queries.

spec:
  global:
    dnssec:
      enabled: true
      validation: true

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"
      - "8.8.4.4"

global.listenOn

Type: array of strings Required: No Default: [“any”]

IPv4 addresses to listen on.

spec:
  global:
    listenOn:
      - "any"              # All IPv4 interfaces
      - "10.0.1.10"        # Specific IP

global.listenOnV6

Type: array of strings Required: No Default: [“any”]

IPv6 addresses to listen on.

spec:
  global:
    listenOnV6:
      - "any"              # All IPv6 interfaces
      - "2001:db8::1"      # Specific IPv6

Status Fields

conditions

Type: array of objects

Standard Kubernetes conditions indicating resource state.

status:
  conditions:
    - type: Ready
      status: "True"
      reason: ReconcileSuccess
      message: "Instance is ready"
      lastTransitionTime: "2024-01-15T10:30:00Z"

Condition Types:

  • Ready - Instance is ready for use
  • Available - Instance is serving DNS queries
  • Progressing - Instance is being reconciled
  • Degraded - Instance is partially functional
  • Failed - Instance reconciliation failed

observedGeneration

Type: integer

The generation of the resource that was last reconciled.

status:
  observedGeneration: 5

replicas

Type: integer

Total number of replicas configured.

status:
  replicas: 3

readyReplicas

Type: integer

Number of replicas that are ready and serving traffic.

status:
  readyReplicas: 3

Complete Example

Primary DNS Instance

# First create the Bind9Cluster
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

---
# Then create the Bind9Instance referencing the cluster
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
  name: primary-dns
  namespace: dns-system
  labels:
    dns-role: primary
    environment: production
spec:
  clusterRef: production-dns  # References cluster above
  role: primary  # Required: primary or secondary
  replicas: 2
  # Inherits version and global config from cluster

Secondary DNS Instance

apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
  name: secondary-dns
  namespace: dns-system
  labels:
    dns-role: secondary
    environment: production
spec:
  clusterRef: production-dns  # References same cluster as primary
  role: secondary  # Required: primary or secondary
  replicas: 2
  # Override global config for secondary role
  global:
    allowTransfer: []  # No zone transfers from secondary
    dnssec:
      enabled: false
      validation: true

Recursive Resolver

# Separate cluster for resolvers
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"
      - "1.1.1.1"
    dnssec:
      enabled: false
      validation: true

---
apiVersion: bindy.firestoned.io/v1alpha1
kind: Bind9Instance
metadata:
  name: resolver
  namespace: dns-system
  labels:
    dns-role: resolver
spec:
  clusterRef: resolver-cluster
  role: primary  # Required: primary or secondary
  replicas: 3
  # Inherits recursive global config from cluster