高可用环境下的服务网格部署实践
2021-07-19贾智宇
赵 鹏 刘 畅 贾智宇 毋 涛 廖 军
中国联通研究院 北京 100176
引言
随着云计算技术得到普遍应用和推广,应用云化已成为企业IT系统演进的主流方向之一。由于应用云化和业务发展带来的IT系统在复杂度、可靠性、成本等方面的问题,云原生、微服务、容器化逐渐成为下一代云计算技术的发展方向[1-2]。云原生是对于应用上云提出的一种应用架构思想和理念。根据CNCF关于云原生的最新定义,云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API[3]。伴随云原生应用的出现和应用的微服务化,应用内服务或组件的数量成几何级别增长。由此带来的多服务间通信成为云原生应用面临的主要问题,而服务网格正是解决这类问题的主要思路之一。
5G网络商用落地的同时,市场呈现出了对5G网络的繁多需求。市场需要已经从单一的网络连接需求转变为对个性化、动态化的通信平台服务的需要。为满足市场不断增长的多样化、差异化需求,全球电信运营商正在尝试使用基于云原生技术的解决方案,实现5G网络的高效运营、业务灵活管理等问题[4]。同时,由于电信行业业务属性之一是始终提供一种长期、稳定可靠的网络连接,所以电信运营商在利用云原生技术灵活、可扩展优势的同时,对云原生方案落地过程中的高可用性提出了更多的要求。本文基于电信行业对云原生和高可用性方案的需要,设计并提出了一套高可用环境下的服务网格系统,并通过实际部署验证了该系统的高可用性。
1 服务网格
1.1 服务网格概念
多组件或多服务之间的通信一直是计算机软件中的基本组成部分。随着应用规模不断发展,单服务器性能瓶颈问题以及服务器扩容升级成本问题凸显,单体应用逐渐向微服务应用转变[5]。单体应用时期,多服务间通信基本在应用内部实现,各个应用的实现方法各不相同。微服务应用时代,伴随着应用的微服务化拆分,相比单体应用而言,多服务间通信方面需要解决的问题反而增多。微服务治理问题凸显,亟待解决服务发现、故障处理、动态调度、调用安全等问题。微服务应用初期,各个应用采用各自方式解决微服务治理问题,导致了解决方案与业务紧耦合,重复开发现象明显。随着微服务治理的发展,一类更具通用性、与业务部分解耦的微服务治理库和框架出现,如 Spring Cloud、Dubbo和Netflix OSS等。但是,这类通用库或框架在解决服务治理问题方面仍然存在一些不足,如与特定语言绑定、技术门槛较高、业务逻辑与框架解耦程度不足等。服务网格就是一种解决以上不足的新型微服务治理方案。
Service Mesh(服务网格)一词最早由Buoyant公司的CEO William Morgan于2016年提出并给出其定义。服务网格是一个专门处理服务间通讯的基础设施层,它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送,在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,并且对应用服务透明[6]。服务网格具有如下特点:云原生、透明、网络代理机制、基础设施层方案。服务网格的基础设施层定位,解决了与特定开发语言的绑定问题;同时,类似于计算、存储等其他基础设施资源一样的使用方式,降低了服务网格的使用难度。通过网络代理机制,服务网格实现了服务治理与业务代码的彻底解耦,实现了服务网格对业务应用的透明。综上所述,服务网格本质上就是一类专门解决应用微服务化带来的多服务间通信的基础设施级解决方案。
1.2 服务网格方案对比
从商业模式角度看,服务网格可以分为开源软件方案和商业版方案。开源方案目前有Istio、Linkerd、Envoy;商业版方案方面,云服务商都推出了各自的商业托管方案,如AWS的APP Mesh,Google的Traffic Director,阿里云的ASM等。商业版本的服务网格大多基于开源软件或部分基于开源软件,并新增了对虚拟机、混合云、多云的支持。例如:AWS的APP Mesh的数据平面代理部分是基于开源Envoy开发的,对AWS生态完全集成,支持的服务运行平台除了AWS EKS平台外,还支持AWS EC2、AWS Fargate以及客户在AWS上自建的Kubernetes集群;Google的Traffic Director整体基于Istio研发,同样支持服务运行在GKE、虚拟机、客户管理的 Kubernetes以及混合云中的服务。
服务网格的开源软件方案数量众多,但是,目前应用最广、最具影响力的开源方案主要是Istio、Linkerd和Envoy。Envoy作为一款开源网络代理被多个服务网格方案采用,并被采纳为服务网格方案中的数据平面代理的具体实现。Envoy具有高性能、支持协议广、流量管理功能丰富等特点。Istio和Linkerd两款开源服务网格方案的对比分析,如表1所示。
表1 开源服务网格Istio与Linkerd对比
通过表1对比发现,Istio和Linkerd方案都相对成熟,具备了生产级的可用性,二者都支持主流的容器管理平台,支持将sidecar自动注入到Pod中,支持多种主流通信协议,均具有完善的流量管理功能。但是,Istio方案具有更丰富的流量管理功能,支持更广的服务平台和更多的安全策略配置。具体实践中应该根据具体需求,在功能丰富度、易用性、性能、兼容性等方面综合考虑并做出选择。
1.3 Istio方案的架构
基于以上对比分析,本文选择Istio作为服务网格的部署方案。Istio方案的架构如图1所示,整体可以分为两个部分,即控制平面部分和数据平面部分。数据平面由代理以边车的形式构成,具体实现服务间的通信和治理。控制平面由三部分组织,分别是Pilot、Citadel、Galley,控制平面负责对所有代理构成的网络整体进行编排管理。
图1 Istio 整体架构图
Isito数据平面中的代理具体是由Envoy实现的。代理以边车的形式与对应服务一同部署。代理负责实现服务间的网络通信,全权代理服务的所有入流量和出流量,同时对应服务对此无感知。同时,代理负责收集并向控制平面报告所有流量数据。Envoy代理本身功能丰富,包括服务发现、负载均衡、熔断、健康检查、故障注入、TLS 终端等。Isito数据平面中的Pilot负责管理数据平面的流量规则和服务发现。Pilot负责将路由策略转换为Envoy特有的配置信息,并下发该信息到Envoy中,由Envoy代理具体实现流量管理。同时,Pilot通过平台适配器和抽象模型,实现与平台无关的服务发现功能。Isito数据平面中的Galley负责将Istio其余组件与从底层平台获取用户配置的细节隔离,由Galley统一向底层平台获取、验证用户配置信息,并将配置信息分发至Istio其余组件。Isito数据平面中的Citadel负责服务间通信和治理的安全,通过内置的身份和证书管理,实现服务与服务、服务与用户间的双向验证和加密通信。Citadel通过RBAC鉴权模型,支持“用户—角色—权限”的多级鉴权认证。
Istio通过以上架构实现了服务网格对服务进行治理的透明度最大化,服务无需任何代码更改,代理只需要消耗少量的资源,并以边车的形式部署到服务旁边,就可以截获流量,实现流量控制。同时,Isito还具备可扩展性和可移植性,流量管理的功能可以通过对接其他系统不断丰富,Isito对底层平台依赖性低,可以方便地实现多云、多集群部署。
2 高可用环境
2.1 高可用概念
可用性是对一个系统在功能正常运行条件下,该系统不中断运行能力的衡量。可用性指标一般使用系统功能正常运行时间与对应统计总时间之间的比值作为具体量化指标。高可用就是可用性的一种相对较高的水平。根据系统与应用场景的不同,高可用对应的可用性指标数值不同,一般认为高可用需要达到99.99%的可用性指标。高可用环境就是为了达到高可用水平的可用性,系统在软硬件方面采取的一系列手段。实现高可用的手段包括负载均衡、数据备份、主备架构、多活等等。
服务网格作为一种微服务应用中的服务治理方案,服务网格的运行以微服务的具体实现方式为基础。目前,容器已经成为微服务的主要实现方式,同时Kubernetes已经成为容器编排管理的事实标准。所以,本文中的高可用环境就是指以容器和Kubernetes为基础,通过各种高可用手段,构建一个适合服务网格运行能够长时间不中断运行的软硬件系统。
2.2 Kubernetes集群高可用
一个基本的Kubernetes集群至少包含以下两类组件:主节点(含etcd数据库)和工作节点。主节点包含API服务器、Scheduler和Controller Manager等组件,主要负责整个集群的控制和管理,实现容器的调度编排。Etcd数据库负责存储整个集群的配置和状态信息。工作节点包含容器运行时、kubelet和kube-proxy等组件,主要负责承载部署到集群中的容器,是业务相关微服务组件的实际运行节点。Kubernetes集群的高可用是指系统在部分节点无法工作的情况下仍能保持正常运行的能力。由于Kubernetes系统自身就支持多个工作节点同时工作,即支持工作节点的高可用;所以,Kubernetes集群的高可用主要是实现主节点和etcd数据库的高可用,即通过多个副本实现集群控制平面的高可用。根据etcd数据库与主节点的关系,Kubernetes集群高可用架构分为堆叠式和外部式,如图2所示。堆叠式和外部式高可用架构都采用分层设计,多个主节点通过负载均衡统一对外服务,多个工作节点通过负载均衡与主节点统一通信。
图2 两种Kubernetes高可用架构
堆叠式高可用架构采用主节点和etcd数据库共享一个节点的方式部署,etcd数据库只与本节点的API服务器通信。外部式高可用中主节点和etcd数据库分别部署在不同的节点上,每一个etcd数据库节点分别与每一个API服务器通信,实现了主节点和etcd数据库的解耦。堆叠式高可用相较外部式高可用存在同时失败的风险,即一个节点故障,将同时导致主节点和etcd数据库故障,从而导致集群中可用性快速下降。反而,外部式高可用可以减少此类故障下的可用性下降程度。
3 部署实践
3.1 系统设计和规划
根据高可用环境部分和服务网格部分的分析,本文提出一种高可用环境下的服务网格系统,系统架构如图3所示,主要包括三个部分,工作节点层、负载均衡层、控制节点层。控制节点层由3个主节点和3个etcd节点构成,采用外部式高可用Kubernetes架构,实现Kubernetes集群的高可用。负载均衡层由两个负载均衡节点组成,二者互为主备,实现负载均衡自身的高可用,同时,通过浮动IP的方式,实现主节点对外的统一IP地址暴露。工作节点层由两个节点构成,实现对服务网格以及其他应用的高可用承载。
图3 高可用环境下的服务网格系统架构
根据以上系统架构,对系统所需服务器、IP地址以及相关软件版本进行规划,总共需要内网IP地址11个,虚拟机或服务器10台,kubernetes集群内部pod和service子网地址段2个,对应软件及其版本如表2所示。
表2 系统规划表
3.2 部署实践
根据上述系统设计与规划,系统部署实践主要分为六个部分,包括:环境准备、负载均衡搭建、etcd集群安装、主节点搭建、工作节点添加、isito和应用部署。前五个部分为高可用环境的部署,第六部分为服务网格以及典型应用的部署。
1)环境准备:该步骤主要是完成操作系统、网络以及基础软件的安装调试,保证网络连通,主要包括在除负载均衡节点以外的所有节点完成docker、kubectl、kubeadm、kubelet等软件的安装。为保证后续步骤的顺利进行,在本步骤中对docker进行设置,主要是将docker程序的cgroupdriver选项设置为systemd,并为docker添加国内镜像仓库。
2)负载均衡搭建:在2个节点安装haproxy和keepalived。Keepalived结合定期健康检查和预先设置的权重,将2个节点分别设置为主备,其中主节点绑定VIP,实现主节点对外IP地址的统一。Haproxy负责实现流量在3个控制节点层的主节点之间的负载均衡。
3)etcd集群安装:由于网络原因,etcd集群安装采用二进制安装方式。提前生成并分发ca、server、client等证书到3个etcd节点,然后通过二进制安装etcd程序,并通过修改etcd集群配置文件,启动etcd集群。最后,通过增删改查等操作,验证了etcd集群的功能和高可用性。
4)主节点搭建:首先利用etcd阶段生成的证书,完成主节点1的初始化。在完成网络组件flannel的安装配置后,再依次添加其他2个主节点加入控制平面。
5)工作节点添加:确认2个工作节点已完成docker安装和配置,根据主节点证书和令牌依次添加2个工作节点。
6)isito和应用部署:通过yaml文件分别安装isito和业务应用,验证了服务网格对业务应用中的微服务进行管理的功能,包括灰度发布、流量调度等。
4 结语
以服务网格为代表的云原生技术凸显了灵活、快速的优势,该技术尤其适合以5G技术为代表的电信运营商。服务网格在满足电信级高可用条件后,将更进一步促使该技术在电信行业落地。本文在分析了主流服务网格Istio和Linkerd方案,并对比了Kubernetes堆叠式和外部式高可用架构的优劣之后,在此基础上提出了一个完整的高可用环境下服务网格系统。本文通过实际部署,验证了服务网格能够在该系统中长期稳定运行,同时通过代理的方式简洁地解决了微服务化应用中服务发现、流量调度等服务治理问题。该系统对后续通信领域服务网络落地实施提供了一定的借鉴和参考。但是,本文所提方案应用于通信领域,推动5G业务快速发展,还需要进一步研究实践,特别是还需要在服务网格多集群、多网格、高可用以及大规模高可用集群环境等方面进行研究与探索。