在上一篇文章中,我们了解了 CoreDNS 的基本概念、安装和配置文件的说明。在本文将深入探讨 CoreDNS 的插件 (Plugins),这是 CoreDNS 强大功能的核心所在。通过理解插件机制和核心插件的工作原理,我们将为后续开发自定义插件和构建 DNS 平台奠定坚实基础。

插件系统设计理念

通常情况下,CoreDNS Plugins在设计上围绕下面的原则进行的

  • 单一职责:每个插件只负责自己负责的功能
  • 链式处理:插件按配置顺序执行链处理请求
  • 可插拔性:插件可以灵活组合和替换
  • 扩展性:支持用户自定义插件开发插件来扩展功能

基于这些原则,使得 CoreDNS 非常强大,非常易于扩展性(对比与最流行的两款开源 DNS 产品来说,Bind, PowerDNS)。

CoreDNS与主流DNS服务产品的对比

下表是调研了三款最流行的 DNS 开源产品来对最符合本项目的后端作为对比,CoreDNS的灵活性相对比较适宜

特性CoreDNSBIND9PowerDNS
类型权威/递归权威/递归权威/递归
AXFR/IXFR 支持支持, trasfer 插件支持支持
view支持(geo, view插件)原生支持(view 指令)支持(仅仅LMDB后端)
数据库支持支持(通过自定义插件 mysql, redis)有限 DLZ模块 (Dynamically Loadable Zones) [1]原生有限支持 [2]
DNSSEC支持(NSEC)全面支持(NSEC/NSEC3)全面支持(NSEC/NSEC3)
扩展性极佳(插件架构)有限扩展,支持c语言库作为plugins良好
易用性高(简单配置,现代化)中(配置复杂,需经验)高(Web 界面、API)
社区与生态活跃(CNCF 项目,Kubernetes 生态)非常活跃(ISC 维护)活跃(商业支持)
与本项目需求契合度极高(插件化支持View, AXFR/IXFR, GEO)高(原生支持VIEW, AXFR/IXFR)高(数据库支持强,API 同步简单)

CoreDNS插件的类型

CoreDNS插件分为两种类型插件,“In-tree Plugins” [3] 和 “External Plugins” [4];“In-tree Plugins” 是 CoreDNS 官方在提供 coredns 二进制文件时就内置编译到程序内的插件,用户可以自己去配置使用这些插件;“External Plugins” 是包含 CoreDNS 官方与三方作者维护的插件,用户如果想使用的话,需要自行编译 coredns 版本使用。

核心插件说明

cache

cache 插件是性能优化的核心组件,通过缓存 DNS 查询结果显著提高响应速度。当 cache 插件在启用后,所有的记录都会被缓存 3600s(除了 transfer 和 metadata 外); cache插件常被用于的场景是当从 backend (上游dns,数据库后端) 中拿取数据代价高时可以提高查询效率。

配置如下

text
1
cache [TTL] [ZONES...]
  • TTL 为秒,如果未指定,则使用最大 TTL,对于 NOERROR 的相应为 3600,拒绝存在 (denial of existence) 则为 1800.
  • ZONE 为要缓存的域名 (ZONE),如果为空,则使用 “配置块” 的zone

如果需要更多控制可以参考下面配置

text
1
2
3
4
5
6
7
8
9
cache [TTL] [ZONES...] {
    success CAPACITY [TTL] [MINTTL]
    denial CAPACITY [TTL] [MINTTL]
    prefetch AMOUNT [[DURATION] [PERCENTAGE%]]
    serve_stale [DURATION] [REFRESH_MODE]
    servfail DURATION
    disable success|denial [ZONES...]
    keepttl
}

上面配置说明了,每一个 cache 部分的详细配置,缓存中的每个元素都根据其TTL缓存,在默认情况下,一个缓存被分为 256 和分块 (shares),每个分块可防止 39 个条目。每个缓存的总大小为 9984 个条目 (TTL最大情况下)。

上面的 “{}” 配置是针对每种类型相应进行缓存的说明:

  1. success: 覆盖缓存成功响应的设置。CAPACITY 指示在开始驱逐(随机)之前我们缓存的数据包的最大数量。TTL 覆盖缓存的最大 TTL。MINTTL 覆盖缓存的最小 TTL(默认 5),可以用来限制对后端的查询。
    • CAPACITY:缓存的最大数据包数,超过后随机逐出(eviction)。
    • TTL:覆盖缓存的最大 TTL,控制成功响应的最长缓存时间。
    • MINTTL:覆盖缓存的最小 TTL(默认 5 秒),用于限制对后端的查询频率。
  2. denial: 覆盖缓存拒绝存在 (NXDOMAIN 或 NODATA)响应的设置。CAPACITY 指示在开始驱逐(LRU)之前我们缓存的数据包的最大数量。TTL 覆盖缓存的最大 TTL。MINTTL 覆盖缓存的最小 TTL(默认 5),可以用来限制对后端的查询。第三个类别(error),不被缓存。
    • CAPACITY:缓存的最大数据包数,超过后使用 LRU(Least Recently Used) 逐出策略。
    • TTL:覆盖缓存的最大 TTL。
    • MINTTL:覆盖缓存的最小 TTL(默认 5 秒),用于减少后端查询。
    • 错误响应(error)不被缓存。
  3. prefetch: 当热门项目即将从缓存中清除时将预取该项目。
    • Item 在 DURATION(默认 1 分钟)内收到 AMOUNT 次查询,且无超过 DURATION 的查询间隔。
    • 预取在 TTL 低于 PERCENTAGE(默认 10%,范围 10%-90%,需带 % 符号)或 TTL 剩余 1 秒时触发。
    • PERCENTAGE:作为整数处理,例如 “10%” 被视为 10。
  4. serve_stale: 当启用 serve_stale 时,缓存会向客户端返回已过期但未超过 DURATION(默认 1 小时)的条目。
    • 默认情况下,发送过期条目后,缓存插件会尝试刷新条目。
    • 响应的 TTL 设为 0。
    • REFRESH_MODE (immediate|verify)
      • immediate(默认):立即返回过期条目,再检查源是否可用。
      • verify:先验证条目是否在源不可用,再返回过期条目(可能增加延迟,但避免返回过时数据)。
  5. servfail: 缓存 SERVFAIL 响应的时间。
    • DURATION 设置为 0 禁用 SERVFAIL 缓存。
    • 默认缓存 5 秒,最大不超过 5 分钟。
  6. disable: 禁用指定 ZONES 的成功 (success) 或拒绝存在 (denial) 的缓存。如果未指定 ZONES,则对所有 ZONES禁用指定的缓存类型。
  7. keepttl: 从缓存返回响应时不减少 TTL(即返回原始 TTL,而不是剩余 TTL)。

更多配置可以参考官方文档 [5]

详细配置示例

text
1
2
3
4
5
6
cache 30 {
    success 10000 300 60    # 缓存10000个成功响应,TTL 300秒,最小TTL 60秒
    denial 1000 60 10       # 缓存1000个失败响应,TTL 60秒,最小TTL 10秒
    prefetch 10 10%         # 当访问量>10且TTL<10%时预取
    serve_stale 24h         # 过期记录可服务24小时
}

forward

forward 插件实现 DNS 查询转发功能,是 CoreDNS 与上游 DNS 服务器交互的核心。

基本配置语法

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
forward FROM TO... {
    except IGNORED_NAMES...
    force_tcp
    prefer_udp
    expire DURATION
    max_fails INTEGER
    health_check DURATION [URL]
    tls CERT KEY CA
    tls_servername NAME
    policy random|round_robin|sequential
    max_concurrent MAX
}
  • FROM 是用于匹配需要转发的请求的基础域。使用展开为多个反向区域的 CIDR 表示法的域不受完全支持;仅使用第一个展开的区域。
  • TO… 是转发到的目标端点。TO 语法允许你指定协议、tls://9.9.9.9dns://(或不指定协议)以获取纯 DNS。上游数量限制为 15 个。

配置示例

forward 中转发策略 (Policy) 还支持多种类型的负载均衡策略

配置示例

text
1
2
3
4
5
6
forward . 8.8.8.8 8.8.4.4 1.1.1.1 {
    policy round_robin      # 轮询策略
    health_check 5s         # 每5秒健康检查
    max_fails 3             # 最大失败次数
    expire 10s              # 故障服务器恢复检查间隔
}

将 “example.org.” 所有请求代理到不同端口上运行的名称服务器

text
1
2
3
example.org {
    forward . 127.0.0.1:9005
}

转发除 example.org域之外的请求

bash
1
2
3
4
5
. {
    forward . 10.0.0.10:1234 {
        except example.org
    }
}

forward 插件支持 DNS over TLS (DoT):

text
1
2
3
4
forward . tls://8.8.8.8 {
    tls_servername dns.google
    health_check 5s
}

更多配置说明可以参考官网说明 [6]

kubernetes

kubernetes plugin 是 CoreDNS 在云原生环境中的核心优势,提供与 Kubernetes 集群的深度集成,该插件实现了 “基于 DNS 的 Kubernetes 服务发现规范 [7]

配置语法如下:

text
1
kubernetes [ZONES...]

kubernetes 插件在配置时,如果仅指定插件 (kubernetes),那该插件使用服务器块(server block)中定义的 ZONE作为默认的权威 ZONE。例如下面所示

text
1
2
3
example.com {
    kubernetes
}

kubernetes 插件会处理这个 “ZONE” 下面的所有 DNS 查询。在这种场景下不会为 “Service” 提供 PTR记录 (Reverse DNS Lookups) 或 “Pod” 的 A 记录。这意味着,在默认配置下,仅仅提供 Service 的 “DNS 解析”。

如果为插件指定了 “ZONE”,kubernetes 会成为这些指定 “ZONE” 的权威DNS。如下面配置所示,

text
1
2
3
kubernetes cluster.local in-addr.arpa {
    ...
}

kubernetes 插件的配置如下

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
kubernetes [ZONES...] {
    # endpoint 为远程 k8s API 终结点指定 URL。如果忽略,则使用集群sa连接到群集内的 k8s。
    endpoint URL
    
    # CERT KEY CACERT 是远程 k8s 连接的 TLS 证书、密钥和 CA 证书文件名。
    # 如果在群集内连接(即未指定endpoint),则会忽略此选项。
    tls CERT KEY CACERT
    
    # KUBECONFIG [CONTEXT] 使用 kubeconfig 文件对远程 k8s 集群的连接进行身份验证。
    # [CONTEXT] 是可选的,如果未设置,则将使用 kubeconfig 中指定的当前上下文。
    # 它支持 TLS、用户名和密码或基于令牌的身份验证。
    # 如果在群集内连接(即未指定端点),则会忽略此选项。
    kubeconfig KUBECONFIG [CONTEXT]
    
    # NAMESPACE [NAMESPACE…] 仅公开列出的 k8s 命名空间。如果忽略此选项,则会公开所有命名空间。
    namespaces NAMESPACE...
    
    # 只暴露匹配特定标签选择器(label selector)的 Kubernetes 对象的 DNS 记录。
    # 例如 labels environment in (staging, qa),application=nginx 为
    # 	只暴露带有标签 environment=staging 或 environment=qa,
    # 	且 application=nginx 的 Kubernetes 对象的 DNS 记录。
    labels EXPRESSION
    
    # 控制 Pod A 记录(如 1-2-3-4.ns.pod.cluster.local 返回 A 1.2.3.4)的处理模式,
    # 方便直接连接 Pod 时使用 SSL 证书。
    # POD-MOD 的有效值
    #    disabled:默认。不处理 Pod 请求,始终返回 NXDOMAIN
    #    insecure:直接根据请求中的 IP 返回 A 记录(不检查 Kubernetes)。
    #		易受恶意使用(如结合通配符 SSL 证书),仅为兼容 kube-dns。
    #    verified:检查同一命名空间内是否有匹配IP的Pod,若存在则返回 A 记录。
    #		需要更多内存,因为需watch所有Pod。
    pods POD-MODE
    
    # 控制endpointA 记录的名称生成方式,
    # 例如“endpoint-name.my-service.namespace.svc.cluster.local. in A 1.2.3.4”
    # 默认:endpoint-name默认使用域名,如果未设置hostname ,使用endpoint的IP的连字符模式“1-2-3-4”
    # 指定该指令,默认使用hostname ,如果未设置hostname ,则使用 endpoint对应的Pod名称
    # 若无Pod或Pod名称超过63字符,使用IP连字符模式。
    endpoint_pod_names
    
    # 允许您为响应设置自定义 TTL。
    # 默认值为 5 秒。允许的最小 TTL 为 0 秒,最大值上限为 3600 秒。
    # 将 TTL 设置为 0 将阻止记录被缓存。
    ttl TTL
    
    # 禁用endpoints的 DNS记录解析。
    # 关闭对endpoints的watch。
    # 所有endpoints查询和无头服务(headless service)查询返回 NXDOMAIN。
    noendpoints
    
    # 故障转移,当插件对某个权威 zone 的查询返回 NXDOMAIN 时,将查询传递到插件链中的下一个插件处理。
    # 如果不指定 [ZONES…],对所有权威 zone 生效。
    # 如果指定 zone(如 in-addr.arpa 或 ip6.arpa),仅对这些 zone 生效。
    fallthrough [ZONES...]
    
    # 为没有任何就绪endpoint地址(例如,就绪Pod)的服务返回 NXDOMAIN。
    # 这允许查询 Pod 继续在搜索路径中搜索服务。例如,搜索路径可以包含另一个 Kubernetes 集群。
    ignore empty_service
}

示例配置

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
kubernetes cluster.local {
    # 限制解析到特定标签的资源。
    labels environment in (staging, qa),application=nginx
    # 启用 Pod A 记录验证。
    pods verified
    # 使用 Pod 名称作为域名名称。
    endpoint_pod_names
    ttl 30
    # 禁用endpoints记录。
    noendpoints
    # 支持查询透传。
    fallthrough in-addr.arpa ip6.arpa
    # 增强跨集群服务发现。
    ignore empty_service
}

这是 coredns 官方提供的 coredns 配置文件 [8],启动存在几个变量,通过查看脚本可以得到他的具体信息。

  • UPSTREAMNAMESERVER 是从本机 /etc/resovle.conf 中读取的
  • CLUSTER_DOMAIN 默认为 cluster.local
  • REVERSE_CIDRS 设置一些反向DNS的域,通常我们一个集群使用的就是 CLUSTER_DOMAIN
yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
  Corefile: |
    .:53 {
        errors # 记录 DNS 查询中的错误,便于调试。
        health {
          lameduck 5s # 提供健康检查端点,表示在 CoreDNS 关闭前等待 5 秒以处理现有请求。
        }
        ready # readiness探针,用于 Kubernetes 探针。默认 :8181/ready 200 ok, 503 not
        kubernetes CLUSTER_DOMAIN REVERSE_CIDRS {
          fallthrough in-addr.arpa ip6.arpa # 允许未解析的反向请求透传到下一个插件。
        }
        prometheus :9153 # 暴露 Prometheus 监控指标,监听在 9153 端口
        forward . UPSTREAMNAMESERVER { # 将非集群内部的 DNS 请求转发到外部 DNS 服务器
          max_concurrent 1000
        }
        cache 30 # 缓存 DNS 响应 30 秒
        loop # 检测并防止 DNS 循环。
        reload # 支持动态重新加载 Corefile 配置。
        loadbalance # 在多个 A/AAAA 记录之间进行负载均衡。
    }STUBDOMAINS    

总结:

kubernetes 插件提供多种服务发现模式:

  1. 服务发现service.namespace.svc.cluster.local
  2. Pod 发现pod-ip.namespace.pod.cluster.local
  3. 端点发现endpoint.service.namespace.svc.cluster.local
  4. K8S中 域名负载均衡模式使用的是 loadbalance 插件实现的

File

note
File插件在第一章介绍 coredns 时已经说明过了。

该示例采自官网的实例,通过使用内置的 file 插件实现一个 Authoritative Server,使用了 example.org. 作为示例 zone ,他的数据将被存储到文件内。

file 插件的域名为

text
1
file DBFILE [ZONES...]

DBFILE 部分为 CoreDNS 读取和解析的数据库文件

ZONES 为指定授权 Zone,如果为空,则继承 Server 块的 Zone

他的参数如下所示:

text
1
2
3
file DBFILE [ZONES... ] {
    reload DURATION
}

reload 表示 SOA 版本更改时执行 ZONE 重新加载的间隔。默认值 1 分钟。 0表示不扫描更改并重新加载。

例如上面配置的扩展,example.org 的数据库由 file 模块提供,transfer 则是提供了

text
1
2
3
4
5
6
example.org {
    file example.org.db
    transfer {
        to * 10.240.1.1
    }
}

那么 example.org.db 数据库文件内应该配置的信息如下

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# $ORIGIN example.org. 定义了“根” zone,这里是 example.com.
# “.” 表示 FQDN
# 这里表示下面的记录都是围绕 “example.com.”
$ORIGIN example.org.

# “@”表示当前zone的根域名(因为 $ORIGIN 是 example.org.)。
# “3600” 为TTL,这条记录缓存时间为1小时(单位秒)
# “IN”表示Internet记录
# “SOA” start of authority,权威起始记录,
# sns.dns.icann.org.主名字服务器的FQDN
# noc.dns.icann.org. zone管理员邮箱,在dns配置中,用“.”替换“@”
# 2017042745 序列号(Serial),通常用于DNS同步
## AXFR (full zone transfer,官方称为 Authoritative Transfer) 理解全量同步
## IXFR (Incremental transfer),可以理解为增量同步
# “7200”表示刷新时间,从服务器每2小时向主服务器检查是否更新(单位秒)
# “3600”表示重试时间,从到主无法连接时,会在1小时后重试(单位秒)。
# “1209600” 表示过期时间“从在两周内无法从主获取更新,则数据失效。
# “3600” 表示“Minimum TTL”,定义改zone中默认的 TTL
@	3600 IN	SOA sns.dns.icann.org. noc.dns.icann.org. 2017042745 7200 3600 1209600 3600

# “NS” Name Server,查询 example.org 的信息,可以去找 a.iana-servers.net 这个DNS服务器
	3600 IN NS a.iana-servers.net.
	3600 IN NS b.iana-servers.net.

# A记录为IPV4
# AAAA记录为IPV6
www     IN A     127.0.0.1
        IN AAAA  ::1
note
下面的内容为不加注释的配置文件,也是 file plugin 中配置的数据库 “example.org.db”
text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ORIGIN example.org.
@	3600 IN	SOA sns.dns.icann.org. noc.dns.icann.org. (
				2017042745 ; serial
				7200       ; refresh (2 hours)
				3600       ; retry (1 hour)
				1209600    ; expire (2 weeks)
				3600       ; minimum (1 hour)
				)

	3600 IN NS a.iana-servers.net.
	3600 IN NS b.iana-servers.net.

www     IN A     127.0.0.1
        IN AAAA  ::1

另外在 bind9 中也有对应的配置

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
example.com. 43200 IN SOA ns1.example.com. other.example.com. (
 2011090302 ;Serial Number
 86400 ;refresh
 7200 ;retry
 1814400 ;expire
 86400 ;minimum
 )

@   SOA ns1 (   ; ns1.basiczone.com is the primary server for basiczone.com
      postmaster  ; contact email for basiczone.com is postmaster@basiczone.com
      2004041700  ; Serial ID in reverse date format
      21600   ; Refresh interval for slave servers
      1800    ; Retry interval for slave servers
      604800    ; Expire limit for cached info on slave servers
      900 )   ; Minimum Cache TTL in zone records

Auto

CoreDNS 的 auto 插件用于从磁盘上的 RFC 1035 格式的主文件(zone file)中自动加载和提供 DNS 区域数据,特别适合传统 DNS 服务器的场景。也可以将 auto 插件视作是 file 插件的扩展,支持所有 file 插件的指令(directive),但增加了自动加载和动态重新加载的功能。

text
1
2
3
4
auto [ZONES...] {
    directory DIR [REGEXP ORIGIN_TEMPLATE]
    reload DURATION
}
  1. ZONES:CoreDNS 会对这些区域的查询返回权威响应。

  2. directory DIR [REGEXP ORIGIN_TEMPLATE] 指定 CoreDNS 从哪个 directory 加载 RFC 1035 格式的区域文件。

    • REGEXP 用于匹配文件名,文件名匹配的会将他作为提取来源。
    • ORIGIN_TEMPLATE 将用作来源模板,例如{1}是第一个匹配项,{2}是第二个。和正则用法类似。
  3. reload DURATION 指定 CoreDNS 扫描 directory 指定的频率,以检测区域文件的添加、删除或修改。

    • 如果 ZONE 文件的 SOA 记录中的序列号 (serial number) 发生变化,CoreDNS 会自动重新加载该 ZONE 的数据。
    • 默认值 1m

示例说明

  1. 默认的 REGEXP 为 db.(.*),默认的 ORIGIN_TEMPLATE 为 {1}
  2. 例如,路径为 db.example.com 时,REGEXP db.(.*) 匹配,ORIGIN_TEMPLATE “(.*)” 提取出 example.com,通过 {1} 转换为 ZONE 名称 example.com。
  3. CoreDNS 将 db.example.com 识别为区域 example.com 的区域文件。
text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
example.org example.com:53 {
    auto {
        directory /etc/coredns/zones db\.(.*) {1}
        reload 30s
    }
    transfer {
        to *
    }
    log
    errors
}

上面示例提到了,这里会对文件例如,example.org 和 example.com 文件拥有权威响应,每 30 秒检查目录,重新加载发生变化的区域文件。

这里的目录文件必须为

text
1
2
3
/etc/coredns/zones/
├── db.example.org
├── db.example.com

再一个示例:从目录 /etc/coredns/zones/org 加载 org 域,并将文件名视为 www.db.example.org ,其中 example.org 为来源。每 45 秒刷新文件一次。

text
1
2
3
4
5
6
org {
    auto {
        directory /etc/coredns/zones/org www\.db\.(.*) {1}
        reload 45s
    }
}

根据这个示例我们来测试 auto 插件

准备 example.org 文件

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ORIGIN example.org.
$TTL 3600
@ IN SOA ns1.example.org. admin.example.org. (
     2025041101 ; serial
     7200       ; refresh
     3600       ; retry
     1209600    ; expire
     3600       ; minimum
)
@ IN NS ns1.example.org.
ns1 IN A 192.0.2.1
www IN A 192.0.2.2
shop IN A 127.0.0.1
blog IN A 10.0.0.1

准备 example.top 文件

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ORIGIN example.top.
$TTL 3600
@ IN SOA ns1.example.top. admin.example.top. (
     124        ; serial
     7200       ; refresh
     3600       ; retry
     1209600    ; expire
     3600       ; minimum
)

@ IN NS ns1.example.top.
ns1 IN A 192.0.2.1
www IN A 10.0.0.2
oom IN A 127.0.0.1
bbs IN A 10.0.0.1

coredns 配置文件为

text
1
2
3
4
5
6
7
8
. {
    auto {
        directory /root/coredns1 (example\.)(.*) {1}{2}
        reload 5s
    }
    log
    errors
}
tips
这里在测试时,ORIGIN_TEMPLATE 必须为 xxx.xx,不能是 org, com 这种,这样会无法得到解析

他的查询结果如下

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ dig @127.0.0.1 www.example.top

; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> @127.0.0.1 www.example.top
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44245
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 866306455fa1c477 (echoed)
;; QUESTION SECTION:
;www.example.top.               IN      A

;; ANSWER SECTION:
www.example.top.        3600    IN      A       10.0.0.2

;; AUTHORITY SECTION:
example.top.            3600    IN      NS      ns1.example.top.

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Fri Jun 13 00:43:13 CST 2025
;; MSG SIZE  rcvd: 127


$ dig @127.0.0.1 shop.example.org

; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> @127.0.0.1 shop.example.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60134
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 8e1827bc713c7cda (echoed)
;; QUESTION SECTION:
;shop.example.org.              IN      A

;; ANSWER SECTION:
shop.example.org.       3600    IN      A       127.0.0.1

;; AUTHORITY SECTION:
example.org.            3600    IN      NS      ns1.example.org.

;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Fri Jun 13 00:43:40 CST 2025
;; MSG SIZE  rcvd: 129

总结

在本章节中,通过 forward, kubernetes, auto, file 展开了核心插件的功能特性。插件是 CoreDNS 强大功能的基础,通过合理配置和组合不同插件,可以构建满足各种需求的 DNS 服务。

在通过这些插件,我们可以大致了解出,在定义 DNS 系统时,这些插件的实现就是作为我们系统定义开发的一个思路,auto 可以让我们自行定义并发现域名配置。以及 kubernetes DNS 部分也有了进一步的了解

在下一篇文章中,开始从 CoreDNS 插件的源码进行分析学习,学习他的定义范式,以及实际开发自定义 CoreDNS 插件,通过实战案例掌握插件开发的完整流程,为构建高性能 DNS 域名平台做好准备。

Reference

[1] Bind DLZ

[2] PowerDNS Backends

[3] in-tree plugins

[4] External Plugins

[5] cache plugin

[6] forward plugin

[7] 基于 DNS 的 Kubernetes 服务发现规范

[8] coredns.yaml.sed