2016-03-01 21:57:14
来 源
中存储网
Docker
本文来自UnitedStack网络工程师秦天欢的《Docker Kubernetes Neutron下的网络》本次分享的话题《Docker Kubernetes Neutron下的网络》,其实就是讲了三个池塘如何与内外沟通的故事。

网络的作用一直就是通道,可以类比公路、水管或者是下水道,只是其中流通的内容是数据。这是网络的本质,不论是在传统物理IT层面,还是在云计算以及容器的今天,网络一直都在执行这样的使命。比如,负载均衡其实就是给数据分类提高速度,相当于分出了快车道慢车道;而VPN隧道技术就是在大管子里套了一个小管子,让小管子里的数据更加安全。到了云计算时代,OpenStack孕育出Neutron,在Docker中孕育出libnetwork,他们的作用都是把OpenStack或者是Docker中的数据与其他网络实现互联互通,或者更形象的说法是,修了一个河道,实现了一个池塘(新平台上的数据)与其他池塘(物理网络)之间的沟通。

本次分享的话题《Docker Kubernetes Neutron下的网络》(点击即可下载pdf版本),其实就是讲了三个池塘如何与内外沟通的故事。

先把三个河道的区别show出来,如图:

docker网络


Docker:
- 提供libnetwork,客户端直接调⽤用libnetwork进行网络相关的配置

Kubernetes:
- 基于分布式协调服务(如etcd/zookeeeper等)提供事件订阅 – 分布式协调服务同时保存元数据

Neutron:
- 数据库保存元数据,数据库在环境就在 – 基于消息进行事件的订阅及响应

一、Docker网络

Docker网络

是通过Linux Bridge建立网桥的形式来实现数据沟通的,数据如何走有两种模式,不通过外网(池塘内)的,就是容器(紫色)之间通过Docker0实现二层转发,从而实现容器之间的数据通信。另一种方式,是需要容器与外网通信(池塘的水流向外部)的,这种类型相对复杂,其实就是通过一个IP Tables的规则来制作的一个NAT(类似于池塘与大海之间的一个阀门)。如图所示:


特别说明,自从Docker快速发展,已经从一个大项目,发展成各自独立的分支,成为package 。libnetwork 就是Docker里的网络部分。以下是libnetwork的一些概念:

关于三个核心概念:

Sandbox:可以理解为namespace,或者传统意义上的虚拟机;

Endpoint:连接起虚拟机和网桥的部件,当Sandbox要和外界通信的时候就是通过Endpoint连接到外界的,最简单的情况就是连接到一个Bridge上。

Network:网络,更加贴切点的话可以认为是Neutron中的一个拥有一个subnet的网络。

关于五个编程对象(结构体):
* NetworkController。用于获取一个控制器,可以认为通过这个控制器可以对接下来的所有网络操作进行操作。Neutron中并没有这么一个概念,因为Neutron中的网络是由agent通过轮询或者消息的方式来间接操作的,而不是由用户使用docker命令直接在本机进行操作。

* Driver。这里的Driver类似于Neutron中的core_plugin或者是ml2下的各种driver,表示的是底层网络的实现方法。比如有bridge的driver,也有基于vxlan的overlay的driver等等。这个概念和Neutron中的driver概念基本上是一样的。

* Network。这里的Network结构体就是对应的上面的Network,表示建立了一个网络。

* Endpoint。这里的Endpoint结构体就是对应上面的Endpoint,通过这个结构体可以对Endpoint进行操作。

Sandbox。这里的Sandbox结构体就是对应上面的Sandbox,表示建立了一个独立的名字空间。可以类比Nova的虚拟机或者是Kubernetes的Pod,亦或是独立的Docker容器。

一般使用libnetwork的方法,具体的步骤如下图:

docker 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方法删除。

二、Kubernetes网络

当有多台物理机的时候,如何实现通信,这不是Docker解决的,而是通过调用Docker的东西解决的,也就是通过控制器解决,Kubernetes就是其中的一种。假设有四个物理机,有一台物理机是控制节点,其他三台是用来提供容器服务的。物理机之间的通信,首先就是要保持网络互通的,联通的方法很多。下图是用VXLAN连接的示意图: 

Kubernetes网络

除了数据流向,Kubernetes中还有一些重要概念,比如:servicekube-proxy以及pause容器。其中,service:⽤用于提供VIP;kube-proxy:负责service相关的iptables规则建⽴立以及提供proxy,因此有人担心kube-proxy会成为瓶颈。pause容器为Pod提供一个⺴络 的Namespace,每个Pod⼀一个。Kubernetes中的服务不是以容器为单位提供,而是以Pod为单位提供的。

三、Neutron网络

Neutron是OpenStack网络中的概念,提供了云平台上数据的流动和管理方法,相对于之前两个概念,发展时间较长,也较成熟,自动化程度较高。

Neutron server 收到信息之后,把网络的信息写道数据库中, 发消息给接听的Agent,Agent去数据库查询,去物理机上进行配置。这样的好处是:只要数据库在,信息就可以恢复;Agent可以有很多类型,DHCP、L3、OVS、SR-IOV、各种SDN Agent…… 

Neutron网络

此时,需要一个重要的概念登场——ML2.The Modular Layer 2 (ml2) plugin是一个CORE PLUGIN,继承NeutronPluginBaseV2 将物理络根据TYPE(VLAN/VXLAN/GRE…)做了规范,因此⽀支持多种Mechanism Driver。翻译过来,就是ML2让不同网络技术(方言)之间可以实现沟通,就是国际会议上面使用的“翻译器”,工作原理如下图:

Neutron网络 的ML2


总结起来,就是网络控制器和调度器一直都在蓬勃发展,但是类似于iptables/NAT、route、namespace 、linux bridge/ovs以及vlan/vxlan/各种tag都是网络的基础组件,他们很少有变化,这也是一个通道能够稳定运行的基础。

作者:秦天欢 UnitedStack网络工程师

秦天欢先后在IBM、阿里巴巴从事运维和开发工作,目前专注于Neutron相关的开发,深入研究OpenStack、容器技术及运维自动化等方面的课题。

声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。