☰
Kubernetes DNS解析原理与CoreDNS实战配置
2026/10/27 16:20:32 网站建设 项目流程

1. Kubernetes DNS 名称解析的核心价值

在容器化部署环境中,服务发现是维持微服务架构正常运转的生命线。传统基于IP的直接访问方式在动态调度的Pod面前完全失效——当一个Pod由于节点故障被重新调度时,它的IP地址会发生改变。2014年Google开源的Kubernetes项目通过内置DNS服务完美解决了这个痛点。

CoreDNS作为Kubernetes默认的DNS服务器(自1.13版本起替代kube-dns),会持续监听API Server中Service和Pod的变化。当你在集群内创建名为web-svc的Service时,CoreDNS会自动生成web-svc.default.svc.cluster.local这样的完整域名记录。这种机制使得无论后端Pod如何漂移,前端应用只需通过固定域名即可访问服务,实现了服务访问与底层基础设施的解耦。

2. Kubernetes DNS 的架构实现细节

2.1 CoreDNS 的工作流程

CoreDNS在Kubernetes中以Deployment形式运行,通常包含两个副本Pod确保高可用。其核心配置文件Corefile通过ConfigMap挂载,默认配置包含以下关键段:

.:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance }

这段配置声明了CoreDNS如何处理不同域名的查询请求。其中kubernetes cluster.local插件是关键,它告诉CoreDNS需要监听Kubernetes中cluster.local域下的资源变更。当收到web-svc.default.svc.cluster.local这样的查询时,处理流程如下:

  1. 客户端向集群DNS(10.96.0.10)发起DNS查询
  2. CoreDNS检查查询域名是否匹配cluster.local后缀
  3. 若匹配则查询API Server获取对应Service的ClusterIP
  4. 返回包含ClusterIP的DNS响应给客户端

2.2 域名记录生成规则

Kubernetes自动生成以下几种类型的DNS记录:

  • Service记录:<service>.<ns>.svc.cluster.local解析到Service的ClusterIP
  • Pod记录:<pod-ip>.<ns>.pod.cluster.local将Pod IP转换为DNS可解析名称(需显式启用)
  • Headless Service记录:当Service没有ClusterIP时,直接解析到后端Pod IP列表

一个生产集群中典型的解析示例如下:

# 查询default命名空间下的nginx服务 nslookup nginx.default.svc.cluster.local Server: 10.96.0.10 Address: 10.96.0.10#53 Name: nginx.default.svc.cluster.local Address: 10.96.152.103 # 查询kube-system命名空间下的kube-dns服务 nslookup kube-dns.kube-system.svc.cluster.local Server: 10.96.0.10 Address: 10.96.0.10#53 Name: kube-dns.kube-system.svc.cluster.local Address: 10.96.0.10

3. 自定义DNS配置实战

3.1 修改集群DNS参数

Kubernetes允许通过修改kubelet参数调整Pod的DNS配置,关键参数包括:

  • --cluster-dns:DNS服务IP列表(逗号分隔)
  • --cluster-domain:集群域名后缀(默认为cluster.local)

这些参数需要在kubelet启动时指定,修改后需要重启kubelet服务生效。例如在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf中添加:

Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10,192.168.1.1 --cluster-domain=company.lan"

3.2 Pod级别的DNS策略

在Pod的YAML定义中,可以通过dnsPolicy字段指定不同的DNS策略:

apiVersion: v1 kind: Pod metadata: name: custom-dns-pod spec: containers: - name: nginx image: nginx dnsPolicy: "None" dnsConfig: nameservers: - 8.8.8.8 searches: - ns1.svc.company.lan - my.dns.search.suffix options: - name: ndots value: "2" - name: edns0

支持的政策类型包括:

  • Default:继承节点上的DNS配置
  • ClusterFirst:优先使用集群DNS(默认值)
  • ClusterFirstWithHostNet:主机网络模式下的特殊策略
  • None:完全自定义DNS配置

4. 常见问题排查指南

4.1 DNS查询超时问题

当Pod内出现nslookup: can't resolve 'kubernetes.default'错误时,建议按照以下步骤排查:

  1. 检查CoreDNS Pod状态:

    kubectl -n kube-system get pods -l k8s-app=kube-dns

    正常应显示两个Running状态的Pod。

  2. 验证Service端点:

    kubectl -n kube-system get ep kube-dns

    输出应包含CoreDNS Pod的IP和端口。

  3. 检查kubelet配置:

    ps aux | grep kubelet | grep cluster-dns

    确认--cluster-dns参数指向正确的DNS服务IP。

  4. 测试DNS连通性: 在问题Pod中执行:

    dig +short kubernetes.default.svc.cluster.local @10.96.0.10

    如果无响应,检查网络插件是否阻止了53端口的UDP通信。

4.2 ndots参数引发的性能问题

Kubernetes默认设置ndots:5,这意味着任何包含至少5个点的域名都会先尝试直接解析,失败后才走搜索域。例如查询api会依次尝试:

api.default.svc.cluster.local. api.svc.cluster.local. api.cluster.local. api.

对于需要频繁访问外部服务的Pod,建议调整此参数:

dnsConfig: options: - name: ndots value: "2"

5. 高级配置与优化实践

5.1 自定义Hosts文件注入

某些场景下需要为Pod注入特定的hosts记录,可以通过hostAliases字段实现:

apiVersion: v1 kind: Pod metadata: name: hostaliases-pod spec: hostAliases: - ip: "192.168.1.100" hostnames: - "foo.local" - "bar.local" containers: - name: cat-hosts image: busybox command: - cat args: - "/etc/hosts"

5.2 使用NodeLocal DNSCache

在大规模集群中,为每个节点部署本地DNS缓存可以显著降低CoreDNS负载。NodeLocal DNSCache以DaemonSet形式运行,监听节点上的169.254.20.10地址。部署步骤:

  1. 下载部署清单:

    wget https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml
  2. 修改配置中的变量:

    - name: __PILLAR__LOCAL__DNS__ value: "169.254.20.10" - name: __PILLAR__DNS__SERVER__ value: "10.96.0.10"
  3. 应用配置:

    kubectl apply -f nodelocaldns.yaml

5.3 外部域名分流策略

通过CoreDNS的forward插件可以实现内外网域名分流解析。例如将公司内部域名转发到私有DNS,其他查询走公共DNS:

corp.local:53 { errors cache 30 forward . 10.10.0.100 10.10.0.101 } .:53 { errors cache 30 forward . /etc/resolv.conf }

6. 监控与日志分析

6.1 CoreDNS监控指标

CoreDNS默认暴露Prometheus指标在9153端口,关键指标包括:

  • coredns_dns_request_count_total:DNS请求总数
  • coredns_dns_request_duration_seconds:请求处理耗时
  • coredns_panic_count_total:崩溃次数

建议设置以下告警规则:

- alert: CoreDNSHighLatency expr: histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket[1m])) by (le)) > 1 for: 5m labels: severity: warning annotations: summary: "CoreDNS high latency detected" description: "DNS 99th percentile latency is {{ $value }} seconds"

6.2 日志分析技巧

启用CoreDNS的log插件可以记录详细查询日志:

.:53 { log errors health kubernetes cluster.local { pods verified } }

典型日志分析场景:

# 统计查询量最多的域名 kubectl logs -n kube-system coredns-xxxx | grep -o 'query:.*' | sort | uniq -c | sort -nr # 查找NXDOMAIN响应 kubectl logs -n kube-system coredns-xxxx | grep -w NXDOMAIN # 跟踪特定客户端的查询 kubectl logs -n kube-system coredns-xxxx | grep 'client 10.244.1.23'

7. 安全加固建议

7.1 DNS劫持防护

为防止中间人攻击篡改DNS响应,建议:

  1. 启用CoreDNS的dnstap插件记录完整流量:

    dnstap tcp://127.0.0.1:6000 full
  2. 配置网络策略限制DNS查询源:

    apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns-access namespace: kube-system spec: podSelector: matchLabels: k8s-app: kube-dns policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: project: my-app ports: - protocol: UDP port: 53

7.2 资源限制配置

为CoreDNS设置合理的资源限制防止资源耗尽:

resources: limits: memory: 512Mi cpu: 1000m requests: memory: 128Mi cpu: 100m

同时建议启用HPA自动扩缩容:

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: coredns-hpa namespace: kube-system spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: coredns minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询