跳到主要内容

CoreDNS 监控与优化指南

📅 创建日期: 2025-05-20 | 更新日期: 2026-02-18 | ⏱️ 阅读时间: 约 13 分钟

在 Amazon EKS 和现代 Kubernetes 集群中,CoreDNS 是负责集群内所有服务发现和外部域名解析的核心组件。CoreDNS 的性能和可用性直接影响应用程序的响应时间和稳定性,因此构建有效的监控和优化架构至关重要。本文分析 CoreDNS 性能监控指标TTL 配置指南监控架构最佳实践以及 AWS 推荐方案和实战案例。各章节通过 Prometheus 指标和 Amazon EKS 环境中的应用示例,深入了解 CoreDNS 监控策略。

1. CoreDNS 性能监控:核心 Prometheus 指标与含义

CoreDNS 通过 metrics 插件提供 Prometheus 格式的指标,在 EKS 中默认通过 kube-dns 服务的 9153 端口暴露。核心指标展示 DNS 请求的吞吐量、延迟、错误和缓存效率等信息,通过监控这些指标可以快速捕获 DNS 性能瓶颈或故障征兆。

CoreDNS 四大黄金信号

🎯 CoreDNS 四大黄金信号
基于 Google SRE 方法论的核心监控指标
📈
流量 (Throughput)coredns_dns_requests_total
每秒 DNS 请求数(QPS)。检查各 Pod 负载是否均衡,持续增长时考虑横向扩展。
⏱️
延迟 (Latency)coredns_dns_request_duration_seconds
P99 响应时间。高于正常值时,检查上游 DNS 延迟或 CoreDNS CPU/内存饱和。
错误 (Errors)coredns_dns_responses_total{rcode=SERVFAIL}
SERVFAIL/REFUSED 比例增加时,检查外部通信或访问权限问题。NXDOMAIN 激增意味着错误的域名查询。
💻
资源使用 (Resource)CPU / Memory utilization
EKS 默认内存请求/限制:70Mi/170Mi。超过 150Mi 时设置告警。CPU 达到限制会导致节流和 DNS 延迟。

CoreDNS 核心 Prometheus 指标

📊 CoreDNS Prometheus 核心指标
EKS 默认通过端口 9153 (/metrics) 暴露
指标
信号
说明 / PromQL
coredns_dns_requests_total
Counter
流量
DNS 请求总数(按协议/类型)。用 rate() 计算 QPS
rate(coredns_dns_requests_total[5m])
coredns_dns_request_duration_seconds
Histogram
延迟
DNS 处理时间分布。P99 > 100ms 时检查上游/资源
histogram_quantile(0.99, rate(coredns_dns_request_duration_seconds_bucket[5m]))
coredns_dns_responses_total
Counter
错误
DNS 响应码分布。跟踪 SERVFAIL/NXDOMAIN 比例
rate(coredns_dns_responses_total{rcode="SERVFAIL"}[5m])
coredns_cache_hits_total
Counter
缓存
缓存命中数(success/denial)。用于计算缓存命中率
rate(coredns_cache_hits_total[5m])
coredns_cache_misses_total
Counter
缓存
缓存未命中数。命中率 = hits / (hits + misses)
rate(coredns_cache_misses_total[5m])
coredns_forward_requests_total
Counter
转发
上游 DNS 转发请求数。缓存未命中时发生
rate(coredns_forward_requests_total[5m])
coredns_forward_responses_total
Counter
转发
上游 DNS 响应数(按 rcode)。监控上游错误
rate(coredns_forward_responses_total[5m])
coredns_panics_total
Counter
稳定性
CoreDNS panic 次数。非零时需立即调查
coredns_panics_total

此外还提供请求/响应大小coredns_dns_request_size_bytes...response_size_bytes)、DO 位设置coredns_dns_do_requests_total)等指标,以及 CoreDNS 加载的各插件附加指标。例如通过 Forward 插件的上游查询时间(coredns_forward_request_duration_seconds)或 kubernetes 插件的 API 更新延迟(coredns_kubernetes_dns_programming_duration_seconds)等。

主要指标含义与活用

例如,通过 coredns_dns_requests_total 的每秒增长率来掌握 DNS QPS,并按 CoreDNS Pod 分别查看负载是否均衡。若 QPS 持续增长,需检讨 CoreDNS 是否需要横向扩展。当 coredns_dns_request_duration_seconds 的 P99 高于正常水平时,表示 CoreDNS 正在经历响应延迟,需检查上游 DNS 延迟或 CoreDNS CPU/内存饱和。此时若 CoreDNS 缓存(coredns_cache_hits_total)命中率较低,需确认 TTL 是否过短导致缓存效果下降并进行调整。若 coredns_dns_responses_totalSERVFAILREFUSED 比例上升,需检查日志确认是否存在 CoreDNS 外部通信问题访问权限问题。若 NXDOMAIN 针对特定域名急增,则可能是应用程序在查询错误的域名。

此外,系统资源指标(CPU/内存)也很重要。监控 CoreDNS Pod 的 CPU/内存使用率,当各 Pod 接近资源限制时设置告警。例如 EKS 默认 CoreDNS 内存请求/限制为 70Mi/170Mi,因此需跟踪内存使用是否超过 150Mi,达到阈值时发出警报并增加内存限制或添加 Pod。CPU 达到限制时 kubelet 会对 CoreDNS 进程进行节流,导致 DNS 延迟,因此 CPU 使用率接近限制时应考虑扩展或增加资源分配。

VPC ENI DNS 包限制

每个节点 ENI 每秒仅允许 1024 个 DNS 包。即使放开 CoreDNS 的 max_concurrent 限制,由于 ENI PPS 限制(1024 PPS),也可能无法达到预期性能。

2. CoreDNS TTL 配置指南与 Amazon EKS 应用示例

TTL(Time-To-Live) 是 DNS 记录的有效缓存时间,适当的 TTL 设置决定了 DNS 流量负载信息新鲜度之间的平衡。CoreDNS 在两个层面处理 TTL:

  • 权威区域记录(SOA)TTL: Kubernetes 集群内部域(cluster.local 等)的 kubernetes 插件响应 TTL,默认值为 5 秒。可在 CoreDNS Corefilekubernetes 部分指定 ttl 选项进行更改,范围从最小 0 秒(不缓存)到最大 3600 秒。
  • 缓存 TTL: cache 插件中缓存条目的最大保留时间,默认为最大 3600 秒(成功响应),可在 CoreDNS 配置中以 cache [TTL] 形式调整。指定的 TTL 作为上限,若实际 DNS 记录的 TTL 更短,则按较短值从缓存中删除。(cache 插件的默认最小 TTL 为 5 秒,可通过 MINTTL 调整)。
⚙️ CoreDNS TTL 配置指南
DNS 流量负载与信息新鲜度之间的最佳平衡
Kubernetes 内部域kubernetes
配置:ttl 30
默认值:5s
推荐:30s
cluster.local 记录的响应 TTL。推荐 30s 以提高缓存命中率
DNS 响应缓存(全局)cache
配置:cache 30
默认值:3600s (max)
推荐:30s
CoreDNS 内部缓存上限。EKS 默认 30s。可分别配置 success/denial
Negative Cache (NXDOMAIN)cache
配置:denial 2000 10
默认值:3600s (max)
推荐:5-10s
NXDOMAIN 响应缓存。过长会延迟新服务发现
预取cache
配置:prefetch 5 60s
默认值:未启用
推荐:5 60s
同一查询超过 5 次时,在 TTL 到期前预取刷新。保持缓存新鲜度
💡 TTL 调优原则: 短 TTL(5s 以下)变更反映快但 CoreDNS 负载增加。长 TTL(数分钟以上)降低负载但可能因过期信息导致连接失败。大多数 EKS 环境中 30 秒是最佳基准。

Amazon EKS 默认 CoreDNS 配置

查看 EKS 部署的默认 CoreDNS Corefile,kubernetes 插件未指定单独的 TTL,使用默认 5 秒,而通过 cache 30 设置将所有 DNS 响应最多缓存 30 秒。即内部服务记录的响应包 TTL 为 5 秒,但 CoreDNS 通过 cache 插件最多缓存 30 秒,避免对相同查询频繁调用 Kubernetes API。外部域名查询也最多缓存 30 秒,确保不会保留过期的 DNS 信息

TTL 设置指南

通常短 TTL(如 5 秒以下) 的优点是 DNS 记录变更(如新服务 IP 或 Pod IP 变化)能快速反映,但会导致客户端或 DNS 缓存的重复查询增多,增加 CoreDNS 负载。相反,长 TTL(如数分钟以上) 减少 DNS 查询频率提高性能,但变更传播延迟,增加因过期信息导致的临时连接失败可能性。推荐方法是根据集群规模和工作负载模式,将 TTL 适当提高(数十秒级)提高缓存命中率同时避免严重的信息延迟。大多数 Kubernetes 环境中 TTL 30 秒左右是一个基准。

Amazon EKS 应用示例

要在 EKS 中调整 TTL,需修改 CoreDNS ConfigMap。例如要增加内部域缓存时间,可在 Corefile 的 kubernetes cluster.local ... 块中添加 ttl 30。这样集群内部 DNS 响应的 TTL 字段增加到 30 秒,客户端(如 NodeLocal DNSCache 或应用运行时)参考此值缓存 30 秒内不再重新查询。但在 Kubernetes 环境中,Linux glibc resolver 不自行缓存而是每次都查询 CoreDNS,因此没有 NodeLocal DNSCache 等辅助缓存的话,增加 TTL 对客户端的优势有限。主要是为了减轻 CoreDNS 本身的负载而调整 TTL。

Aurora DNS 负载均衡问题

AWS Aurora 等服务使用极低的 TTL(1 秒) 进行 DNS 负载均衡。此时 CoreDNS 由于默认最小 TTL 5 秒,会将原本 1 秒的 TTL 过度缓存为 5 秒,导致 Aurora Reader 端点流量分配失衡。这种情况下需要引入针对特定域名降低 TTL 的配置

实际案例中,通过在 NodeLocal DNSCache CoreDNS 配置中对 amazonaws.com 区域应用 cache 1success/denial 1 TTL 细分设置,使 Aurora 端点遵循原始 1 秒 TTL,从而解决了问题。因此外部服务的 TTL 策略也需要纳入 CoreDNS TTL 和缓存策略的调优考虑。

3. CoreDNS 监控架构最佳实践

CoreDNS 监控架构理想情况下应构建为包含指标收集(Prometheus 等)日志收集(如 Fluent Bit 等) 以及可视化和告警体系的综合可观测性管道。在 Amazon EKS 环境中,可以结合托管服务开源工具实现稳定且可扩展的监控系统。

🏗️ CoreDNS 监控架构
AMP + ADOT vs CloudWatch Container Insights 对比
AMP + ADOTManaged OSS
ADOT Collector / Prometheus 抓取 CoreDNS 指标 → AMP remote write → Grafana(AMG) 可视化
优点
+ PromQL 原生查询
+ 长期存储 & 大规模集群支持
+ Terraform 自动化加速器
注意事项
- 需要安装 ADOT/Prometheus
- 基于摄入指标的费用
CloudWatch Container InsightsAWS Native
CloudWatch Agent DaemonSet → kube-dns:9153 抓取 → CloudWatch Metrics 存储 → CloudWatch 仪表盘/告警
优点
+ AWS 托管 - 无需额外基础设施
+ CloudWatch Alarm 原生集成
+ 可在 AMG 中作为数据源
注意事项
- CloudWatch 指标采集/存储费用
- 使用 CloudWatch 查询语法而非 PromQL
管道层次
采集 (Collection)ADOT Collector · Prometheus · CloudWatch Agent · Fluent Bit
存储 (Storage)AMP (Prometheus) · CloudWatch Metrics · CloudWatch Logs
可视化 (Visualization)AMG (Grafana) · CloudWatch Dashboards
告警 (Alerting)Alertmanager · CloudWatch Alarms · SNS / PagerDuty / Slack
💡 推荐: 使用 Prometheus Operator (kube-prometheus-stack) 时,可通过 ServiceMonitor 自动抓取 kube-system/kube-dns (k8s-app=kube-dns) 服务的 9153 端口。

指标收集与存储

在 Amazon EKS 中收集 CoreDNS 的 Prometheus 指标通常有两种方法

  1. Amazon Managed Service for Prometheus (AMP): AWS 提供的完全托管 Prometheus 兼容服务,通过远程写入(remote write)从集群收集指标并存储在高扩展性时序数据库中。在 EKS 集群中安装 ADOT(AWS Distro for OpenTelemetry)CollectorPrometheus 服务器,抓取 CoreDNS 指标后发送到 AMP。AMP 中存储的指标可通过 PromQL 查询,适合长期保留和大规模集群支持。

  2. CloudWatch Container Insights(及 CloudWatch Agent): 利用 AWS CloudWatch 将 Prometheus 指标收集到 CloudWatch。将 CloudWatch Agent 部署为 DaemonSet,配置从 kube-system/kube-dns 服务的 9153 端口抓取 CoreDNS 指标。

ServiceMonitor 配置

Amazon EKS 的 kube-dns 服务提供 metrics 端口,使用 Prometheus Operator 时可创建 ServiceMonitor,针对 kube-system 命名空间中 k8s-app=kube-dns 标签的服务抓取 9153 端口。

日志收集

CoreDNS 的查询日志和错误日志在诊断性能问题或安全监控(如特定域名的爆发查询)方面非常有用。CoreDNS 默认 Corefile 中没有 log 插件,但可根据需要启用 logerrors 插件。实践中,为收集 CoreDNS Pod 标准输出(stdout/stderr)的日志,通常以 DaemonSet 方式运行 Fluent BitFluentd 将日志导出到 CloudWatch Logs。

日志收集注意事项

为避免过度日志收集导致的负载,仅保留必要级别的日志非常重要。EKS 最佳实践建议配置 Fluent Bit 等 Agent 的元数据缓存Kube_Meta_Cache_TTL=60 等),避免重复查询 Kubernetes API,并减少不必要的字段收集。

可视化与仪表盘

收集的 CoreDNS 指标通常通过 Grafana 进行监控仪表盘可视化。Amazon Managed Grafana (AMG) 与 AMP 和 CloudWatch 原生集成可作为数据源,并通过 IAM 联合 SSO 控制访问。在 Grafana 中构建 CoreDNS 仪表盘时,配置请求率(QPS)、响应延迟(histogram)、错误率(rcode 分布)、缓存命中率等面板。

告警/Alerting

应使用 Prometheus Alertmanager 或 CloudWatch Alarms 设置 DNS 异常征兆的告警。典型的 CoreDNS 相关 Alertmanager 规则示例如下:

  • CoreDNSDown: 一定时间内(for: 15m 等)CoreDNS 指标(up{job="kube-dns"} 等)未报告时告警。
  • HighDNSLatency: coredns_dns_request_duration_secondsP99 延迟超过例如 100ms 且高于正常水平时告警。
  • DNSErrorsSpike: coredns_dns_responses_totalrcode 标签为 SERVFAILNXDOMAIN 的比例超过一定阈值时告警。
  • ENIThrottling: AWS 环境特有指标,监控 EC2 网络接口(ENI)DNS 包限制超标的告警。
  • HighCoreDNSCPU/Memory: CoreDNS Pod 的 CPU/内存使用率监控告警。

4. Amazon EKS 最佳实践与客户案例(DNS 瓶颈应对等)

AWS 通过文档和博客提供针对云环境的 EKS DNS 运维最佳实践。以下是主要推荐方案和客户案例中常见的场景:

🛡️ EKS 最佳实践 & 实战案例
AWS 推荐的 CoreDNS 优化策略和故障应对案例
📈
Cluster Proportional AutoscalerDNS QPS 线性扩展
EKS 默认 CoreDNS 副本数为 2。根据节点数/CPU 核心数自动扩展,分散 DNS 负载。
🗄️
NodeLocal DNSCacheRTT 降低,ENI 瓶颈消除
在所有节点上运行 DNS 缓存代理(DaemonSet),提供本地 DNS。消除网络延迟和 ENI 限制。
🔒
DNS 包限制 & 流量分散避免 ENI PPS 瓶颈
VPC ENI 限制每秒 1024 个 DNS 包。将 CoreDNS Pod 分散到不同节点(Pod Anti-Affinity)以分散 ENI 限制。
🔄
优雅终止 (Lameduck)Zero-downtime DNS 滚动更新
防止 CoreDNS 重启/缩容时的临时 DNS 故障。配置 lameduck 30s + /ready Readiness Probe。
实战故障应对案例
案例 1:ENI PPS 限制导致的 DNS 延迟
症状:特定服务 DNS 响应延迟 → 整体响应时间增加 1 秒以上
原因:CoreDNS 查询的 VPC DNS Resolver 达到 ENI PPS 限制(1024 PPS)导致丢包
解决:引入 NodeLocal DNSCache + CoreDNS Pod 节点分散(Anti-Affinity)
案例 2:Aurora DNS TTL 缓存导致的读取器偏斜
症状:Aurora 读取器节点会话偏斜 → 部分读取器过载
原因:Aurora Reader 端点 DNS TTL 为 1 秒,但 CoreDNS 最小 TTL 5 秒导致过度缓存
解决:在 NodeLocal DNSCache 中为 amazonaws.com 配置 cache 1、success/denial 1
⚠️ ENI DNS 包限制: 每个节点 ENI 每秒仅允许 1024 个 DNS 包。即使提高 CoreDNS 的 max_concurrent,ENI PPS 限制(1024 PPS)也可能制约性能。

CoreDNS 水平扩展(副本数调整)

EKS 集群创建时默认 CoreDNS Deployment 副本数固定为 2,但随着节点数和工作负载增加可能需要水平扩展。AWS 最佳实践是使用 Cluster Proportional Autoscaler 根据节点数或 CPU 核心数按比例自动增加 CoreDNS 副本数。

引入 NodeLocal DNSCache

大规模集群DNS 流量非常频繁的工作负载中,CoreDNS 集中处理方式可能因网络延迟和 ENI 限制成为瓶颈。Kubernetes 官方插件 NodeLocal DNSCache 通过在所有节点上以 DaemonSet 运行 DNS 缓存代理(基于 CoreDNS),在各节点提供本地 DNS

DNS 包限制与流量分散

AWS 环境中常见瓶颈是 VPC DNS 包限额(1024 PPS/ENI)。实践中,若大量外部 DNS 查询的应用存在时,CoreDNS 的 2 个 Pod 都在同一节点上,该节点的单个 ENI 承载所有外部 DNS 查询,存在超出限额的风险。

优雅终止设置(Lameduck & Ready 插件)

防止 CoreDNS Pod 重启或缩容时发生的临时 DNS 故障的设置。AWS 最佳实践是对 CoreDNS 应用 lameduck 30s 设置,并将 Readiness Probe 配置为 /ready 端点。

需要更高 QPS 时

  1. 提高 max_concurrent: 可调至 2000 以上,但需同时考虑内存使用(2 KB × 并发查询数)和上游 DNS 延迟。

  2. CoreDNS 水平扩展: 增加 Replica 数,或通过 Cluster Proportional Autoscaler、HPA 或 NodeLocal DNSCache 将查询分散到节点级别。

  3. ENI 限制监控: 对 aws_ec2_eni_allowance_exceeded(CloudWatch)或 linklocal_allowance_exceeded 指标设置告警,提前检测 ENI PPS 超标。

核心总结

🎯 性能基准 & 调优指南
CoreDNS 核心性能目标和调优参数
指标
目标
临界
说明
查询延迟 (P99)
< 50ms
> 100ms
99% 的 DNS 查询在 50ms 内完成
吞吐量 (QPS/Pod)
> 10K
< 5K
每个 Pod 每秒处理超过 10,000 次查询
缓存命中率
> 80%
< 50%
TTL 30s 基准,80% 以上缓存利用
错误率 (SERVFAIL)
< 0.1%
> 1%
SERVFAIL 响应比例保持在 0.1% 以下
CPU 使用率
< 60%
> 80%
CPU 达到限制时,节流会导致 DNS 延迟
内存使用率
< 120Mi
> 150Mi
EKS 默认限制 170Mi。超过 150Mi 时设置告警
调优参数
max_concurrent
1000
2000+
并发查询限制。考虑内存 2KB × 并发查询数
Replica Count
2
按节点比例自动
应用 Cluster Proportional Autoscaler
lameduck
5s
30s
滚动更新时防止 DNS 故障
💡 基准测试工具: dnsperf -s <COREDNS_IP> -d queries.txt -c 10 -T 10 测量 CoreDNS QPS 和延迟。
  • 监控指标: requests_totalrequest_duration_secondscache_hits/missesresponses_total{rcode}、CPU/内存
  • TTL 推荐值: 服务记录 30s,cache(success 30,denial 5-10),prefetch 5 60s
  • 监控: kube-prometheus-stack 默认仪表盘 + Alertmanager 规则,必要时通过 NodeLocal DNSCache 横向扩展

附录:配置示例

Corefile 推荐配置

.:53 {
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30 # Service/POD 记录 TTL
}

cache 30 { # 最大保留 30 秒
success 10000 30 # capacity 10k, maxTTL 30s
denial 2000 10 # negative cache 2k, maxTTL 10s
prefetch 5 60s # 同一查询 5 次以上时提前刷新
}

forward . /etc/resolv.conf {
max_concurrent 2000
prefer_udp
}

prometheus :9153
health {
lameduck 30s
}
ready
reload
log
}

Alertmanager 规则示例

- alert: CoreDNSHighErrorRate
expr: >
(sum(rate(coredns_dns_responses_total{rcode!~"NOERROR"}[5m])) /
sum(rate(coredns_dns_requests_total[5m]))) > 0.01
for: 10m
labels:
severity: critical
annotations:
description: "CoreDNS error rate > 1% for 10 min"

- alert: CoreDNSP99Latency
expr: >
histogram_quantile(0.99,
sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (le)) > 0.05
for: 5m
labels:
severity: warning

调试命令

# 检查 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=100

# 测试 DNS 解析
kubectl run -it --rm debug --image=nicolaka/netshoot --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local

# 检查 CoreDNS 指标
kubectl port-forward -n kube-system deployment/coredns 9153:9153
curl http://localhost:9153/metrics

大规模集群(>100 节点或 QPS > 5k)

  1. NodeLocal DNSCache(DaemonSet 形式)在节点本地缓存,缩短 RTT
    • nodelocaldns 指标也收集到 Prometheus,与 CoreDNS 进行比较
  2. CloudWatch Container Insights(EKS 专用)
    • Prometheus 收集困难的环境可通过 cwagent + adot-internal-metrics 选项将 CoreDNS 容器指标发送到 CloudWatch(另收费用)