- CoreDNS 开发系列-1:CoreDNS核心概念和安装配置说明
- CoreDNS 开发系列-2:CoreDNS插件详解
- CoreDNS 开发系列-3:开发自定义插件
- CoreDNS 开发系列-4:高并发域名平台架构设计
- CoreDNS 开发系列-5:高性能域名平台项目开发
CoreDNS 概述
什么是CoreDNS
CoreDNS 是一个由 Go 编写的灵活、可扩展的 DNS 服务器。他非常灵活,几乎全部功能都由 plugin 来实现,CoreDNS 官网也有说 “CoreDNS is powered by plugins.” 。Plugins 能够作为 “独立” 或和 CoreDNS “共同” 来执行 “DNS Function” 在 CoreDNS 中被设计为是一个由 “软件实现的 CoreDNS Plugin API”,例如 Kubernetes Provider 可以提供在 k8s 集群里的服务发现。再例如 file 可以提供作为一个 DB 来使用。
CoreDNS 的设计与 与 Caddy 一样也是通过 “插件” 进行扩展,并原生支持 Prometheus 也是 CoreDNS 的一大优势,这意味着我们可以将其连接到现有的 Prometheus 基础架构中进行监控、警报和仪表板管理。
CoreDNS 核心架构
- Server:负责监听 DNS 查询请求
- Plugins Chain:按照配置顺序串联起来的插件序列
- Handler:每个插件实现的请求处理器
- Middleware:在请求处理过程中的中间件
DNS 请求在 CoreDNS 中的处理流程如下:
- Server 接收 DNS 查询请求
- 请求按顺序通过插件链
- 每个插件决定是处理请求还是传递给下一个
- 如果某个插件成功处理,生成响应返回
- 如果整个插件链都无法处理,返回 SERVFAIL
安装 CoreDNS
由于 CoreDNS 是基于 Go语言开发的,官方提供了预编译包,再不进行插件编写的情况下可以自行部署,也可以使用官方的 Docker 镜像运行。本文基于整理文档时最新版 CoreDNS (v1.12.1) 进行演示。
coredns 的参数很少,可以使用 –help 来查看
|
|
可以通过 -plugins
参数来查看内置的所有 “plugins” 的列表
|
|
这里和官网实例一样使用 1053 端口来展示 coredns 测试示例
|
|
|
|
coredns配置原理
CoreDNS 的配置文件的配置内容要求必须是编译在 coredns 中的插件才可以使用,添加和删除插件都很容易,但是需要重新编译 coredns。
在使用配置文件来启动 coredns 时,首先可以通过 -conf
参数来指定配置文件。但当未指定时,会从当前目录下寻找 “Corefile” 作为配置文件。
配置文件内容由一个或多个 Server 块 (Blocks) 组成,每一个 Server 块包含了一个或多个插件。插件也可以通过插件的 “指令” 来对插件做更多配置。
Corefile 中插件配置的顺序并不决定插件链的执行顺序。插件执行顺序由 plugin.cfg 中的顺序决定。
配置文件中以 “#” 作为注释
coredns 配置说明
Server Block
- server 块的开头可以对多个域名表示权威性(authoritative 在 DNS 系统属于中通常指,可以可以正确的解析 domain 到 IP,通过上下文来理解就是对一个 zone 拥有的权威性;也可以理解为对一个域名的最终的权威性)
- 多个 zone 通过 “空格” 进行分开。
- Server 块是以 “{” (opening brace) 开始,以 “}” (closing brace) 结束。其中 “.” 表示根 zone,可以处理所有查询。
|
|
下面是一个实例
|
|
Server 部分也可以指定监听端口,默认为 “53” (标准DNS服务的端口),使用 “:” 来划分 zone 和它的监听端口,例如 1053
|
|
-dns.port
指定了参数没法覆盖配置文件中指定的端口。使用同个 zone 指定已经分配的 Server 块,或者他们运行在同一个端口上,这个配置文件在启动时会抛出错误。例如下面配置所示。
|
|
可以通过 bind 插件来让他绑定到不同的网卡上,可以实现使用不同网络接口或者IP地址的情况下使用相同的端口来提供服务。
|
|
配置协议
截至目前 CoreDNS (v1.12.1) 支持四种不同类型的协议
- DNS:
dns://
,也是默认的协议,如果 scheme 未指定,则默认为 dns 协议 - DNS over TLS (DoT):
tls://
- DNS over HTTP/2 (DoH):
https://
- DNS over gRPC:
grpc://
插件配置
在一个 Server 块中,可以通过 “插件名称” 来使用对应的插件,例如
|
|
对于每个插件的配置,和 Server 块相同,以 “{” (opening brace) 开始,以 “}” (closing brace) 结束,来表示这个插件的配置项,如下所示
|
|
下面是四个 zone 在两个不同的端口上提供服务
|
|
配置示例:来自 file plugin 的 Authoritative Serving
该示例采自官网的实例,通过使用内置的 file 插件实现一个 Authoritative Server,使用了 example.org.
作为示例 zone ,他的数据将被存储到文件内。
file 插件的域名为
|
|
DBFILE 部分为 CoreDNS 读取和解析的数据库文件
ZONES 为指定授权 Zone,如果为空,则继承 Server 块的 Zone
他的参数如下所示:
|
|
reload 表示 SOA 版本更改时执行 ZONE 重新加载的间隔。默认值 1 分钟。 0
表示不扫描更改并重新加载。
例如上面配置的扩展,example.org 的数据库由 file 模块提供,transfer 则是提供了
|
|
那么 example.org.db 数据库文件内应该配置的信息如下
|
|
|
|
另外在 bind9 中也有对应的配置
|
|
配置示例:transfer 和AXFR配置
transfer插件可以响应 AXFR (full zone transfer) 请求和 IXFR (incremental zone transfer) 请求,当 server 端无法通过 IXFR 更新时,会回退为 AXFR (AXFR fallback),就是如果 IXFR 客户端没法通过 IXFR 更新数据,那么服务端会返回 “整个域” 给 IXFR 客户端 [7]
配置语法
|
|
ZONE 部分表示相应 zone transfer 请求的域,如果左边为空,这些 zone 将继承于 “server 块”
to ADDRESS… 部分表示允许 trasfer 的地址,使用 “*” 表示允许 transfer 到所有的 “ADDRESS”,当 zone 改变时通知将会发送到所有 “ADDRESS” ;“ADDRESS” 可以是 IP,也可以是 IP:PORT,也可以指定多次。
例如,下面配置表示 transfer 到一个 secondary DNS server (10.240.1.1),这里可以使用一个或多个 transfer 指令,也可以使用 CIRD,在这个Zone发生任何改变时,CoreDNS将通知这些 “secondary DNS server”
|
|
总结
本文从零带入了 CoreDNS 的安装配置和主要功能特性。CoreDNS 作为一个现代化的 DNS 服务器,以其模块化设计、插件扩展性和云原生特性,为构建高性能 DNS 平台提供了坚实基础。
在后续文章中,将进一步探讨 CoreDNS 的插件部分,并深入研究如何开发自定义插件来扩展 CoreDNS 功能,最终实现一个完整的 DNS 域名管理平台。
Reference
[1] what-is-coredns
[2] Installation
[3] configuration
[4] What is the difference between authoritative and recursive DNS nameservers?
[5] RR TYPE IANA Considerations
[6] bind: what is the zonefile SOA RR grammar?
[7] An IXFR Fallback to AXFR Case draft-song-dnsop-ixfr-fallback-01