Pampas 的虚拟域名实现原理

为什么要用虚拟域名?

各位小伙伴在开发过程中, 经常会使用域名的方式访问本地服务. 公司中最常见的就是后端 spring-boot-starter-session 需要设置 cookieDomain. 这样做有什么好处呢?

  • cookie 在各自域名下, 不存在干扰的情况
  • 可以通过域名区分服务, 而不需要记忆端口号

如何使用虚拟域名?

常见设置本地域名, 来访问本地服务的场景, 基本步骤如下:

配置 /etc/hosts -> 设置 Proxy (通常是 Nginx) -> 通过虚拟域名访问服务

相对来讲, 步骤其实不是很长, 不过过程中确实比较麻烦. 比如:

  • 修改 /etc/hosts 需要 root 权限
  • 设置 proxy 需要考虑其他配置的影响

针对于以上问题, 社区中有很多开源的解决方案, 这里列举两个典型:

pow 默认支持的是 rack 应用, 而 hotel 支持则更为广泛.

Pampas 的虚拟域名

Pampas 自身内置了虚拟域名的服务, 默认约定为 endpoints 下的所有终端服务, 以 -front 结尾的则会认为是前端模块, 会自动截取作为顶级域名访问.

endpoints/admin-front 启动后可以直接访问 http://admin.pampas.

如此便不再需要开发人员配置, 而且可以快速便捷的访问对应服务.

虚拟域名的原理

重点来啦, 类似于 powhotel 这种服务是基于什么原理实现的呢?

首先, 基本流程依然是:

域名解析至本地 -> 通过 Proxy 代理至对应服务

那么我们分而治之, 域名解析至本地是如何完成的?

域名解析至本地

域名解析现阶段已知的实现方式基本如下:

  • 修改 /etc/hosts
  • 本地 DNS 服务
  • PAC 脚本

/etc/hosts

修改 hosts 则不再介绍, 此种方式需要持续拥有 root 权限, 这个在很多场景是不太现实的, 而且有一个严重的问题, hosts 是主机绑定, 是不支持泛域名解析的.

DNS 服务

即本地起一个 DNS 服务, 并且指定网络使用本地 DNS 解析地址, 将固定的虚拟域名解析至本地即可. 在初次安装时, 需要 root 权限修改网络, 应用 DNS 配置. 一次配置后, 基本可以灵活使用, 且不影响其他服务.

PAC 脚本

经常翻墙的同学基本都会接触 PAC (Proxy auto-config) 脚本. 顾名思义, 就是配置代理用的, 此种方式不需要 root, 但是需要配置浏览器, 否则还是需要 root 权限改变网络, 而且可能对已经使用 PAC 的同学造成影响.

开源工具的选择

上面介绍的两个开源工具, 在域名解析的实现方式其实不太一样, 其中 pow 采用的是本地 DNS 服务的实现方式, 而 hotel 默认则使用 PAC 列表.

请求代理

请求代理这部分, 在此就不展开来讲了, 方式基本差不多, 开源方案也很多, 支持动态配置即可.

Pampas 的实现方式

上面基本介绍了实现原理, 那么 Pampas 使用的是何种方案呢?

不卖关子了, Pampas 采用本地 DNS 服务解析至本地, 并使用 Nginx 将请求转发, 实现虚拟域名的功能.

至于 Nginx 的动态配置, 实际上是用 Golang 写了一个配置解析, 在 Pampas 启动时生成配置, 即根据需代理服务列表, 通过模板生成 Nginx 的配置文件.

如此配置后, 所有的域名解析请求都会被 Pampas DNS 拦截, 符合 .pampas 域名结尾的, 直接返回 A 记录 指向 127.0.0.1, 同样本地有一个监听 80 端口的代理服务, 负责将请求转发至目标服务, 整体流程就是如此.

blog 不支持 markdown 的时序图, 我只能在其他地方写了截图过来了....

另外, 设置本地 DNS 使用了一个异常诡异的方式, 在安装 Pampas 时, 会自动写入一个 resolver 配置在 /etc/resolver/pampas, 并且通过新增网络, 切换之后再删除的方式重启网络, 以保证 DNS 配置生效...

诡异至极, 脚本如下:

  echo "*** Reloading system network configuration..."
  local location=$(sudo networksetup -getcurrentlocation)
  sudo networksetup -createlocation "pampas$$" >/dev/null 2>&1
  sudo networksetup -switchtolocation "pampas$$" >/dev/null 2>&1
  sudo networksetup -switchtolocation "$location" >/dev/null 2>&1
  sudo networksetup -deletelocation "pampas$$" >/dev/null 2>&1

耿荣

Read more posts by this author.

中国浙江省杭州市

Subscribe to The Terminus Blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!