externaldns

package module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

README

CoreDNS External-DNS Plugin

A CoreDNS plugin that serves DNS records from external-dns DNSEndpoint CRDs.

How It Works

  1. Watches Kubernetes Resources:
    • DNSEndpoint CRDs for generic DNS record definitions
    • Services (Type LoadBalancer) for automatic service discovery
    • Ingresses for HTTP/HTTPS routing discovery
  2. Caches records in memory for fast DNS query responses
  3. Serves DNS queries directly from the cache
  4. Auto-generates PTR records when enabled via annotation

Quick Start

# Deploy with Helm
helm install coredns-externaldns oci://ghcr.io/ionos-cloud/coredns-externaldns/charts/coredns-externaldns

# Or build and run standalone
git clone https://github.com/ionos-cloud/coredns-externaldns
cd coredns-externaldns
make build
./coredns-externaldns -conf Corefile.standalone

Configuration

Corefile Example
.:53 {
    externaldns {
        namespace default              # Optional: watch specific namespace
        ttl 300                       # Optional: default TTL (seconds)
        configmap_name zone-serials   # Optional: ConfigMap for serial persistence
        soa_ns ns1.example.com        # Optional: SOA nameserver for AXFR
        soa_mbox admin.example.com    # Optional: SOA mailbox for AXFR
        authoritative_zones example.com,test.com  # Optional: explicit zone list
    }
    forward . 8.8.8.8
    log
    errors
}
Authoritative Zones

Configure authoritative_zones to define which DNS zones this plugin serves. This enables proper zone boundaries and DNS NOTIFY functionality.

By default, the plugin uses the zones from the Corefile where it's loaded (e.g., example.com:53). Setting authoritative_zones overrides this with an explicit zone list.

Format: Comma-separated zone list

authoritative_zones example.com,internal.local,test.net

With DNS NOTIFY:

transfer { to * }
externaldns {
    authoritative_zones example.com
    soa_ns ns1.example.com
}
DNSEndpoint Example
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
  name: example
  annotations:
    coredns-externaldns.ionos.cloud/create-ptr: "true"  # Enable PTR records
spec:
  endpoints:
  - dnsName: app.example.com
    recordType: A
    targets: ["192.168.1.100"]
    recordTTL: 300

Service Support

The plugin automatically creates DNS records for Services of type LoadBalancer.

Requirements
  • Service must be of type LoadBalancer
  • Must have external-dns.alpha.kubernetes.io/hostname annotation
Example
apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: nginx.example.com
    external-dns.alpha.kubernetes.io/ttl: "60"
    coredns-externaldns.ionos.cloud/create-ptr: "true"
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx

Ingress Support

The plugin automatically creates DNS records for Ingress resources.

Configuration

Hostnames are discovered from the following sources (can be combined):

  1. Explicit Hostname: Using external-dns.alpha.kubernetes.io/hostname annotation
  2. From Rules: Using coredns-externaldns.ionos.cloud/ingress-from-rules: "true" annotation to use hosts defined in spec.rules

If both are present, records will be created for all unique hostnames found.

Example (Explicit Hostname)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: nginx.example.com
    coredns-externaldns.ionos.cloud/create-ptr: "true"
spec:
  rules:
  - host: nginx.internal
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80
Example (From Rules)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    coredns-externaldns.ionos.cloud/ingress-from-rules: "true"
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app
            port:
              number: 80

PTR Record Feature

The plugin can automatically create reverse DNS (PTR) records for A and AAAA records.

How to Enable

Add this annotation to your DNSEndpoint, Service, or Ingress:

metadata:
  annotations:
    coredns-externaldns.ionos.cloud/create-ptr: "true"
How It Works
  1. Forward Record: app.example.com A 192.168.1.100
  2. Auto-Generated PTR: 100.1.168.192.in-addr.arpa PTR app.example.com

When you query 192.168.1.100 for reverse DNS, it returns app.example.com.

Supported: Works with both A (IPv4) and AAAA (IPv6) records.

RBAC Requirements

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: coredns-externaldns
rules:
- apiGroups: ["externaldns.k8s.io"]
  resources: ["dnsendpoints"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update"]
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch"]

Supported Record Types

A, AAAA, CNAME, MX, TXT, SRV, PTR, NS, SOA

License

Apache 2.0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Core settings
	Namespace string
	TTL       uint32
	Zones     []string

	// SOA configuration
	SOA SOAConfig

	// ConfigMap settings for zone serial persistence
	ConfigMap ConfigMapConfig
}

Config holds the plugin configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a configuration with sensible defaults

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the configuration is valid

type ConfigMapConfig

type ConfigMapConfig struct {
	Name      string // ConfigMap name
	Namespace string // ConfigMap namespace
}

ConfigMapConfig holds ConfigMap settings

type Plugin

type Plugin struct {
	Next plugin.Handler
	// contains filtered or unexported fields
}

Plugin represents the ExternalDNS CoreDNS plugin

func New

func New(config *Config) *Plugin

New creates a new ExternalDNS plugin instance

func (*Plugin) Name

func (p *Plugin) Name() string

Name implements the plugin.Handler interface

func (*Plugin) OnAdd

func (p *Plugin) OnAdd(endpoint *externaldnsv1alpha1.DNSEndpoint) error

OnAdd handles DNSEndpoint addition events

func (*Plugin) OnDelete

func (p *Plugin) OnDelete(endpoint *externaldnsv1alpha1.DNSEndpoint) error

OnDelete handles DNSEndpoint deletion events

func (*Plugin) OnIngressAdd

func (p *Plugin) OnIngressAdd(ing *networkingv1.Ingress) error

OnIngressAdd handles Ingress addition events

func (*Plugin) OnIngressDelete

func (p *Plugin) OnIngressDelete(ing *networkingv1.Ingress) error

OnIngressDelete handles Ingress deletion events

func (*Plugin) OnIngressUpdate

func (p *Plugin) OnIngressUpdate(ing *networkingv1.Ingress) error

OnIngressUpdate handles Ingress update events

func (*Plugin) OnServiceAdd

func (p *Plugin) OnServiceAdd(svc *corev1.Service) error

OnServiceAdd handles Service addition events

func (*Plugin) OnServiceDelete

func (p *Plugin) OnServiceDelete(svc *corev1.Service) error

OnServiceDelete handles Service deletion events

func (*Plugin) OnServiceUpdate

func (p *Plugin) OnServiceUpdate(svc *corev1.Service) error

OnServiceUpdate handles Service update events

func (*Plugin) OnUpdate

func (p *Plugin) OnUpdate(endpoint *externaldnsv1alpha1.DNSEndpoint) error

OnUpdate handles DNSEndpoint update events

func (*Plugin) ServeDNS

func (p *Plugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error)

ServeDNS implements the plugin.Handler interface

func (*Plugin) Start

func (p *Plugin) Start(ctx context.Context) error

Start initializes and starts the plugin

func (*Plugin) Stop

func (p *Plugin) Stop()

Stop stops the plugin

func (*Plugin) Transfer

func (p *Plugin) Transfer(zone string, serial uint32) (<-chan []dns.RR, error)

Transfer implements the transfer.Transfer interface for AXFR support

type SOAConfig

type SOAConfig struct {
	Nameserver string // NS field
	Mailbox    string // MBOX field
	Refresh    uint32 // Refresh interval
	Retry      uint32 // Retry interval
	Expire     uint32 // Expire time
	MinTTL     uint32 // Minimum TTL
}

SOAConfig holds SOA record configuration

Directories

Path Synopsis
cmd
internal
dns

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL