多集群网络通讯原理与架构分析¶
近年来,多集群架构已经成为“老生常谈”。我们喜欢高可用,喜欢异地多可用区,而多集群架构天生就具备了这样的能力。 另一方面我们也希望通过多集群混合云来降低成本,利用到不同集群各自的优势和特性,以便使用不同集群的最新技术与支持现实中越来越复杂的云上业务。 最为本质的问题时单集群模式下存在承载能力上限,并且集群故障时,无法快速故障转移。
就是因为这些种种原因,多集群几乎成为了云计算的新潮流。 随着新架构的诞生,新的难题也接踵而来,尤其是在多集群场景下,其中业务的治理、监控、网络通讯也面临着严重的考验。 这时不得不提到服务网格,该技术从理论上来说对于多云多集群场景下,从设计基因中就自带了解决上面问题的能力。
为什么说服务网格能够支持复杂的多云场景呢? 服务网格将自身能力下沉到基础设施层面,因此从理论上来说,在多云环境中,它天然能够感知自己云上业务的各种信息,比如说服务地址、服务之间链路关系等网络信息, 网格将感知的信息聚会成一个完整的多云网络拓扑,在一个已知且能控制的多云拓扑中,用户能够从高纬度的观测并且控制业务通讯。
上述都只理论分析,再多的理论分析也不如一个实践论证,因此我们将自身服务网格产品(Mspider)到底如何支持多云环境进行一个由浅入深的整体剖析。
多云服务网格的优势¶
首先,我们回到最初的起点,我们为什么要选择多云服务网格? 所有的技术都是为了解决问题而存在,不具有优势与解决问题的技术,是虚假且没有意义的。 因此我们简单介绍一下相对于单集群场景下,多云场景下的服务网格能够给我们带来哪些优势?
故障隔离与故障转移¶
在单集群场景下,业务服务 A 出现问题时,我们通过将业务流量转移到同集群的另一个业务实例上。 但是如果集群出现故障时,这时候会变成多个业务同时故障,这时候如何将该集群的所有业务转移到另一个集群上,这是已经非常费时且复杂地。 但是实际地生产环境下,每分每秒是非常昂贵。 但是多云场景下,集群维度的故障转移是基本能力,用户能够快速地转移其所有业务的流量。 用户只需要定义集群之间故障转移的策略,例如 A 集群故障时,将业务流量转移到集群 B 中。
地域感知与故障转移¶
当多云环境下,对云上的地域进行定义;在业务健康时,可以让业务之间通讯以就近原则,发生故障时,可以快速转移至最近的地域环境中。
地域感知对于多云的重要性不言而喻。 因为现实世界、实际地域区域会影响网络通讯,中间有时间空间资源等多种因素。 例如当中国北京的集群都故障时,随机将业务转移到美国,但是实际环境中中国上海的集群空闲在那里,这肯定是不合理的。
多维度团队或项目隔离¶
虽然随着多云的体量扩大,但是团队的复杂度并没有增加,团队可以将多云划分成不同的区域、不同的集群、不同业务项目。 团队拥有多云能力的情况下,可以只需要管理自己相关的集群与业务。
多云维度的观测能力¶
单集群模式下,用户只能知道当前集群内的业务运行情况,每个集群之间的业务通讯时不透明且独立的。用户无法感知到集群外的业务通讯链路。
但是多云场景下,只要属于同一个网格,网格能将同一网络下不同集群之间的通讯情况进行聚合分析,将其绘制成一张完整的多云网络拓扑。 好比原先的单集群只是一张 2D 的照片,现在多云场景下,服务网格能够提供一张 3D 立体的拓扑网络。 这不仅仅是范围的扩大,而是维度层次上的增加。
多云下网络通讯原理¶
在了解了多云场景下巨大的优势,我们回归现实,多云场景有伴随着哪些问题? 其中哪个问题最为根本? 首先我们从字面上理解一下这个意思,多个云环境?多个云厂商? 多个云集群?这里的多个,就意味着存在不同。 而且在多云世界里,网络通讯是一个非常硬核的问题,云厂商之间能够直接通讯吗? 多集群之间如何通讯无阻?
在单集群的情况,所以的工作负载都在同一网络上(集群内部网络),但是多集群的场景下,每个集群可能存在多种因素导致网络无法互通,这里列举常见的几种情况:
- 地域问题导致集群实际网络之间存在网络隔离
- 初始化集群时,保持默认配置导致集群子网都一样,因此集群与集群之间网络会存在 IP 冲突。 以上几种情况下的多集群之间网络通讯是存在问题的,为了保持集群内部网络的独立性以及集群网络之间网络打通,Istio 提供了两种网络模型,用户可以根据集群状态与用户需求自由选择不同的网络模型。
单一网络模型¶
顾名思义,在单一网络的情况下,多集群之间的网络实例能给直接通讯,这时候不需要网格进行任何操作,服务之间网络通讯能够直达,其架构图如下:
单一网络模型的优势是非常明显的,用户通讯时,无需复杂的配置和中转,因此网络解析也更加直观,因此也能带来更高的网络性能。
在这时不得不提的是,有的用户会问,如果拥有多个集群,并且当时多集群之间网络存在冲突,但是又想要多集群之间网络选择单一网络模型时如何做?在这里简单提供一些网络改造需要解决的问题:
- 子网冲突问题:需要解决集群实例网络与集群服务网络的子网冲突问题
- 网络隔离问题:集群之间网络可能由于地域、安全等多种因素造成网络隔离的现状,用户可以选择通过隧道或直接路由,解决跨多个集群的 Pod IP 路由。
多网络模型¶
在多网络模型中,不同网络中的工作负载实例不能够直接通讯,因此服务网格提供了一种解决方案,让业务实例通过一个或多个 Mesh 网关相互访问,从而解决工作实例网络不能互相通讯的问题。
在服务通讯时,网格会根据网络分区进行服务发现,当请求服务与目标服务不属于同一网络分区时,服务请求将会转发给目标分区的东西网关,通过东西网关路由到真实的目标服务。
多云服务网格架构的抉择¶
在上述网络方面的思考以后,用户可能对服务网格自身架构存在好奇,例如服务网格控制面组件位置在哪里? 如何运行多集群模式? 这架构拥有哪些优势或者缺陷? 让我们具体分析现有服务网格提供的架构,现在主要有如下三种架构:
- 单集群单控制面
- 多集群单控制面
- 多集群多控制面
单集群单控制面¶
在最简单的情况下,可以在单一集群上使用控制平面运行网格。
多集群单控制面¶
多集群部署也可以共享控制平面实例。 在这种情况下,在核心控制集群部署核心的共享控制面实例,其网格核心的通讯策略都由 共享控制面实例 控制。 在从集群中,其实也存在一个从控制面实例,该实例其核心能力是 控制本集群的边车生命周期管理 。
思考一个问题,从集群的边车如何与共享控制面建立连接?其回答时共享控制面需要暴露自身控制面服务。
在单一网络模型中主集群的共享控制平面可以通过稳定 IP(例如集群 IP)访问。
但是在多网络模型的多集群中,需要通过 Mesh 网关对外 暴露 共享控制平面。
在实际的生产环境,可以根据实际的云供应商或者内部网络的规划灵活选择; 例如内部负载平衡器,避免将控制面暴露到公共网络中,因为其存在潜在的安全隐患。
共享控制面在上面描述中都是属于某一个网格集群中,其实其远程共享控制面也可以部署在网格外的集群中, 这样能够让网格的控制面与数据面在物理上实现隔离,避免主集群的控制面与数据面同时出现问题,可以分散风险。
多集群多控制面¶
为了获得高可用性,您可以在多个集群、区或地域之间部署多个控制平面实例。
在具有多个共享控制面的多集群场景下,每个控制面都属于某个集群, 共享控制面接受用户定义的配置(例如 Service
、ServiceEntry
、DestinationRule
等)来则自身集群的 Kubernetes API Server。 因此每个主控制面集群都拥有独立的配置来源。
因此这里存在一个问题,多个控制面集群如何同步配置? 这是一个很复杂的问题,需要增加另外的同步操作。 在大型的生产环境可能需要配合 CI/CD 工具一起自动化该过程,实现配置同步。
在这种多控制面模型下的在部署难度与配置复杂度上需要付出很大代价。 但是也能收获更高的回报,其核心优势在于:
- 高可用 :如果控制平面不可用,故障范围仅限于由该控制平面管理的群集中的工作负载。
- 配置隔离 :您可以在一个群集,区域或地区中进行配置更改,而不会影响其他群集。
- 控制面分区域滚动发布 :能够在不同的控制面区域内,对网格控制面进行滚动发布,包括金丝雀发布网格控制面,其影响范围也只是该控制面所在的区域。
多云环境下的服务发现¶
了解了服务网格控制面架构以后,这时候我们不得不提到服务网格数据面的通讯与运行原理, 理解这些原理能提高我们在实际运行服务网格遇到问题的解决能力。其中服务网格数据面通讯里面最为核心的技术便是服务发现能力。
在单集群模式下,服务网格控制面会从集群注册中心获取所有注册在集群中的服务,然后将集群注册中心获取到的服务信息聚合成一个服务端点列表,向每个边车提供。
在多群集场景下的服务发现能力更加复杂,因为集群之间存在注册中心隔离,网格为了运行多集群采用的解决方案是服务网格控制平面会观察并且记录每个集群中的注册中心的服务, 然后将集群中的 同命名空间下 的 同名服务 进行聚合,最后梳理成一张完整的 网格服务端点列表 ,然后下发给网格内的边车。因此服务才能具有发现其他集群服务端点的能力。
因此网格控制面为了能够访问其控制面的多集群的注册中心,在部署阶段需要从集群 授权远程密钥 给所属的控制面集群。 授权以后控制面才能对多集群进行服务发现,因此才具有后续的跨集群负载均衡能力。
在多集群网格部署模型下,多集群服务默认的策略是:每个集群均衡负载。 但是在复杂且庞大的生产环境中,其实很多服务只需要在某些区域进行流量通讯,这时候就可以采用本地优先负载均衡策略(具体方式为参考 Istio 官方提到的 Locality Load Balancing)。
在某些场景下我们会发现,跨集群的流量负载能力并不是频繁操作,时时刻刻的跨集群负载也不是我们所期望的。 例如说我们只是需要进行蓝绿部署,其版本位于不同的集群中; 例如当某个集群的某个服务出现故障时,能够切换到备用集群的服务中。 这些场景都是偶发的。发生频率很低,但是又是刚需。
这时候我们怎么样才能通过网格实现呢?在 Istio 服务网格下有两种方式:
-
我们可以不交换集群的
API Server
远程密钥,这样的话集群只能进行自身集群内的服务发现。 如果需要进行跨集群流量负载,可以通过ServiceEntry
配合外部负载器的方式实现。 -
通过配置
VirtualService
与DestinationRule
策略,禁用多集群之间的流量负载。
服务网格技术方案¶
上述几个章节我们简单围绕服务网格三个核心维度(网络模型、控制面架构、数据面服务发现)分析其相关原理与优势。 但是这时候我们会发现在网络模型和控制面架构部分介绍时都存在多种方案的情形,那么我们如何选择具体那种方案呢?
DaoCloud 深耕在服务网格产品多年的 ,拥有实际落地客户,以及从单集群演变到多集群客户解决方案的经验,我们产品内部也经过了多种方案的验证与实践,采集多位客户的场景,最后将我们的多集群服务网格产品的架构选型方案如下:自由的网络模型 + 多集群单控制面。
网络模型¶
在选择网格模型落地时,其实并不是非 A 即 B。 比如说用户需要更高效果,其打通部分集群之间网络成本在用户容忍范围内,用户可以选择部分集群网络为单一网络模式,在无法打通集群网络的集群中选择多网络模式。
每种模型都有自己独特的优势与代价,那么我能不能同时拥有呢? 这个答案时肯定的,我们都要。所以我们提出一个全能网络模型的概念,用户可以根据自己的需要选择网络模型:
- 单一网络
- 多网络
- 单一网络 + 多网络
这样丰富的网络模型方案,让我们能够更加贴合用户需求解决实际问题。
多集群单控制面¶
到这一部分,很多人会提问为什么选择多集群单控制面模式呢?从上述文章看起来多集群多控制面提供的能力不是更加丰富吗?
这里不得不提到实现多集群多控制面在落地的时候存在一个非常痛苦的点:多控制面从部署到运用到维护的成本非常高。 我们怎么得出这个结论的呢?在早期我们内部选择了多集群多控制面的验证,但是在这个过程中发现多控制面存在一些弊端:
-
策略复杂高隐患:
- 配置复杂:不同的控制面需要不同的策略,虽然换个角度看是独立的控制面策略,但是在多集群场景下,集群肯定是简单的一个两个,应用的总数也会随着集群的扩大变得更加复杂,非常容易发生部分集群忘记配置,或者更改配置时需要重复配置多套相同的策略。
- 策略冲突:多套控制面的策略非常多,用户需要准确掌握每个策略,不然很容易造成策略冲突。
-
控制面部署与升级维护成本高:当存在多套控制面时,我们需要维护多套控制面的部署与升级。
- 污染多个控制面集群:由于网格需要聚会多集群命名空间与服务,会污染控制面集群。让我举例说明:当集群 A 拥有命名空间 N1、N2;集群 B 拥有命名空间 N3 时;且集群 A、B 都控制面集群时,集群 A 需要新增 N3,集群 B 需要新增 N1、N2。当多集群与集群中业务到达一定体量时,这是非常恐怖的。
但是在多集群单控制面模式下能够大部分避免上面存在的问题,尤其是其中治理策略复杂这块,所有的策略将会统一在一个集群中,因此其中配置难度与管理难度将大大降低。
服务网格架构¶
接下来让我们来了解一下服务网格的实际架构:
在原生的多集群单控制面下其实并不能解决上文提到的污染多个控制面集群问题,但是我们仔细看上面的架构,大家会发现在这部分架构与社区提供的方案有一个很大的不同,在控制面集群中多了一套服务网格组件,这一套组件的最大的特色是提供了一个虚拟集群,该集群与网格控制面连接,并且目的是将网格资源与控制面集群的资源进行隔离,避免产生脏资源,这时候就能完美解决治理资源污染集群的问题,并且避免用户误操作删除控制面策略资源。
总结一下服务网格技术选型方案的的优势:
- 更简单的管理 : 将整个服务网格的管理集中在一个控制平面中,可以帮助组织更方便、更快速地管理整个服务网格。
- 低复杂度的配置与更好的性能 : 通过将整个服务网格的所有数据都统一在一个控制平面中,可以更快速地处理服务的路由和治理策略,从而提高整个服务网格的性能。
- 更强的安全性 :在单控制面多集群模式中,我们可以更好地控制对整个服务网格的访问,并使用更严格的安全策略来保护其数据。
- 支持跨集群负载与容灾能力 :能够灵活的配置跨集群流量负载与容灾策略。
- 策略配置统一高效 :不需要配置复杂的控制面配置同步与合并问题,尤其是控制面越多,其业务服务的体量越大,其同步和合并一定会是一个非常复杂且存在风险的存在。
- 灵活的控制面与数据面隔离 :服务网格允许用户将网格控制面与数据面集群进行隔离,并且在用户资源有限的情况下也支持集群同时兼具控制面与数据面在同一集群下。
- 网络模式灵活切换 :服务网格默认场景是多集群位于单网络,但是多网络模式也能够支持部署。
- 网格资源隔离 :在开源模式下,控制面集群需要管理所有集群的网格策略,这时候会存在污染控制面集群的命名空间,或者部分网格资源会受到集群本身操作影响(例如某个命名空间被删除)。
参考¶
本文部分图片来自 Istio 官网与 DaoCloud 文档网站。
参阅 Istio 部署模型。