一、 概述与核心概念

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 定义。其基本结构如下:

# ZONE: 定义服务器负责的区,PORT 默认为 53
ZONE:[PORT] {
  # PLUGIN: 定义要加载的插件及其参数
  [PLUGIN] [PLUGIN_ARGUMENTS]...
}

示例

.:53 {
    whoami
}

weiyigeek.top {
    file db.weiyigeek.top
}

二、 安装与基础配置

2.1 安装 CoreDNS

方式一:二进制安装(推荐)

COREDNS_VERSION="1.11.1"
wget https://github.com/coredns/coredns/releases/download/v${COREDNS_VERSION}/coredns_${COREDNS_VERSION}_linux_amd64.tgz
tar xf coredns_${COREDNS_VERSION}_linux_amd64.tgz -C /usr/local/bin/
ln -s /usr/local/bin/coredns /usr/bin/coredns

方式二:从源码编译

git clone -b v1.11.1 https://github.com/coredns/coredns
cd coredns
make
# 或使用 Docker 环境编译
docker run --rm -i -t -v $PWD:/v -w /v golang:1.21 make
2.2 系统服务化部署
  1. 创建专用用户和目录
useradd coredns -s /sbin/nologin
mkdir -p /etc/coredns/
chown -R coredns /etc/coredns/
  1. 创建 Systemd 服务文件 (/usr/lib/systemd/system/coredns.service):
[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
systemctl daemon-reload
systemctl enable coredns
  1. 配置防火墙
firewall-cmd --permanent --add-service=dns
firewall-cmd --reload
2.3 基础配置文件示例

创建 /etc/coredns/Corefile,配置一个简单的 DNS 服务器,使用 hosts 插件进行本地解析,并转发未知查询到上游 DNS。

.:53 {
    bind 0.0.0.0
    hosts {
        # 自定义本地解析
        192.168.1.2 www.weiyigeek.top
        192.168.1.3 blog.weiyigeek.top
        ttl 60
        reload 1m
        fallthrough # 未匹配时继续执行下一个插件
    }
    # 转发未知查询到公共 DNS
    forward . 223.6.6.6 114.114.114.114
    cache 120 # 缓存
    log       # 记录日志
    errors    # 记录错误
}
  1. 启动并测试
systemctl start coredns
dig www.weiyigeek.top @localhost
dig google.com @localhost # 应被转发解析

三、 插件系统详解

3.1 插件概述与工作模式

CoreDNS 的功能完全由插件驱动。插件分为两类:

  • Normal 插件:参与请求处理逻辑,并出现在插件链中(如 hosts, file, forward)。
  • Other 插件:不参与请求逻辑,仅修改服务器配置(如 health, ready, prometheus)。

插件链执行逻辑

  1. 请求进入匹配的 Server Zone。
  2. plugin.cfg 定义的顺序依次执行插件链上的插件。
  3. 每个插件决定如何处理请求:直接响应、传递 (fallthrough)、或添加信息后继续传递。

查看可用插件coredns -plugins

3.2 常用插件详解
hosts 插件

用于从 /etc/hosts 风格的文件或内联配置提供 A/AAAA/PTR 记录。适合少量静态记录。

  • 语法
hosts [FILE] {
    [INLINE_ENTRIES]
    ttl SECONDS
    reload DURATION
    fallthrough [ZONES...]
}
  • 示例
.:53 {
    hosts {
        192.168.1.10 api.internal
        192.168.1.11 db.internal
        fallthrough
    }
    forward . 8.8.8.8
}
file 插件

用于从符合 RFC 1035 标准的主区域文件提供 DNS 服务。适合大量记录或需要标准区域文件管理的场景。

  • 语法
file DBFILE [ZONES...] {
    reload DURATION
}
  • 示例
weiyigeek.top {
    file /etc/coredns/db.weiyigeek.top
}
*区域文件示例 (`/etc/coredns/db.weiyigeek.top`)*:
$TTL 86400
@   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 服务器。是构建递归解析器或指定上游的关键插件。

  • 语法
forward . UPSTREAM_DNS...
  • 示例
.:53 {
    forward . 8.8.8.8:53 1.1.1.1:53 /etc/resolv.conf
    cache 60
}
cache 插件

缓存 DNS 响应,减少上游查询,提升性能。

  • 语法
cache [TTL] {
    success CAPACITY [TTL]
    denial CAPACITY [TTL]
}
  • 示例
.: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 配置
.: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 可以定义多个服务器块,处理不同域或端口的请求。

# 处理内部域
internal.company {
    file /etc/coredns/db.internal
    log
}

# 处理外部域,监听在5300端口
example.com:5300 {
    forward . 8.8.8.8
    cache 300
}

# 默认处理所有其他查询
.:53 {
    forward . 1.1.1.1 9.9.9.9
    cache 60
    errors
    log
}
4.2 DNSSEC 配置

CoreDNS 支持动态 DNSSEC 签名。

  1. 生成 DNSSEC 密钥
cd /etc/coredns
dnssec-keygen -a ECDSAP256SHA256 -f KSK weiyigeek.top
# 生成 Kweiyigeek.top.+013+12345.key 和 .private 文件
  1. 使用 dnssec 插件(动态签名响应):
weiyigeek.top {
    file /etc/coredns/db.weiyigeek.top
    dnssec {
        key file /etc/coredns/Kweiyigeek.top.+013+12345.key
    }
}
  1. 使用 sign 插件(预签名区域文件):
weiyigeek.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)安全。

  1. 生成 TSIG 密钥
tsig-keygen -a hmac-sha256 dns-tsig-key. > /etc/coredns/dns-tsig.secrets
  1. 配置 tsig 插件
weiyigeek.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 从中读取。

etcd-weiyigeek.local:53 {
    etcd {
        path /skydns
        endpoint http://172.22.50.98:2379
        fallthrough
    }
    cache 160
    log
}

在 etcd 中存储记录

  • 1
etcdctl put /skydns/local/etcd-weiyigeek/www '{"host":"172.22.50.100","ttl":60}'

查询dig www.etcd-weiyigeek.local

五、 故障排查与性能优化

  • 查看日志:确保配置中启用了 logerrors 插件。
  • 检查插件顺序:插件链顺序很重要,例如 cache 应在 forward 之后。
  • 监控:启用 prometheus 插件(默认在 :9153 端口)以获取指标。
  • 性能调优

    • 合理设置 cache 插件的 TTL 和容量。
    • 根据负载调整 forward 插件中的上游 DNS 服务器列表。
    • 使用 loadbalance 插件实现上游 DNS 的轮询负载均衡。

六、 总结

CoreDNS 凭借其插件化、高性能和易配置的特性,已成为从传统 DNS 到云原生服务发现的理想选择。通过灵活组合 hostsfileforwardcache 等插件,可以轻松构建出满足各种需求的 DNS 架构。对于 Kubernetes 环境,它更是不可或缺的核心组件。

官方资源