- 后端
- 网络
- 云原生
【免费下载链接】coredns
CoreDNS is a DNS server that chains plugins
CoreDNS 1.4.0 是 CoreDNS 成为 CNCF 毕业项目(graduated project)后的首个发布版本,也是 1.3.1 中预告的一系列弃用(deprecation)真正落地执行的关键版本。本文以官方发布说明 notes/coredns-1.4.0.md 为主线,结合当前仓库源码,逐一解读auto/file/health/proxy的弃用与替代方案、kubernetes / hosts / etcd / log / forward 五个插件的修复细节,以及 gRPC watch 功能移除等结构性变更,帮助读者在升级与配置 CoreDNS 时做出正确决策。
一、版本背景:CNCF 毕业后的第一个发布
CoreDNS 1.4.0 于 2019 年 3 月 3 日发布(发布说明中的日期字段为2019-03-03),这是 CoreDNS 成为 CNCF 毕业项目之后的首个版本。对 CoreDNS 而言,"毕业"意味着项目的治理、稳定性和社区参与度都得到了基金会层面的认可,因此这一版本在生态层面具有标志性意义。
从发布说明(notes/coredns-1.4.0.md)可以看到,1.4.0 的重点并不在于引入大量新插件,而是:
- 兑现上一版本的弃用承诺:1.3.1 中宣布的弃用项在 1.4.0 中正式生效;
- 为下一版本铺垫弃用路线图:针对auto、file、health、proxy四个插件发布弃用预告;
- 移除未使用的 gRPC watch 功能:简化服务端结构;
- 修复一批已知问题:涉及 kubernetes、hosts、etcd、log、forward 五个插件。
同时,发布说明也承认当时有两个已知 bug(issue #2593 与 #2624)正在积极修复中,计划在较短时间内通过后续版本解决。
二、下一版本的弃用预告(Deprecation Notice)
1.4.0 发布说明明确列出了针对下一个版本(即 1.5.0)的四项弃用计划,理解这些预告对规划升级路径至关重要。
1.auto弃用 TIMEOUT,改用 RELOAD
auto插件用于"旧式"权威 DNS 服务器场景:从磁盘上的 RFC 1035 风格 master 文件加载区域数据。1.4.0 宣布auto将弃用TIMEOUT配置,推荐改用RELOAD(对应 issue #2516)。
在 1.4.0 时代,auto的配置中同时存在timeout与reload两个语义相近的选项。弃用 TIMEOUT 的意图非常明确:统一重载机制,只保留reload一个配置入口。从当前仓库的 plugin/auto/setup.go 可以看到,reload指令的解析逻辑为:
case "reload": t := c.RemainingArgs() if len(t) < 1 { return a, errors.New("reload duration value is expected") } d, err := time.ParseDuration(t[0]) if d < 0 { err = errors.New("invalid duration") } if err != nil { return a, plugin.Error("file", err) } a.ReloadInterval = d也就是说,reload接受一个 Gotime.ParseDuration格式的时长字符串(如30s、1m),负值会被判为非法。默认情况下(未显式配置reload时),ReloadInterval会被设为 60 秒(见 plugin/auto/setup.go)。这一默认值在 plugin/auto/README.md 中也有说明:reload默认一分钟扫描一次目录。
2.auto与file弃用 NO_RELOAD
auto和file插件将弃用NO_RELOAD选项,推荐使用RELOAD 0来达到等效效果(对应 issue #2536)。这一弃用的语义是:"禁止重载"这个布尔开关被一个语义更统一的时长配置取代——reload 0表示不扫描目录变更、不做重载。
在 plugin/auto/setup_test.go 的测试用例中,可以清楚地看到这两项弃用的痕迹:
// NO_RELOAD has been deprecated. // TIMEOUT has been deprecated.测试注释直接点明这两个旧选项已被弃用,佐证了发布说明中的路线图确实已在代码与文档层面落地。
3.health回归进程级健康检查,ready插件接管插件就绪状态
health插件将回退为只报告进程级别的健康状态,不再聚合各插件的状态。取而代之的是一个全新的ready插件,专门负责确认"所有插件都至少完成了启动序列"。
这一设计的职责分离在源码中体现得非常清晰:
- plugin/health/health.go 中,health 的 HTTP 处理函数无条件返回
200 OK,注释直接写着// We're always healthy.——它只表达"进程活着"这一层语义; - plugin/ready/ready.go 则完全不同:
/ready端点会检查所有已注册插件是否就绪,未就绪时返回503并列出尚未就绪的插件名:
rd.mux.HandleFunc("/ready", func(w http.ResponseWriter, _ *http.Request) { rd.Lock() defer rd.Unlock() if !rd.done { w.WriteHeader(http.StatusServiceUnavailable) io.WriteString(w, "Shutting down") return } ready, notReadyPlugins := plugins.Ready() if ready { w.WriteHeader(http.StatusOK) io.WriteString(w, http.StatusText(http.StatusOK)) return } log.Infof("Plugins not ready: %q", notReadyPlugins) w.WriteHeader(http.StatusServiceUnavailable) io.WriteString(w, notReadyPlugins) })从 plugin.cfg 的插件执行顺序可以看出,ready被排在health之前:
ready:ready health:health这与发布说明的描述完全一致:health 负责存活(liveness),ready 负责就绪(readiness)。在 Kubernetes 等编排场景中,这一区分尤为重要——存活探针失败会重启容器,就绪探针失败只会摘除流量,两者语义不同,不应混用。
4.proxy插件移出默认插件集,forward成为替代方案
proxy插件将被迁移到外部仓库,并从默认插件集中弃用,官方推荐的替代品是forward插件。
forward 与 proxy 在功能上高度重叠,但 forward 的设计更现代、维护更活跃。从 plugin.cfg 可以看到,当前仓库中 forward 依然位于默认插件列表的尾部(forward:forward),而 proxy 插件在仓库中已经不见其身影——这正印证了发布说明中"移出默认插件集"的预告已经兑现。
从当前仓库的 plugin/forward/README.md 可以看到 forward 插件的典型用法,例如配置转发目标与并发限制:
. { forward . 8.8.8.8 9.9.9.9 { max_concurrent 1000 } }其中max_concurrent用于限制并发查询数,超过上限的查询会收到 REFUSED 响应;在 1.4.0 时代,forward还会对应暴露coredns_forward_max_concurrent_rejects_total这一指标用于统计被拒绝的查询数。如果读者仍在使用 proxy,应尽早迁移到 forward。
三、上一版本弃用的正式生效
发布说明明确写到:"The [previous] announced deprecations have been enacted"——即 1.3.1 发布中预告的弃用项,在 1.4.0 中已经正式执行。
这意味着在升级到 1.4.0 时,用户需要检查自己的 Corefile 中是否还残留有上一版本预告弃用的指令或插件。虽然 1.4.0 的发布说明没有逐一列举这些生效项,但结合 1.4.0 的弃用预告可以反推:CoreDNS 的弃用节奏是"一版预告、一版生效",因此升级前建议对照 1.3.1 的发布说明核对配置,尤其关注 proxy、auto 的 timeout/no_reload、health 的状态聚合等易变点。
四、结构变更:移除未使用的 gRPC watch 功能
1.4.0 从服务端移除了未使用的 gRPC watch 功能。这是一次减法式的结构简化——gRPC 服务器中 watch 相关的代码路径被删除,减少了一个从未被实际使用(unused)的功能面,也降低了后续维护成本。
从当前仓库的 core/dnsserver/server_grpc.go 以及 pb/ 下的dns_grpc.pb.go可以看出,如今的 gRPC 服务器聚焦于纯粹的 DNS 查询/响应转发,不再包含 watch 订阅这类非核心功能。对于使用 gRPC 协议接入 CoreDNS 的用户,这一移除不产生任何功能影响——因为 watch 此前就未被使用;但若你的调用方恰好依赖了该功能,则需要在升级前确认并调整。
五、插件更新与修复详解
1.4.0 对多个插件进行了文档与测试层面的随机更新("Random updates in documentation and fixes in tests and various plugins"),其中五个插件的修复值得专门说明。
1.kubernetes:日志库从 glog 切换到 klog
kubernetes 插件的修复背景是:Kubernetes 官方 client 库的日志库从 glog 切换到了 klog,CoreDNS 的 kubernetes 插件随之修复了日志适配。
从当前仓库源码可以清楚看到这一适配的产物:
- plugin/kubernetes/setup.go 中导入了
k8s.io/klog/v2,并通过klog.SetLogger(logr.New(&loggerAdapter{P: log}))将 klog 的输出重定向到 CoreDNS 自己的日志系统; - plugin/kubernetes/logger.go 的注释说明了这一设计的动机:通过 adapter 让 CoreDNS 能够记录来自 Kubernetes client 的日志消息/错误,同时将 verbosity 的控制权保留在 klog 库内部;
- plugin/kubernetes/logger_test.go 中还有针对 klog 行为(key/value 对齐等)的回归测试。
值得注意的是 setup.go 中的一行注释提示:不要在 reload 场景下调用klog.InitFlags(nil),否则会导致 CoreDNS reload 时 panic(plugin/kubernetes/setup.go)。这是从 1.4.0 时代沿袭下来的一个关键注意事项,对使用 reload 插件热加载配置的用户尤其重要。
2.hosts:修复 IPv6 语法中的 IPv4 地址解析
hosts 插件修复了"以 IPv6 语法书写的 IPv4 地址"(IPv4 addresses in IPV6 syntax)无法正确解析的问题。所谓 IPv6 语法,包括带 zone identifier 的地址形式(如fe80::1%eth0)等。
当前仓库 plugin/hosts/hostsfile.go 中的解析辅助函数正是这一修复的延续:
// parseIP calls discards any v6 zone info, before calling net.ParseIP. func parseIP(addr string) net.IP { // discard ipv6 zone addr = strings.SplitN(addr, "%", 2)[0] return net.ParseIP(addr) }该函数在调用net.ParseIP之前先剥离 IPv6 的 zone 信息(%之后的部分),从而保证带 zone 的地址也能被正确解析。仓库中的 plugin/hosts/hostsfile_test.go 提供了包含 IPv6 主机行的测试数据(并引用了 RFC 5952、RFC 4007),可对照验证修复行为。
3.etcd:新增凭据支持与空 host 字段修复
etcd 插件在 1.4.0 中获得了两项能力提升:
(1)凭据支持(credential support):etcd 插件新增了credentials USERNAME PASSWORD配置指令,用于访问启用了认证的 etcd 集群。这一功能在 plugin/etcd/README.md 中有明确记录:
credentials USERNAME PASSWORD源码层面,plugin/etcd/setup.go 的解析逻辑要求credentials必须携带两个参数(用户名和密码),否则返回credentials requires 2 arguments, username and password错误;随后在 plugin/etcd/setup.go 中将凭据写入 etcd v3 客户端配置:
if username != "" && password != "" { etcdCfg.Username = username etcdCfg.Password = password }plugin/etcd/setup_test.go 中覆盖了"有效凭据""缺少密码""完全没有凭据"等多种输入组合,并对etcd.Client.Username/etcd.Client.Password做了断言,是理解该指令行为边界的最佳参考。
(2)空 host 字段的回复修复:当 etcd 中存储的记录host字段为空时,1.4.0 修复了此前回复中的异常行为。这一修复与 plugin/etcd/msg/service.go 中 host 相关的序列化/反序列化逻辑直接相关——host字段是Service结构的核心成员(plugin/etcd/msg/service.go),它被用于生成 A/AAAA、SRV、MX、NS 等各类应答记录,因此空值处理必须健壮。
4.log:效率优化
log 插件在 1.4.0 中被"made more efficient"(变得更高效)。这是一次面向性能的优化,目标是在高查询量下降低日志路径的开销。由于发布说明没有给出具体实现细节,可以确定的是:log 插件的查询处理路径经过了一次效率层面的重构,功能语义保持不变——它依然是"按查询匹配规则输出日志"的查询日志插件。
5.forward:丢弃乱序消息,解决偶发 FORMERR
forward 插件的修复解决了一个困扰用户的真实问题:丢弃乱序的消息(drops out of order messages),从而解决人们偶尔看到的 FORMERR(格式错误)响应。
这里的背景是 DNS over TCP / 连接复用场景:当多个查询在同一个连接上以流水线方式发送时,如果上游返回的响应顺序与请求顺序不一致,旧逻辑可能产生解析错位,进而表现为 FORMERR。1.4.0 的修复是:检测到乱序响应时直接丢弃,而不是将其错误地匹配给其他在途查询。
从当前仓库 plugin/forward/forward.go 及其相关测试(如 plugin/forward/dot_test.go 中对 TCP/DoT 场景下响应 ID 与答案的严格断言)可以看出,forward 对上游响应的 ID 匹配、答案正确性有着严格的校验逻辑,这正是"乱序即丢"策略得以安全实施的基础。
六、升级与迁移实战建议
综合 1.4.0 发布说明与仓库现状,给读者的升级建议如下:
- 迁移 proxy → forward:proxy 已从默认插件集移除,若 Corefile 中仍配置 proxy,应立即改用 forward。参考 plugin/forward/README.md 中的语法调整配置。
- 统一 auto/file 的重载配置:删除 TIMEOUT 与 NO_RELOAD,改用
reload DURATION;需要"禁用重载"时配置reload 0(仅指不扫描变更、不自动重载),默认值为一分钟。 - 区分 health 与 ready 探针:进程存活用 health(默认
:8080/health,plugin/health/health.go 中恒返回 200);插件就绪用 ready(默认:8181/ready,plugin/ready/ready.go 中未就绪返回 503)。在 Kubernetes 中就绪探针请指向 ready,而非 health。 - 为 etcd 启用认证时配置凭据:使用
credentials USERNAME PASSWORD指令;注意该指令必须同时提供两个参数,缺一不可。 - 升级前核对 1.3.1 弃用项:1.4.0 已正式执行上一版本预告的弃用,检查 Corefile 中是否残留已生效弃用的指令。
- 注意 reload 与 klog 的兼容性:使用 reload 热加载时,勿在插件初始化中调用
klog.InitFlags(nil),否则可能导致 panic(plugin/kubernetes/setup.go 注释)。 - 关注已知 bug 的后续修复:1.4.0 发布时 issue #2593 与 #2624 仍在修复中,升级后如遇到相关现象,可留意后续版本(1.4.1 等)的发布说明。
七、小结
CoreDNS 1.4.0 是一个"承上启下"的版本:它兑现了 1.3.1 的弃用承诺,同时为 1.5.0 划定了清晰的弃用路线图;它没有引入新的插件明星,却通过 kubernetes(klog 适配)、hosts(IPv6 语法解析)、etcd(凭据支持)、log(效率优化)、forward(乱序丢弃)五项修复提升了既有能力的可靠性与可用性。对运维与开发者而言,1.4.0 最重要的迁移信号是:proxy 时代结束、forward 时代开始,health 与 ready 职责分离。理解这些变化,才能在升级 CoreDNS 时平稳过渡、少踩坑。
如需更完整的配置语法,建议直接阅读仓库内对应插件的 README:plugin/auto/README.md、plugin/file/README.md、plugin/health/README.md、plugin/forward/README.md、plugin/etcd/README.md;发布说明原文见 notes/coredns-1.4.0.md。
- 后端
- 网络
- 云原生
【免费下载链接】coredns
CoreDNS is a DNS server that chains plugins
相关推荐
django CMS 4.1.1 升级指南:首个社区版发布详解、新特性与底层实现剖析
django CMS 4.1.1 升级指南:首个社区版发布详解、新特性与底层实现剖析 导读 :django CMS 4.1.1 是 django CMS 4 系
CMS后端Electric 加入 Databricks:WASM Postgres、实时同步引擎与 Lakebase 平台的技术演进
Electric 加入 Databricks:WASM Postgres、实时同步引擎与 Lakebase 平台的技术演进 2026 年 8 月,Electri
后端网络云原生VoiceStudio TTS 微调实战指南:用两卡 5000 步训练你的专属音色
VoiceStudio TTS 微调实战指南:用两卡 5000 步训练你的专属音色 VoiceStudio 是一款开源、完全本地运行的 TTS 平台,支持 64
人工智能语音音频本地部署MCP 服务桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考