问题背景

有时候 kubernetes 集群中的应用需要通过域名访问集群外部的一些服务,虽然 ip 是可以正常通信,但是因为没有可用解析域名的 DNS 服务器,从而导致了应用无法正常访问外部域名。

解决方案一

对于单个应用,可以给 Pod 的 hosts(/etc/hosts)添加条目。

编辑应用,点击右下角的 显示高级选项,在网络选项中设置 /etc/hosts

解决方案二

对于方案一,少数应用或者临时测试是没有问题。但是对于大量应用需要同时修改配置,工作量就挺大了。这个时候就需要一个中间的 DNS 代理服务,只需要修改一次代理服务即可。

kubernetes 集群中内置了 DNS 服务器软件。在 rancher 或者 rke 集群中,不同的版本内置的 DNS 服务器软件不同。下表列出了对应关系:

https://rancher.com/docs/rke/latest/en/config-options/add-ons/dns/

RKE 版本KUBERNETES 版本默认 DNS PROVIDER
v0.2.5 and higherv1.14.0 and higherCoreDNS
v0.2.5 and higherv1.13.x and lowerkube-dns
v0.2.4 and lowerallkube-dns

注意:不建议再使用kube-dns。可以升级 RKE 或者 Rancher 版本,然后升级 kubernetes 版本,DNS 服务器软件将会自动更新。

hosts 插件

Pod 的 /etc/resolv.conf 配置中默认的 DNS 为 CoreDNS(10.43.0.10)。应用访问外部域名的时候,会先把请求发送给 CoreDNS。

  1. 在 CoreDNS 中未配置 hosts 插件的情况下
    • 如果 CoreDNS Server 内部数据库中有对应的 DNS 记录,则返回域名对应的 IP 给应用,应用则可以正常连接,相反则无法连接。
  2. 在 CoreDNS 中配置 hosts 插件的情况下
    • 如果 CoreDNS Server 内部数据库中有对应的 DNS 记录,则返回域名对应的 IP 给应用。
    • 如果 CoreDNS 内部数据库中没有对应的DNS 记录,根据 hosts 的配置,如果匹配上对应的主机名,则把对应的 IP 返回给应用。

配置格式

hosts [FILE [ZONES...]] {
[INLINE]
ttl SECONDS
no_reverse
reload DURATION
fallthrough [ZONES...]
}
  • FILE:需要读取与解析的 hosts 文件;如果省略,默认取值 “/etc/hosts”;每 5s 扫描一次 hosts 文件的变更。

  • ZONES:如果为空,取配置块中的 zone。

  • INLINE:宿主机 hosts 文件在 corefile 中的内联;在 “fallthrough” 之前的所有 “INLINE” 都可视为 hosts 文件的附加内容,hosts 文件中相同条目将被覆盖,以 ”INLINE” 为准。

  • ttl:更改生成的 DNS 记录的 TTL(正向和反向),默认值为3600秒(1小时)。

  • no_reverse:禁用自动生成主机的in-addr.arpaip6.arpa条目。

  • reload:文件重新加载之间的时间间隔

  • fallthrough:如果 zone 匹配且无法生成记录,将请求传递给下一个插件;如果省略,对所有 zones 有效,如果列出特定 zone,则只有列出的 zone 受到影响。

配置方法

依次访问 system 项目|资源|配置映射,在 kube-system 命名空间中找到 coredns,点击右侧省略号菜单并选择编辑。

配置示例

.:53 {
errors
health {
lameduck 5s
}
ready
hosts {
# 1个hostname映射1个ip;
172.30.200.21 www.test1.local
172.30.200.22 www.test2.local
172.30.200.23 www.test3.local
fallthrough
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . "/etc/resolv.conf"
cache 30
loop
reload
loadbalance
}