一、背景
1.1 Istio的服务网格
从服务架构的演绎过程来看,服务架构经历了从单体架构到SOA架构,并到微服务架构的演进,在微服务架构中,我们需要关注服务间怎么通信,服务怎么查找,服务故障怎么处理等,在现有的微服务架构中,SpringCloud提供了比较成熟的微服务治理全家桶方案,阿里也形成了以Dubbo为基础的微服务技术体系,包括服务注册和配置中心Nacos、隔离熔断Sentinel、分布式事务Seata、分布式任务调度SchedulerX等。而SpringCloud/Dubbo框架提供的服务治理能力是代码侵入的,主要支持Java,其它语言像go/nodejs/python等需要定制开发对应的SDK才能享有完整的服务治理能力。
因此,需要把与应用业务逻辑无关的功能抽象到共同基础设施,来降低应用程序代码和底层平台的耦合度,使开发者更能专注于本身的业务逻辑,而无需耗费精力在基础代码的设计上。在微服务和容器化之后,异构语言使用的增加,服务的数量激增,容器的生命周期变短是导致服务网格出现的根本原因。
Kubernetes 到 Istio 的架构改变示意图
从上面 Kubernetes 到 Istio 的架构的转变的描述中,我们可以看到为了让开发者最小成本地管理服务间的流量,Istio 需要解决三个问题:
- 透明劫持应用间的流量:Istio 开源最初的目标是成为网络基础设施,就像水和电人类的基础设施一样,我们使用水电不需要关心如何取水和发电,只需要打开水龙头,按下开关即可。透明流量劫持对于开发者来说,就像使用水和电,不需要修改应用程序就可以快速使用 Istio 带来的流量管理能力;
- 代理集群的运维:如何为每个应用注入一个代理,同时高效地管理这些分布式的 sidecar 代理;
- 可编程代理:代理可以通过 API 动态配置,还要有出色的性能与可扩展性;
1.2 主从集群架构
主从集群架构是一种常见的分布式系统架构,用于解决多个问题,包括高可用性、可伸缩性和容错性等。
高可用性:主从集群架构通过将系统的负载和数据分布在多个节点上,确保系统的可用性。如果主节点出现故障,备用的从节点可以接管主节点的工作,保证系统的持续运行,从而降低单点故障的风险。
负载均衡和扩展性:主从集群架构可以通过将负载分散到多个节点上来实现负载均衡。请求可以在多个从节点之间进行分发,从而提高系统的性能和扩展性。此外,可以动态地添加或删除从节点,以适应不同的负载需求,实现系统的水平扩展。
容错性:通过在主从集群中使用冗余的节点和数据复制机制,主从集群架构可以提供容错能力。如果某个节点或数据发生故障,备用的从节点可以继续提供服务,而数据的冗余副本可以用于恢复和修复损坏的数据。
并行处理和性能优化:主从集群架构可以通过并行处理来提高系统的性能。不同的从节点可以同时处理请求,从而减少了系统的响应时间。
二、Istio主从集群结构
本次项目部署方案采用了跨网络的一主多从架构,结构图如下图所示:
Istio安装部署的时序图如下:
三、Istio主从集群部署流程
3.1 主集群Istio控制面部署
用户通过控制台创建服务网格实例,选择一个集群作为主集群控制面服务安装部署Istio,需要经过集群信息初始化,设置网格属性如MeshId、NetworkId存储到数据表中,之后再通过Operator安装Istio控制面服务。
3.2 主集群EastwestGateway负载均衡部署
用户绑定ELB服务到东西向网关来作为网格内部服务通信使用,如果检测到当前主集群EastwestGateway资源类型的状态是未安装状态,则执行CRD资源的安装和ELB服务绑定,由于ELB绑定服务依赖外部链路,因此该步骤为异步处理,只记录资源类型为EastwestGateway的状态为ELB绑定中。后续状态流转交给异步任务处理。
3.3 主集群开放控制面服务部署
定时任务遍历EastwestGateway资源类型状态为安装中的列表,通过检测Service的ExternalIP是否存在来判断网关的负载均衡服务是否安装成功,决定是否进入下个状态,成功则最后开放stiod服务,更新EastwestGateway资源类型状态为已安装。
3.4 从集群Istio服务部署
主集群安装成功后,进入从集群Istio部署,需要用到主集群的ExternalIP,在从集群部署成功后,需要从从集群获取token应用到主集群的Secret资源中,同时更新Secret资源类型状态为安装中。
3.5 从集群添加到主集群状态检测
通过在从集群创建测试Namespace来检测主集群是否成功添加从集群,如果成功,主集群命名空间服务会检测到从集群创建Namespace事件,下发configmap给从集群,用来主从之间的通信认证。
四、Isitio多集群原理
4.1 主集群Secrets资源
从集群要添加到主集群,需要将从集群的kubecofig信息以secret的方式添加主集群中,Secret资源文件如下:
apiVersion: v1
kind: Secret
metadata:
annotations:
networking.istio.io/cluster: clusterName
labels:
istio/multiCluster: "true"
其中,最关键的是istio/multiCluster: "true"标签,控制面集群就是通过该label来检测从集群连接。
4.2 Istiod多集群连接
4.2.1 LeaderElector选举
在 Istio 中,LeaderElector 模块通过使用 Kubernetes 的 ConfigMap 和 Lease 资源来处理多个集群之间的选主。
- ConfigMap:LeaderElector 使用 Kubernetes 的 ConfigMap 来协调多个集群之间的选主过程。每个集群都会创建一个 ConfigMap 对象,其中包含了选主的相关信息,例如当前的领导者、候选者等。
- Lease 资源:LeaderElector 还使用 Kubernetes 的 Lease 资源来维护选主的状态。Lease 是一种 Kubernetes 资源,用于表示一个特定的持有者(例如领导者)在一段时间内拥有对资源的访问权限。
- 选主过程:每个集群中的 LeaderElector 实例会通过与其他集群的 LeaderElector 实例进行通信,共同参与选主过程。它们会通过 ConfigMap 和 Lease 资源来共享选主的状态和信息。
- 候选者竞争:每个集群中的 LeaderElector 实例将自己注册为候选者,并尝试竞争成为领导者。它们会根据选举算法(如基于 Raft 或 Paxos 的算法)来进行投票和计算。
- 跨集群通信:集群中的 LeaderElector 实例通过与其他集群的 LeaderElector 实例进行通信,交换选票和选主的状态信息。它们会使用 ConfigMap 和 Lease 资源来同步选主状态,并确保一致性和正确性。
- 领导者通知:选主完成后,每个集群中的 LeaderElector 实例将选出的领导者信息写入到对应的 ConfigMap 中。其他集群的 LeaderElector 实例可以通过监测 ConfigMap 的变化来获知领导者的选举结果。
通过以上机制,Istio 的 LeaderElector 实现了多个集群之间的选主过程。它使用 Kubernetes 的 ConfigMap 和 Lease 资源来共享选主状态和信息,并通过跨集群通信来完成选举和选主结果的同步。这样可以确保多个集群之间的选主一致性和可靠性。
4.2.2 从集群连接检测
从集群的Istio服务部署成功后,主集群的Istiod服务开始检测从集群是否能成功连接。如何自动化检测是一个问题,一般可以采用方式有两种:
- 通过查询控制面Istiod的日志,获取从集群添加成功标识,则标志从集群添加成功;该方法需要不断轮询控制面Istiod服务日志,如果从集群数量过大,对主集群访问压力太大,一般不采用;
- 通过在从集群部署测试服务,检测从集群的Pod服务的Sidecar容器是否启动成功来检测从集群是否添加成功;该方法需要再从集群上部署测试服务资源,还需要不断查看Pod容器中的Sidecar状态,操作复杂,成功之后还要删除对应的资源文件;
本项目基于Isito多集群实现原理,从集群的Namespace控制器监听命名空间事件以及主从集群通信需要安全认证,从集群需要控制面CA生成证书的原理,在从集群创建测试Namespace,从集群Namespace控制器监听到Ns创建事件后,会调用控制面集群Istiod的caBundleWatcher生成istio-ca-root-cert的configMap挂载到从集群。因此,只需检测对应的configmap是否生成就可以判断从集群是否添加成功,而无需创建Pod服务验证。