Skip to content
Back to skills

Coredns

ASecurity

Expert coverage of CoreDNS cloud-native DNS server: Corefile plugin-chain configuration, Kubernetes DNS (cluster.local, services, pods, headless, ExternalName), NodeLocal DNSCache, custom Go plugins, forward/cache/rewrite/prometheus plugins, ConfigMap management, and DNS performance in large clusters. Use for \"CoreDNS\", \"Corefile\", \"Kubernetes DNS\", \"kube-dns\", \"NodeLocal DNSCache\", \"CoreDNS plugin\", \"cluster.local\", \"CoreDNS ConfigMap\". Do NOT use for cross-vendor comparison,...

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
devopsgobashnodekubernetesgitapibackendsecurityperformance

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add chrishuffman5/domain-expert --skill coredns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Coredns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Coredns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-coredns/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-coredns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: coredns
description: "Expert coverage of CoreDNS cloud-native DNS server: Corefile plugin-chain configuration, Kubernetes DNS (cluster.local, services, pods, headless, ExternalName), NodeLocal DNSCache, custom Go plugins, forward/cache/rewrite/prometheus plugins, ConfigMap management, and DNS performance in large clusters. Use for \"CoreDNS\", \"Corefile\", \"Kubernetes DNS\", \"kube-dns\", \"NodeLocal DNSCache\", \"CoreDNS plugin\", \"cluster.local\", \"CoreDNS ConfigMap\". Do NOT use for cross-vendor comparison, platform selection, or category-wide architecture -- use the `dns` skill."
license: MIT
---

# CoreDNS

This skill covers CoreDNS (1.13), the cloud-native DNS server written in Go that serves as the default DNS service for Kubernetes (since 1.13). Areas of expertise include:

- Plugin-chain architecture with Corefile configuration
- Kubernetes DNS specification: service/pod resolution, headless services, ExternalName, SRV records
- NodeLocal DNSCache for high-performance per-node caching in large clusters
- Core plugins: kubernetes, forward, cache, loop, loadbalance, rewrite, prometheus, errors, health, ready
- ConfigMap-based hot-reload for Kubernetes deployments
- Custom Go plugin development (plugin.Handler interface)
- Conditional forwarding for hybrid DNS (Kubernetes + corporate DNS)
- DNS performance optimization in microservices architectures

## How to Approach Tasks

1. **Classify** the request:
   - **Kubernetes DNS** -- Service discovery, pod resolution, ConfigMap configuration
   - **Plugin configuration** -- Corefile syntax, plugin chaining, conditional forwarding
   - **Performance** -- NodeLocal DNSCache, cache tuning, conntrack issues
   - **Custom development** -- Go plugin development, build system, plugin.cfg
   - **Architecture** -- Load `references/architecture.md` for plugin chain, Kubernetes integration, NodeLocal DNSCache

2. **Identify deployment** -- Kubernetes CoreDNS (most common), standalone CoreDNS, or NodeLocal DNSCache DaemonSet.

3. **Identify cluster scale** -- Small (< 100 pods) vs large (1000+ pods). Scale determines whether NodeLocal DNSCache is needed and cache sizing.

4. **Recommend** -- Provide Corefile configuration blocks. For Kubernetes, show ConfigMap edits with `kubectl edit configmap coredns -n kube-system`.

## Core Architecture

### Plugin Chain

CoreDNS processes queries through an ordered chain of plugins:
- Each `server block` in the Corefile binds to an address:port and chains plugins
- Plugins execute in the order specified in `plugin.cfg` (compile-time), not Corefile order
- First plugin to handle a query responds; remaining plugins are skipped
- Plugin writes a response OR calls `plugin.NextOrFailure()` to pass to next plugin

### Corefile Structure

```
.:53 {
    errors
    health {
       lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
       pods insecure
       fallthrough in-addr.arpa ip6.arpa
       ttl 30
    }
    prometheus :9153
    forward . /etc/resolv.conf {
       max_concurrent 1000
    }
    cache 30
    loop
    reload
    loadbalance
}
```

Multiple server blocks for different zones:
```
cluster.local:53 {
    kubernetes cluster.local
    cache 30
}

corp.internal:53 {
    forward . 10.0.0.53
    cache 60
}

.:53 {
    forward . 8.8.8.8 1.1.1.1
    cache 30
}
```

## Kubernetes DNS

### Record Types

| Query Pattern | Record Type | Resolution |
|---|---|---|
| `<svc>.<ns>.svc.cluster.local` | A/AAAA | ClusterIP |
| `<pod-ip-dashes>.<ns>.pod.cluster.local` | A | Pod IP |
| `_<port>._<proto>.<svc>.<ns>.svc.cluster.local` | SRV | Named port endpoints |
| Headless service | A | All pod IPs (multiple records) |
| ExternalName service | CNAME | External FQDN |

### Kubernetes Plugin Configuration

```
kubernetes cluster.local in-addr.arpa ip6.arpa {
    pods insecure                          # pod record mode: disabled|insecure|verified
    fallthrough in-addr.arpa ip6.arpa      # pass unresolved reverse to next plugin
    ttl 30                                 # TTL for DNS records
    endpoint_pod_names                     # use pod names in A record responses
    namespaces <ns1> <ns2>                 # restrict to specific namespaces
}
```

Pod modes:
- `disabled`: no pod records
- `insecure`: return pod IP for any query matching pod IP format (default)
- `verified`: verify pod exists in Kubernetes API before returning record

### ConfigMap Hot-Reload

The `reload` plugin watches for ConfigMap changes and hot-reloads without pod restart:

```bash
kubectl edit configmap coredns -n kube-system
```

Changes take effect within the reload interval (default 30s, configurable).

### Conditional Forwarding (Hybrid DNS)

Add stub domains for corporate/internal DNS resolution:

```
corp.internal:53 {
    errors
    cache 30
    forward . 10.0.0.53 10.0.0.54
}

consul.local:53 {
    errors
    cache 15
    forward . 10.0.0.8600
}
```

## NodeLocal DNSCache

Improves DNS performance in large Kubernetes clusters:

```
Pod ──► NodeLocal DNSCache (169.254.20.10) ──► kube-dns ClusterIP ──► CoreDNS
        (per-node DaemonSet)                    (on cache miss)
```

- Runs CoreDNS as DaemonSet on every node
- Each node has local cache at link-local IP `169.254.20.10`
- **Eliminates iptables DNAT and conntrack for DNS** -- critical at scale
- Conntrack table exhaustion is a common DNS failure mode in large clusters
- Cache misses forwarded to kube-dns ClusterIP
- Reduces p99 DNS latency significantly for DNS-heavy workloads

### Deployment

```bash
kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml
```

Requires kubelet `--cluster-dns=169.254.20.10` configuration.

## Core Plugins

| Plugin | Purpose | Key Config |
|---|---|---|
| `kubernetes` | Kubernetes service/pod resolution | Zone, pod mode, fallthrough |
| `forward` | Upstream forwarding | Servers, max_concurrent, policy |
| `cache` | Response caching | TTL, max size, denial caching |
| `loop` | Loop detection (prevent forwarding loops) | Auto-detection |
| `loadbalance` | Round-robin A/AAAA records | Automatic |
| `health` | Health probe endpoint (:8080/health) | lameduck duration |
| `ready` | Readiness probe endpoint (:8181/ready) | Per-plugin readiness |
| `prometheus` | Metrics endpoint (:9153/metrics) | Automatic |
| `errors` | Error logging | Consolidation period |
| `log` | Query logging | Response class filter |
| `rewrite` | Name/type/class rewriting | Pattern, answer rewriting |
| `hosts` | Zone from hosts file format | Inline entries, fallthrough |
| `dnssec` | Inline DNSSEC signing | Key file, zones |
| `transfer` | AXFR zone transfer | To/from configuration |
| `etcd` | SkyDNS v1 compatibility | etcd endpoints |
| `grpc` | gRPC DNS backend | Server address |

### Forward Plugin Options

```
forward . 8.8.8.8 1.1.1.1 {
    max_concurrent 1000                    # concurrent queries per upstream
    policy round_robin                     # round_robin | random | sequential
    health_check 5s                        # upstream health check interval
    tls_servername dns.google              # for DNS over TLS
    force_tcp                              # force TCP transport
    expire 10s                             # connection expiry
}
```

### Rewrite Plugin

```
rewrite name exact old.example.com new.example.com
rewrite name suffix .old.example.com .new.example.com answer auto
rewrite type AAAA A                        # rewrite query type
```

## CoreDNS 1.13 Features

- **DoH3 (DNS over HTTP/3)**: experimental QUIC/HTTP3 transport support
- **Regex length limit**: security hardening in `rewrite` plugin
- **QUIC listener initialization**: safer startup preventing race conditions
- **Kubernetes API rate limiting**: improved rate limiting with metrics
- **Reduced SOA warnings**: fewer misleading log entries
- **Data race fix in `uniq` plugin**: stability for response deduplication

## Custom Go Plugins

Extend CoreDNS by implementing `plugin.Handler`:

```go
package myplugin

import (
    "github.com/coredns/coredns/plugin"
    "github.com/miekg/dns"
)

type MyPlugin struct {
    Next plugin.Handler
}

func (m MyPlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
    // Custom logic here
    return plugin.NextOrFailure(m.Name(), m.Next, ctx, w, r)
}

func (m MyPlugin) Name() string { return "myplugin" }
```

Build with custom `plugin.cfg`:
```
# Add custom plugin to plugin chain
myplugin:github.com/myorg/coredns-myplugin
```

Compile: `go generate && go build`

## Common Pitfalls

1. **Loop detection false positive** -- The `loop` plugin detects forwarding loops by sending a test query. If CoreDNS forwards to itself (e.g., via /etc/resolv.conf pointing to localhost), it shuts down. Fix: ensure `forward . <upstream>` does not point back to CoreDNS.
2. **Conntrack exhaustion without NodeLocal DNSCache** -- In large clusters, DNS queries through kube-proxy iptables consume conntrack entries. At scale, conntrack table exhaustion causes DNS failures. Deploy NodeLocal DNSCache.
3. **ConfigMap edit syntax errors** -- YAML indentation errors in CoreDNS ConfigMap cause CoreDNS to crash-loop. Always validate YAML before applying. Use `kubectl logs -n kube-system -l k8s-app=kube-dns` to check for errors.
4. **Stub domain ordering** -- More specific zones must have separate server blocks. Zone matching is longest-suffix-first, but plugin chain order within a block matters.
5. **Cache TTL too high for dynamic environments** -- Default 30s cache is fine for stable services. For rapidly changing endpoints (canary, blue-green), reduce or disable cache for specific zones.
6. **Missing `fallthrough` on kubernetes plugin** -- Without `fallthrough`, reverse DNS queries for non-Kubernetes IPs return NXDOMAIN instead of forwarding to upstream. Add `fallthrough in-addr.arpa ip6.arpa`.

## Reference Files

- `references/architecture.md` -- Plugin architecture, Corefile, Kubernetes DNS, NodeLocal DNSCache

Files in this skill

  • SKILL.md9.8 KB
  • references/architecture.md8.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…