在大部分与容器网络相关的场景中,覆盖网络都处于核心地位。在本章中会介绍原生Docker覆盖网络的基本要素,以及覆盖网络在Docker Swarm集群中的实现。
12.1 Docker覆盖网络——简介
在现实世界中,容器间通信的可靠性和安全性相当重要,即使容器分属于不同网络中不同主机。这也是覆盖网络大展拳脚的地方,它允许读者创建扁平的、安全的二层网络来连接多个主机,容器可以连接到覆盖网络并且直接相互通信。
Docker提供了原生覆盖网络的支持,易于配置并且非常安全。其背后是基于Libnetwork以及相应的驱动来构建的。
- Libnetwork
- 驱动
Libnetwork是CNM的典型实现,从而可以通过插拔驱动的方式来实现不同的网络技术和拓扑结构。Docker提供了一些诸如Overlay的原生驱动,同时第三方也可以提供驱动。
12.2 Docker覆盖网络——详解
在2015年3月,Docker公司收购了一个叫做Socket Plane的网络初创企业。收购的原因有二,首先是因为这会给Docker带来真正意义的网络架构,其次是容器间联网变得非常简单,以至于开发人员都可以配置它。
12.2.1 在Swarm模式下构建并测试Docker覆盖网络
其实我们在前面已经配置使用过覆盖网络了,因为我们在部署Swarm的时候,创建的服务默认会把所有的节点加入到名为 ingress的覆盖网络。正因为如此,所以Swarm下所有节点的容器才能够轻松地实现互通。下面我们示例如何创建一个覆盖网络,并且把创建的服务加入到创建的网络上。
实验的流程分为几步:构建Swarm——>创建新的覆盖网络——>将服务连接到覆盖网络——>测试覆盖网络。本实验要求至少有两台Docker主机。
-
构建Swarm这一步略掉,前面章节已有介绍。
-
创建新的覆盖网络
在管理节点上执行 docker network create 命令,创建一个名为 uber-net的网络。
docker network create -d overlay uber-net
通过 docker network ls 我们可以看到刚刚创建的网络。
[pangcm@docker01 ~]$ docker network ls
NETWORK ID NAME DRIVER SCOPE
7cb75625ceeb bridge bridge local
u8vvkh4r4io7 uber-net overlay swarm
- 将服务连接到覆盖网络
下面我们创建一个2个副本的名为test的服务。
docker service create --name test --network uber-net \
--replicas 2 alpine sleep 1d
上面我们创建了test服务,并连接到uber-net网络上。在这个示例中,我们使用sleep命令来保持容器运行。
使用 docker service ps test 查看下刚刚创建的服务。
[pangcm@docker01 ~]$ docker service ps test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
9v7muoa0h4kd test.1 alpine:latest docker01 Running Running 26 seconds ago
wabd836cry3j test.2 alpine:latest docker03 Running Running 26 seconds ago
- 测试覆盖网络
首先,我们要先知道这两个容器获取到的IP地址是什么先,分别在两个节点上使用 docker network inspect 命令查看网络,获取IP地址。
[pangcm@docker01 ~]$ docker network inspect uber-net
...
"Containers": {
"409062f55feb0371e7548f7b1e5a88067313b9f2bfaf7958eb3251a045b49cfe": {
"Name": "test.1.9v7muoa0h4kdoqf1zzgp399hz",
"EndpointID": "3b273aa02c46ae8b477db2726933a460497d695b33553d0723e0dde33143e055",
"MacAddress": "02:42:0a:00:02:8b",
"IPv4Address": "10.0.2.139/24",
"IPv6Address": ""
},
...
[pangcm@docker03 ~]$ docker network inspect uber-net
...
"Containers": {
"3c535be36493c5181e3768762cd0c304c3aa807dfae7a28c5c9ba4d60c58ed3d": {
"Name": "test.2.wabd836cry3jnyz3cz9gattbj",
"EndpointID": "ac1bba42f6303d3080b239c5559c9895226153be85990dba6c1b234c7f9b83c5",
"MacAddress": "02:42:0a:00:02:8c",
"IPv4Address": "10.0.2.140/24",
"IPv6Address": ""
},
...
然后我们登录到其中的某一个容器上,去ping一下另外一个容器的IP即可。
12.2.2 工作原理
- VXLAN入门
Docker使用VXLAN隧道技术创建了虚拟二层覆盖网络。在VXLAN的设计中,允许用户基于已经存在的三层网络结构创建虚拟的二层网络。在前面的示例中创建一个子网掩码为 10.0.0.0/24 的二层网络,该网络是基于一个三层IP网络实现的,三层网络IP由两个Docker主机去构成。
VXLAN的美妙之处在于它是一种封装技术,能使现存的路由器和网络架构看起来就像是普通的IP/UDP包一样,并且处理起来毫无问题。
为了创建二层覆盖网络,VXLAN基于现有的三层IP网络创建了隧道。读者可能听过基础网络(Underlay Network)这个术语,它用于指代三层之下的基础部分。
VXLAN隧道两端都是VXLAN隧道终端(VXLAN Tunnel Endpoint,VTEP)。VTEP完成了封装和解压的步骤,以及一些功能实现所必需的操作。
- 两个容器通信的示例
在前面我们在两台Docker主机上分别运行一个容器,为该容器创建了一个VXLAN覆盖网络。为了实现上述场景,在每台主机上都新建了一个Sandbox(网络命名空间)。Sandbox就像是一个容器,但是其中运行的不是应用,而是当前主机上独立的网络栈。
在Sandbox内部创建了一个名为Br0的虚拟交换机。同时Sandbox内部还创建了一个VETP,其中一端接入到名为Br0的虚拟交换机当中,另一端接入主机网络栈(VETP)。在主机网络栈中的终端从主机所连接的基础网络中获取到IP地址,并以UDP Socket的方式绑定到4789端口。不同主机上的两个VTEP通过VXLAN隧道创建了一个新的覆盖网络,如下图所示。
这是VXLAN上层网络创建和使用必须的。接下来每个容器都会有自己的虚拟以太网(veth)适配器,并接入本地Br0虚拟交换机。目前的拓扑结构如下图所示,虽然是在主机所属网络相互独立的情况下,但这样更容易看出分别位于两个不同主机上的容器之间时如何通过VXLAN上层网络进行通信的。
12.3 Docker覆盖网络——命令
- docker network create 是创建新网络所使用的命令,-d 参数允许用户指定所用驱动,常见的驱动是 Overlay。
- docker network ls 用于列出Docker主机上全部可见的容器网络。Swarm模式下的Docker主机只能看到已经接入运行中的容器的网络。这种方式保证了Gossip开销最小化。
- docker network inspect 用于查看特定容器网络的详情。其中包括范围、驱动、IPV6、子网配置、VXLAN网络ID以及加密状态。
- docker network rm 删除指定网络。
12.4 本章小结
本章首先介绍了通过 docker network create 命令创建新的Docker覆盖网络有多简单。接下来介绍了Docker如何利用VXLAN技术来实现网络间的连接。
网友评论