问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Kubernetes DNS解析机制揭秘

创作时间:
作者:
@小白创作中心

Kubernetes DNS解析机制揭秘

引用
10
来源
1.
https://blog.haohtml.com/posts/dns-resolv-in-kubernetes-networking/
2.
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/configure-coredns
3.
https://www.cnblogs.com/styshoo/p/6687318.html
4.
https://qingwave.github.io/k8s-dns-optimize/
5.
https://hansedong.github.io/2018/11/20/9/
6.
https://cloud.tencent.com/developer/article/1796826
7.
https://developer.aliyun.com/article/1111137
8.
https://www.cnblogs.com/dahuige/p/15011201.html
9.
https://www.cnblogs.com/zhangmingcheng/p/14986821.html
10.
https://imroc.cc/kubernetes/best-practices/dns/optimize-coredns-performance

在现代云原生架构中,Kubernetes已成为容器编排的标准工具。其内置的DNS解析服务使得各个服务能够通过域名相互通信,而无需直接使用IP地址。本文将深入探讨Kubernetes集群内部的DNS解析机制,帮助读者更好地理解和运用这一关键功能。

01

DNS解析原理

在Kubernetes集群中,DNS解析的核心组件是CoreDNS。当集群安装时,会在kube-system命名空间中自动创建两个CoreDNS Pod:

$ kubectl get pods --selector=k8s-app=kube-dns -n kube-system
NAME                       READY   STATUS    RESTARTS      AGE
coredns-76f75df574-7pbp8   1/1     Running   1 (31m ago)   3d18h
coredns-76f75df574-cp4zg   1/1     Running   1 (31m ago)   3d18h

同时,集群会通过一个名为kube-dns的服务为集群内域名解析提供DNS解析服务:

$ kubectl get svc  -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   3d20h

每个Pod在启动时,都会通过kubelet配置使用kube-dns服务的IP地址作为DNS服务器。我们可以通过查看Pod内的/etc/resolv.conf文件来确认DNS配置:

$ kubectl exec pod/nginx-69b68b44b9-xc9rk -- cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

这里包含了三类配置:

  1. search:DNS搜索域的顺序
  2. nameserver:DNS服务器地址
  3. options:DNS解析选项

当Pod需要解析一个域名时,会按照search配置的顺序依次尝试附加不同的域,直到找到匹配的FQDN(全限定域名)。如果解析失败,才会回退到公网DNS服务器。

02

DNS记录类型

Kubernetes支持多种类型的DNS记录,主要包括:

  1. Service DNS记录

    • 普通Service:格式为my-svc.my-namespace.svc.cluster.local,解析结果为服务的集群IP。
    • Headless Service:同样使用my-svc.my-namespace.svc.cluster.local格式,但解析结果为后端Pod的IP列表。
  2. SRV记录

    • 用于命名端口服务,格式为_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local
    • 对于普通服务,解析结果包含端口号和CNAME;对于Headless服务,会解析出多个结果,每个Pod一个。
  3. Pod DNS记录

    • 格式为pod-ip-address.my-namespace.pod.cluster.local,例如1-2-3-4.default.pod.cluster.local
    • Pod的hostname可以通过metadata.namepod.beta.kubernetes.io/hostname注解来指定。
03

CoreDNS配置详解

CoreDNS的配置通过Corefile实现,支持多种插件配置:

  1. 日志记录

    .:53 {
        errors
        log
        health {
           lameduck 15s
        }
        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 {
              prefer_udp
        }
        cache 30
        loop
        reload
        loadbalance
    }
    
  2. 自定义DNS服务器

    • 特定域名使用自建DNS服务器:
      example.com:53 {
        errors
        cache 30
        forward . 10.10.0.10 {
        prefer_udp
        }
      }
      
    • 所有外部域名使用自建DNS服务器:
      .:53 {
          errors
          health {
             lameduck 15s
          }
          ready
          kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
            ttl 30
          }
          prometheus :9153
          forward . 10.10.0.10 10.10.0.20 {
            prefer_udp
          }
          cache 30
          loop
          reload
          loadbalance
      }
      
  3. 自定义Hosts

    .:53 {
        errors
        health {
           lameduck 15s
        }
        ready
        
        hosts {
          127.0.0.1 www.example.com
          fallthrough
        }
      
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
          ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
          prefer_udp
        }
        cache 30
        loop
        reload
        loadbalance
    }
    
04

性能优化建议

在高并发场景下,Kubernetes内置的DNS插件可能会遇到性能瓶颈。以下是一些优化建议:

  1. 调整dnsPolicy

    • 默认为ClusterFirst,会导致额外的DNS查询次数。
    • 如果不访问集群内部服务,可以调整为Default,直接使用宿主机的DNS。
  2. 优化ndots参数

    • 默认值为5,会导致多次不必要的DNS查询。
    • 调整为1可以减少查询次数,但需要注意service域名的分割问题。
  3. 使用NodeLocalDNS缓存

    • 通过在每个节点上运行DNS缓存代理来提高性能。
    • 避免iptables DNAT规则和连接跟踪的开销。
  4. 合理配置CoreDNS副本数

    • 建议按照coredns:node=1:8的比例配置副本数。
    • 启用AutoPath插件减少查询次数。

通过以上优化措施,可以显著提升Kubernetes集群内DNS解析的性能和稳定性。

05

常见问题与解决方案

  1. 跨命名空间访问

    • 使用service-name.namespace-name.svc.cluster.local格式的FQDN进行访问。
    • 确保search配置中包含正确的搜索域。
  2. 外部DNS解析

    • 调整dnsPolicy为Default或None。
    • 优化ndots参数减少外部DNS查询次数。
  3. DNS解析延迟

    • 检查CoreDNS的配置和性能。
    • 考虑启用NodeLocalDNS缓存。

通过深入理解Kubernetes的DNS解析机制,我们可以更好地设计和优化容器化应用的网络架构,提升系统的整体性能和可靠性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号