4、CoreDNS 配置详解:Corefile 语法、常用插件配置
CoreDNS 是 Kubernetes 集群默认的 DNS 组件,其核心配置文件 Corefile 采用类似 Caddyfile 的 DSL 语法。理解 Corefile 的结构与常用插件(kubernetes、forward、errors、log、health、ready)的配置方式,是精准定位 DNS 故障、优化集群 DNS 性能的基础。
4.1 Corefile 语法基础
Corefile 由 Server Block 和 Plugin Chain 组成。每个 Server Block 定义一组监听端口和域名匹配规则,内部按顺序串联多个插件。
# 基本语法结构
<zone> [<zone>...] {
<plugin> [<args>...]
<plugin> [<args>...]
...
}
| 语法元素 | 说明 | 示例 |
|---|---|---|
| zone | 匹配的 DNS 域名,支持通配符 . 表示所有域名 |
cluster.local、. |
| plugin | 插件名称,按声明顺序执行 | kubernetes、forward |
| args | 插件参数,多个参数用空格分隔 | cluster.local in-addr.arpa ip6.arpa |
| 注释 | 以 # 开头,仅支持行注释 |
# 这是注释 |
. 根域,通常先执行 errors、health、ready 等管理类插件,再执行 kubernetes 或 forward 等业务类插件。
4.2 常用插件配置详解
4.2.1 kubernetes 插件
核心插件,负责将 Kubernetes Service 和 Pod 的 DNS 记录转换为 DNS 响应。支持 Service(A/AAAA/SRV)、Pod(A/AAAA)、Cluster IP、Headless Service 等记录类型。
kubernetes [ZONES...] {
fallthrough [ZONES...]
ttl TTL
namespaces NAMESPACES...
pods POD-MODE
endpoint_pod_names
upstream [ADDRESS...]
transfer { ... }
}
| 参数 | 默认值 | 说明 |
|---|---|---|
fallthrough |
无 | 当本 zone 无匹配时,将查询传递给下一个插件 |
ttl |
5 | DNS 响应的 TTL 值(秒),调低可加速变更生效 |
namespaces |
所有 namespace | 限制仅解析指定 namespace 内的资源 |
pods |
disabled | Pod 记录模式:disabled、insecure、verified |
endpoint_pod_names |
false | 使用 Pod 名称作为端点主机名(Headless Service) |
namespaces 是否限制了范围;pods 模式设为 verified 可防止伪造 Pod 记录,但会增加 API Server 查询压力。
4.2.2 forward 插件
将无法在集群内解析的 DNS 查询转发到上游 DNS 服务器(如集群外部 DNS、云厂商 DNS)。支持多个上游、健康检查、轮询策略。
forward [ZONES...] ADDRESS... {
except DOMAIN...
force_tcp
prefer_udp
expire DURATION
max_fails INTEGER
health_check DURATION
policy [random|round_robin|sequential|first]
}
| 参数 | 默认值 | 说明 |
|---|---|---|
except |
无 | 排除不需要转发的域名列表 |
force_tcp |
false | 强制使用 TCP 协议转发 |
prefer_udp |
true | 优先使用 UDP 协议 |
expire |
30s | 连接缓存过期时间 |
max_fails |
2 | 连续失败次数后标记上游不可用 |
health_check |
5s | 上游健康检查间隔 |
policy |
random | 上游选择策略 |
. 根域,建议配置 2-3 个上游 DNS 服务器,使用 round_robin 策略,开启 health_check 并设置 expire 30s 避免缓存陈旧连接。
4.2.3 errors 插件
捕获 CoreDNS 内部错误并输出到标准错误(stderr),默认输出格式为 <timestamp> [ERROR] <plugin>: <message>。支持自定义日志格式和输出目标。
errors {
stacktrace
log_file PATH
log_level [debug|info|warn|error|panic]
}
log_level 临时调整为 debug 可捕获更详细的错误堆栈;生产环境建议保持 error 级别,避免日志过多。
4.2.4 log 插件
记录所有 DNS 查询请求和响应日志,支持自定义日志格式(Common Log Format / Combined Log Format)。
log [ZONES...] {
format [common|combined|json|<template>]
class [success|denial|error|all]
}
| 格式 | 示例输出 |
|---|---|
common |
[INFO] 10.0.0.1:54321 - 12345 "A IN kubernetes.default.svc.cluster.local. udp 54" 128 0.12s |
combined |
在 common 基础上增加 >rcode> >size> >duration> |
json |
结构化 JSON 输出,适合日志采集系统 |
log 插件会显著增加 CPU 和磁盘 I/O 开销。建议仅在故障排查时临时启用,或使用 class denial 仅记录拒绝查询。
4.2.5 health 插件
提供 HTTP 健康检查端点(默认 :8080/health),用于 Kubernetes livenessProbe 和 readinessProbe。当 CoreDNS 进程正常运行时返回 200 OK。
health [ADDRESS] {
lameduck DURATION
}
| 参数 | 默认值 | 说明 |
|---|---|---|
ADDRESS |
:8080 |
监听地址和端口 |
lameduck |
0s | 优雅退出前的“跛脚鸭”时间,在此期间仍响应健康检查但标记为不健康 |
lameduck 10s 让 CoreDNS 在滚动更新时先停止接收新流量,再完成存量请求,避免 DNS 查询中断。
4.2.6 ready 插件
提供就绪检查端点(默认 :8181/ready),用于 Kubernetes readinessProbe。当 CoreDNS 完成插件初始化并可以正常处理 DNS 查询时返回 200 OK。
ready [ADDRESS]
health 检查进程是否存活,ready 检查插件是否就绪。滚动更新时,ready 在新 Pod 完全加载插件链后才返回成功,避免流量过早导入。
4.3 完整 Corefile 示例与插件链分析
以下为 Kubernetes 集群默认的 CoreDNS ConfigMap 配置,结合了上述所有插件:
.:53 {
errors
health {
lameduck 10s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods verified
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
- errors — 最先注册,捕获后续所有插件的错误
- health / ready — 管理端点,不参与 DNS 查询路径
- kubernetes — 处理集群内部域名解析
- prometheus — 暴露指标,不影响查询逻辑
- forward — 转发外部域名查询
- cache — 缓存前序插件的响应结果
- loop — 检测 DNS 循环转发
- reload — 自动重载配置
- loadbalance — 对多 IP 记录做轮询响应
4.4 Corefile 配置故障排查清单
| 故障现象 | 可能原因 | Corefile 检查点 |
|---|---|---|
| 集群内 Service 解析失败 | kubernetes 插件 zone 未匹配 |
检查 kubernetes 后的域名列表是否包含 cluster.local |
| 外部域名解析超时 | forward 上游不可达 |
检查 forward 地址、health_check 状态 |
| Pod 启动后 DNS 间歇性失败 | ready 未就绪即接收流量 |
确认 ready 插件存在且 readinessProbe 配置正确 |
| 日志量过大导致磁盘满 | log 插件记录所有查询 |
限制 class 为 denial 或 error |
| 滚动更新时 DNS 中断 | 缺少 lameduck 配置 |
在 health 插件中添加 lameduck 10s |
reload 插件热加载配置,无需重启 Pod。但若修改了监听端口或 reload 插件本身,则需要手动重启。