您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
PPTV Docker集群的网络方案选型
 
作者:李周 来源;微信 发布于 2016-9-13
  3235  次浏览      24
 

术语

DCOS:(DataCenterOperating System,数据中心操作系统)是为整个数据中心提供分布式调度与协调功能,实现数据中心级弹性伸缩能力的软件堆栈。它将所有数据中心的资源当做一台大型计算机来调度,可以视作这个大型主机的操作系统。

IPAM:IP地址管理。这个IP地址管理并不是容器所特有的,传统的网络比如说DHCP其实也是一种IPAM,到了容器时代我们谈IPAM。主流的两种方法:基于CIDR的IP地址段分配地或者精确为每一个容器分配IP。但总之一旦形成一个容器主机集群之后,上面的容器都要给它分配一个全局唯一的IP地址,这就涉及到IPAM的话题

Overlay:在现有二层或三层网络之上再构建起来一个独立的网络。这个网络通常会有自己独立的IP地址空间、交换或者路由的实现。

VxLAN:由VMware、Cisco、RedHat等联合提出的一个解决方案。这个解决方案最主要是解决VLAN支持虚拟网络数量(4096)过少的问题。因为在公有云上每一个租户都有不同的VPC,4096明显不够用。就有了VxLAN,它可以支持1600万个虚拟网络,基本上公有云是够用的。

网桥Bridge:连接两个对等网络之间的网络设备,但在本文里指的是Linux Bridge。

BGP:主干网自治网络的路由协议。今天有了互联网,互联网由很多小的自治网络构成的,自治网络之间的三层路由是由BGP实现的。

1. PPTV OAK项目介绍

项目背景

PPTV作为国内视频领域的领先者,对于大规模流媒体的存储、处理、分发及应用,有着迫切的要求。容器技术及微服务模式的出现,使大规模的研发交付效率大为提高。本文介绍了PPTVOAK项目中Docker网络方案选型,以及对比了多种docker网络解决方案的特点后,最终结合PPTV网络架构的特点,选定了PPTV的Docker网络方案。 刚才有一个关键词叫OAK,OAK是橡树的英文单词。PPTV的OAK项目,基于Docker技术打造了DCOS。底层基于Mesos + Marathon 为核心,结合Docker和Nginx,在此基础上开发了DCOS管理控制台、权限管理模块、统一日志管理模块、IP池管理模块、存储管理模块,并与持续集成平台Jenkins集成,实现应用容器的创建、运行。OAK致力于快速部署、弹性扩缩容、助力敏捷开发、实现故障自愈以及提高资源利用率。

OAK建设历程

图 1 OAK建设历程 OAK功能框架

OAK功能框架

图2 OAK功能框架

2016年初的时候,我们开始在测试环境引入Docker。最早的计划是将PPTV的所有开发测试环境都迁移到容器里,考虑用户群(研发/测试人员)对Docker的命令行操作不熟悉,如果我们直接把Docker底层的管理操作暴露给用户,他们的学习成本会很高。为此我们使用了Mesos+ Marathon,可以通过Marathon快速创建容器,实现容器故障自动恢复。而实际上用户对于容器的操作和原理完全不关心,他们只关心如何可以快速、简单的构建一个开发或者测试环境。Marathon对于用户来说还是过于生疏。为了让用户能更容易接受Docker,我们将容器的创建与Jenkins平台结合。Jenkins是开发、测试人员比较熟悉的平台。我们在Jenkins的编译job中,把编译出来的应用包保存到一台集中的服务器上,同时调用Marathon的API创建一个与之对应的APP。这个APP会通过Marathon的uri参数把编译好的应用包挂载到容器中,实现应用自动部署。

到了这里,还存在一个问题,用户要怎么访问已经部署好的应用?容器里的网络默认用是一个私网的IP,此IP与容器所在宿主机上的Docker0网卡做了桥接,是不能跟外界通信。所以Marathon在创建容器的时候,通过NAT将容器服务端口映射到宿主机的一个随机端口上。也就是说,每一次容器重启之后,对应的服务地址是会动态变化的。为此,我们引入了consul实现服务注册和服务发现。每次容器服务地址变化时,将其更新到nginx反向代理的记录中。同时,,应用的域名解析到nginx上。用户访问应用域名的时候,nginx会将请求转发到具体的容器里。到此为止,用户已经可以通过Jenkins“一键”生成运行环境。

OAK架构图

图3 OAK架构图

2016年6月的时候,PPTV已经有80%以上的应用将测试环境迁移到了docker中,所以我们也开始将目标转移到了生产环境上。与测试环境不同,PPTV的生产环境网络流量很大(以视频播放为主),所以对网络性能要求非常严格。Docker默认的bridge模式无法满足。另外,生产环境是运维在管理。运维人员希望像管理虚拟机一样管理容器,希望容器有自己的IP,通过这个IP SSH登录到这个容器里,他可以查日志,监控,同步配置,或做一些其他的操作。到了这里,就对容器的网络有了更高的要求,除了性能,还需要独立IP,docker集群之间的容器要互通,容器还需要和传统环境的网络打通,能和传统环境里的应用IP通讯。

对Docker了解比较早同学应该会清楚。在Docker早期,还有Mesos+Marathon框架早期,是没法满足容器独立IP的需求的。一直到2015年的11月,Docker1.9发布,正式支持overlay网络,支持跨主机网络模块的通讯。

2. Docker网络方案对比

早期的容器网络

早期的容器网络,就是主机内部的网络,想要把服务暴露出去需要通过iptables做端口映射。这是属于“远古时代”的东西,很难被企业使用。

图4 早期的容器网络

Docker早期的4种网络模式:

Bridge模式:默认模式,为容器分配namespace、网卡和IP等,并连接到宿主机的虚拟网桥(docker0)

HOST模式:使用宿主机namespace、IP和端口

Container模式:使用已经存在容器的namespace、IP和端口

None模式:容器拥有自己的namespace,需要另外添加网卡、配置IP等

Docker overlay网络

图 5 Docker overlay网络

Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发,而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制,支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。

在Docker的1.9中版本中正式加入了Overlay网络的支持。

Flannel容器网络

图 6 Flannel容器网络

Flannel是由CoreOS主导的解决方案。Flannel为每一个主机的Dockerdaemon分配一个IP段,通过etcd维护一个跨主机的路由表,容器之间IP是可以互相连通的,当两个跨主机的容器要通信的时候。会在主机上修改数据包的header,修改目的地址和源地址,经过路由表发送到目标主机后解包。封包的方式,可以支持udp、vxlan、host-gw等,但是如果一个容器要暴露服务,还是需要映射IP到主机侧的。

Calico 网络方案


图 7 calico网络

Calico是个年轻的项目,基于BGP协议.完全通过三层路由实现,对网络不熟悉的同学可能都没有听说过。Calico的目标很大,可以应用在虚机,物理机,容器环境中。在Calico运行的主机上可以看到大量由linux路由组成的路由表,这是calico通过自有组件动态生成和管理的。这种实现并没有使用隧道,没有NAT,导致没有性能的损耗,性能很好,从技术上来看是一种很优越的方案。这样做的好处在于,容器的IP可以直接对外部访问,可以直接分配到业务IP,而且如果网络设备支持BGP的话,可以用它实现大规模的容器网络。但BGP带给它的好处的同时也带给他的劣势,BGP协议在企业内部还很少被接受,企业网管不太愿意在跨网络的路由器上开启BGP协议

方案对比小结 简单总结一下上边提到的几种网络方案,不外乎出自两个技术流派,隧道方案和路由方案。

隧道方案

比如Flannel的VxLan。特点是对底层的网络没有过高的要求,一般来说只要是三层可达就可以,只要是在一个三层可达网络里,就能构建出一个基于隧道的容器网络。问题也很明显,一个大家共识是随着节点规模的增长复杂度会提升,而且出了网络问题跟踪起来比较麻烦,大规模集群情况下这是需要考虑的一个点。

路由方案

路由技术从三层实现跨主机容器互通,没有NAT,效率比较高,和目前的网络能够融合在一起,每一个容器都可以像虚拟机一样分配一个业务的IP。但路由网络也有问题,路由网络对现有网络设备影响比较大,路由器的路由表应该有空间限制一般是两三万条。而容器的大部分应用场景是运行微服务,数量集很大。如果几万新的容器IP冲击到路由表里,导致下层的物理设备没办法承受;而且每一个容器都分配一个业务IP,业务IP消耗会很快。

3.PPTV Docker网络解决方案

对比了几种解决方案之后,结合PPTV的实际情况:

1.网络组人力不足以维护一个Overlay网络,Overlay网络出问题排查复杂,会出现失控的状态。

2.隧道技术影响性能,不能满足生产环境对网络性能的要求。

3.开启bgp对现有网络改动太大,无法接受。

4.运维组同学希望能通过网络桥接的方案解决容器网络。

容器网络桥接

最终,我们的解决方案,基于docker的bridge模式,将默认的docker bridge网桥替换为linuxbridge,把linuxbridge网段的ip加入到容器里,实现容器与传统环境应用的互通。

实现思路很简洁清晰,现在有一个Mesos主机

1.首先会在该主机上添加一个linux bridge,把主机网卡,可以是物理机的,也可以是虚拟机的,把这个网卡加入bridge里面,bridge配上网卡原本的管理IP。

2.创建一个新的docker bridge网络,指定bridge子网,并将该网络的网桥绑定到上一步创建的网桥上。

3.容器启动时候,指定容器网络为第二步中创建的bridge网络,同时为容器指定一个该网络子网内的IP。容器启动后网络IP默认即可与外界互通。

这里要注意的是第二步,我们的同学在研究这个方案的时候绕了一个很大的圈子,因为docker容器使用dockerbridge网络模式的时候,在容器启动时会默认把容器的网关指向到宿主机上的网桥IP,即linux bridge的IP,而这个IP并不是该网段的网关。所以我们需要在容器启动的时候将容器网关指向到实际的网关地址,而解决这个问题的方法在docker官方文档中并没有提到,我们最终是在一个issue里找到了解决办法。

链接在此 https://github.com/docker/docker/issues/20758

给个简单的例子

docker network create --gateway10.199.45.200 --subnet 10.199.45.0/24 -o

com.docker.network.bridge.name=br-oak--aux-address "DefaultGatewayIPv4=10.199.45.1" oak-net

关键参数: --aux-address"DefaultGatewayIPv4=10.199.45.1"

以上边的命令为例,该命令中创建了一个dockerbridge网络,并与docker所在主机的br-oak网桥做桥接,该网络的使用了10.199.45.0/24这个子网,同时通过 --aux-

address"DefaultGatewayIPv4=10.199.45.1" 这个参数将容器启动时的网关指向到10.199.45.1

通过网桥的方式解决容器网络有两个问题:

1.linux bridge 只能添加跟slavehost 同一个vlan的IP,也就是说容器IP必须要和宿主机在同一vlan下,这在一定程度上就限制了容器跨宿主机漂移的范围。

不过这个问题在PPTV的生产环境中天然不存在,因为我们的生产环境中,每个数据中心的主机都在一个很大的子网内,基本能满足容器在整个数据中心的任意节点下漂移。

2.要让容器IP在不同的宿主机上漂移,宿主机的docker网络需要使用同一个CIDR,也就是各宿主机的容器使用同一个网段。而不同宿主机的使用同一个容器网段就会涉及到IPAM的问题,因为宿主机的docker daemon只知道他本机上的容器使用了哪些IP,而这些IP在其他宿主机上有没有被使用,是不知道的。

在默认的docker bridge中,因为这些ip不会直接与外部通信,所以容器使用相同IP也不会有问题,但是当容器网络通过linux bridge打通以后,所有容器都是2层互通的,也就是会出现IP冲突的问题。

为了解决上边提到的问题,实现全局的IP管控,我们开发了IP池管理平台,实现对容器IP的分配管理。由这个平台管理的IP有三种状态:

1.未分配给应用

2.已非配给应用并且在使用中

3.已分配给应用但是当前未使用

管理平台以marathon上的app信息作为数据源,定期去调用marathon的API更新IP列表。当我们要在marathon上创建一个使用固定IP的容器时,首先会请求IP池管理平台的IP分配接口,请求的时候把app id发给分配接口,管理平台根据appid 判断这个应用是否是新应用,如果是新应用则从IP池中返回一个未使用的IP,并将此IP与应用关联。如果是已经存在的应用则分配已关联的IP。IP与应用关联之后,此IP就不会再分配给其他应用,除非IP池已经没有可用IP,这样做是为了防止应用如果重启或者重新构建的时候,IP有可能会被其他在同一时间启动的实例使用掉的风险。

IP池管理模块分配IP的流程图大致如下:

图 8 ip分配流程图

后续工作

网络方案搞定,固定IP搞定。我们要做的还有很多。

通过网桥的方式、解决了容器网络的问题,我们接下来还要面临其他的问题。

首当其冲的就是原先的服务自动注册、自动发现,不再适应了。因为原先的方案是基于NAT的模式做的,而现在实现了独立IP的功能。我们需要将现有的平台与PPTV内部的DNS做自动化对接,每当有容器创建和生成时,都会自动对容器的IP做DNS解析。

另外一个问题是负载均衡,PPTV的负载均衡基本都是通过LVS + nginx实现的,但对于后台的容器应用来说,每次扩容和缩容、或者创建新的应用,负载均衡的后端配置也是需要自动更新的。

对这篇文章你有什么想法和观点?欢迎在后台给我们留言

   
3235 次浏览       24
 
相关文章

云计算的架构
对云计算服务模型
云计算核心技术剖析
了解云计算的漏洞
 
相关文档

云计算简介
云计算简介与云安全
下一代网络计算--云计算
软浅析云计算
 
相关课程

云计算原理与应用
云计算应用与开发
CMMI体系与实践
基于CMMI标准的软件质量保证
最新活动计划
软件架构设计方法、案例与实践 8-23[特惠]
Linux内核编程及设备驱动 8-15[北京]
Python、数据分析与机器学习 8-23[特惠]
嵌入式软件架构设计 8-22[线上]
QT应用开发 9-5[北京]

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件的思考
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS
更多...   
相关培训课程

云计算原理与应用
Windows Azure 云计算应用

摩托罗拉 云平台的构建与应用
通用公司GE Docker原理与实践
某研发中心 Openstack实践
知名电子公司 云平台架构与应用
某电力行业 基于云平台构建云服务
云计算与Windows Azure培训
北京 云计算原理与应用