专栏名称: vipdocker
VIPDOCKER关注Docker、Mesos等容器化技术
目录
相关文章推荐
51好读  ›  专栏  ›  vipdocker

容器网络方案Bridge/Vlan模式的演进

vipdocker  · 公众号  · 后端  · 2016-12-08 14:27

正文

感谢各位已经关注我的微信公众号(VIPDOCKER)的同学,正是你们的鼓励让我能继续坚持写下来,如果还没有关注,欢迎你的加入!新近公众被赋予了原创公众号权限,大家可以直接留言了,欢迎任何建议,谢谢!

容器网络背景


如果只是在一台机器上使用Docker,或许你基本不用关心网络配置,因为Docker Daemon默认模式还是比较友好的,直接帮你们生一个Bridge命名为Bridge0,这样你可以通过端口映射的模式或是主机模式就可以让容器与外部互联互通了,而不用使用任何网络工具(brctl, iptables)手工创建。但是如果将容器放到一个集群环境中(如使用Mesos或者K8S编排工具),这个网络问题就比较痛苦了。因为需要保证如何暴露容器给外部访问,同时又没有过多的额外性能开销,网络方案又是比较可控稳定,这成为了一个基于容器的PaaS平台的成功的关键因素。

我们的需求:独立IP

除了网络性能和网络稳定性的问题需要考量外,我们内部有个很重要的要求就是一定要确保每个容器获得一个独立的IP,并且确保每个容器间可以相互访问。因为我们有自己的基于RPC的服务化体系(有兴趣可以搜索我的分享《唯品会:分布式服务框架实践与容器化演进》),需要一个平面的通讯网络,并且关联系统如APM系统,都是依赖这个独立IP做分析的

网络方案选型

第一次做容器化的架构(半年前),选择网络方案的要点是简单和成熟的方案。网络选型主要有两个大方向,一个是物理机器方案即通过交换机的方式做方案如VLAN模式,VxLan模式等。另一个是软件方案SDN,如Overlay网络等。因为是我们第一次做容器方案,为了保险起见,我们更信任物理设备的方式,所以我们选择了VLAN的模式作为第一次选择,而VxLan对于物理设备有要求,先暂时放弃。不过如果有硬件基础的,则可以有限考虑VxLan方式

第一版的VLAN网络方案


对于使用VLAN的模式,一开始我们都没有找到合适的资料,都是自己摸索出来的,后来新版本的docker支持docker network命令后,这些就简单一些。而我们是无需用docker create network的。主要方案如下:


"vlan mode"

详细内容,参见我之前的文章《Docker的VLAN网络模式配置》,可以在我的公众号的Docker系列文章中找到。

第一版方案的缺陷

从第一版的方案上看,虽然简单而且也比较稳定,我们在生产上跑了4个多月了,没有出现过问题。但是从管理监控的角度看,这个方案还是有明显的缺陷,只是在容器规模还没有达到一定的量的时候,这个缺陷是可以忍受的。但是对于这些缺陷,我们在做下一版的平台的时候就需要寻找合适的解决方案了。

这些缺陷主要是:

第二版的VLAN网络方案


第二版网络需求

动态IP管理方案

对于要使容器有独立的IP,又要使每个主机的IP的管理动态化,那么就需要将IP分配放在docker daemon/mesos+marathon的外部管理,通过插件plugin的方式集成。目前可选的方式是docker daemon的IPAM接口,或者是mesos slave的IPAM接口。虽然都叫IPAM,但是他们基于的机制不同。

Docker的IPAM(IP address management)是在Docker daemon的CNM(Container Network Model)机制下的IP管理驱动。CNM的设计模型,可以参考 CNM Design 。 Docker IPAM可以参考 Docker IPAM

而对于Mesos则是遵循CNI的规范。CNI规范可以参看 CNI Spec

不过对于只需要动态管理IP地址的话,基于任何一种IPAM的接口都是可以的。所以我们经过老肖(@熟人云)介绍,参考了Talking Data公司的 Shrike 来做动态的IP管理。Shrike是基于Docker deamon的IPAM的方案, 所以只能用于基于Docker容器的方案,如果是用mesos unified container,则需要自己去改造成对接CNI的IPAM的接口。

虽然Shrike比较简单,但是目前Shrike有些局限,所以我们需要在上面做一些改造,以支持后续的扩展。主要包括:

  • Shrike 这个进程如果意外退出,IP的释放消息( Release address )未被处理,就会造成IP被永久占用。目前我们的思路是,在 shrike 启动的时候主动去扫描本机的docker container,然后和etcd上的数据比对,如果有IP没有被释放,则主动清理。

  • 对于上面这个约束,我们需要改造Etcd中数据结构,以支持将主机IP存入etcd中,便于后续的主动清理。同时改造etcd数据结构也是为了限流使用。

网络限流方案

对于网络限流,一开始的思路是想利用mesos+marathon方案的自定义资源管理的方式,但是因为marathon迟迟不支持自定义资源调度,所以这个方式暂时放下了。希望用这样的方式管理的原因是想把网卡变成类似cpu/mem的资源同等对待,只要分配了带宽给容器的综合超过一定数就不再这个主机启动容器了。Mesos的自定义资源参考 mesos attr resource

在这里还是要吐槽一下 Marathon ,开发的进度和 Mesos 太不一致了,希望Mesosphere的同学好好push一下。

这条路暂时走不通,那么在用 Shrike 做动态IP分配的时候,我想能不能在IP动态分配的时候就同时做了这个容器的带宽限制呢?所以就有了以下方案


"shrike"

主要的流程如下:

  • 在Shrike中增加一个Throttling的模块,Shrike动态分配IP后发送一条消息给这个Throttlilng模块,包含容器ip信息(可惜没有容器的id)

  • Throttling模块收到消息后,调用docker daemon接口查询这个ip对应的容器在主机的网络名称(这里可以用unix socket接口或者http接口,因为是本机调用)

  • 查询这个容器的环境变量如net_in, net_out的值(这个目前是启动容器的时候配置上去的)

  • 通过调用linux下的wondershape工具来对容器进行限制带宽

这个方案还有后续几个事宜我们还没有处理的:







请到「今天看啥」查看全文