PPTV Docker集群的网络方案选型

 原作者:李周     转载来源:http://dockone.io/article/1673

 

PPTV Docker集群的网络方案选型

 

作者介绍:李周,现PPTVDCOS技术主要负责人。专注于Docker网络解决方案、容器监控、DevOps。目前主要研究方向是容器网络改造、多套测试环境隔离、容器深度监控。之前在中小创业公司长期负责客户现场实施工作;积累了大量关于网络、监控、权限认证、大数据、Oracle、中间件等经验;擅长linux系统和网络的各种操作,同时也喜欢研究各种新兴技术。

 

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.png


图 1 OAK建设历程

OAK功能框架

2副本.jpg


图 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副本.jpg


图 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网络,支持跨主机网络模块的通讯。

Docker网络方案对比

早期的容器网络

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

4.jpg


图 4 早期的容器网络

Docker早期的4种网络模式:

  1. Bridge模式:默认模式,为容器分配Namespace、网卡和IP等,并连接到宿主机的虚拟网桥(docker0)
  2. HOST模式:使用宿主机Namespace、IP和端口
  3. Container模式:使用已经存在容器的Namespace、IP和端口
  4. None模式:容器拥有自己的Namespace,需要另外添加网卡、配置IP等

 

Docker Overlay网络

5.jpg


图 5 Docker overlay网络

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

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

Flannel容器网络

6.jpg


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

Calico 网络方案

7副本.jpg


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

方案对比小结

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

  • 隧道方案
    比如Flannel的VxLan。特点是对底层的网络没有过高的要求,一般来说只要是三层可达就可以,只要是在一个三层可达网络里,就能构建出一个基于隧道的容器网络。问题也很明显,一个大家共识是随着节点规模的增长复杂度会提升,而且出了网络问题跟踪起来比较麻烦,大规模集群情况下这是需要考虑的一个点。
  • 路由方案
    路由技术从三层实现跨主机容器互通,没有NAT,效率比较高,和目前的网络能够融合在一起,每一个容器都可以像虚拟机一样分配一个业务的IP。但路由网络也有问题,路由网络对现有网络设备影响比较大,路由器的路由表应该有空间限制一般是两三万条。而容器的大部分应用场景是运行微服务,数量集很大。如果几万新的容器IP冲击到路由表里,导致下层的物理设备没办法承受;而且每一个容器都分配一个业务IP,业务IP消耗会很快。

 

PPTV Docker网络解决方案

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

  1. 网络组人力不足以维护一个Overlay网络,Overlay网络出问题排查复杂,会出现失控的状态。
  2. 隧道技术影响性能,不能满足生产环境对网络性能的要求。
  3. 开启bgp对现有网络改动太大,无法接受。
  4. 运维组同学希望能通过网络桥接的方案解决容器网络。

 

容器网络桥接

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

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

  1. 首先会在该主机上添加一个Linux bridge,把主机网卡,可以是物理机的,也可以是虚拟机的,把这个网卡加入bridge里面,bridge配上网卡原本的管理IP。
  2. 创建一个新的Docker bridge网络,指定bridge子网,并将该网络的网桥绑定到上一步创建的网桥上。
  3. 容器启动时候,指定容器网络为第二步中创建的bridge网络,同时为容器指定一个该网络子网内的IP。容器启动后网络IP默认即可与外界互通。


这里要注意的是第二步,我们的同学在研究这个方案的时候绕了一个很大的圈子,因为Docker容器使用Docker bridge网络模式的时候,在容器启动时会默认把容器的网关指向到宿主机上的网桥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"

以上边的命令为例,该命令中创建了一个Docker bridge网络,并与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发给分配接口,管理平台根据APP ID判断这个应用是否是新应用,如果是新应用则从IP池中返回一个未使用的IP,并将此IP与应用关联。如果是已经存在的应用则分配已关联的IP。IP与应用关联之后,此IP就不会再分配给其他应用,除非IP池已经没有可用IP,这样做是为了防止应用如果重启或者重新构建的时候,IP有可能会被其他在同一时间启动的实例使用掉的风险。

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

8.png


图 8 IP分配流程图

后续工作

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

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

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

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



原文链接:PPTV Docker集群的网络方案选型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值