微服务应用平台的网络性能研究与优化
2018-05-30毕小红
毕小红,刘 渊,陈 飞
(江南大学 数字媒体学院,江苏 无锡 214122)
0 概述
目前,伴随着云计算服务的快速发展,百度、阿里巴巴、AWS、Google等互联网公司纷纷提供了云平台。然而,具有不易扩展、难以维护、升级风险大等特点的日益庞大的单体应用程序,其开发正变得越来越复杂,甚至在很大程度上已经不能适应当前快速变化的市场环境。分布式微服务软件架构模式以其模块化、可扩展、高可用的应用能力以及其促进组织架构融合方面的优势,可以显著地为企业增强市场竞争力。虽然微服务架构为应用程序的开发带来了诸多优势[1],但是其在构建、部署、维护分布式的微服务系统方面并不容易。而容器所提供的轻量级、面向应用的虚拟化运行环境为微服务提供了理想的载体。基于容器技术的容器集群部署管理工具Kubernetes极大地简化了容器化微服务创建、集成、部署、运维的整个流程,从而推动了微服务在云端的大规模使用。微服务由于独立进程众多、以容器为应用发布的载体,其架构下各组件的沟通、协调对网络有较高的要求。目前,基于Flannel的网络采用封包解包的NAT机制实现网络通信,导致了一定的网络性能消耗[2]。因此,需要研究更快速的Docker容器网络构建方式来满足容器集群对高带宽通信服务的要求。
本文将Calico网络与Kubernetes集成进行结合,建立微服务容器化应用平台,并基于该平台对Web微服务做进一步测试与评估。
1 研究现状
1.1 微服务与Docker
微服务架构[3]是一项在云中部署应用和服务的新技术,其以专注于单一责任与功能的小型功能区块为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关的API集相互通信。微服务采用分布式应用,应用程序按照功能被分解成一组松耦合的服务,这些程序可能运行在不同的设备上,每个服务实例一般都是一个进程。服务间的交互通过进程间的通信来实现,服务间的通信[4]意味着需要处理诸如网络延迟、不可靠的网络和应用层中的变化负载等相关问题。因此,保证网络的可靠性、合理地部署微服务是有效提高微服务性能的关键。
Docker[5-6]是一个基于Go语言开发、遵从Apache 2.0协议、轻量级虚拟化的容器管理引擎。Docker通过Namespace实现资源隔离,由于该特征,Docker容器在运行时没有类似于虚拟机的额外操作系统开销,从而提高了资源利用率,并且提升了诸如IO等方面的性能。Docker具有细粒度、松耦合、可移植、轻量级虚拟化的特点,与微服务的理念相辅相成,为微服务提供匹配的实现机制,可实质性地改变新型应用的开发和发布方式。
Docker利用传统客户端-服务器的架构模式[7],用户通过Docker客户端与Docker服务器进行通信,并将请求发送给服务器Docker守护进程,Docker守护进程执行一系列的容器管理命令。Docker总架构如图1所示。
图1 Docker总架构
1.2 容器网络发展现状与分析
Docker使用Namespace作为网络实现的基础。Namespace主要提供关于网络资源的隔离[8],包括网络设备、IPv4和IPv6协议栈、IP路由表、防火墙等所有网络资源[9]。在图1中,Docker通过driver模块创建执行环境。Libcontainer是一个独立的容器管理包,当需要为容器创建网络环境时,Network driver创建并配置Docker容器的网络环境,通过Libcontainer实现对容器的具体操作。目前,Docker总架构中网络部分已经被抽离出来,称之为Libnetwork[9]模块,Libnetwork定义一个容器网络模型,提供一个一致的编程接口和应用程序网络抽象,可以通过插件的形式给容器提供网络功能,也可以与第三方网络插件进行结合以满足开发者在各种场景下的需要。Libnetwork容器网络模型如图2所示。其中,网络Sandbox[10]代表容器的网络命名空间,包含容器的完整网络栈,不同的容器间可以完全隔离。Endpoint相当于一个容器接入网络的虚拟网卡。Network代表一组可以直接相互通信的容器集合。宿主机上同一网络的容器都通过Veth链接到该网络命名空间上。
图2 Libnetwork容器网络模型
Docker从其1.9版本开始,就实现了基于Libnetwork的多主机覆盖网络模式[11],其中包括bridge、host、null、remote、overlay、macvlan 6种网络驱动,bridge是Docker默认的网络驱动,Libnetwork的remote驱动定义了基本的创建网络、创建端口的接口,对应的REST Server实现了这些接口,并可以提供整套Docker网络。
随着Docker的迅速发展,越来越多的云计算厂商开始探索Docker在实际生产环境中的应用。由于Docker原生网络功能无法满足广大云计算厂商的要求,因此出现了大批第三方SDN解决方案,以弥补在部署大规模Docker集群时Docker网络性能低下、功能不足的缺陷。文献[12]针对Kubernetes设计了一个重载网络工具Flannel。文献[13]开发了跨宿主机的容器网络工具Weave和Calico跨主机网络插件等。文献[14]创建了一个虚拟网络,通过在容器中添加专用的虚拟网卡来搭建自己的网络,用以连接部署在多台主机上的Docker容器。基于Weave网络的容器如同被接入了同一个网络交换机,从而在不破坏Docker容器原有网络的同时,实现了跨主机通信。Weave能够穿透防火墙并运行在部分连接的网络上,此外,Weave的通信支持加密,因此,用户可以通过一个不受信任的网络连接到主机[15]。但是,从性能和使用角度来看,Weave也有较大的缺陷:Weave自定义容器数据包封包解包方式的传输效率较低,性能上的损失也较大,集群配置较复杂,需要通过Weave命令行来手工构建网络拓扑,这在大规模集群的情况下自动化程度较低。
Flannel是由CoreOS团队针对Kubernetes设计的一个重载网络工具,其目的在于帮助每一个使用Kubernetes的CoreOS主机构建一个完整的子网[16]。类似于Weave、Vxlan,Flannel提供了一个可配置的虚拟覆盖网络。Flannel以守护进程的形式运行,负责子网的分配,使用Etcd存储、交换网络配置、状态等信息,其网络架构如图3所示。
图3 Flannel网络架构
Flannel和Overlay方案均使用覆盖网络[17],尽管覆盖网络对底层网络依赖较少,配置相对简单,但是其网络封装是一种传输开销,对网络性能会有影响,不适用于对网络性能要求较高的生产场景,且由于对底层网络结构缺乏了解,因此覆盖网络无法做到真正有效地控制流量,这也会对网络性能产生影响[18]。
2 Calico网络与Kubernetes集成
Calico[19]是一个3层的数据中心网络方案,能够支持高效可控的虚拟机、容器、裸机间的通信,其基于BPG协议和Linux本身的路由转发机制,不依赖特殊硬件,没有使用NAT或Tunnel等技术。Calico没有使用重载网络,能够方便地部署在物理服务器、虚拟机(如OpenStack)及容器环境下。同时,其自带的基于Iptables的访问控制(ACL)管理组件,能够满足比较复杂的安全隔离需求。Calico为每个工作负载提供一个完全自动化的虚拟防火墙,以保护工作负载,并在该工作负载受损时保护其余应用程序。Calico能够自动将任何网络策略概念从编排环境映射到Calico网络环境[20]。
Calico使用与互联网相似的原则构建其高度可扩展的网络架构,并提供一个平面IP网络,可以在没有任何封装的情况下进行通信。此外,其网络架构还使用无状态IP-in-IP覆盖,可以路由已存在的覆盖网络数据包。基于Calico的容器网络实现3层隔离,有效避免了ARP风暴。此外,基于Iptable/Linux内核转发,有效提高了转发效率,降低了性能损耗。
Kubernetes是Google开发的集群管理系统平台,其在Docker技术的基础上被构建出来[21],为容器化的应用提供资源调度、部署运行、服务发现、灰度升级及在线升级等一系列功能。同时,Kubernetes还提供了完善的管理工具,可以进行管理开发、测试、监控的各个环节。因此,Kubernetes能够提供一个全新的基于容器技术的分布式架构解决方案。
Kubernetes的网络基于Docker设计,其模型的设计遵循以下原则:每个Pod都有一个独立的IP地址,所有的Pod都在一个可以连通的扁平网络空间中。运行在不同的基础设施节点上的Pod可以通过IP地址进行互相访问。同时,在Kubernetes集群的网络中,所有的容器都不用NAT的方式进行通信,所有节点都可以直接通信。在Kubernetes系统中,同一个Pod内的不同容器共享一个网络命名空间,同一个Pod内的容器可以通过本机连接另一容器的端口,且可以共享部分资源,通过共享资源,容器之间的相互通信可以更高效。Google公司设计的Kubernetes主要在云环境GCE中运行,在该环境下,Kubernetes无需第三方网络支持。但是,若脱离GCE环境运行Kubernetes与Docker集成平台,就需要网络插件的支持。目前,Kubernetes使用第三方支持的Flannel网络插件实现网络通信。
2.1 Calico网络架构
Calico网络架构及其核心组件如图4所示。Calico架构主要由Felix、Etcd、BGP 客户端、BIRD(路由反射器)4个核心组件构成。Felix运行在每台需要运行容器的节点上,负责配置路由及ACLs等信息来确保各终端的连通状态;Etcd是分布式键值存储,负责网络元数据的一致性,确保Calico网络状态的准确性;BGP客户端负责把Felix写入内核的路由信息并分发到当前Calico网络,确保节点间通信的有效性;BIRD(路由反射器)是在大规模部署时使用,其摒弃所有节点互联的网格模式,通过一个或多个BIRD(路由反射器)来完成集中式的路由分发。
图4 Calico网络架构
Calico网络在每一个节点利用Linux内核实现一个虚拟路由,以此负责数据的转发,每个虚拟路由通过BGP协议将自身运行的路由信息向整个Calico网络内传播,较小规模的应用部署可以直接互联,大规模应用下,可通过指定的BIRD(路由反射器)来完成通信。在Calico中,数据包有可能跨多个节点传输,但是无需对其中间节点进行配置。对于一个被送到容器的数据包,最后的一跳是从该容器的宿主到容器自身。此外,Calico基于Iptables还提供丰富而灵活的网络策略,通过各个节点上的访问控制(ACLs)来提供工作节点的多租户隔离、安全组以及其他可达性限制等功能。
2.2 基于Calico与Kubernetes集成的网络通信
本文设计的基于Calico网络与Kubernetes集成的网络通信架构模型如图5所示。其中,API是整个集群的核心,负责各个模块之间的通信。集群内部的功能模块通过API将信息存入Etcd,控制器、调度器通过API读取这些信息,从而实现各模块之间的信息交换。
图5 基于Calico与Kubernetes的网络通信架构
控制器作为集群内部的管理控制中心,主要负责管理Node、Pod副本、服务端点、命名空间、服务账号、资源定额等处于预期的工作状态。调度器的作用是实时监测集群中已调度的Pod及待调度的Pod,按照特定的调度算法和调度策略将其绑定到集群中的一个Node节点上,并将信息写入Etcd中。Kube-proxy通过Etcd客户端监测服务器和终端的变化,当新增服务时,服务处于监听状态,此时初始化Iptable规则。当新增终端endpoint时,注册endpoint以便负载均衡器选择。Node节点上的Kubelet周期性地向API报告自身的状态,API接受后将信息保存到Etcd中,并监测来自File、Etcd、Http的Pod配置信息,当配置发生变化时,Kubernetes把期望状态和当前运行状态进行同步。在Kubernetes集群中,每个工作节点上都会运行Kubelet以守护进程,Kubelet处理Master发布给本节点的任务。并用Pause容器为每个Pod创建容器。
Calico作为Kubernetes依赖的底层网络,在每个Node节点上构建虚拟路由,通过Calico虚拟路由可将本节点上在同一网段中的网络报文以原始的状态传递到目标容器中。该过程的实现无需如Flannel网络的叠加网络传递过程,从而可以大大降低网络性能损耗。
3 实验测试与结果分析
3.1 实验配置环境
本文实验的3个操作系统为Centos 7.0虚拟机,内存1 GB,CPU 1核,主频为2.6 GHz,IP地址分别为192.168.159.128(Kube-Master节点),192.168.159.129(Node节点),192.168.159.130(Node节点),其中,Master节点作为Kubernetes集群中的管理节点,2个Node节点作为Kubernetes集群中的工作节点。实验采用一个可访问的Etcd集群(192.168.159.128:2379),Calico使用其进行数据的存放和服务发现。此外,将3个节点上的Iptables INPUT策略设为ACCEPT,同时安装Docker,并设置Docker守护进程的启动,参数cluster-store为Etcd集群(192.168.159.128:2379)。分布式安装并配置Kubernetes容器编排系统,设置192.168.159.128主机为Kube-Master节点,其余2个主机为Kube-Node节点。在Node节点上安装Calico-cni插件,当Pod创建后,将该Pod添加到Calico网络。使用Calico进行网络的连接和IPAM的配置。代码如下所示。
{
“name”:“my_name”,
“type”:“Calico”,
“Kubernetes”:{
“k8s_api_root”:“http://192.168.159.128:8080”
}
“IPAM”:{
“type”:“Calico-IPAM”
}
}
Calico网络控制器运行在Kubernetes的Pod里,实现了多种网络策略的自定义。网络策略管理网络的连通性。网络策略通过Label标签筛选作用到每个Pod和服务上,同时需要网络插件配合实现网络策略。
Calico节点启动后会查询Etcd,其他Calico节点使用BGP协议建立连接。容器启动时,劫持相关Docker API并进行网络初始化。查询Etcd自动分配一个可用IP,创建一对Veth接口用于容器和主机间的通信,并在主机路由表添加指向该接口的路由。
3.2 Calico网络测试与结果分析
通过上述对Calico网络和其他各种网络的通信原理之间的比较,以及对Kubernetes网络原理进行的分析,理论上可以得出,基于Calico的Docker网络具有良好的网络性能,Calico网络与Kubernetes的集成设计具有可行性。本文在相同的测试环境下进一步对Docker容器在跨主机通信中不同的网络模式进行实验测试,通过实验分析Calico的网络性能。
Iperf3是一种开源的网络性能测试工具,可以测量最大TCP带宽,此外,其具有多种参数和UDP特性,可以报告带宽、延迟抖动和数据包丢失等数据。本文采用Iperf3测试容器带宽以得出平均网络传输速率。
3.2.1 网络测试方案
第2节详细叙述了Calico网络与Kubernetes集成的实现,本节在此基础上对该网络的性能进行针对性的测试,同时在相同环境下将其与其他多主机容器网络性能进行比较,构建Docker容器并测试不同容器间的通信质量。本文实验采用带宽性能指标来体现网络的传输速率与性能,实验测试方案如表1所示。
表1 网络测试方案
方案的设计主要针对微服务之间的通信模式,测试其网络速率。方案1针对单宿主机,在基于bridge、Weave、Flannel、Calico网络模式下,容器C1作为Iperf3服务器,容器C2作为Iperf3客户端,测试Docker容器的通信速率并进行比较。方案2测试容器跨主机通信的模式,当容器底层为overlay、Weave、Flannel、Calico与物理主机网络时,将通信速率进行比较。通过上述测试反映出容器网络在通信过程中的损耗。
上述方案对容器节点对进行了网络性能比较,本文进一步从微服务应用的角度考虑,增加Node节点,并在多容器节点的环境下测试Calico网络性能的变化。在待新增Node上部署好软件环境,并修改Kubernetes的配置文件,指定主节点IP地址和端口号,再启动该Node上的Kubelete和Kube-proxy服务,实现软件环境Node节点的扩展。最后,分别在容器节点数量为2、10、20、30、40、50、60、70、80、90、100时,测试网络速率的变化情况。
3.2.2 测试结果分析
针对表1中的2种方案进行TCP测试,多次测量容器在60 s内传输的数据信息量和带宽数据,结果如图6、图7所示。
图6 单宿主机不同网络模式下的带宽比较
图7 跨宿主机不同网络模式下的带宽比较
在多节点环境下,Calico的网络性能测试结果如图8所示。
图8 多节点下Calico网络性能
本文实验是在同一软、硬件环境配置的基础上进行的,由图6可以看出,单节点情况下各种网络的通信速率相差甚微,说明容器在同一宿主机中的网络传输损耗相对较少。因此,在微服务应用的部署方式上,可以考虑尽可能地将耦合度比较高的容器应用部署在同一台宿主机上,这样会大大提高微服务应用的效率。由图7可以看出,在进行跨主机通信时,基于Calico网络容器的传输速率非常接近于宿主机的传输速率,基于Weave、Flannel、overlay网络的容器在数据转发速率上,相对于物理网络损耗了约50%,其中Flannel网络带宽只占物理网络的10%左右。由图8可以看出,随着容器节点数的增加,网络性能有所下降,但是相对于单节点对下Flannel网络的性能,多节点下的Calico网络仍然具有很大的性能优势。因此,在大规模的微服务应用部署和调度上,基于Calico网络的容器在性能上具有明显的优势。
4 微服务应用的设计与实现
4.1 Web微服务应用设计
通过Docker容器的Calico网络与Kubernetes集成构建微服务应用的PaaS平台,本文通过设计Web微服务应用案例,进一步验证该平台的高可用性及强大的扩展能力。Web应用系统架构如图9所示。
图9 Web微服务应用系统架构
Web微服务应用系统是基于PHP+Redis 2层分布式架构的Web应用,通过Web读写分离的高可用集群进行部署。其中共有3个service和16个Pod节点,每个Pod中运行一个容器。主数据库Redis Pod运行Master-Redis数据库容器,用于Web应用进行“写”的操作,将“写”的内容保存在Redis-Master中;从数据库Redis Pod运行Redis-slave容器,同时采用5个Pod构建,用于前端Web读取数据,并与Master-Redis中数据保持同步。Frontend-Pod运行PHP Web服务,在网页上输入和输出内容,同时启动10个实例组成集群,实现客户端对网站访问的负载均衡。通过Kubectl客户端命令(Kubectl scale rc-replicas=x)改变replicas参数的值来增加Pod数量,通过命令Kubectl rolling-update -f xx.yaml来升级Pod中容器,实现应用容器的可扩展,最后,创建Redis-Master服务、Redis-slave服务和php-Frontend服务。
4.2 系统实现
系统实现硬件环境:采用VMware Workstation 10虚拟网卡,3台64位的Centos 7虚拟机,内存1 GB,Intel CPU 1核,主频为2.6 GHz。软件环境:操作系统 Liunx/amd 64,底层网络采用Calico v 1.0.2,高可用存储软件Etcd v 3.0.5,容器编排软件Kubernetes v 1.4,Docker容器v 1.12。
通过Makefile构建所需要的Redis容器和Web页面容器,上传至镜像仓库,配置服务及副本控制器的yaml文件,利用Kubernetes创建并启动容器。服务器通过Labels标签选择Pod对象实现负载均衡功能。设置NodePod参数映射物理机端口,提供服务器的对外访问。服务器之间通过Kubernetes系统中的DNS进行注册与发现,进而实现微服务之间的通信。系统搭建完成后,用户通过访问服务器地址以访问Web系统,其中系统内部Pod之间的相互通信通过查询服务器IP地址和端口号实现,客户端获得服务列表如表2所示。
表2 服务列表
利用Web压力测试工具测试整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时间,其中50%的用户响应时间小于1 043 ms,60%的用户响应时间小于1 147 ms,最大的响应时间小于8 785 ms。Web服务器每秒处理的请求数为87,相对基于Flannel网络的处理请求数目(63)提高了38%。实验结果表明,Web服务器处理并发请求时对网络的性能具有依赖性,本文对应用部署平台网络性能进行了优化,提高了微服务的应用能力,同时也验证了Kubernetes的高可用性与高效性。
5 结束语
本文研究基于Calico网络的容器化应用平台,提出实现微服务容器化应用的方案,实验结果表明,该方案能有效提高容器跨主机网络通信的性能,为Docker容器提供了丰富、灵活和安全的网络策略。此外,因为Calico网络易于部署,可扩展至数以万计的服务器和数以百万的工作负载,所以本文方案也为大规模分布式部署微服务应用提供了理想的网络解决途径。下一步将针对网络的规模和稳定性做深入探究。
[1] 郝庭毅,吴 恒,吴国全,等.面向微服务架构的容器级弹性资源供给方法[J].计算机研究与发展,2017,54(3):597-608.
[2] RAMALHO F,NETO A.Virtualization at the network edge:a performance comparison[C]//Proceedings of 2016 IEEE International Symposium on a World of Wireless,Mobile and Multimedia Networks.Washington D.C.,USA:IEEE Press,2016:1-6.
[3] YOUSIF M.Microservices[J].IEEE Cloud Computing,2016,3(5):4-5.
[4] BALALAIE A,HEYDARNOORI A,JAMSHIDI P.Microservices architecture enables DevOps:migration to a cloud-native architecture[J].IEEE Software,2016,33(3):42-52.
[5] 王 鹃,胡 威,张雨菡,等.基于Docker的可信容器[J].武汉大学学报(理学版),2017,63(2):15-25.
[6] BERNSTEIN D.Containers and cloud:from LXC to docker to Kubernetes[J].IEEE Cloud Computing,2014,1(3):81-84.
[7] 杨 鹏,马志程,彭 博,等.集成Docker容器的OpenStack云平台性能研究[J].计算机工程,2017,43(8):26-31.
[8] 齐 勇.基于docker的网络服务质量控制器的设计与实现[D].济南:山东大学,2015.
[9] Docker container networking[EB/OL].[2017-05-10].https://docs.docker.com/ engine/userguide/networking/.
[10] EDELMAN J.Docker networking[EB/OL].[2017-04-25].http://www.dasblinkenlichten.com/docker-networking-101-hostmode/.
[11] XIE Bin,SUN Guanyi,GUO Ma.Docker based overlay network performance evaluation in large scale streaming system[C]//Proceedings of 2016 IEEE Conference on Advanced Information Management,Communicates,Electronic and Automation Control.Washington D.C.,USA:IEEE Press,2016:366-369.
[12] 龚 正,吴治辉,叶伙荣,等.Kubernetes权威指南[M].北京:电子工业出版社,2016.
[13] Google.Calico documentation[EB/OL].[2017-05-10].http://docs.projectcalico.org/v2.0/introduction/.
[14] 冯明振.基于macvlan的Docker容器网络系统的设计与实现[D].杭州:浙江大学,2016.
[15] 王亚玲,李春阳,崔 蔚,等.基于Docker的PaaS平台建设[J].计算机系统应用,2016,25(3):72-77.
[16] DUSIA A,YANG Y,TAUFER M.Network quality of service in Docker containers[C]//Proceedings of 2015 IEEE International Conference on Cluster Computing.Washington D.C.,USA:IEEE Press,2015:527-528.
[17] 何震苇,严丽云,李慧云.基于开源PaaS技术的互联网业务平台自动部署方案[J].电信科学,2015,31(10):172-179.
[18] JARAMILLO D,NGUYEN D V,SMART R.Leveraging microservices architecture by using Docker technology[J].IEEE SoutheastCon,2016,16(5):1-5.
[19] CALINCIUC A,SPOIALA C C,TURCU C O,et al.OpenStack and Docker:building a high-performance IaaS platform for interactive social media applications[C]//Proceedings of 2016 International Conference on Develop-ment and Application Systems.Washington D.C.,USA:IEEE Press,2016:287-290.
[20] Google.Network policies[EB/OL].[2017-05-10].http://Kubernetes.kansea.com/docs/user-guide/networkpolicies.
[21] MEDEL V,RANA O,BAARESJ,et al.Adaptive appli-cation scheduling under interference in Kubernetes[C]//Proceedings of the 9th IEEE/ACM International Conference on Utility and Cloud Computing.Washington D.C.,USA:IEEE Press,2016:426-427.