Pod در Kubernetes با IP کار میکند — اما application با نام صحبت میکند:
curl http://api.default.svc.cluster.localبدون DNS، service discovery از کار میافتد. هر query داخلی، هر اتصال به RDS خارج cluster، هر lookup برای TLS certificate — همه از DNS engine cluster عبور میکنند.
CoreDNS همان engine است:
DNS and Service Discovery — A flexible DNS server written in Go, powered by plugins.
یعنی یک process، یک config (Corefile) — نه سه container در یک Pod مثل kube-dns قدیمی.
CNCF Graduated — ۲۴ ژانویه ۲۰۱۹. از Kubernetes v1.13 بهعنوان default cluster DNS. MIT، Infoblox، SoundCloud، Admiral — production at scale.
مشکل DNS سنتی در cluster
kube-dns (legacy):
kubedns → cluster service lookup
dnsmasq → cache + forward (CVE history)
sidecar → metrics + health
CoreDNS:
single binary → plugin chain → answer or forward| معیار | BIND/Knot | kube-dns | CoreDNS |
|---|---|---|---|
| هدف | authoritative/recursive عمومی | فقط K8s | flexible — هر محیط |
| معماری | monolithic | ۳ container | plugin chain |
| Config | zone files + named.conf | limited args | Corefile |
| K8s native | manual | built-in | kubernetes plugin |
| Observability | stats zone | sidecar | prometheus plugin |
| CNCF | — | — | ✅ Graduated ۲۰۱۹ |
CoreDNS برای cloud-native service discovery طراحی شده — Kubernetes، etcd، Route53، Azure DNS، GCP Cloud DNS — همه via plugin.
CoreDNS چیست؟
CoreDNS DNS server است که:
- Go نوشته شده — single static binary (یا Docker image scratch-based)
- Plugin-based — هر «تابع DNS» یک plugin با Plugin API
- Corefile configure میکند — Server Block + zone + plugins
- Flexible — authoritative، recursive forward، service discovery، rewrite، cache، metrics — در یک chain
Repo: github.com/coredns/coredns
License: Apache 2.0
Latest release: v1.14.6 (ژوئیه ۲۰۲۶)
تاریخچه و CNCF
| تاریخ | رویداد |
|---|---|
| مارس ۲۰۱۶ | First commit — Miek Gieben و community |
| فوریه ۲۰۱۷ | CNCF Sandbox |
| فوریه ۲۰۱۸ | CNCF Incubating |
| ۲۴ ژانویه ۲۰۱۹ | CNCF Graduated |
| Kubernetes v1.13 | Default cluster DNS — جایگزین kube-dns |
| ongoing | ~۳۰ built-in plugin + external plugins |
Adopters: Kubernetes (built-in)، MIT، Infoblox، SoundCloud، Admiral، SBG — هر clusterی که kube-dns ندارد، CoreDNS دارد.
معماری: Server، Zone، Plugin Chain
CoreDNS بعد از parse کردن Corefile، یک یا چند Server بالا میآورد. هر Server:
- Zone مشخص — مثلاً
.،cluster.local،coredns.io:53 - Port/Protocol — DNS، DoT (
tls://)، DoH (https://)، gRPC - Plugin Chain — ترتیب ثابت از
plugin.cfg
مسیریابی query
Client query → port 53
↓
Longest suffix match → Server Block مناسب
↓
Plugin chain (plugin.cfg order)
↓
Answer → client OR SERVFAILنکته حیاتی: ترتیب plugins در Corefile تعیینکننده ترتیب اجرا نیست. ترتیب واقعی در plugin.cfg هنگام compile fix است — مثلاً cache قبل از kubernetes اجرا میشود.
چهار حالت پردازش query
| حالت | رفتار | مثال |
|---|---|---|
| Processed | plugin پاسخ میدهد، chain متوقف | whoami |
| Not processed | به plugin بعدی | — |
| Fallthrough | backend NXDOMAIN داد، plugin بعدی هم چک کند | hosts، kubernetes |
| Hint | query را pass میکند، response را inspect | prometheus |
Corefile: زبان configuration
Corefile از Server Block تشکیل شده:
# zone[:port] {
# plugin [directives]
# plugin {
# block directives
# }
# }
.:53 {
errors
health
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}Server Block
- Zone:
.= root (catch-all)،example.org= authoritative - Port:
.:1053— default 53 - Protocol prefix:
tls://،https://،grpc://،dns:// - Comments:
#تا انتهای خط
Snippets و import
(common) {
errors
log
prometheus :9153
}
.:53 {
import common
kubernetes cluster.local
forward . 8.8.8.8
cache 30
}Environment variables
. {
forward . {$UPSTREAM_DNS}
}Syntax: {$ENV_VAR} یا {%ENV_VAR%}
Plugins اصلی
CoreDNS ~۳۰ plugin built-in دارد + external plugins. مهمترینها:
kubernetes
Service discovery داخل cluster — از Kubernetes API:
kubernetes cluster.local in-addr.arpa ip6.arpa {
kubeconfig /root/.kube/config
pods verified
endpoint_pod_names
ttl 30
fallthrough
}cluster.local— default cluster domainpods verified— فقط Podهایی که Service endpoint دارندpods insecure— همه Podها (deprecated pattern)fallthrough— query unresolved به plugin بعدی
نامگذاری استاندارد:
<service>.<namespace>.svc.cluster.local
<pod-ip-dashed>.<namespace>.pod.cluster.localforward
Queryهای unresolved را به upstream میفرستد:
. {
forward . 8.8.8.8 9.9.9.9
}
. {
forward example.org 8.8.8.8
forward . /etc/resolv.conf
}policy— random، round_robin، sequentialhealth_check— upstream monitoringmax_concurrent— limit parallel upstream queries
cache
پاسخ DNS را cache میکند — قبل از data plugins در chain:
cache [TTL] [zones...] {
success 9984 30
denial 9984 5
}Default TTL داخلی Kubernetes: ۳۰ ثانیه. Cache باعث میشود query تکراری به kubernetes یا forward نرود.
file / auto
Authoritative serving از zone file:
example.org {
file db.example.org
log
}auto — zone files را از disk watch میکند.
etcd
Dynamic records از etcd — برای service discovery خارج Kubernetes:
cluster.local {
etcd {
path /skydns
endpoint http://etcd:2379
}
}hosts
Static entries شبیه /etc/hosts:
hosts {
10.0.0.1 api.internal
fallthrough
}rewrite
Query یا response را transform میکند:
rewrite name regex (.*)\.nginx\.default\.svc\.cluster\.local {1}.default.svc.cluster.localprometheus / health / ready / errors / log
| Plugin | کار |
|---|---|
| prometheus | metrics روی :9153/metrics |
| health | HTTP health endpoint (global) |
| ready | readiness — kubernetes plugin synced |
| errors | log errors |
| log | log every query |
سایر plugins مفید
- loop — detect forwarding loops
- reload — reload Corefile on change
- loadbalance — round-robin A/AAAA records
- template — dynamic responses
- transfer — zone transfer (AXFR/IXFR)
- sign — DNSSEC signing
- route53 / azure / gcp — cloud DNS backends
- acl — access control
- dnssec — DNSSEC validation
CoreDNS در Kubernetes
از Kubernetes v1.13، CoreDNS default cluster DNS است. Deployment در kube-system:
kubectl get deployment -n kube-system coredns
kubectl get svc -n kube-system kube-dns
kubectl get configmap -n kube-system coredns -o yamlCorefile پیشفرض (تقریبی)
.: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
}Pod DNS config
هر Pod از /etc/resolv.conf cluster DNS استفاده میکند:
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
dnsPolicy: ClusterFirst # default
dnsConfig:
nameservers:
- "10.96.0.10"
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "5"| dnsPolicy | رفتار |
|---|---|
| ClusterFirst | cluster DNS → upstream (default) |
| ClusterFirstWithHostNet | host network + cluster DNS |
| Default | node resolv.conf |
| None | فقط dnsConfig |
Service: kube-dns
ClusterIP (معمولاً 10.96.0.10) — همان IP در kubectl get svc kube-dns.
مقیاسپذیری
kubectl scale deployment coredns -n kube-system --replicas=3برای cluster بزرگ: NodeLocal DNSCache — cache روی هر node:
# DaemonSet — listens 169.254.20.10 on each node
# kubelet → NodeLocal → CoreDNS cluster IPمزایا: latency کمتر، traffic به CoreDNS central کمتر، cache محلی.
DNS flow در cluster
Pod query: api.default.svc.cluster.local
↓
/etc/resolv.conf → kube-dns ClusterIP (10.96.0.10)
↓
CoreDNS Pod
↓
cache → hit? return
↓ miss
kubernetes plugin → API server lookup
↓
Service ClusterIP + Endpoints
↓
A record → PodQuery خارجی:
Pod query: google.com
↓
kubernetes → NXDOMAIN (not cluster.local)
↓
forward → /etc/resolv.conf → upstream (node DNS)
↓
cache → store 30sاین flow با Cilium CNI و Kube-OVN سازگار است — DNS مستقل از data plane است.
پروتکلهای مدرن DNS
CoreDNS از چند transport پشتیبانی میکند:
# DNS over TLS (RFC 7858)
tls://.:853 {
tls cert.pem key.pem
forward . 8.8.8.8
}
# DNS over HTTPS (RFC 8484)
https://.:443 {
tls cert.pem key.pem
forward . 1.1.1.1
}
# DNS over gRPC
grpc://.:5353 {
forward . /etc/resolv.conf
}برای TLS certificate management در cluster، cert-manager میتواند cert برای DoH/DoT صادر کند.
نصب standalone
Binary
curl -LO https://github.com/coredns/coredns/releases/download/v1.14.6/coredns_1.14.6_linux_amd64.tgz
tar xzf coredns_1.14.6_linux_amd64.tgz
./coredns -plugins # list compiled pluginsDocker
docker run -d --name coredns \
-p 53:53 -p 53:53/udp \
-v $(pwd)/Corefile:/Corefile \
coredns/coredns:1.14.6systemd
[Unit]
Description=CoreDNS DNS server
After=network.target
[Service]
ExecStart=/usr/local/bin/coredns -conf /etc/coredns/Corefile
Restart=on-failure
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.targetCustom Corefile در Kubernetes
ویرایش ConfigMap
kubectl edit configmap coredns -n kube-systemمثال: custom upstream
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
fallthrough in-addr.arpa ip6.arpa
}
forward . 1.1.1.1 8.8.8.8 {
policy sequential
}
cache 30
loop
reload
}kubectl rollout restart deployment coredns -n kube-systemمثال: static record + fallthrough
.:53 {
kubernetes cluster.local {
fallthrough
}
file /etc/coredns/extra.db cluster.local
forward . /etc/resolv.conf
cache 30
}extra.db:
extra.cluster.local. IN A 10.0.0.99Observability
Prometheus metrics
prometheus :9153Metrics مهم:
coredns_dns_requests_total— by type، zonecoredns_dns_request_duration_secondscoredns_cache_hits_total/coredns_cache_misses_totalcoredns_forward_healthcheck_broken_total
Health check
curl http://<coredns-pod-ip>:8080/health
curl http://<coredns-pod-ip>:8181/readyDebug query
# از داخل cluster
kubectl run -it --rm debug --image=busybox --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local
kubectl run -it --rm debug --image=nicolaka/netshoot --restart=Never -- \
dig @kube-dns.kube-system.svc.cluster.local kubernetes.default.svc.cluster.local
# CH class — version
dig @10.96.0.10 -p 53 CH version.bind TXTTroubleshooting
nslookup: can't resolve
# 1. CoreDNS running?
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 2. Service endpoint
kubectl get ep -n kube-system kube-dns
# 3. Corefile syntax
kubectl logs -n kube-system -l k8s-app=kube-dns
# 4. Pod resolv.conf
kubectl exec -it <pod> -- cat /etc/resolv.confSERVFAIL مکرر
- upstream DNS unreachable —
forwardconfig - API server timeout —
kubernetesplugin - loop detected —
loopplugin؛ circular forward
Slow DNS
- scale CoreDNS replicas
- enable NodeLocal DNSCache
- tune
cacheTTL max_concurrentدر forward
NXDOMAIN برای service موجود
- namespace/search path —
ndotsoption - typo در FQDN
- Service/Endpoints وجود ندارد
Corefile parse error
Error during parsing: Unknown directiveمعمولاً plugin خارج Server Block — همه plugins باید داخل { } باشند.
CoreDNS vs جایگزینها
| سناریو | انتخاب |
|---|---|
| Kubernetes cluster DNS | CoreDNS (built-in) |
| Enterprise authoritative DNS | BIND، Knot، PowerDNS |
| Recursive resolver عمومی | Unbound، BIND |
| Service mesh + mTLS | CoreDNS + Cilium |
| Custom service discovery | CoreDNS + etcd/file plugin |
| Multi-cloud DNS | CoreDNS + route53/azure/gcp plugins |
CoreDNS جایگزین BIND برای internet authoritative نیست — اما برای dynamic service discovery و Kubernetes ایدهآل است.
امنیت
- dnsmasq حذف شد — attack surface kube-dns کمتر شد
- ACL plugin — restrict queries by source IP
- DNSSEC — sign/validate plugins
- NetworkPolicy — limit who can query CoreDNS (Cilium L7 policy)
- Minimal image — scratch + binary + CA certs
Best practices
- replicas ≥ 2 — HA برای DNS critical path
- PodDisruptionBudget — حداقل یک CoreDNS همیشه up
- NodeLocal DNSCache — cluster > ۵۰ node
- monitor prometheus metrics — latency و cache hit rate
- loop plugin — همیشه enable
- reload plugin — ConfigMap change بدون restart (با احتیاط)
- upstream redundant — چند DNS در forward
- resource limits — CPU/memory برای spike query
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Miارتباط با stack شما
Kubernetes node
├── kubelet → CRI ([containerd](/blog/containerd-container-runtime-guide/) / [CRI-O](/blog/cri-o-kubernetes-container-runtime-guide/))
├── CNI ([Cilium](/blog/cilium-ebpf-kubernetes-networking/) / Kube-OVN)
└── Pod → CoreDNS → service discovery
└── forward → external (RDS، S3، API)Ingress (nginx) و TLS (cert-manager) به DNS سالم وابستهاند — hostname باید resolve شود قبل از handshake.
چه زمانی CoreDNS؟
✅ استفاده کنید
- هر Kubernetes cluster — already default
- Dynamic service discovery — K8s، etcd، Consul
- Custom DNS policy — rewrite، split horizon، conditional forward
- Unified observability — prometheus native
- Edge/multi-cloud — cloud provider plugins
⚠️ شاید نه
- Authoritative DNS برای domain عمومی با DNSSEC پیچیده — BIND/Knot matureتر
- Full recursive resolver at internet scale — Unbound/BIND
- بدون نیاز به flexibility — managed DNS (Route53، Cloud DNS) کافی است
جمعبندی
| مفهوم | توضیح |
|---|---|
| CoreDNS | DNS server مبتنی بر plugin — Go، CNCF Graduated |
| Corefile | config — Server Block + zone + plugins |
| Plugin chain | ترتیب از plugin.cfg — cache قبل از kubernetes |
| kubernetes plugin | *.svc.cluster.local service discovery |
| forward plugin | upstream برای query خارج cluster |
| cache plugin | TTL 30s default — performance |
| kube-dns | legacy — CoreDNS جایگزین از K8s 1.13 |
CoreDNS ستون service discovery در Kubernetes است — بدون آن Podها همدیگر را پیدا نمیکنند. با plugin architecture، همان engine برای edge caseهای DNS در production قابل customize است.
منابع
- CoreDNS — coredns.io
- CoreDNS Manual
- Plugins Documentation
- How Queries Are Processed
- CNCF CoreDNS Project
- Kubernetes DNS for Services and Pods
- GitHub — coredns/coredns
P30Light — زیرساخت، Kubernetes و DNS.