容器网络聚焦:CNM和CNI

容器的网络技术日新月异。业界逐渐聚焦到Docker的CNM和CoreOS的CNI。

目前关于Linux容器网络接口的配置有两种的可能的标准:容器网络模型(CNM)和容器网络接口(CNI)。网络是相当复杂的,而且提供某种功能的方式也多种多样。

在斟酌某项技术的时候,我们需要考虑采纳的成本;是否会增加对供应商的依赖。社区的采纳程度和支持程度也是比较重要的考量。插件开发者还需要考虑哪种方式相对比较容易实现。

Container Network Model(CNM)

CNM是一个被 Docker 提出的规范。现在已经被Cisco Contiv, Kuryr, Open Virtual Networking (OVN), Project Calico, VMware 和 Weave 这些公司和项目所采纳。

 

20161124135614

 

Libnetwork是CNM的原生实现。它为Docker daemon和网络驱动程序之间提供了接口。网络控制器负责将驱动和一个网络进行对接。每个驱动程序负责管理它所拥有的网络以及为该网络提供的各种服务,例如IPAM等等。由多个驱动支撑的多个网络可以同时并存。网络驱动可以按提供方被划分为原生驱动(libnetwork内置的或Docker支持的)或者远程驱动 (第三方插件)。原生驱动包括 none, bridge, overlay 以及 MACvlan。驱动也可以被按照适用范围被划分为本地(单主机)的和全局的 (多主机)。

 

20161124135713

 

『Network Sandbox』– 一个容器内部的网络栈。

『Endpoint』– 一个通常成对出现的网络接口。一端在网络容器内,另一端在网络内。 一个Endpoints可以加入一个网络。一个容器可以有多个endpoints。

『Network』– 一个endpoints的集合。该集合内的所有endpoints可以互联互通。

最后,CNM还支持标签(labels)。Lable是以key-value对定义的元数据。用户可以通过定义label这样的元数据来自定义libnetwork和驱动的行为。

Container Network Interface(CNI)

CNI是由CoreOS提出的一个容器网络规范。已采纳改规范的包括Apache Mesos, Cloud Foundry, Kubernetes, Kurma 和 rkt。另外 Contiv Networking, Project Calico 和 Weave这些项目也为CNI提供插件。

 

20161124135721

 

CNI 的规范比较小巧。它规定了一个容器runtime和网络插件之间的简单的契约。这个契约通过JSON的语法定义了CNI插件所需要提供的输入和输出。

一个容器可以被加入到被不同插件所驱动的多个网络之中。一个网络有自己对应的插件和唯一的名称。CNI 插件需要提供两个命令:一个用来将网络接口加入到指定网络,另一个用来将其移除。这两个接口分别在容器被创建和销毁的时候被调用。

CNI Flow

容器runtime首先需要分配一个网络命名空间以及一个容器ID。然后连同一些CNI配置参数传给网络驱动。接着网络驱动会将该容器连接到网络并将分配的IP地址以JSON的格式返回给容器runtime。

Mesos 是最新的加入CNI支持的项目。Cloud Foundry的支持也正在开发中。当前的Mesos网络使用宿主机模式,也就是说容器共享了宿主机的IP地址。Mesos正在尝试为每个容器提供一个自己的IP地址。这样做的目的是使得IT人员可以自行选择适合自己的组网方式。

目前,CNI的功能涵盖了IPAM, L2 和 L3。端口映射(L4)则由容器runtime自己负责。CNI也没有规定端口映射的规则。这样比较简化的设计对于Mesos来讲有些问题。端口映射是其中之一。另外一个问题是:当CNI的配置被改变时,容器的行为在规范中是没有定义的。为此,Mesos在CNI agent重启的时候,会使用该容器与CNI关联是的配置。

CNI和CNM

这两种方案都使用了驱动模型或者插件模型来为容器创建网络栈。这样的设计使得用户可以自由选择。两者都支持多个网络驱动被同时使用,也允许容器加入一个或多个网络。两者也都允许容器runtime在它自己的命名空间中启动网络。

这种模块化驱动的方式可与说对运维人员更有吸引力。因为运维人员可以比较灵活的选择适合现有模式的驱动。两种方案都提供了独立的扩展点,也就是插件的接口。这使得网络驱动可以创建、配置和连接网络。也使得IPAM可以配置,发现和管理IP地址。这种分离让编排变得容易。

CNM 模式下的网络驱动不能访问容器的网络命名空间。这样做的好处是libnetwork可以为冲突解决提供仲裁。一个例子是:两个独立的网络驱动提供同样的静态路由配置,但是却指向不同的下一跳IP地址。与此不同,CNI允许驱动访问容器的网络命名空间。CNI正在研究在类似情况下如何提供仲裁。

CNI支持与第三方IPAM的集成,可以用于任何容器runtime。CNM从设计上就仅仅支持Docker。由于CNI简单的设计,许多人认为编写CNI插件会比编写CNM插件来得简单。

这些模型增进了系统的模块化,增加了用户的选择。也促进了第三方网络插件以创新来提供更高级的网络功能。

总结

容器网络领域随着供应商和各种项目的不断变化而变化。有些被合并,例如Docker兼并SocketPlan;Flannel到Tigera的迁移 – Tigera的Canal将Calico和Flannel两个项目组合在一起了。 CoreOS会继续为Flannel提供支持,并且会将Canal集成在它们的企业级Kubernetes方案 – Tectonic 里面。同时,新的发布版本也带来新的变化。Docker 1.12中包括的underlay和load-balancing等新特性,也将该项目的网络支持提升到新的高度。

虽然在容器网络方面有各种各样的技术,我们值得庆幸的是(至少是现在)容器生态圈基本上聚焦在这两个模型上。开发人员和运维人员都希望能够最终自动化网络配置。在没能完全自动配置之前,解决方案之一是一些人工参与的预先配置好的资源。比如运维人员可以预先分配一些网络,包括IP地址空间,IPAM,QoS等等。开发人员可以根据自己应用的需要来从中选择网络。

分享到:更多 ()