Docker跨主机通信解决方案探讨

发表于:2018-5-24 09:20  作者:佚名   来源:IT解忧知识库

字体: | 上一篇 | 下一篇 |我要投稿 | 推荐标签: Docker 软件开发 云计算

  背景
  Docker 容器技术正在被企业应用在越来越多的领域中,比如快速部署环境、简化基础设施的配置流程等等。当你开始在真实的生产环境使用 Docker容器去部署应用系统时,你可能需要用到多个容器部署一套复杂的多层应用系统,其中每个容器部署一个特定的应用系统。此时可能就会遇到如下问题:有多台宿主机,我们事先不知道会在哪台宿主机上创建容器,如何保证在这些宿主机上创建的容器们可以互相联通?
  本文介绍了Docker容器平台中的跨主机通信方案,包括libnetwork,calico,weave,flannel,Kuryr,并对各个方案的原理进行阐述,最后对Calico,Weave,Flannel,overlay(libnetwork)四种常见网络模式进行了对比,为测试和生产环境的方案选型提供参考。
  一、Libnetwork
  Libnetwork是从1.6版本开始将docker网络部分抽离出来成为一个单独的项目,libnetwork 的目标是定义一个健壮的容器网络模型(Container Network Model),提供一个一致的编程接口和应用程序的网络抽象。从1.9版本开始,docker已经实现了基于Libnetwork和libkv库的网络模式—多主机的Overlay网络。
  1、模型
  libnetwork 引入了容器网络模型(CNM)的概念,CNM 定义了三个新的术语,分别是网络沙箱、Endpoint、Network。
  1)Sandbox。Sandbox包含容器网络栈的配置,包括容器接口,路由表,DNS配置等的管理。 linux network namespace是常见的一种sandbox的实现。Sandbox中包含众多网络中的若干Endpoint。
  2)Endpoint。Neutron中和Endpoint相对的概念应该是VNIC,也就是虚拟机的虚拟网卡(也可以看成是VIF)。Endpoint的常见实现包括veth pair、Openvswitch的internal port。当Sandbox要和外界通信的时候就是通过Endpoint连接到外界的,最简单的情况就是连接到一个Bridge上。
  3)Network。Network是一组可以互相通信的Endpoints集合,常见的实现包括linux bridge,vlan等。libnetwork中的Network大家可以认为是Neutron中的network即可,更加贴切点的话可以认为是Neutron中的一个拥有一个subnet的network。
  2、结构体对象
  下面我们看下libnetwork为了对外提供这几个概念而暴露的编程结构体:
  1)NetworkController。用于获取一个控制器,可以认为通过这个控制器可以对接下来的所有网络操作进行操作。Neutron中并没有这么一个概念,因为Neutron中的网络是由agent通过轮询或者消息的方式来间接操作的,而不是由用户使用docker命令直接在本机进行操作。
  2)Driver。这里的Driver类似于Neutron中的core_plugin或者是ml2下的各种driver,表示的是底层网络的实现方法。比如有bridge的driver,也有基于vxlan的overlay的driver等等。这个概念和Neutron中的driver概念基本上是一样的。
  3)Network。这里的Network结构体就是对应的上面CNM中的Network,表示建立了一个网络。通过这个结构体可以对建立的网络进行操作。
  4)Endpoint。这里的Endpoint结构体就是对应上面CNM中的Endpoint,表示建立了一个VNIC或者是VIF。通过这个结构体可以对Endpoint进行操作。
  5)Sandbox。这里的Sandbox结构体就是对应上面CNM中的Sandbox,表示建立了一个独立的名字空间。可以类比Nova的虚拟机或者是Kubernetes的Pod,亦或是独立的Docker容器。
  3、API使用步骤
  接着我们看下一般使用libnetwork的方法,具体的步骤一般是下面这样的:
  (1)获取一个NetworkController对象用于进行下面的操作。获取对象的时候指定Driver。
  (2)通过NetworkController对象的NewNetwork()建立一个网络。这里最简单的理解就是现在我们有了一个bridge了。
  (3)通过网络的CreateEndpoint()在这个网络上建立Endpoint。这里最简单的理解就是每建立一个Endpoint,我们上面建立的bridge上就会多出一个VIF口等着虚拟机或者Sandbox连上来。假设这里使用的是veth,则veth的一头目前接在了bridge中,另一头还暴露在外面。
  (4) 调用上面建立的Endpoint的Join方法,提供容器信息,于是libnetwork的代码就会建立一个Sandbox对象(一般这里的Sandbox就是容器的namespace,所以不会重复建立),然后将第三步建立的veth的一头接入到这个Sandbox中,也就是将其放到Sandbox的namespace中。
  (5)当Sandbox的生命周期结束时,调用Endpoint的Leave方法使其从这个Network中解绑。简单的说就是将veth从Sandbox的namespace中拿出来回到物理机上。
  (6)如果一个Endpoint无用了,则可以调用Delete方法删除。
  (7)如果一个Network无用了,则可以调用Delete方法删除。
  4、driver类型
  包含四种类型的driver包:
  Host:主机网络,只用这种网络的容器会使用主机的网络,这种网络对外界是完全开放的,能够访问到主机,就能访问到容器。
  Null:无网络,使用这种网络的容器会完全隔离。
  Bridge:桥接网络,除非创建容器的时候指定网络,不然容器就会默认的使用桥接网络。属于这个网络的容器之间可以相互通信,不过外界想要访问到这个网络的容器呢,需使用桥接网络,有点像主机和容器之间的一座桥,对容器有一点隔离作用。
  Overlay:Overlay驱动可以实现通过vxlan等重叠网络封装技术跨越多个主机的网络,目前Docker已经自带该驱动。
  Remote:Remote驱动包不提供驱动,但是提供一个支持远端传输的方式,驱动的实现可以由你自己喜欢的语言来实现。
  二、Calico
  Project Calico 是纯三层的 SDN 实现,没有使用重载网络,它基于 BPG 协议和 Linux 自己的路由转发机制,不依赖特殊硬件,没有使用 NAT 或 Tunnel 等技术。能够方便的部署在物理服务器、虚拟机(如 OpenStack)或者容器环境下。同时它自带的基于 Iptables 的 ACL 管理组件非常灵活,能够满足比较复杂的安全隔离需求。
  所有的容器均通过配置使用calico-node实现网络互通及访问以太网。
  基本原理
  拓扑图
  模块间的关系(控制平面):
  Calico把每个操作系统的协议栈认为是一个路由器,然后把所有的容器认为是连在这个路由器上的网络终端,在路由器之间跑标准的路由协议——BGP的协议,然后让它们自己去学习这个网络拓扑该如何转发。所以Calico方案其实是一个纯三层的方案,也就是说让每台机器的协议栈的三层去确保两个容器,跨主机容器之间的三层连通性。对于控制平面,它每个节点上会运行两个主要的程序,一个是Felix,它会监听ECTD中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是分配了一个容器等。接着会在这台机器上创建出一个容器,并将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。绿色部分是一个标准的路由程序,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这里,你们路由的时候得到这里来。
  由于Calico是一种纯三层的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,没有任何的overlay,所以它的转发效率可能是所有方案中最高的,因为它的包直接走原生TCP/IP的协议栈,它的隔离也因为这个栈而变得好做。因为TCP/IP的协议栈提供了一整套的防火墙的规则,所以它可以通过IPTABLES的规则达到比较复杂的隔离逻辑。
  Calico已知问题
  (1) 只支持tcp,udp,icmp,icmpv6协议,如果需要支持其他L4协议,需要选择其他网络模式;
  (2) 没有对数据路径进行加密,因此对于不信任的网络是不安全的;
  (3) 在公众网络上需要使用-ipip选项,该选项采用IP-over-IP的效率很低;
  (4) 通常 跑在一个大二层的网络里,对于大二层网络其实就是没有任何三层的网关,所有的机器、宿主机、物理机在二层是可达的,此时任何一个都会有一定的硬件风险会让整个大二层瘫痪;
  (5) Calico跑在了一个三层网关的物理网络上时,它需要把所有机器上的路由协议和整个物理网络里面的路由器的三层路由全部用BGP打通。这其实会带来一个问题,这里的容器数量可能是成千上万的,然后你让所有物理的路由学习到这些知识,这会给物理集群里的BGP路由带来一定的压力
  Calico既可以单独配置也可以作为docker libnetwork的一个驱动使用。
  三、Weave
  其中Weave是由Zett.io公司开发的,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。
  外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上,另外,Weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。

【有奖活动】填问卷 送70G测试大牛精品资料(干货+视频)!
21/212>

评 论

论坛新帖

顶部 底部


建议使用IE 6.0以上浏览器,800×600以上分辨率,法律顾问:上海瀛东律师事务所 张楠律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2018, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪公网安备 31010102002173号

51Testing官方微信

51Testing官方微博

扫一扫 测试知识全知道