4. 日志采集基础:CoreDNS 日志格式与结构化字段

在灾备缓存巡检场景中,CoreDNS 日志是判断缓存命中率、解析延迟和异常流量的第一手数据源。本节聚焦 log 插件的日志格式定义、关键结构化字段(Qname、Rcode、Duration)以及生产环境中的日志采样策略,为后续的日志关联与根因定位打下采集基础。

4.1 CoreDNS log 插件与默认日志格式

CoreDNS 的 log 插件负责记录每个 DNS 请求的处理结果。默认情况下,log 插件输出 Common Log Format (CLF) 格式的文本行,但生产环境通常使用 JSON 格式 以支持结构化解析。

推荐做法: 在 Corefile 中显式指定 log . { combined } 或自定义 JSON 模板,避免使用默认的短格式(仅包含少量字段)。

Corefile 配置示例(JSON 格式):

# 启用 JSON 结构化日志输出
. {
    log . {
        output file /var/log/coredns/access.log {
            roll_size 100mb
            roll_keep 7
        }
        format json
    }
    errors
    cache
    forward . 8.8.8.8:53
}

启用 format json 后,每条日志记录将输出为一个 JSON 对象,包含以下核心字段:

字段名 类型 说明 示例值
qname string 查询的域名(全限定域名,含根点) www.example.com.
qtype string 查询类型(A、AAAA、MX、CNAME 等) A
rcode string DNS 响应码(NOERROR、NXDOMAIN、SERVFAIL 等) NOERROR
duration float64 请求处理耗时(单位:秒,精度纳秒) 0.002345
remote string 客户端 IP 地址 10.0.1.100:54321
size int 响应报文大小(字节) 123
timestamp string 请求到达时间(RFC3339 格式) 2025-03-15T10:30:00.123Z

4.2 关键结构化字段详解

4.2.1 Qname:查询域名

qname 是日志关联的核心键。在灾备缓存巡检中,通过 qname 可以聚合统计每个域名的缓存命中率、平均延迟和错误率。注意 CoreDNS 输出的 qname 始终以 . 结尾(FQDN 格式),在日志分析时需做统一处理。

4.2.2 Rcode:响应码

rcode 直接反映 DNS 解析结果。异常巡检重点关注以下 Rcode:

  • NXDOMAIN:域名不存在,可能为缓存污染或配置错误。
  • SERVFAIL:上游 DNS 服务器故障或超时,需结合 duration 判断。
  • REFUSED:请求被拒绝,可能因 ACL 限制或服务过载。
  • NOERROR + 空应答:域名存在但无记录,需与预期记录集对比。

4.2.3 Duration:处理耗时

duration 是衡量缓存性能的关键指标。在灾备场景中,缓存命中时的 duration 通常 < 1ms,而缓存未命中(需向上游转发)时 duration 可能达到 10ms~100ms。通过 duration 的 P99 变化可以快速发现上游链路抖动或缓存失效。

巡检阈值参考: 缓存命中延迟 < 2ms,缓存未命中延迟 < 50ms(内网环境)。当 duration 持续超过 100ms 时,应触发告警并关联上游 DNS 日志。

4.3 日志采样策略

生产环境中 CoreDNS 实例可能每秒处理数万甚至数十万请求,全量日志采集会带来巨大的存储和计算开销。合理的采样策略可以在保证异常检测覆盖率的同时控制成本。

常见采样策略对比:

策略 实现方式 适用场景 优缺点
固定比率采样 每 N 条记录 1 条(如 1:100) 流量平稳、异常率低的场景 实现简单;但可能漏采偶发异常
自适应采样 根据 Rcode 或 duration 动态调整采样率 需要保证异常全量采集 异常不漏采;实现复杂度较高
错误全量 + 正常采样 Rcode != NOERROR 全量,其余按比率 灾备巡检、SLA 监控 平衡存储与异常覆盖率;推荐方案
基于 Qname 的哈希采样 对 qname 做一致性哈希,固定采样部分域名 需要持续跟踪特定域名集合 保证同一域名日志连续性;配置维护成本高
避坑提示: 不要在生产环境使用 log . { format json } 而不加任何采样控制。当 QPS 超过 10k 时,全量 JSON 日志的磁盘写入会成为性能瓶颈,甚至导致 CoreDNS 进程 OOM。建议结合 errors 插件和 log 插件的 class 指令做分级采样。

4.4 日志采集架构与采样决策流程

下图展示了从 CoreDNS 日志产生到采集、采样、存储的完整链路,以及异常场景下的采样决策逻辑。

CoreDNS 日志采集与采样决策流程 CoreDNS 实例 JSON 日志输出 采样决策模块 错误全量 + 正常比率 异常日志(全量) 正常日志(1:100) Rcode != NOERROR Rcode == NOERROR 日志存储(Elasticsearch / Loki) 说明:异常日志(Rcode != NOERROR 或 duration > 100ms)全量采集,正常日志按 1:100 比率采样,平衡存储与异常覆盖率

4.5 生产级日志采集配置建议

结合上述采样策略,推荐以下 Corefile 配置实现错误全量 + 正常采样:

# 生产环境推荐配置:错误全量 + 正常 1:100 采样
. {
    log . {
        output file /var/log/coredns/access.log {
            roll_size 200mb
            roll_keep 14
        }
        format json
        # 采样控制:仅记录 1% 的正常请求
        class denial error
        class all 0.01
    }
    errors
    cache 30
    forward . 10.0.0.53:53 {
        max_concurrent 1000
    }
}
关键参数说明:
class denial error:全量记录 NXDOMAIN、SERVFAIL 等错误响应。
class all 0.01:对所有请求(包括正常)按 1% 比率采样。由于 denial/error 已全量,实际正常请求采样率为 1%。
建议同时开启 errors 插件捕获 CoreDNS 自身错误,与 access log 分开存储。

通过上述配置,可以在灾备缓存巡检场景中确保所有异常 DNS 响应都被记录,同时将正常日志的存储开销降低 99%,为后续的日志关联与根因定位提供高质量、低成本的数据基础。