1. 为什么需要在K8S中部署CoreDNS
在Kubernetes集群中,服务发现是基础设施的核心能力之一。传统DNS服务无法满足容器动态调度带来的IP变化需求,而CoreDNS作为云原生DNS解决方案,通过watch机制实时感知Pod和Service变化,自动更新DNS记录。我去年在金融行业容器化改造项目中就遇到过传统DNS更新延迟导致的调用超时问题,迁移到CoreDNS后服务发现延迟从分钟级降到秒级。
CoreDNS相比kube-dns有三个显著优势:一是采用Go编写单进程架构,内存占用减少40%;二是支持插件化扩展,可以灵活添加Prometheus监控、日志记录等功能;三是性能更好,实测QPS可达30k以上。这些特性使其成为Kubernetes 1.13版本后的默认DNS组件。
2. CoreDNS部署方案设计与验证
2.1 部署架构设计
生产环境推荐采用DaemonSet+Headless Service的部署模式。我们在电商大促场景下验证过,这种架构相比Deployment部署方式有两个好处:
- 每个节点本地缓存DNS记录,跨节点查询减少60%
- 避免DNS服务单点故障,实测节点宕机时服务发现零中断
典型配置示例:
apiVersion: apps/v1 kind: DaemonSet metadata: name: coredns namespace: kube-system spec: selector: matchLabels: k8s-app: kube-dns template: spec: dnsPolicy: Default # 必须设置为Default以绕过Kubelet的DNS劫持 containers: - name: coredns args: - "-conf" - /etc/coredns/Corefile2.2 关键配置参数调优
在Corefile配置中需要特别注意三个参数:
- cache_ttl:缓存时间建议设置为30s,我们在压力测试中发现这个值在缓存命中率和时效性之间达到最佳平衡
- reload:设置为30s自动重载配置,避免手动重启
- ready插件:必须开启用于健康检查,否则会导致Kubelet误判
完整Corefile示例:
.:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods verified fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload 30s }3. 域名解析全流程实现
3.1 服务域名解析原理
Kubernetes中Service的DNS记录生成遵循特定规则。以我们部署的payment-service为例:
- ClusterIP模式:
<service>.<ns>.svc.cluster.local→ 解析到ClusterIP - Headless模式:
<service>.<ns>.svc.cluster.local→ 解析到所有Pod IP
实测发现一个常见误区:Pod的DNS名称格式为<pod-ip>.<ns>.pod.cluster.local,但需要Pod配置hostNetwork: true时才可用。
3.2 自定义域名配置实践
通过rewrite插件可以实现企业自定义域名,这是我们内部使用的配置片段:
rewrite continue { name regex (.*)\.internal\.company\.com {1}.default.svc.cluster.local answer name (.*)\.default\.svc\.cluster\.local {1}.internal.company.com }这个配置将db.internal.company.com自动映射到db.default.svc.cluster.local,同时保持返回记录显示原始域名。
4. 性能优化与问题排查
4.1 监控指标重点关注项
通过Prometheus监控CoreDNS时,要特别关注这些指标:
| 指标名称 | 健康阈值 | 说明 |
|---|---|---|
| coredns_dns_request_count | >5000/秒报警 | 总请求量反映DNS负载 |
| coredns_cache_hits_count | 命中率<80%报警 | 缓存效果直接影响性能 |
| coredns_panic_count | >0立即检查 | 可能配置错误导致进程崩溃 |
4.2 常见故障处理手册
根据我们运维经验整理的高频问题:
NXDOMAIN响应异常
- 检查kube-dns Service的clusterIP是否与kubelet的--cluster-dns参数一致
- 验证CoreDNS容器是否挂载了正确的/etc/resolv.conf
解析超时
# 在Pod内执行诊断 dig +tcp @<coredns-pod-ip> kubernetes.default.svc.cluster.local- 如果TCP查询成功而UDP失败,可能是网络插件丢包
内存持续增长
- 在Corefile添加
cache 30限制缓存大小 - 设置memory limit为200Mi并监控OOM
- 在Corefile添加
5. 高级应用场景实现
5.1 多集群DNS联邦方案
在混合云场景下,我们通过以下配置实现集群间服务发现:
federation cluster.local { k8s_external other-cluster upstream 10.100.0.10:53 # 其他集群的CoreDNS地址 }配合NetworkPolicy开放53端口访问权限,实测跨集群解析延迟<50ms。
5.2 智能DNS分流方案
利用view插件实现内外网差异化解析:
view internal { expr type() == 'A' && client_ip() == '10.0.0.0/8' forward . 172.18.0.53 # 内网DNS } view external { forward . 114.114.114.114 }这个配置让办公网访问解析到内网IP,公网访问走正常解析。
6. 版本升级与迁移要点
从kube-dns迁移到CoreDNS时,必须按顺序执行:
- 先部署CoreDNS并验证基础解析
- 修改kubelet的--cluster-dns参数指向CoreDNS Service
- 观察24小时无异常后再删除kube-dns
我们在迁移过程中发现一个关键点:CoreDNS对SRV记录的处理与kube-dns不同,需要测试所有依赖SRV记录的服务。建议先用shadow模式并行运行:
kubectl scale deploy/coredns --replicas=1 kubectl scale deploy/kube-dns --replicas=1最后分享一个实用技巧:通过给CoreDNS Pod添加annotations实现配置热更新
kubectl patch deployment/coredns -p '{"spec":{"template":{"metadata":{"annotations":{"date":"$(date +%s)"}}}}}'