想象这样一个场景,一开始在公司里,所有的部门的物理机、POD都在一个经典网络内,它们可以通过 IP 访问彼此,没有任何限制。因此有很多系统基于此设计了很多点对点 IP 直连的访问,比如中心控制服务器 S 会主动访问物理机上的 Agent 从而拉取信息或下发配置,假设调用频率很高,数据量很大。
现在由于各种原因,各个部门之间的网络不再被允许互通,而是出现了隔离:
相当于对于每个部门来说,物理机处于一个单独的 VPC 内,POD 处于另外一个单独的 VPC 内,默认情况下 VPC 与 VPC 之间是网络隔离的。
这里我们先假设所有部门的物理机和 POD 的 IP 依旧不会重复,从而先简化问题的讨论。
上述只是我创造的一个虚拟场景,实际并不是这样的,但也不影响问题讨论。
由于网络隔离的出现它会导致:
我们的系统严格依赖上述2点,因此网络隔离的出现导致我们的系统连基本功能都用不了。我们并不想为每个部门单独部署一套我们的系统(运维成本高),而是想使用一套系统服务所有部门。
面对该问题考虑了如下解法:
解法1需要将点对点访问变成边缘 Agent 对中心控制服务器 S 的访问,一般来说 Agent 访问哪台 S 都是可以的,因此可以给 S 挂一个 VIP,让 Agent 去访问该 VIP 即可。
但这涉及整个系统架构大改,暂时不考虑。
解法2的来源是想到如果每台 Agent、中心控制服务器 S 能找一个第三方组成一个 VPN 网络,那么每个成员都会有一个新的虚拟 IP,使用该新的虚拟 IP 就可以实现原来的点对点IP直连访问。而我们要做的是在访问时,查询一下原始IP对应的新的虚拟IP,然后访问该 IP 即可。
但是组 VPN 了解不够,并且只有一台VPN服务器也是不够的,应该是需要VPN集群,这对我来说就更难了。
后来经过一些调研,发现有一个技术叫做“反向代理”,相关的软件参考了 frp https://github.com/fatedier/frp
假设有如下4个角色:
A: 处于 VPC 1 内
R: 处于 VPC 1 内 (R 也可以就是 A 自身)
S: S代表一组服务器,处于 VPC 2 内; 并且它配置了一个 VIP, VIP 可以被 VPC 1 里的成员访问
B: 处于 VPC 2 内 (B 也可以就是 S 自身)
此时 VPC 1 与 VPC 2 网络不通,仅 VPC 1 的成员可以通过 S 的 VIP 访问到 S。
A 向 S 的 VIP 发起反向代理请求 (R IP, R port),S 的某个成员 S' 收到了反向代理请求 (R IP, R port),S' 为反向代理请求分配一个随机端口 S' port (也可以是固定端口,不过在我们这个场景下随机更好)。
此后,B 就可以通过 (S' IP, S' port) 访问到 (R IP, R port)。
因此,如果你有一个公网IP,那么你就可以把你某个内网的端口通过该公网IP做反向代理暴露出去。经常折腾软路由的人应该对此了解较深。
假设我们在中心引入一个 proxy server (简称PS)的角色,让每台 Agent、中心控制服务器 S 通过 VIP 找到任意一台中心 PS 服务器建立反向连接,建立反向连接后可以得到一条反向链路:(某PS的IP,某PS的端口,某Agent的IP,某Agent的端口),以下简称反向连接4元组.
当我们要访问(某Agent的IP,某Agent的端口)时, 换成去访问(某PS的IP,某PS的端口)就可以了。
当每台 PS 服务器建立反向连接时,它会将该反向连接4元组记录在某个地方供后续查询。当然销毁反向连接时也要记得删除4元组。
考虑到还有其他应用也会访问物理机上的Agent,我们可以将该4元组的查询做成服务或者SDK供其他应用使用。但是这种方式对这些应用有一定侵入性,他们不一定愿意接入。
我们还可以使用 socks5 代理技术来简化其他应用访问物理机上的Agent的流程。
我们实现一个 socks5 server 的角色,对外提供一个 VIP:port 供其他应用连接,其他应用要做的仅仅只是在它们发网络请求的地方配置 socks5 代理(socks5 代理的支持很普遍的)。这个 socks5 server 的实现就是根据目标 IP 去查 4 元组,然后将请求转发到对应的 (PS IP,PS port) 上。
如果你的Agent提供的是 HTTP 服务,那么你可以提供 HTTP 代理服务器而非 socks5,那应该会更简单一些。
一般来说,公司之所以要引入 VPC 网络架构,就是为了隔离各部门的网络,属于有意为之。而我们的这种做法无疑是打破了这种隔离。但好在我们打破的范围仅仅局限在我们系统的业务 POD 之间,并不涉及其他业务 POD(虽然说我们确实有这个能力)。所以我的这种做法目前是可以被接受的。