九、Docker Network

原创
2019/06/29 18:54
阅读数 103

本节将介绍Docker网络的基本原理,比如Container Network Model (CNM) 和libnetwork。

Docker在容器内运行应用程序,这需要在大量不同的网络上进行通信。这意味着Docker需要很强的网络能力。幸运的是,Docker有容器-容器网络的解决方案,也有连接到已存在网络和VLANs的解决方案。后者对于将app装箱是非常重要的,这需要和外部系统诸如VM‘s和物理机上的功能和服务进行通信。

Docker网络是基于一个叫做Container Network Model (CNM)的开源可插拔的架构。libnetwork是Docker真实世界的CNM实现。它提供了Docker所有的核心网络能力。驱动插入libnetwork网络以提供特定的网络拓扑。

为创建平滑的开箱即用的体验,Docker用一组原生驱动来处理大多数通用的网络需求。这包含单主机桥接网络、多主机的overlays,插入已存在VLANs的选项。生态系统合作者扩展了这个,在未来可能提供他们自己的驱动。

最后,libnetwork提供了本机服务发现和基本容器负载平衡解决方案。

(一)、理论

在最高层次,Docker网络由三个主要组件:Container Network Model (CNM)、libnetwork、Drivers。

CNM是设计规范。它概括出了Docker网络的 基础构建块。

libenetwork是CNM的实际实现,被Dokcer使用。用Go语言编写,实现了CNM里的核心组件。

Drivers通过实现特定的网络拓扑(诸如基于VXLAN的overlay网络)来扩展了模型。

1、Container Network Model (CNM)

每件事都是从设计开始。

Docker网络的设计指导是CNM。它概括出了Docker网络的基本构建块,可以从https://github.com/docker/libnetwork/blob/master/docs/design.md读取到全部规范。从更高层级上看,它定义了三个构建块:Sandboxes、Endpoints、 Networks。
sandbox是一个隔离的网络栈,包括以太网接口、端口、路由表和DNS配置。

Endpoints是虚拟的网络接口(E.g. veth),和正常网络接口一样,他们负责建立连接。在CNM的情况下,endpoint的工作室连接sandbox到网络。

Networks 是802.1d桥接(大多数通常成为switch)的软件实现。因此,他们将需要通信的一系列endpoint进行分组并隔离。

2、Libnetwork

CNM是设计doc,libnetwork是典型实现。是开源的,用Go编写,跨平台,被Docker使用。

在Docker的早起,所有的网络代码存在于daemon,现在所有的核心Docker网络代码存在于libnetwork。libnetwork实现了定义在CNM中的所有三个组件。它也实现了本地服务发现,基于ingress的容器负载 均衡、网络控制平面和管理平面功能

3、Drivers

如果libnetwork实现了平面和管理平面,那么驱动实现了数据平面。例如连接性和隔离性完全由驱动控制,它是网络对象的真实创建。关系如下:

Docker有几个内置驱动,也称之为原生驱动或本地驱动,在Linux上包括bridge, overlay和macvlan。在Windows上包括nat, overlay, transparent, and l2bridge。

第三方也可以写Docker网络驱动,他们称之为远程驱动( remote drivers)。每一个驱动负责网络上 所有资源的真实创建和管理。

为了满足复杂的高流动性环境的需求,libnetwork运行同时有多个网络驱动器处于激活状态。意味着Docker环境可以是异构网络。
(二)、单主机桥接网络

Docker网络最简单的类型是单主机桥接网络(2层桥接网络)。Linux上的Docker用内置的桥接驱动创建了单主机桥接网络。下图显示了两个Docker主机有同样的本地桥接网络叫做“mynet”。尽管网络一样,但他们是独立隔离的网络,意味着容器不能直接通信,因为他们在不同的网络上。

每一个Docker主机都有一个缺省的单主机桥接网络,在Linux叫“bridge”,在Windows上叫“nat”,缺省情况下,所有新容器将会附着到这个网络。除非使用--network标志重写。可以使用命令:docker network ls,如下所示:

通过docker network inspect<network-name|network-id>,可以查看网络的详细情况。

在Linux主机上,使用桥接驱动构建的Docker网络是基于battlehardened linux桥接技术,其在Linux内核中已经存在了多余15年。这意味着高性能且极度稳定。也意味着可以使用标准的Linux工具库。例如ip link show docker0。

Docker缺省“bridge”网络和Linux内核中的“docker0”桥接的关系如下:

由于所有新创建的容器被注册在嵌入式的Docker DNS服务中,因此在相同网络中的其他容器可以通过名字进行解析。
注:Linux中缺省的桥接网络不支持通过Docker DNS服务进行名字解析,所有其他用户定义的桥接网络支持。

单主机桥接网络仅用于本地开发和很小的应用程序。因为仅有一个单一容器可以绑定到主机上的任何端口。这意味着没有其他的容器将会使用主机上的端口5000。

(三)、多主机overlay网络

下一节将着重介绍多主机overlay网络,所以这里只做简短介绍。

overlay网络是多主机的。他们允许一个单一网络跨多个主机,使得在不同主机上的容器可以再二层进行通信。他们很适合于容器-容器通信,包括仅容器应用程序。

Docker为overlay网络提供了一个原生驱动。这使得创建他们非常简单,仅 在docker network create命令后 增加--d overlay 标志。

(四)、连接到已存在网络

连接已装箱app到外部系统和物理网络的能力是很重要的。一个通用的例子是部分装箱app,装箱的部分需要一种方式去和运行在外部物理网络和VLANs中的非装箱部分进行通信。考虑到这一点,创建了内置的MACVLAN网络。通过给定每一个容器他们自己的MAC和IP地址,使得容器成为已存在网络上的一等公民。


积极的一面,MACVLAN性能 是好的,因为它不需要进行端口映射或者额外的桥接,通过主机接口就可以连接容器接口。然而,反面来看,它需要主机的NIC处于promiscuous模式,这在大多数公共云平台式 是不允许的。因此MACVLAN非常适合你自己的企业数据中心网络,但是不能在公共云工作。

在下属图片和假设例子的帮助下,让我们更深的进行理解。


现在,我们增加一个Docker主机,如下所示:

我们现在有一个需求,将一个容器(app服务)插入到VLAN100中。这样做,我们使用macvlan创建一个新的Docker网络。然而,macvlan需要我们告诉它一些关于网络的事情。比如子网信息、网关、可以分配给容器的IP范围、主机所使用的接口或者子接口。

创建一个叫做“macvlan100”的MACVLAN网络,将会把容器连接到VLAN 100.命令如下:

docker network create -d macvlan --subnet=10.0.0.0/24 --ip-range=10.0.00/25 --gateway=10.0.0.1 -o parent=eth0.100 macvlan100

上述命令执行完后,如下所示:

MACVLAN使用标准的Linux子接口,你可以使用你将要连接的VLAN的ID来给他们打标签。在上述例子中,我们将要连接到VLAN 100,所以我们用.100(etho.100)来给子接口打标签。

我们也可以使用--ip-range标志来告诉MACVLAN 网络哪些IP地址的子集可以分配给容器。这个范围的地址为Docker保留是很重要的,不能被其他的节点或者DHCP服务器使用。
执行命令:docker container run -d --name mactainer1 --network macvlan100 alpine sleep 1d,此时网络结构如下:

注意:上述的基础网络VLAN 100并不能看到任何MACVLAN,它仅能看见带有MAC和IP地址的容器。

现在,我们获得了一个MACVLAN,用它将一个新容器连接到一个已存在的VLAN。Docker MACVLAN驱动是构建在同名的Linux内核上 。它支持VLAN的trunk功能。这意味着我们可以创建多个MACVLAN网络,在相同的Docker主机上按照如下方式连接容器。

(五)、服务发现

除核心网络之外,libnetwork也 提供了一些重要的网络服务。

服务发现允许所有的容器和Swarm服务通过名称来互相定位。唯一的需求是他们在相同的网络上。这利用了Docker的嵌入式DNS服务,也为每个容器提供了一个DNS解析器。如下图所示,c1容器通过名称来ping c2容器。

(六)、Ingress网络

Swarm支持两种发布模式,可以使得服务访问集群外主机:Ingress mode (default)、Host mode。

通过ingress模式发布的服务可以被swarm中的任何一个节点访问—甚至节点没有 运行服务副本。通过主机模式发布的服务仅能通过运行服务副本的节点访问。下图显示了这两种 模式的不同。

Ingress 模式是常用模式。其使用叫做Service Mesh或Swarm Mode Service Mesh的4层路由mesh,下图显示了外部请求到暴露在ingress模式中服务的基本流向。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部