跨Kubernetes集群pod通通信的必要性
截止到2020年,K8S已经基本统一了容器调度平台。也就是说,K8S、OpenShift已经像Linux那样,成为了一种平台产品(当然层级不同)。一个产品一旦成为平台,那随之对其高可用、灾备,甚至双活的需求就来了。
OCP(OpenShift的简称)的高可用设计此前很多文章已经介绍过了,我去年发行的那本《OpenShift在企业中的实践》也讲的十分细致,不再赘述。
但目前无论是OCP还是K8S,都不能实现真正意义上的双活。
什么是真正意义上的双活?就是两个数据中心的两个OCP集群上,部署一个应用,当主数据中心出现问题,业务不受到影响。
在虚拟机时代,我们要实现双活,很关键一点是打通大二层。也就是说,两个DC的VM不仅可以直接通讯,而且要在一个二层网络里,这样才能让应用双活。
在K8S时代,情况类似,想要在两个DC部署一个应用,就必须要能做到pod的跨集群通信。如果解决不了这个问题,那么双活只能是在两个DC两个OCP集群各部署一套应用(建议使用模板),然后前面接负载均衡器。
跨Kubernetes集群pod通信的实现
在目前阶段,针对OCP,如果想实现pod跨集群访问,主要有两种方法:
(1) 通过使用OCP4的多网络平面,将pod的第二个虚拟网卡的IP与数据中心拉齐。这样技术跨DC,只要网络可达,那么pod之间就可以直接通信了。这里我推荐使用macvlan。关于多网络平面的macvlan的配置步骤,我之前已经分享过了。这种方法好处是:性能高(macvlan性能好)、配置简便。缺点是:IP用的多,如果把OCP部署到公有云上,IP资源是按照个数收钱的。
(2)Submariner开源项目
Submariner是一种用于连接不同Kubernetes群集的覆盖网络的工具。虽然大多数测试都是针对启用了Flannel / Canal / Weavenet / OpenShiftSDN的Kubernetes集群执行的,但是Submariner应该与任何与CNI兼容的集群网络提供商兼容,因为它利用了StrongSwan / Charon等现成的组件来建立IPsec隧道。
请注意,Submariner处于预Alpha阶段,不应用于生产目的。
Submariner的架构
Submariner由可以在Kubernetes自定义资源定义(CRD)中运行的一些组件组成。Submariner CRD是clusters.submariner.io和endpoints.submariner.io。
Submariner的前提:
At least 2 Kubernetes clusters, one of which is designated to serve as the central broker that is accessible by all of your connected clusters; this can be one of your connected clusters, but comes with the limitation that the cluster is required to be up in order to facilitate interconnectivity/negotiation
至少有两个K8S集群,其中一个是central broker,负责多个集群之间的信息交互枢纽。
Different cluster/service CIDR's (as well as different kubernetes DNS suffixes) between clusters. This is to prevent traffic selector/policy/routing conflicts. Note: Submariner also supports clusters with Overlapping CIDRs via Globalnet Controller.
不同集群使用不同的CIDR
Direct IP connectivity between instances through the internet (or on the same network if not running Submariner over the internet). Submariner supports 1:1 NAT setups, but has a few caveats/provider specific configuration instructions in this configuration.
如果Submariner在互联网上运行,那么不同Submariner实例之间需要使用IP直连。
Knowledge of each cluster's network configuration
Helm version that supports crd-install hook (v2.12.1+)
Worker node IPs on all the clusters must be outside of the cluster/service CIDR ranges.
OCP集群worker node的ip不能和Submariner集群在一个网段
相连集群中的两个主要Submariner组件是:
Submariner gateway(DaemonSet)
submariner-route-agent(DaemonSet)
Submariner gateway Pod在带有网关标签的节点上运行,并在它们之间进行leader选举,以选择活动的IPsec端点。submariner-route-agent组件在每个节点上运行,并且知道当前的活动网关。当在活动网关节点上运行时,submariner-route-agent将通过与活动网关节点的VTEP建立VXLAN隧道,创建一个VxLAN VTEP接口,其他工作节点上运行的submariner-route-agent实例将连接到该接口。submariner-route-agent还配置路由并编写必要的iptable规则,以实现与远程集群的完全连接。Submariner VxLAN隧道的MTU是基于主机上默认接口的MTU减去VxLAN开销来配置的。
启动后,被选为leader的Submariner gateway pod将执行协调过程,以确保它是该群集的唯一端点。这就是为什么在群集之间具有唯一的群集ID很重要的原因之一,因为具有相同ID的两个群集将相互协调而不存在。
发生故障后,另一个submariner-gateway
pod(在其他网关节点之一上)将获得领导权并执行和解,以确保它是活动的leader。完成后,远程群集将IPsec端点与新端点协调,并重新建立连接。此外,submariner-route-agent pod将更新每个节点上的路由表,以指向新的活动网关节点。
Submariner使用center broker促进信息交换并在群集之间同步CRD。数据存储同步器在leader选举的Submariner pod内作为控制器运行,并负责在数据存储区和Submariner CRD的本地群集之间执行双向同步。datastoresyncer仅将CRD数据推送到本地集群的中央代理(基于集群ID),并且当数据与本地集群不匹配时,将从本地代理将来自代理的所有数据同步到本地集群(以防止循环循环)
现在OCP4上已经有Submariner Operator了。
由于这个方案处于初期(使用大概率会遇到bug),我们暂不进行功能验证。
结论
在目前情况下,如果跨OCP集群pod的通信是小范围使用,建议使用多网络平面+macvlan。我在项目中遇到的比较典型的场景是:两个OCP集群都运行SpringCloud,但服务注册中心在第三个OCP集群上,这时候就需要pod与注册中心直连。