# 异地 Kubernetes 集群如何互通:VPN、网关、Submariner 与 Cilium Cluster Mesh 选型实战
很多人说“把两个 K8s 集群连起来”,实际可能指三件完全不同的事:统一管理两个集群、让 A 集群访问 B 集群的服务、或者让两个集群的 Pod IP 直接互通。目标不同,方案复杂度相差很大。本文用容易理解的方式,把选择和实施步骤讲清楚。
## 一、先理解推荐架构
通常不建议把相隔很远的服务器加入同一个 Kubernetes 集群。控制面、etcd、心跳和存储都对延迟与网络稳定性敏感。更可靠的做法是两地分别运行独立集群:
```text
用户或业务
│
集群 A:Ingress / Gateway
│
专线、IPsec 或 WireGuard 隧道
│
集群 B:Ingress / Gateway → Service → Pod
```
这样一地故障不会直接拖垮另一地,升级、扩容和回滚也可以分别进行。
## 二、先回答三个问题
### 1. 只是想统一管理吗?
Rancher、Karmada、Open Cluster Management 等平台可以统一查看和下发资源,但“统一管理”不等于“网络已经互通”。业务流量仍然需要 VPN、专线或网关。
### 2. 只需要访问对方的服务吗?
这是最常见的需求,也是最推荐的方式。把目标服务通过内部 Ingress、Gateway API 或内网负载均衡暴露,只允许对端集群网段访问。调用方不需要知道对方 Pod IP。
### 3. 必须让 Pod IP 互相访问吗?
只有服务网格、全局服务发现、跨集群调度或某些中间件明确要求时,才考虑 Pod 到 Pod 的全网互通。可选择 Submariner 或 Cilium Cluster Mesh,但网络、路由和排障复杂度都会上升。
## 三、部署前必须检查网段
记录两个集群的四类地址:节点网段、Pod CIDR、Service CIDR、机房出口网段。
```bash
kubectl cluster-info dump | grep -m 1 cluster-cidr
kubectl get nodes -o wide
kubectl get svc -A -o wide
ip route
```
示例规划:
```text
集群 A 节点:10.10.0.0/16 Pod:10.110.0.0/16 Service:10.210.0.0/16
集群 B 节点:10.20.0.0/16 Pod:10.120.0.0/16 Service:10.220.0.0/16
```
任何需要互通的网段都不能重叠。如果两边都使用 10.244.0.0/16,路由器无法判断数据包应该发往哪里。此时应做服务级网关互通,或者重新规划网段,不要依赖大量 NAT 规则硬撑。
## 四、最容易落地的方案:VPN 加内部网关
### 第一步:建立站点到站点隧道
优先使用运营商专线、云企业网、IPsec 或 WireGuard,让两地节点或网关网段可达。VPN 两端建议做双机或双隧道,避免单点故障。
隧道建立后测试:
```bash
ping <对端网关IP>
traceroute <对端网关IP>
nc -vz <对端内部网关IP> 443
```
### 第二步:在目标集群发布内部服务
通过内部 Ingress、Gateway 或 LoadBalancer 提供一个稳定地址,例如 10.20.10.50:443。不要直接暴露某个 Pod IP,因为 Pod 重建后地址会变化。
### 第三步:配置最小权限防火墙
只允许来源集群的出口网段访问目标网关的必要端口。不要开放 etcd 的 2379/2380,也不要把 kube-apiserver、NodePort 全部暴露到公网。
### 第四步:配置私有 DNS
例如让 order.cluster-b.internal 解析到集群 B 的内部网关。可以使用企业 DNS,或者在 CoreDNS 中配置条件转发:
```text
cluster-b.internal:53 {
forward . 10.20.0.53
}
```
修改 CoreDNS 前先备份 ConfigMap,并在测试命名空间验证解析。
### 第五步:启用加密和身份认证
VPN 只能保护链路,服务仍应使用 HTTPS 或 mTLS。为调用方配置独立身份和最小权限,证书需要监控有效期并支持自动轮换。
## 五、需要 Pod 直连时怎么选
### Submariner
适合两个集群使用不同 CNI、跨云或跨机房的情况。它通过网关节点和加密隧道连接集群,并可提供跨集群服务发现。部署前要确认网段、网关高可用、UDP 端口、防火墙和 NAT 环境。
### Cilium Cluster Mesh
适合两个集群都使用 Cilium。它可以实现跨集群 Pod 互通、全局服务和安全策略。官方要求各集群 Pod CIDR 唯一,并且集群节点的 InternalIP 之间具有网络连通性,通常仍需先建立网络对等或 VPN。
### Istio 多集群
适合已经使用 Istio、希望实现服务级流量治理、mTLS、就近访问和故障切换的团队。它解决的是服务网格问题,不应把它当作替代底层网络的万能工具。多集群会增加证书、信任域、东西向网关和控制面运维成本。
## 六、最容易忽略的 MTU 问题
原始以太网 MTU 通常是 1500,VPN、VXLAN、Geneve 等封装会增加包头。如果隧道和 CNI 都封装,实际可用 MTU 会变小。典型现象是:ping 小包正常,HTTPS 握手、大响应或文件传输超时。
```bash
ping -M do -s 1400 <对端地址>
tracepath <对端地址>
ip -s link
```
逐步减小报文找到可用值,再统一调整 VPN、节点和 CNI 的 MTU。不要只在某个 Pod 临时修改。
## 七、上线验证清单
1. 两边网段无冲突,路由去程和回程一致。
2. DNS 连续解析正常,不出现偶发 SERVFAIL。
3. TCP、HTTPS、长连接和大包传输正常。
4. NetworkPolicy 和防火墙只放行需要的源与端口。
5. 主隧道断开后备用链路能够接管。
6. 集群 B 故障时,集群 A 能快速失败、降级或切换。
7. 监控隧道状态、延迟、丢包、重传、证书和网关容量。
## 八、生产环境推荐结论
大多数公司应选择“两个独立集群 + 专线或 WireGuard/IPsec + 双向内部网关 + 私有 DNS + TLS/mTLS”。它不追求所有 Pod 彼此可见,而是只开放真正需要的服务,安全边界清楚,排障也最简单。
只有明确需要全局服务、Pod 直连或服务网格故障切换时,再引入 Submariner、Cilium Cluster Mesh 或 Istio 多集群。架构越复杂,越要提前准备监控、容灾、证书轮换和回滚方案。
## 参考资料
- [Cilium Cluster Mesh 官方文档](https://docs.cilium.io/en/stable/network/clustermesh/clustermesh/)
- [Istio 多集群部署模型](https://istio.io/latest/docs/ops/deployment/deployment-models/)
- [Istio 多集群安装文档](https://istio.io/latest/docs/setup/install/multicluster/)