同程容器云平台网络方案演进

本文讲的是同程容器云平台网络方案演进【编者的话】同程旅游PaaS平台是从2014年开始搭建的,到现在已经持续发展了三个年头。规模从原来的几百个容器到现在上万个容器。在容器调度上从原来的手动操作到现在的自动伸缩与扩容,在宿主机部署密度上从原来的十几个容器到现在上百个容器……我们的PaaS云平台在三年间进行了3次大版本的迭代。本文主要介绍同程旅游PaaS云平台在持续集成和持续部署方面,基于Docker对网络方案的选型及应用,以及随着业务需求的增加而经历的网络方案变更过程。

【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

系统的初始形态

PaaS平台最初是基于Swarm搭建的,Swarm是Docker公司推出的一套容器调度平台。它的特点是简单易用,部署方便,学习成本低,因为它所有的命令和Docker命令基本上是一致的。容器有4种网络模式Bridge、Host、Container以及None ,开始我们使用的网络方案是Host模式,这种模式下,容器没有独立的IP网络栈,它共用了宿主机的IP地址。为了防止端口冲突,应用对外暴露服务的时候,需要指定端口,并且这个端口在同一宿主机上唯一(不然会冲突),然后再对接负载均衡器,这样就打通了整个网络链路。整个架构非常简洁,对于当时每天几十个容器以及无状态的应用,是能够完全满足需要的。

网络访问流程如下所示:

后来随着业务的发展,各种业务也慢慢的容器化,比如说Redis、Hadoop、Database、中间件等等。Host模式越来越显得力不从心,最严重的情况是很多应用没办法往上部署。举个例子来说,像Redis应用,它主要功能是做缓存,在高并发的情况下,一个Redis容器能把网络跑满,如果同一台宿主机上还有其它容器,这就会导致其它容器无法正常对外提供服务。像Database服务,为了做HA,需要容器拥有独立的网络,在迁移的时候保持IP不变。

但在Host模型下,容器网络依赖宿主机网络,容器对外访问需要通过宿主机IP加容器唯一端口,当容器发生迁移的时候,访问容器的方式(IP:Port)也要跟着改变,无法满足用户在平台外部需要直接使用IP访问的需求。为了解决此类问题,急需对容器进行网络隔离,让每个容器拥有独立IP。

基于Public IP的网络订制

为了满足业务需求,开始研究如何使容器实例以Public IP方式供用户使用。首先什么是Public IP,Public IP就是让容器拥有一个独立的网络协议栈,有一个独立的IP地址。用户可以直接通过这个独立的IP地址访问应用,这样可以方便地解决端口冲突问题。有了这个目标以后,接下来就对目前现有的Docker网络方案进行调研评估。首先简单介绍下现有的容器网络方案,网上也看了很多对比,对于各方案的优缺点这里也做一个简单的总结。

隧道方案

其典型的代表是:
  • Weave,UDP广播,本机建立新的BR,通过PCAP互通。
  • Open vSwitch(OVS),基于VxLAN和GRE协议,但是性能方面损失比较严重。
  • Flannel,UDP广播,VxLan。

隧道方案在IaaS层的网络中应用也比较多,大家共识是随着节点规模的增长复杂度会提升,而且出了网络问题跟踪起来比较麻烦,大规模集群情况下这是需要考虑的一个点。另外,由于隧道方案性能损失比较严重,所以隧道方案暂时不考虑使用。

路由方案

其比较典型的代表有:
  • Calico,基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较高。
  • Macvlan,从逻辑和Kernel层来看隔离性和性能最优的方案,基于二层隔离,所以需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。

路由方案一般是从3层或者2层实现隔离和跨主机容器互通的,出了问题也很容易排查。

在这里我们说一下Calico。

首先它既支持Docker的CNM网络模型也支持像Kubernetes主推的CNI网络模型。既有着不俗的性能表现,提供了很好的隔离性,而且还有不错的ACL控制能力。通过将整个互联网的可扩展IP网络原则压缩到数据中心级别,Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。这样保证最终所有的workload之间的数据流量都是通过IP路由的方式完成互联的。

此外,Calico基于iptables还提供了丰富而灵活的网络Policy,保证通过各个节点上的ACLs来提供Workload的多租户隔离、安全组以及其他可达性限制等功能。

Calico 架构如下图所示:

对于Calico方案,我们也做了一些测试,首先它的网络转性能非常高,接近原生物理网卡的性能。但Calico依赖BGP协议,需要根据需要,频繁变更物理路由器的配置。对于传统物理网络有一定的侵入性,为了兼容以往的网络架构只能放弃。

Vlan方案

其比较典型的代表有:
  • Contiv netplugin
  • Pipework

这里我们着重讲一下Contiv。

Contiv是Cisco开源出来的针对容器的基础架构,主要功能是提供基于Policy的网络和存储管理,是面向微服务的一种新基架,同时它又支持CNM以及CNI网络模型。Contiv能够和主流的容器编排系统整合,包括:Docker Swarm、Kubernetes、Mesos and Nomad。

如上图所示,Contiv比较“诱人”的一点就是,它的网络管理能力,既有L2(VLAN)、L3(BGP),又有 Overlay(VxLAN),而且还能对接Cisco自家的 SDN 产品 ACI。可以说有了它就可以无视底层的网络基础架构,向上层容器提供一致的虚拟网络了。

最主要的一点是,既满足了业务场景,又兼容了以往的网络架构。在转发性能上,它能达到物理网卡95%的性能。在高并发的场景下,OVS可能会消耗一部分CPU性能。对于这方面后期打算通过DPDK来做改善。另外,Contiv netmaster节点Down了以后不会造成网络中断,可以降低风险。还有一个优点是基于OVS可以灵活地做Policy/ACL/Qos监控等等,最终选择使用Contiv netplugin。

接下来我们说一下Contiv Netplugin在公司的落地情况。

首先根据实际网络访问描述下Contiv在PaaS平台整体部署结构:

目前我们通过Mesos + Marathon实现了容器的动态扩容以及动态负载,能够根据业务负载快速响应,做到自动伸缩,下面我们介绍一下网络模块Contiv。

Contiv主要包含3部分:
  1. netctl客户端主要用来发送命令到Contiv Netmaster;
  2. Netmaster服务端用来管理所有的Netplugin,以及提供IP地址分配IPMI功能;
  3. Netplugin插件跑在每个swarm node节点上,接收Netmaster指令控制OVS实现路由转发功能。

Contiv带来的方便是用户可以根据实例IP直接进行访问,可以借助ovs做很多策略,以及监控等,Contiv Netplugin特性主要有以下几点:
  1. 多租户网络混部在同一台主机上;
  2. 集成现有SDN方案;
  3. 能够和非容器环境兼容协作,不依赖物理网络具体细节;
  4. 即时生效的容器网络Policy/ACL/QoS规则。

可以说Contiv有很多丰富的特性,能够满足大部分业务场景,但有些场景目前Contiv还无法支持需要做二次开发,比如说应用容器IP固定,流量监控等。接下来讲一下我们是如何基于Contiv做IP持久化的。

大家都知道,Docker容器网络模型使用的是CNM(Container Network Model),这的底层是通过Libnetwork实现的,只要符合这个模型的网络接口就能被用于容器之间通信,而通信的过程和细节可以完全由网络接口来实现。

  • Sandbox:对应一个容器中的网络环境,包括相应的网卡配置、路由表、DNS配置等。CNM很形象的将它表示为网络的『沙盒』,因为这样的网络环境是随着容器的创建而创建,又随着容器销毁而不复存在的。沙盒的实现可以是Linux Network Namespace、FreeBSD Jail之类的概念,并包含连接多个网络的Endpoint;
  • Endpoint:实际上就是一个容器中的虚拟网卡,在容器中会显示为eth0、eth1依次类推。它可以是veth对,或者Open vSwitch的internal port。一个Endpoint只能属于一个沙盒;
  • Network:指的是一个能够相互通信的容器网络,加入了同一个网络的容器直接可以直接通过对方的名字相互连接。它的实体本质上是主机上的虚拟网卡或网桥。

在CNM模型下,容器需要先通过IPMI获取IP,然后再创建Endpoint。我们的做法是,在启动容器之前,先调用Contiv rest API获取IP,Contiv Netmaster收到allocate ip的请求以后,将分配的IP保留起来,接下来在创建容器的时候指定所获取的IP,Netmaster收到创建Endpoint的请求将,保留的IP分配给容器,这样就做到了IP持久化。

创建容器的时序图如下:

网络监控

在网络流量监控方面,我们通过使用OVS的sFlow来抓取宿主机上所有的网络流量,然后自开发了一个简单的sFlow Collecter,服务器收到sFlow的数据包进行解析,筛选出关键数据,丢到Redis(这里的Redis是做来做缓存的作用)。然后再通过ELK集群定时从Redis拉取数据,进行汇总分析。前端通过调用ELK的API,得到所需要的监控数据。

通过对网络进行改造,目前已经将Redis,大数据,DB等诸多复杂的业务成功的跑在了容器中,切切实实解决了业务的痛点。随着PaaS云平台的演进,由Swarm切换为Mesos + Marathon,后期也会根据需求对Contiv不断优化。

三年多的持续迭代,只为达到更高的要求。
铭记初心,只为让更多人享受旅游的乐趣。


——王文建

原文链接:同程容器云平台网络方案演进(作者:王文建)

原文发布时间为:2017-07-26

本文作者:王文建

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:同程容器云平台网络方案演进

你可能感兴趣的:(同程容器云平台网络方案演进)