背景
由于家境贫寒没钱,只有一台 2c4g 的云服务器,基本部署不了什么服务。但是,作为一个垃圾佬,本地的资源可以说是非常过剩。因此,就想着,能不能通过部署在公网的集群,把在内网的集群也暴露到公网上。
目标
主要分为 http 服务和 tcp 服务,比如说网页服务和数据库服务。
Http
由于 http 服务使用 80 和 443 端口,原集群和本地集群必然使用同一个端口,所以需要做到合理的分流。
分类显然就是基于域名的了,和虚拟主机一个道理。我规定 k.suyiiyii.top
将会路由到公网的集群,而 kl.suyiiyii.top
将会路由到本地的集群。
TCP
这个就主要靠端口区分了,虽然有根据 tls sni 嗅探做分流的技术,但毕竟不是每一个应用都会用标准的 tls,所以还是要基于更底层的端口。
打通内网
实现转发之前,总要让云端的集群能够访问本地的集群吧。这里我使用的是 tailscale,在本地的一台机器上面配置 subnet,然后其他机器就可以直接访问内网了,参考文档。
Http
转发的方法还是使用 Service + Endpoints 来实现,下面给出 manifest:
|
|
然后是 ingress,这里我使用了 traefik 的 crds,IngressRoute,多了一个可以使用正则匹配域名的功能:
|
|
这样,再把 kl.suyiiyii.top
和 *.kl.suyiiyii.top
都解析到云端的集群,就可以实现 http 协议的自动转发了了。
Https
事情到了 https 这里,就变得复杂起来了。
谁加密请求
首先,要问自己一个问题,tls 加密的部分,应该是谁来做处理?是云端集群还是本地集群?
- 云端集群:那么本地集群就只暴露 http 服务,云端集群配置域名相关 tls
- 本地集群:本地集群配置 tls,并且同时暴露 http 和 https 服务,云端集群只提供转发服务
这里我采用的是后者。如果采用的是前者,那么配置本地集群服务的同时需要在云端集群配置要转发的域名。而采取的后者,只需要在本地集群配置即可。同时,应用和应用入口的配置在同一个集群,也方便应用的迁移(不需要修改 manifest)。
怎么分流流量
http 协议可以通过读取请求头中的 Host 字段来判断请求的主机,但 https 是 http 的加密版本,整个请求是全部加密的,根本读取不到 Host 字段,我们需要其他的手段来实现 https 请求分流。
现在,http 协议由更下次的 tls 协议包裹,所以我们要把目光聚焦于 tls 协议了
我们查询相关资料,发现 tls 协议有一个 sni 扩展,似乎可以解决这个问题。
简单来说,就是在 https 刚被发明出来的一段时间,人们也发现了 https 无法根据主机名称进行分流这个问题,所以既然 Host 字段被放到内层加密了,那我就在外层再添加一个 Host 不就行了。
sni 扩展就是做这个事情的,目前 sni 已经被广泛使用,所以我们可以基于 sni 做分流。
|
|
记得开了 tls passthrough,表示云端集群不处理 tls 相关逻辑,而是直接转发。
有的朋友可能有疑问,现在不都是 https 了吗,还有必要配置 http 的转发吗?
其实是有的,因为本地集群也需要签发证书等操作,let’s encrypt 的服务器需要通过 http 服务检查我们对服务器的控制权,所以还是要开启 http 转发。
TCP
这个比较简单,就参考前一篇文章即可
总结
通过上述的方式,成功将本地的集群也暴露到了公网上面,并且各种访问方式与原生公网集群无异,又是一次酣畅淋漓的折腾。🥰🥰🥰