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 环境下典型的插件链执行流程:

CoreDNS 插件链执行流程(Kubernetes 环境) DNS 请求进入 errors(错误日志) health / ready kubernetes(集群域名) 匹配成功 未匹配(fallthrough) 直接响应 进入 forward
关键理解:
  • 顺序敏感:kubernetes 插件必须在 forward 之前,否则集群域名会被错误转发到上游。
  • fallthrough:当 kubernetes 插件无法处理某个查询时(例如非集群域名),fallthrough 允许请求继续传递到下一个插件(通常是 forward)。
  • loop 插件:通常放在 forward 之后,用于检测是否将请求转发回了自己。

4.4 配置热加载(reload 插件)

CoreDNS 支持通过 reload 插件实现配置热加载,无需重启 Pod 即可应用 Corefile 变更。其工作机制如下:

  1. 定时扫描:reload 插件每隔 interval(默认 30 秒)扫描一次 Corefile 的修改时间。
  2. 语法校验:检测到变更后,CoreDNS 会解析新配置。如果语法错误,则保留旧配置并记录错误日志。
  3. 优雅切换:新配置生效时,旧配置的 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 请求被中断。