写在最前

  • 你还记得吗,我们前面在dev环境中部署了dnsmasq对一些中间件使用了统一的域名解析例如app-mysql1.basic.tanqidi.com,那么kubernetes中如何动态识别它呢?并且解析绑定到某个deploymen的servcie或者headless中的pod上(我知道你肯定想说为什么不直接用它提供的集群内域名呢?目前我的做法是兼容允许两种并存使用)

  • 我相信你已经对 Kubernetes 做到了扎实掌握,因此我后续将会使用文字交流来代替截图,这将使我们的讨论更高效、专注于关键技术细节。

1. 前置条件

  1. 部署 kubesphere 单机 all-in-one 模式

2. 配置流程

2.1 coredns

自定义域名解析

将这份配置文件挂载到coredns的/etc/add-hosts目录即可

kind: ConfigMap
apiVersion: v1
metadata:
  name: coredns-custom-hosts
  namespace: kube-system
  annotations:
    kubesphere.io/creator: admin
data:
  custom-hosts: |-
    127.0.0.1 baidu.com
    127.0.0.1 jd.com

image-dpec.png

image-rftu.png

然后编辑coredns的configmap添加hosts插件片段,允许它自定义解析coredns-custom-hosts里面的域名

hosts /etc/add-hosts/custom-hosts . {
   fallthrough .
}

image-uagd.png

自定义域名重写

这里我就演示一个,因为redis我部署在k8s中的是一个deployment单节点不是集群,如果是集群那么就写多个rewrite后面就是headless集群内服务名了。

rewrite name app-redis1.basic.tanqidi.com redis.basic.svc.cluster.local

# rewrite name app-nacos1.basic.tanqidi.com nacos-1.basic.svc.cluster.local
# rewrite name app-nacos2.basic.tanqidi.com nacos-2.basic.svc.cluster.local
# rewrite name app-nacos3.basic.tanqidi.com nacos-3.basic.svc.cluster.local

image-qnsm.png

2.3 nodelocaldns

.:53 {
    errors
    cache 30
    reload
    loop
    bind 169.254.25.10
    #forward . /etc/resolv.conf
    forward . 10.233.0.3 {
        force_tcp
    }
    prometheus :9253
}

image-ycau.png

image-yozi.png

3. 深入解析

image-mieg.png

3.1 coredns

在 CoreDNS 的配置中,插件的执行顺序是按照配置文件中的顺序来的。因此,CoreDNS 会先处理上面的 hosts 插件,再处理 forward 插件。

执行顺序

  1. hosts /etc/add-hosts/custom-hosts . { fallthrough . }

    • CoreDNS 首先会根据 hosts 插件尝试匹配 /etc/add-hosts/custom-hosts 中的记录。

    • 如果在 custom-hosts 文件中找到了匹配的域名(比如 jd.com 被解析为 127.0.0.1),那么查询就会终止,并返回该结果,不会继续往下执行其他插件。

    • fallthrough .:当 hosts 插件没有找到匹配时,fallthrough 指示 CoreDNS 将查询交给下一个插件继续处理。

  2. forward . /etc/resolv.conf { prefer_udp max_concurrent 1000 }

    • 如果 hosts 插件没有匹配到请求的域名,查询会继续到 forward 插件。

    • 在这里,forward 插件会将未匹配的查询转发给 /etc/resolv.conf 中定义的上游 DNS 服务器。

关键点

  • 优先匹配 hosts 插件:因为 hosts 插件在 forward 插件之前,所以优先级更高。只要 hosts 插件成功匹配到域名(如 jd.com),CoreDNS 就会直接返回结果,不会继续执行 forward 插件。

  • 匹配不到时才走 forward:如果 hosts 文件中没有匹配到查询的域名,才会走 forward 插件,将查询转发到 /etc/resolv.conf 指定的上游 DNS 服务器。

3.2 nodelocaldns

  1. NodeLocalDNS 是每个 Kubernetes 节点上的本地 DNS 缓存 daemonset,它的作用是减少对 CoreDNS 的请求量,并加速集群内服务的 DNS 解析。

  2. 在没有命中集群内域名的时候 NodeLocalDNS 默认会去/etc/resolv.conf 中去对它进行解析,它没有来到CoreDNS自然也就无法实现自定义解析的目的了,因此我们对它进行了修改默认非集群内域名也来去CoreDNS解析,即使配置 NodeLocalDNS 通过 forward . 10.233.0.3 转发到 CoreDNS,NodeLocalDNS 的缓存机制仍然生效。

3. 试验结果

image-rufw.png

4. 写在最后

本篇章解释了一下coredns与nodelocaldns的原理和关系,并稍稍自定义修改了一下他们两个的configmap,以达到我们期望的自定义域名重写到集群内域名,以及自定义域名解析等有趣功能。