0x01 前言

我目前使用 Rancher 运行一些可容器化的服务,这里面就包含一些 HTTP 服务,这时候就有域名解析和 IP 指向的问题。

0x02 大致情况

我家里的服务器运行着 ESXI,并且由 vCenter 进行管理,所以我在 Rancher 做出相关配置,让它们实现联动:

在 Rancher 2 中,这叫主机池,可以根据负载情况实现 Worker 与 Master 的自动伸缩:

很明显,这些虚拟机需要通过网络进行通讯,而进行网络通讯就需要 IP 地址及其他相关信息,如 DNS、网关、NTP等。

因为主机池自动伸缩的行为是全自动的,也就是说虚拟机在调用 vCenter API 在 ESXI HOST 内创建于销毁虚拟机都是自动的,而其中的信息也无法预测。当虚拟机创建的时候会由 vCenter 生成随机的 MAC 地址,最终从 DHCP 服务器获取到一个随机的 IP 地址。这个 IP 地址可以在上图中虚拟机名称下找到,网段如下:

  • 10.1.3.0/24

在 Rancher 环境中的 ingresses 只支持7层负载均衡,而且7层的负载均衡需要在 ingresses 中绑定域名,并且这个域名的 IP 必须为 Worker 的IP,这样就可以通过域名与 TCP 80/443 端口进行通讯。如果不需要绑定域名,在使用 IP:Port(非 TCP 80/443) 的情况下可以直接将流量指向 Master。

还有一个需要注意的地方,如果一个集群内有多个 Worker,那么域名可以解析到任意一个 Worker 的 IP 上,无论目标容器运行在哪个 Node 上,流量都会被牵引至目标 Node,完成处理后再原路返回,大致如下:

0x03 问题与解决方案

目前我遇到一个非常突出的问题,就是 DNS IP 指向的问题。因为所有 Node 都是自动创建的,所以没法给予固定IP,也无法确保它永远都不会被销毁,怎么实现 DNS 记录自动更新就是我需要解决的问题。

对于这个问题,我有两个解决方案,其中一个是在集群内部署一个服务,运行着 Bind Pod,它只负责一项工作:返回所有 Node 的 IP 地址,外部也部署一个,将需要解析的域名通过 CNAME 指向集群内的 Bind 域名,大致如下:

这种服务架构的实现利用了 ingresses 的特性,只需要将 DNS TTL 设置小点即可,实现起来非常简单。

另一种实现方案是我目前使用的域名泛解析方案,但这种方案会出现上面所说的问题。因为泛解析需要将域名指向一个单一的 IP,如果这个 Worker 被销毁,那么这个 IP 也不复存在。这里就需要保证这个 Node 不会被销毁,可以将它设为禁止运行任何 Pod,从而保证它符合健康检查的要求。另外,还需要将 DNS TTL 尽可能降低,保证在紧急情况下切换 DNS 之后尽可能快地生效。

在我的环境中,我使用 Pfsense 作为路由器,DNS 服务器也是运行在它上面,我是用的是 DNS 解析器,也就是 unbound。在操作前需要查询相关文档:

使用起来非常简单,只需要在 DNS 解析器中的 Custom options 中增加以下内容即可:

server:
local-zone: "dev.t.com" redirect
local-data: "dev.t.com 10 IN A 10.1.3.106"

这样就会将 dev.t.com 这个三级域名下的所有子域名都指向 10.1.3.106 这个 IP 地址。紧接着在 Rancher ingresses 中配置自定义域名即可:

只要访问设定的域名,所有流量都会被牵引至 10.1.3.106 这个 Node。

注意!通过 Custom options 配置的 DNS 解析记录的优先级高于 Host Overrides 与 Domain Overrides,请选择合适的二级或三级域名进行解析,以避免影响现有的 DNS 解析记录。

0x04 结语

对于这个问题,还可以通过网关的形式进行解决,这个方案在 Rancher 1.x 中得以实践应用,但 Rancher 2.x 与 1.x 的区别非常明显,经过长时间的搜索,都没有发现相关问题比较好的解决方案。