4. CoreDNS 配置详解:Corefile 语法、常用插件与配置热加载
CoreDNS 的行为完全由 Corefile 控制。Corefile 是一种基于 Caddy 配置语法的 DSL(领域特定语言),它定义了 DNS 服务器监听哪些端口、处理哪些域名、使用哪些插件链。理解 Corefile 是排查 DNS 故障和进行性能调优的第一步。
4.1 Corefile 语法基础
Corefile 由 Server Block(服务器块)和 Plugin Block(插件块)组成。一个典型的 Corefile 结构如下:
.:53 { # Server Block:监听所有接口的 53 端口,处理根域 (.)
errors # 插件:错误日志
health # 插件:健康检查端点
ready # 插件:就绪检查端点
kubernetes cluster.local in-addr.arpa ip6.arpa { # 插件:Kubernetes 服务发现
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
forward . /etc/resolv.conf { # 插件:转发未知域名
max_concurrent 1000
}
cache 30 # 插件:缓存 30 秒
loop # 插件:检测 DNS 循环
reload # 插件:自动热加载配置
loadbalance # 插件:轮询负载均衡
}
语法要点:
- Server Block:以
ZONE:PORT开头,例如.:53表示监听所有网络接口的 53 端口处理根域。 - 插件顺序:插件按在 Corefile 中出现的顺序执行,形成 插件链。顺序错误可能导致逻辑异常。
- 花括号:插件参数如果跨多行,必须使用花括号包裹。
- 注释:使用
#进行单行注释。
4.2 常用插件详解
下表列出了 CoreDNS 在 Kubernetes 环境下最核心的插件及其关键配置参数:
| 插件名称 | 核心功能 | 关键配置项 | 故障排查要点 |
|---|---|---|---|
| kubernetes | 将 Kubernetes Service/Pod 的 DNS 记录转换为 DNS 响应 | pods insecure/verified/disabled、fallthrough、ttl |
检查 pods 模式;确认 fallthrough 是否覆盖了反向查询域 |
| forward | 将无法本地解析的 DNS 请求转发到上游 DNS 服务器 | max_concurrent、prefer_udp、force_tcp、health_check |
max_concurrent 限制不足会导致请求被丢弃;上游服务器不可用会触发超时 |
| loop | 检测并中断 DNS 解析循环(CoreDNS 自身转发给自己) | 无参数 | 如果检测到循环,CoreDNS 会直接退出并报错 Loop detected |
| health | 暴露 HTTP 健康检查端点(默认 :8080/health) |
lameduck 时长 |
Kubernetes liveness probe 依赖此端点;lameduck 设置优雅退出时间 |
| ready | 暴露 HTTP 就绪检查端点(默认 :8181/ready) |
无参数 | Kubernetes readiness probe 依赖此端点;插件链全部加载完毕后才返回 200 |
| cache | 缓存 DNS 响应,减少上游查询压力 | success 容量/TTL、denial 容量/TTL、prefetch |
缓存命中率低时检查 TTL 设置;prefetch 可提前刷新热点记录 |
| reload | 自动检测 Corefile 变更并执行热加载 | interval 扫描间隔(默认 30 秒) |
变更后需等待扫描间隔;语法错误会导致加载失败,旧配置继续运行 |
4.3 插件链执行流程
CoreDNS 的插件链是顺序执行的。当一个 DNS 请求到达时,它会依次经过每个插件,直到某个插件生成响应或显式调用 next 将请求传递给下一个插件。下图展示了 Kubernetes 环境下典型的插件链执行流程:
关键理解:
- 顺序敏感:
kubernetes插件必须在forward之前,否则集群域名会被错误转发到上游。 - fallthrough:当
kubernetes插件无法处理某个查询时(例如非集群域名),fallthrough允许请求继续传递到下一个插件(通常是forward)。 - loop 插件:通常放在
forward之后,用于检测是否将请求转发回了自己。
4.4 配置热加载(reload 插件)
CoreDNS 支持通过 reload 插件实现配置热加载,无需重启 Pod 即可应用 Corefile 变更。其工作机制如下:
- 定时扫描:reload 插件每隔
interval(默认 30 秒)扫描一次 Corefile 的修改时间。 - 语法校验:检测到变更后,CoreDNS 会解析新配置。如果语法错误,则保留旧配置并记录错误日志。
- 优雅切换:新配置生效时,旧配置的 in-flight 请求会通过
health插件的lameduck机制优雅完成。
热加载避坑指南:
- ConfigMap 挂载延迟:在 Kubernetes 中,ConfigMap 更新后挂载到 Pod 的文件可能延迟数秒到数十秒,reload 插件可能无法立即感知。
- 语法错误导致静默失败:如果新 Corefile 有语法错误,reload 会失败但 CoreDNS 不会退出,旧配置继续运行。务必通过
kubectl logs检查错误日志。 - 插件顺序错误:热加载不会校验逻辑顺序,例如将
forward放在kubernetes之前可能导致集群解析异常。
4.5 生产环境 Corefile 最佳实践
以下是一个经过性能调优的生产级 Corefile 示例:
.:53 {
# 1. 错误日志(必须放在最前)
errors
# 2. 健康检查
health {
lameduck 5s
}
ready
# 3. Kubernetes 服务发现
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods verified
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
# 4. 转发上游
forward . 10.0.0.1 10.0.0.2 {
max_concurrent 2000
health_check 5s
prefer_udp
}
# 5. 缓存(提升性能)
cache {
success 10000 30
denial 5000 5
prefetch 3 30m 20%
}
# 6. 循环检测
loop
# 7. 自动重载
reload 15s
# 8. 负载均衡
loadbalance
}
调优要点:
- max_concurrent:根据 CoreDNS Pod 的 CPU 和内存限制调整,避免上游连接耗尽。建议设置为
2000-5000。 - prefetch:对热点记录提前刷新,减少客户端等待时间。建议设置为
prefetch 3 30m 20%。 - lameduck:在 Pod 被终止时,给已有连接 5 秒的优雅关闭时间,避免 DNS 请求被中断。