在大部分与容器网络相关的场景中,覆盖网络都处于核心地位。介绍原生Docker覆盖网络的基本要素,以及覆盖网络在Docker Swarm集群中的实现。

Docker覆盖网络——简介

Docker 提供了原生覆盖网络的支持,易于配置且非常安全。其背后是基于Libnetwork以及相应的驱动来构建的。
● Libnetwork。
● 驱动。
Libnetwork是CNM的典型实现,从而可以通过插拔驱动的方式来实现不同的网络技术和拓扑结构。Docker提供了一些诸如Overlay的原生驱动,同时第三方也可以提供驱动。

接下来的内容会分为如下两部分。
● 在Swarm模式下构建并测试Docker覆盖网络。
● 工作原理

在Swarm模式下构建并测试Docker覆盖网络

需要两台Docker主机,并通过一个路由器上两个独立的二层网络连接在一起。如图所示,注意节点位于不同网络之上。

docker entrypoint 覆盖 docker覆盖网络_IP


可以选择Linux容器主机或者Windows容器主机。Linux内核版本不能低于4.4(高版本更好)

1.构建Swarm
首先需要将两台主机配置为包含两个节点的Swarm集群。接下来会在node1节点上运行docker swarm init命令使其成为管理节点,然后在node2节点上运行docker swarm join命令来使其成为工作节点

需要在自己的环境中继续下面的示例,则需要先将环境中的IP地址、容器ID和Token等替换为正确的值。

在node1节点上运行下面的命令。

docker entrypoint 覆盖 docker覆盖网络_IP_02


在node2上运行下面的命令。(如果需要在Windows环境下生效,则需要修改Windows防火墙规则,打开2377/tcp、7946/tcp以及7946/udp等几个端口。

docker entrypoint 覆盖 docker覆盖网络_运维_03


两个节点的Swarm集群建立好了

2.创建新的覆盖网络

创建一个名为uber-net的覆盖网络。

docker entrypoint 覆盖 docker覆盖网络_docker_04


创建了一个崭新的覆盖网络,能连接Swarm集群内的所有主机,并且该网络还包括一个TLS加密的控制层!如果还想对数据层加密的话,只需在命令中增加-o encrypted参数。

可以通过docker network ls命令列出每个节点上的全部网络。

如果在node2节点上运行docker network ls命令,就会发现无法看到uber-net网络。这是因为只有当运行中的容器连接到覆盖网络的时候,该网络才变为可用状态。这种延迟生效策略通过减少网络梳理,提升了网络的扩展性。

3.将服务连接到覆盖网络
接下来新建一个Docker服务并连接到该网络。Docker服务会包含两个副本(容器),一个运行在node1节点上,一个运行在node2节点上。这样会自动将node2节点接入uber-net网络。

在node1节点上运行下面的命令。

docker entrypoint 覆盖 docker覆盖网络_运维_05


该命令创建了名为test的新服务,连接到了uber-net这个覆盖网络,并且还基于指定的镜像创建了两个副本(容器)。

在两个示例中,均在容器中采用sleep命令来保持容器运行,并在休眠结束后退出该容器。由于运行了两个副本(容器),而Swarm包含两个节点,因此每个节点上都会运行一个副本。

可以通过docker service ps命令来确认上面的操作。

4.测试覆盖网络

现在使用ping命令来测试覆盖网络。

docker entrypoint 覆盖 docker覆盖网络_docker_06


运行docker network inspect查看被分配给覆盖网络的Subnet。

通过输出可见,uber-net的子网是10.0.0.0/24。注意,这与两个节点的任意底层物理网络IP均不相符(172.31.1.0/24和192.168.1.0/24)。

读者需要在两台节点上分别运行上述命令,获取两个容器的ID和IP地址。

实际网络情况如图

docker entrypoint 覆盖 docker覆盖网络_IP_07

工作原理

1.VXLAN入门

首先必须知道,Docker使用VXLAN隧道技术创建了虚拟二层覆盖网络。所以,在详解之前,先快速了解一下VXLAN。在VXLAN的设计中,允许用户基于已经存在的三层网络结构创建虚拟的二层网络。在前面的示例中创建了一个子网掩码为10.0.0.0/24的二层网络,该网络是基于一个三层IP网络实现的,三层IP网络由172.31.1.0/24和192.168.1.0/24这两个二层网络构成。具体如图

docker entrypoint 覆盖 docker覆盖网络_IP_08


VXLAN的美妙之处在于它是一种封装技术,能使现存的路由器和网络架构看起来就像普通的IP/UDP包一样,并且处理起来毫无问题。为了创建二层覆盖网络,VXLAN基于现有的三层IP网络创建了隧道。读者可能听过基础网络(Underlay Network)这个术语,它用于指代三层之下的基础部分。VXLAN隧道两端都是VXLAN隧道终端(VXLAN Tunnel Endpoint, VTEP)。VTEP完成了封装和解压的步骤,以及一些功能实现所必需的操作

2.梳理一下两个容器的示例

在前面的示例中,通过IP网络将两台主机连接起来。每个主机运行了一个容器,之后又为容器连接创建了一个VXLAN覆盖网络。为了实现上述场景,在每台主机上都新建了一个Sandbox(网络命名空间)。正如前文所讲,Sandbox就像一个容器,但其中运行的不是应用,而是当前主机上独立的网络栈。

在Sandbox内部创建了一个名为Br0的虚拟交换机(又称做虚拟网桥)。同时Sandbox内部还创建了一个VTEP,其中一端接入到名为Br0的虚拟交换机当中,另一端接入主机网络栈(VTEP)。在主机网络栈中的终端从主机所连接的基础网络中获取到IP地址,并以UDP Socket的方式绑定到4789端口。不同主机上的两个VTEP通过VXLAN隧道创建了一个覆盖网络

接下来每个容器都会有自己的虚拟以太网(veth)适配器,并接入本地Br0虚拟交换机。目前拓扑结构如图12.7所示,虽然是在主机所属网络互相独立的情况下,但这样能更容易看出两个分别位于不同主机上的容器之间是如何通过VXLAN上层网络进行通信的

以太网(veth)适配器接入本地Br0虚拟交换机

docker entrypoint 覆盖 docker覆盖网络_网络_09

需要注意的是,Docker支持使用同样的覆盖网络实现三层路由。例如可以创建包含两个子网的覆盖网络,Docker会负责子网间的路由。创建的命令如docker network create --subnet=10.1.1.0/24 --subnet=11.1.1.0/24 -d overlay prod-net。该命令会在Sandbox中创建两个虚拟交换机,默认支持路由。

Docker覆盖网络——命令

● docker network create是创建新网络所使用的命令。-d参数允许用户指定所用驱动,常见的驱动是Overlay。也可以选择使用第三方驱动。对于覆盖网络,控制层默认是加密的。需要指定-o encrypted对数据层进行加密(会导致额外的性能开销)。

● docker network ls用于列出Docker主机上全部可见的容器网络。Swarm模式下的Docker主机只能看到已经接入运行中的容器的网络。这种方式保证了网络Gossip开销最小化。

● docker network inspect用于查看特定容器网络的详情。其中包括范围、驱动、IPv6、子网配置、VXLAN网络ID以及加密状态。

● docker network rm删除指定网络。

这些内容只是Docker 覆盖网络全部功能的冰山一角。初步了解docker覆盖网络