1. 关于 DNS
1.1 DNS 服务的用途
DNS 提供的是域名到 IP 的映射服务。例如,在浏览器输入 https://www.chenshaowen.com 访问页面,但数据链路是基于 IP 的通信,无法识别 www.chenshaowen.com 。这时就需要进行 DNS 查询,输入参数是 www.chenshaowen.com ,返回结果是 IP 地址。可以看到 DNS 提供了一种助记方法,我们不必关注 IP 地址以及其变动,而只需记住一段英文字符串,就能够找到服务。一种常见的服务发现机制是配置管理中心,存储 Key/Value 值,例如 Consul、ZooKeeper、Etcd 等。而 DNS 提供的功能,也可以满足微服务架构中服务发现的需求,Kubernetes 就是采用的这种方式。Kubernetes 从 1.11 版本开始,使用 CoreDNS 替代 KubeDNS 成为了内置的 DNS 服务。
1.2 resolv.conf
/etc/resolv.conf
是 DNS 客户端的配置文件,主要有四部分组成:
- nameserver ,DNS 服务器的 IP 地址
- domain ,本地域名的后缀
- search ,搜索的域名后缀
- sortlist ,对查询结果进行特定排序
当遇到无法解析的域名时,解析器才会用到 domain 、search 。例如,访问 http://abc/index.html, 解析器无法解析 abc ,就会拼接 domain 或 search 的配置作为后缀继续解析。当配置了 search 时,domain 失效。
2. CoreDNS
2.1 简介
CoreDNS 是 CNCF 正式毕业的项目。它是一个基于 Caddy 实现,模块化且可插拔的 DNS 服务器。每个插件都遵循一个特定的接口协议。在 Corefile 文件中采用 DSL 定义 DNS 服务,可以很方便地开启各种插件,定制 DNS 服务。下面是一个示例:
|
|
这个配置暴露了一个 DNS Server ,监听在 8000 端口,根据不同的域名匹配不同的处理逻辑。每个逻辑,加载指定的插件处理。
2.2 相关插件
常用的插件包括:
- hosts,配置集群全局可解析的 hosts ,需要注意的是域名后缀需要与 search 保持一致,例如,cluster.local ,否则 nodelocaldns 无法上报 coredns 解析
- errors, 错误记录到 stdout
- health,提供健康报告接口
- kubernetes,解析为 Kubernetes 集群服务的 IP 地址
- prometheus,提供 Prometheus 的 Metrics 接口
- proxy,不在集群域内的查询转到指定解析器
- cache,启用缓存
- loop,检测死循环,并中断
- reload,自动加载 Corefile,热更新
- loadbalance,DNS 负载均衡器
2.3 集群 ConfigMap 配置
- 查看 CoreDNS 的服务:
|
|
- 查看 CoreDNS 的配置
|
|
DNS 的默认端口是 53 。cluster.local 、 in-addr.arpa 、 ip6.arpa 格式的域名将被解析为 Kubernetes 的内部 IP 地址。
3. NodelocalDNS
3.1 简介
为了避免 Pod 进行 DNS 解析时,频繁查询 CoreDNS ,NodelocalDNS 在每个节点上都以 DaemonSet 运行 DNS 缓存以提高集群性能。NodelocalDNS 的原理是,运行一个 hostNetwork 网络模式的 Pod,创建一个网卡绑定本地 DNS 的 IP 地址。节点上的 Pod 请求 DNS 解析时,将被拦截到 NodelocaDNS 。NodelocalDNS 通过取缓存或向上游请求 DNS ,完成解析过程。
3.2 集群 ConfigMap 配置
- 查看 NodelocalDNS 服务
|
|
- 查看 NodelocalDNS 配置
|
|
同样使用 53 端口提供 DNS 服务,但是根据不同的域名,NodelocalDNS 提供了不同的解析策略。 cluster.local、in-addr.arpa、ip6.arpa 格式的域名从 CoreDNS 解析后缓存到本地,其他则使用节点的 DNS 解析后缓存。
4. Kubernetes Pod 中的 DNS 解析
- 创建测试用的 Pod
|
|
|
|
- 查看 DNS 解析配置
|
|
- 解析正常的内部服务
|
|
解析链路:nodelocaldns -> 缓存 -> coredns -> 返回 IP其中涉及 search 添加域名后缀的逻辑,在此不再表述。
- 解析不存在的服务
|
|
解析链路:nodelocaldns -> 节点配置的 DNS -> 未找到
- 解析正常的外部服务
|
|
解析逻辑:nodelocaldns -> 节点配置的 DNS -> 返回 IP
5. ExternalName - CNAME 解析
ExternalName Service 是 Service 的一个特例,没有选择器,可以用于给外部服务取一个内部别名。
- 创建 ExternalName Service
|
|
|
|
- 测试访问内部服务
|
|
chenshaowen.default 将会被映射到 www.chenshaowen.com ,这是通过 DNS 的 CNAME 记录实现的。
6. 参考
- https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/
- https://github.com/coredns
- https://draveness.me/dns-coredns/