Rocky Linux 9 从入门到精通007 — DNS 管理(CoreDNS 插件篇)

前述

CoreDNS 的插件非常丰富,在文章 《Rocky Linux 9 从入门到精通007 — DNS管理(CoreDNS 集群部署篇)》中对此有详细介绍,本文主要是对一些常用插件配置进行讲解,后续也会陆续补充其他插件的使用技巧。

Hosts 解析配置

hosts 插件可以实现 Hosts 解析,类似于本地主机上的 Hosts 文件绑定。在 Linux 系统中,可以通过修改 /etc/hosts 文件实现。在 Windows 系统中,则通过修改 C:\Windows\System32\drivers\etc\hosts 文件实现。默认情况下,hosts 插件默认每隔 5 秒钟重新加载一次 hosts 文件。

[root@coredns-001 ~]# cat > /etc/coredns/Corefile << \EOF
.:53 {
    log  # 启用日志记录
    loop # 防止 DNS 查询在多个 DNS 服务器之间循环,导致无限查询循环。如果检测到循环,CoreDNS 会中止查询。
    errors  # 启用错误日志记录
    reload 30s # 通过 reload 插件实现热加载功能,确保在不重启 CoreDNS 服务的情况下,动态应用新的配置,每隔 30 秒重载一次 Corefile 配置文件。
    cache 300s # 配置 DNS 查询的缓存时间为 300 秒,减少重复查询,提高响应速度和性能。
    ready 0.0.0.0:8181 # 在指定地址和端口上提供 readiness(就绪)探针。
    health 0.0.0.0:8080 # 在指定地址和端口上提供健康检查(health check)。
    prometheus 0.0.0.0:9253 # 在指定地址和端口上启用 Prometheus metrics。
    loadbalance round_robin # 使用轮询模式进行负载均衡。

    hosts /etc/coredns/hosts {  # hosts 解析插件
        fallthrough  # 当在 hosts 解析中没有获取到解析信息,将 DNS 查询传给其它插件。
    }

    forward . 223.6.6.6 114.114.114.119 # DNS 转发
}
EOF

# hosts 文件配置
[root@coredns-001 ~]# cat > /etc/coredns/hosts << \EOF
192.168.2.1 a.rockylinux.cn
192.168.2.2 b.rockylinux.cn
EOF
特别提醒
在 CoreDNS 中插件的顺序非常重要,因为请求在配置文件(Corefile)中被依次传递给插件来处理。对于 hostsforward 插件的顺序,通常 hosts 插件应放在 forward 插件之前。这是因为 hosts 插件根据静态文件内容处理 DNS 请求,而 forward 插件则将请求转发到上游 DNS 服务器。如果 hosts 插件在 forward 插件之后,任何匹配 hosts 文件中的请求将不会有机会被 hosts 插件处理,因为这些请求已经被 forward 插件转发出去了。

客户端测试验证,因为 reload 插件会每隔 30 秒加载一次 Corefie 文件,所以不需要重启 coredns 服务,等待 30 秒即可测试验证。

# host 解析验证
[root@client-001 ~]# dig @192.168.1.1 a.rockylinux.cn

; <<>> DiG 9.10.6 <<>> @192.168.1.1 a.rockylinux.cn
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- \opcode: QUERY, status: NOERROR, id: 59996
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;a.rockylinux.cn.           IN  A

;; ANSWER SECTION:
a.rockylinux.cn.        3600    IN  A   192.168.2.1 # 获取解析信息

;; Query time: 1 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Tue Jul 09 17:10:25 CST 2024
;; MSG SIZE  rcvd: 71

# 怎么知道是不是从 hosts 解析直接返回的了?可以使用 tcpdump 抓包验证。
[root@client-001 ~]# tcpdump -n -i any port 53  
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
18:41:05.345118 enp6s0f0 In  IP 192.168.3.1.51685 > 192.168.1.1.domain: 5458+ [1au] A? a.rockylinux.cn. (42) # 客户端请求 A 记录解析
18:41:05.345390 enp6s0f0 Out IP 192.168.1.1.domain > 192.168.3.1.51685: 5458*- 1/0/1 A 192.168.2.1 (71) # 服务器直接返回对应解析记录,没有去到任何上级 DNS 服务器进行解析,说明通过 hosts 解析。

Forward 域名转发器配置

Forward 域名转发器插件,主要用于将指定域名解析转发至指定 DNS 服务器进行解析。它支持 UDP、TCP 和 DNS-over-TLS,并自带健康检查。健康检查循环运行,每 0.5 秒进行一次检查,只要上游报告不健康,就会持续进行。一旦上游恢复健康,将停止健康检查(直到下一次错误)。健康检查使用递归 DNS 查询(. IN NS)来获取上游健康状况。任何非网络错误的响应(REFUSEDNOTIMPLSERVFAIL 等)都被视为上游健康。健康检查使用与 TO 中指定的相同协议。如果 max_fails 设置为 0,则不进行检查,上游将始终被视为健康。当所有上游都关闭时,它会认为健康检查作为一种机制已经失败,并会尝试连接到一个随机的上游(也许可用,也许不可用)。

[root@coredns-001 ~]# cat > /etc/coredns/Corefile << \EOF
.:53 {
    log  # 启用日志记录
    loop # 防止 DNS 查询在多个 DNS 服务器之间循环,导致无限查询循环。如果检测到循环,CoreDNS 会中止查询。
    errors  # 启用错误日志记录
    reload 30s # 通过 reload 插件实现热加载功能,确保在不重启 CoreDNS 服务的情况下,动态应用新的配置,每隔 30 秒重载一次 Corefile 配置文件。
    cache 300s # 配置 DNS 查询的缓存时间为 300 秒,减少重复查询,提高响应速度和性能。
    ready 0.0.0.0:8181 # 在指定地址和端口上提供 readiness(就绪)探针。
    health 0.0.0.0:8080 # 在指定地址和端口上提供健康检查(health check)。
    prometheus 0.0.0.0:9253 # 在指定地址和端口上启用 Prometheus metrics。
    loadbalance round_robin # 使用轮询模式进行负载均衡。

    hosts /etc/coredns/hosts {  # hosts 解析插件
        fallthrough  # 当在 hosts 解析中没有获取到解析信息,将 DNS 查询传给其它插件。
    }

    forward . 223.6.6.6 114.114.114.119 # DNS 转发
}

# 域名转发器配置有两种写:多个域名指向同一个转发器或单个域名指向一个转发器
google.com:53 facebook.com:53 youtube.com:53 {
    forward . 8.8.8.8 4.4.4.4
    log
    errors
}

cloudflare.com:53 {
    forward . 1.1.1.1 1.0.0.1
    log
    errors
}
EOF
温馨提示
在 CoreDNS 中插件的匹配优先级是基于配置块的顺序和具体性。就 Forward 插件而言,配置的优先级取决于域名的匹配精确度。cloudflare.com:53 优化级高于 .:53。在这个配置中,cloudflare.com:53 配置块具有更高的匹配优先级,因为它更具体,仅针对 cloudflare.com 及其子域名。而 .:53 配置块更泛,匹配所有域名。因此,对于解析 cloudflare.com 及其子域名(例如 www.cloudflare.com)的请求,会先匹配到 cloudflare.com:53 配置块,并使用 1.1.1.11.0.0.1 作为上游 DNS 服务器。而对于其他所有域名的请求,会匹配到 .:53 配置块,使用 8.8.8.84.4.4.4 作为上游 DNS 服务器。

客户端测试验证,因为 reload 插件会每隔 30 秒加载一次 Corefie 文件,所以不需要重启 coredns 服务,等待 30 秒即可测试验证。

[root@client-001 ~]# dig @192.168.1.1 www.youtube.com

; <<>> DiG 9.10.6 <<>> @192.168.1.1 www.youtube.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- \opcode: QUERY, status: NOERROR, id: 19199
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.youtube.com.       IN  A

;; ANSWER SECTION:
www.youtube.com.    300 IN  CNAME   youtube-ui.l.google.com.
youtube-ui.l.google.com. 300    IN  A   172.217.160.110
youtube-ui.l.google.com. 300    IN  A   172.217.163.46
youtube-ui.l.google.com. 300    IN  A   142.251.43.14
youtube-ui.l.google.com. 300    IN  A   142.251.42.238

;; Query time: 26 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Tue Jul 09 18:24:11 CST 2024
;; MSG SIZE  rcvd: 252

# 同样通过抓包可以看到对应 DNS 解析请求,转发至 8.8.8.8 进行解析。
[root@client-001 ~]# tcpdump -n -i any port 53  
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
18:24:11.484957 enp6s0f0 In  IP 192.168.3.1.54716 > 192.168.1.1.domain: 19199+ [1au] A? www.youtube.com. (44)
18:24:11.485225 enp6s0f0 Out IP 192.168.1.1.64080 > 8.8.8.8.domain: 20107+ [1au] A? www.youtube.com. (44) # 在这里可以明确看到 DNS 服务器地址 8.8.8.8
18:24:11.510638 enp6s0f0 In  IP 8.8.8.8.domain > 192.168.1.1.64080: 20107 5/0/1 CNAME youtube-ui.l.google.com., A 172.217.160.110, A 172.217.163.46, A 142.251.43.14, A 142.251.42.238 (142)
18:24:11.510830 enp6s0f0 Out IP 192.168.1.1.domain > 192.168.3.1.54716: 19199 5/0/1 CNAME youtube-ui.l.google.com., A 172.217.160.110, A 172.217.163.46, A 142.251.43.14, A 142.251.42.238 (252)

Header 配置

Header 插件,主要用于标记处理 DNS 查询和响应所需要的状态。修改对于客户端和后续插件而言是透明的。当前支持的标记包括:

  • aa – 权威(答案)
  • ra – 递归可用
  • rd – 需要递归

那么在哪些场景需要用到这个插件了?

在使用 nslookup 测试 DNS 解析过程中,发现当使用 hosts 插件进行 Hosts 解析时,nslookup 会提示主 DNS 服务器无法进行递归查询,尝试下一个服务器(如下所示)。实际上当您指定 DNS 解析服务器时,是不会存在此问题的。

[root@client-001 ~]# nslookup a.rockylinux.cn
;; Got recursion not available from 192.168.1.1, trying next server # 报错信息
Server:     192.168.1.2
Address:    192.168.1.2#53

Name:   a.rockylinux.cn
Address: 192.168.2.1

指定主 DNS 服务器 IP 进行解析,一切正常。

[root@client-001 ~]# nslookup a.rockylinux.cn 192.168.1.1
Server:     192.168.1.1
Address:    192.168.1.1#53

Name:   a.rockylinux.cn
Address: 192.168.2.1

另外通过 dig 进行解析不会存在此问题。

[root@client-001 ~]# dig a.rockylinux.cn
; <<>> DiG 9.10.6 <<>> a.rockylinux.cn
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- \opcode: QUERY, status: NOERROR, id: 63643
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;a.rockylinux.cn.   IN  A

;; ANSWER SECTION:
a.rockylinux.cn. 3600   IN  A   192.168.2.1

;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Wed Aug 14 17:56:19 CST 2024
;; MSG SIZE  rcvd: 95

查看 CoreDNS 解析日志会发现,两台服务器都同时响应了对应的 DNS 请求(CoreDNS 集群对于此请求放大了 N 倍,N 值的大小取决于 CoreDNS 集群的大小)。

[root@coredns-001 ~]# journalctl -f -u coredns | grep a.rockylinux.cn
Aug 14 17:47:50 coredns-001 coredns[79104]: [INFO] 192.168.3.1:56640 - 18234 "A IN a.rockylinux.cn. udp 43 false 512" NOERROR qr,aa,rd 84 0.00007369s
Aug 14 17:47:51 coredns-001 coredns[79104]: [INFO] 192.168.3.1:50982 - 51134 "A IN a.rockylinux.cn. udp 43 false 512" NOERROR qr,aa,rd 84 0.0000588s
[root@coredns-002 ~]# journalctl -f -u coredns | grep a.rockylinux.cn
Aug 14 17:47:50 coredns-002 coredns[125676]: [INFO] 192.168.3.1:60336 - 18234 "A IN a.rockylinux.cn. udp 43 false 512" NOERROR qr,aa,rd 84 0.000122s
Aug 14 17:47:51 coredns-002 coredns[125676]: [INFO] 192.168.3.1:54437 - 51134 "A IN a.rockylinux.cn. udp 43 false 512" NOERROR qr,aa,rd 84 0.000117659s

实际上这是 nslookup 的问题,man nslookup 查看帮忙时,会看到如下信息:

[root@client-001 ~]# man nslookup
            [no]recurse
               Tell the name server to query other servers if it does not have the information.
               (Default = recurse; abbreviation = [no]rec)

也就是 DNS 服务器没有这条解析记录时,就会查询下一台 DNS 服务器,本质在于 nslookup 解析时,不认为 hosts 插件查询是支持递归查询的结果。这时候,如果将客户端的 DNS 服务器设置成单个主 DNS 服务器地址: 192.168.1.1,再去使用 nslookup 解析就不会存在此问题了。

至此,Header 插件就可以发挥作用了,实际上只需要使用 CoreDNS 的 Header 插件设置响应头值为 ra 即递归可用即可。

同时在 coredns-001 及 coredns-002 添加以下配置:

.:53 {
    log  # 启用日志记录
    loop # 防止 DNS 查询在多个 DNS 服务器之间循环,导致无限查询循环。如果检测到循环,CoreDNS 会中止查询。
    errors  # 启用错误日志记录
    reload 30s # 通过 reload 插件实现热加载功能,确保在不重启 CoreDNS 服务的情况下,动态应用新的配置,每隔 30 秒重载一次 Corefile 配置文件。
    cache 300s # 配置 DNS 查询的缓存时间为 300 秒,减少重复查询,提高响应速度和性能。
    ready 0.0.0.0:8181 # 在指定地址和端口上提供 readiness(就绪)探针。
    health 0.0.0.0:8080 # 在指定地址和端口上提供健康检查(health check)。
    prometheus 0.0.0.0:9253 # 在指定地址和端口上启用 Prometheus metrics。
    loadbalance round_robin # 使用轮询模式进行负载均衡。

    hosts /etc/coredns/hosts {  # hosts 解析插件
        fallthrough  # 当在 hosts 解析中没有获取到解析信息,将 DNS 查询传给其它插件。
    }

    header {
        response set ra # 设置 Header 头 response 为 ra 即可
    }

    forward . 223.6.6.6 114.114.114.119 # DNS 转发
}

这时候客户端再通过 nslookup 解析正常。

[root@client-001 ~]# nslookup a.rockylinux.cn
Server:     192.168.1.1
Address:    192.168.1.1#53

Name:   a.rockylinux.cn
Address: 192.168.2.1

从服务器端日志来看,解析时响应结果会由 qr,aa,rd 变成 qr,aa,rd,ra,也就是告诉客户端此结果为递归查询结果。此时,只会从主 DNS 服务器进行解析,不会再出现转到从 DNS 服务器解析的情况。

[root@coredns-001 ~]# journalctl -f -u coredns | grep a.rockylinux.cn
Aug 14 18:50:18 coredns-001 coredns[79104]: [INFO] 192.168.3.1:60322 - 65343 "A IN a.rockylinux.cn. udp 43 false 512" NOERROR qr,aa,rd,ra 84 0.000129409s
Aug 14 18:50:31 coredns-001 coredns[79104]: [INFO] 192.168.3.1:58872 - 25669 "A IN a.rockylinux.cn. udp 43 false 512" NOERROR qr,aa,rd,ra 84 0.000101711s

显然在使用 hosts 插件时,header 插件的使用,可以有效降低 CoreDNS 集群的资源消耗。当然 header 插件还有很多其它使用场景。

Avatar photo

关于 木子

Founder of the Rocky Linux Chinese community, MVP、VMware vExpert、TVP, advocate for cloud native technologies, with over ten years of experience in site reliability engineering (SRE) and the DevOps field. Passionate about Cloud Computing、Microservices、CI&CD、DevOps、Kubernetes, currently dedicated to promoting and implementing Rocky Linux in Chinese-speaking regions.
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇