CoreDNS构建高性能DNS服务器
一、 概述与核心概念
1.1 什么是 CoreDNS?
CoreDNS 是一个用 Go 语言编写的、高度可扩展和插件化的 DNS 服务器。它来自云原生计算基金会(CNCF),是 Kubernetes 的默认 DNS 服务器,其设计目标是易于使用且功能强大。
核心特点:
- 插件化架构:几乎所有功能都通过插件实现,可以灵活组合,适用于传统 DNS、服务发现、负载均衡等多种场景。
- 高性能与可靠性:基于 Go 语言,性能优异。支持自动重试、健康检查和负载均衡。
- 易于配置:使用简单易懂的
Caddyfile格式配置文件。 - Kubernetes 原生:深度集成 K8s,用于集群内服务发现。
1.2 CoreDNS 与传统 DNS(如 BIND)的区别
传统 DNS 服务器功能固定且庞大。CoreDNS 则像一个“DNS 功能总线”,通过加载不同的插件来实现特定功能,这使得它更轻量、更灵活。正如其官方所说:CoreDNS is powered by plugins.
1.3 核心配置文件:Corefile
CoreDNS 的行为由 Corefile 定义。其基本结构如下:
1 | # ZONE: 定义服务器负责的区,PORT 默认为 53 |
示例:
1 | .:53 { |
二、 安装与基础配置
2.1 安装 CoreDNS
方式一:二进制安装(推荐)
1 | COREDNS_VERSION="1.11.1" |
方式二:从源码编译
1 | git clone -b v1.11.1 https://github.com/coredns/coredns |
2.2 系统服务化部署
- 创建专用用户和目录:
1
2
3useradd coredns -s /sbin/nologin
mkdir -p /etc/coredns/
chown -R coredns /etc/coredns/ - 创建 Systemd 服务文件 (
/usr/lib/systemd/system/coredns.service):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[Unit]
Description=CoreDNS DNS server
Documentation=https://coredns.io
After=network.target
[Service]
LimitNOFILE=1048576
User=coredns
WorkingDirectory=/etc/coredns
ExecStart=/usr/bin/coredns -conf=/etc/coredns/Corefile
ExecReload=/bin/kill -SIGUSR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
1 | systemctl daemon-reload |
- 配置防火墙:
1
2firewall-cmd --permanent --add-service=dns
firewall-cmd --reload
2.3 基础配置文件示例
创建 /etc/coredns/Corefile,配置一个简单的 DNS 服务器,使用 hosts 插件进行本地解析,并转发未知查询到上游 DNS。
1 | .:53 { |
- 启动并测试:
1
2
3systemctl start coredns
dig www.weiyigeek.top @localhost
dig google.com @localhost # 应被转发解析
三、 插件系统详解
3.1 插件概述与工作模式
CoreDNS 的功能完全由插件驱动。插件分为两类:
- Normal 插件:参与请求处理逻辑,并出现在插件链中(如
hosts,file,forward)。 - Other 插件:不参与请求逻辑,仅修改服务器配置(如
health,ready,prometheus)。
插件链执行逻辑:
- 请求进入匹配的 Server Zone。
- 按
plugin.cfg定义的顺序依次执行插件链上的插件。 - 每个插件决定如何处理请求:直接响应、传递 (
fallthrough)、或添加信息后继续传递。
查看可用插件:coredns -plugins
3.2 常用插件详解
hosts 插件
用于从 /etc/hosts 风格的文件或内联配置提供 A/AAAA/PTR 记录。适合少量静态记录。
- 语法:
1
2
3
4
5
6hosts [FILE] {
[INLINE_ENTRIES]
ttl SECONDS
reload DURATION
fallthrough [ZONES...]
} - 示例:
1
2
3
4
5
6
7
8.:53 {
hosts {
192.168.1.10 api.internal
192.168.1.11 db.internal
fallthrough
}
forward . 8.8.8.8
}
file 插件
用于从符合 RFC 1035 标准的主区域文件提供 DNS 服务。适合大量记录或需要标准区域文件管理的场景。
- 语法:
1
2
3file DBFILE [ZONES...] {
reload DURATION
} - 示例:*区域文件示例 (
1
2
3weiyigeek.top {
file /etc/coredns/db.weiyigeek.top
}/etc/coredns/db.weiyigeek.top)*:1
2
3
4
5
6
7
8
9
10
1186400
@ IN SOA ns1.weiyigeek.top. admin.weiyigeek.top. (
2023082501 ; Serial
7200 ; Refresh
3600 ; Retry
1209600 ; Expire
3600 ) ; Negative Cache TTL
;
@ IN NS ns1
ns1 IN A 192.168.1.100
www IN A 192.168.1.101
forward 插件
将查询转发到上游 DNS 服务器。是构建递归解析器或指定上游的关键插件。
- 语法:
1
forward . UPSTREAM_DNS...
- 示例:
1
2
3
4.:53 {
forward . 8.8.8.8:53 1.1.1.1:53 /etc/resolv.conf
cache 60
}
cache 插件
缓存 DNS 响应,减少上游查询,提升性能。
- 语法:
1
2
3
4cache [TTL] {
success CAPACITY [TTL]
denial CAPACITY [TTL]
} - 示例:
1
2
3
4
5
6
7
8
9.:53 {
forward . 8.8.8.8
cache 120 # 缓存所有响应120秒
# 或更精细控制
cache {
success 5000 300
denial 1000 60
}
}
3.3 Kubernetes 集成插件 (kubernetes)
CoreDNS 在 K8s 中的核心插件,用于服务发现(将 Service 名称解析为 ClusterIP)。
- 典型 K8s 配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods verified
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
四、 高级配置与实战
4.1 多区域与复杂配置
一个 Corefile 可以定义多个服务器块,处理不同域或端口的请求。
1 | # 处理内部域 |
4.2 DNSSEC 配置
CoreDNS 支持动态 DNSSEC 签名。
- 生成 DNSSEC 密钥:
1
2
3cd /etc/coredns
dnssec-keygen -a ECDSAP256SHA256 -f KSK weiyigeek.top
# 生成 Kweiyigeek.top.+013+12345.key 和 .private 文件 - 使用
dnssec插件(动态签名响应):1
2
3
4
5
6weiyigeek.top {
file /etc/coredns/db.weiyigeek.top
dnssec {
key file /etc/coredns/Kweiyigeek.top.+013+12345.key
}
} - 使用
sign插件(预签名区域文件):签名后的区域文件将保存在1
2
3
4
5
6weiyigeek.top {
sign /etc/coredns/db.weiyigeek.top {
key file /etc/coredns/Kweiyigeek.top.+013+12345.key
directory /var/lib/coredns
}
}/var/lib/coredns/db.weiyigeek.top.signed。
4.3 TSIG 配置(事务签名)
用于验证和签名 DNS 请求/响应,常用于区域传输(AXFR/IXFR)安全。
- 生成 TSIG 密钥:
1
tsig-keygen -a hmac-sha256 dns-tsig-key. > /etc/coredns/dns-tsig.secrets
- 配置
tsig插件:1
2
3
4
5
6
7
8
9
10weiyigeek.top {
file /etc/coredns/db.weiyigeek.top
tsig {
secrets /etc/coredns/dns-tsig.secrets
require AXFR IXFR # 要求区域传输必须签名
}
transfer {
to * # 允许向任何请求者传输(生产环境应限制IP)
}
}
4.4 使用 etcd 插件实现动态服务发现
可以将服务记录存储在 etcd 中,CoreDNS 从中读取。
1 | etcd-weiyigeek.local:53 { |
在 etcd 中存储记录:
1 | etcdctl put /skydns/local/etcd-weiyigeek/www '{"host":"172.22.50.100","ttl":60}' |
查询:dig www.etcd-weiyigeek.local
五、 故障排查与性能优化
- 查看日志:确保配置中启用了
log和errors插件。 - 检查插件顺序:插件链顺序很重要,例如
cache应在forward之后。 - 监控:启用
prometheus插件(默认在:9153端口)以获取指标。 - 性能调优:
- 合理设置
cache插件的 TTL 和容量。 - 根据负载调整
forward插件中的上游 DNS 服务器列表。 - 使用
loadbalance插件实现上游 DNS 的轮询负载均衡。
- 合理设置
六、 总结
CoreDNS 凭借其插件化、高性能和易配置的特性,已成为从传统 DNS 到云原生服务发现的理想选择。通过灵活组合 hosts、file、forward、cache 等插件,可以轻松构建出满足各种需求的 DNS 架构。对于 Kubernetes 环境,它更是不可或缺的核心组件。
官方资源:
- 文档:https://coredns.io/manual/toc/
- 插件列表:https://coredns.io/plugins/
- GitHub:https://github.com/coredns/coredns
提示:生产环境部署时,请务必关注安全最佳实践,如使用非 root 用户运行、配置适当的防火墙规则、为区域传输启用 TSIG、以及定期更新 CoreDNS 版本。