一、跨主机网络概述

前面已经学习了 Docker 的几种网络方案:none、host、bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题。本章的重点则是讨论跨主机容器间通信的方案。

  • docker 原生的 overlay 和 macvlan。
  • 第三方方案:常用的包括 flannel、weave 和 calico。

二、准备 overlay 环境

为支持容器跨主机通信,Docker 提供了 overlay driver。Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,我们这里使用 Consul。

1、环境描述

我们会直接使用上一节 docker-machine 创建的实验环境。在 docker 主机 host1(192.168.1.201)和 host2(192.168.1.203)上实践各种跨主机网络方案,在 192.168.1.200 上部署支持的组件,比如 Consul。

2、创建 consul

在 192.168.1.200 这台设备上面执行如下命令。

docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap

容器启动后,可以通过 http://192.168.1.200:8500 访问 Consul。

3、修改 docker 配置文件

接下来修改 host1 和 host2 的 docker daemon 的配置文件 /etc/systemd/system/docker.service.d/10-machine.conf。

--cluster-store 指定 consul 的地址。

--cluster-advertise 告知 consul 自己的连接地址。

重启 docker daemon。

systemctl daemon-reload
systemctl restart docker.service

host1 和 host2 将自动注册到 Consul 数据库中。

4、准备就绪

准备就绪,实验环境如下图:

三、创建 overlay 网络

1、在 host1 中创建网络

在 host1 中创建 overlay 网络 ov_net1。

[root@ubuntu ~ [host1]]# docker network create -d overlay ov_net1
49a8ea9add6a80d44cbd6becf22d66af40072cf9c3a346d66f94a6e72d8042e5
  • -d overlay 指定 driver 为 overlay。

docker network ls 查看当前网络:

[root@ubuntu ~ [host1]]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d0829fccb85c bridge bridge local
f59af6b0b523 host host local
2613e0c2029e none null local
49a8ea9add6a ov_net1 overlay global

2、host2 查看创建的网络

注意到 ov_net1 的 SCOPE 为 global,而其他网络为 local。在 host2 上查看存在的网络:

[root@ubuntu ~ [host1]]# eval $(docker-machine env host2)
[root@ubuntu ~ [host2]]# docker network ls
NETWORK ID NAME DRIVER SCOPE
25f2e4a0bc16 bridge bridge local
bdab05c9c6b9 host host local
240f2dc93d43 none null local
49a8ea9add6a ov_net1 overlay global

host2 上也能看到 ov_net1。这是因为创建 ov_net1 时 host1 将 overlay 网络信息存入了 consul,host2 从 consul 读取到了新网络的数据。之后 ov_net 的任何变化都会同步到 host1 和 host2。

3、查看 ov_net1 详细信息

[root@ubuntu ~ [host2]]# docker network inspect ov_net1
[
{
"Name": "ov_net1",
"Id": "49a8ea9add6a80d44cbd6becf22d66af40072cf9c3a346d66f94a6e72d8042e5",
"Created": "2018-05-03T11:29:11.802222991+08:00",
"Scope": "global",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

IPAM 是指 IP Address Management,docker 自动为 ov_net1 分配的 IP 空间为 10.0.0.0/24。

四、在 overlay 中运行容器

1、创建容器 bbox1

在 host1 运行一个 busybox 容器并连接到 ov_net1。

[root@ubuntu ~ [host1]]# docker run -itd --name bbox1 --network ov_net1 busybox
5246d782fc8fd30890bcf2bb34374c54db3ee277cae585572f4b20129b68e3fe

2、查看 bbox1 网络配置

[root@ubuntu ~ [host1]]# docker exec bbox1 ip r
default via 172.18.0.1 dev eth1
10.0.0.0/24 dev eth0 scope link src 10.0.0.2
172.18.0.0/16 dev eth1 scope link src 172.18.0.2

bbox1 有两个网络接口 eth0 和 eth1。

eth0 IP 为 10.0.0.2,连接的是 overlay 网络 ov_net1。eth1 IP 172.18.0.2,容器的默认路由是走 eth1,其实,docker 会创建一个 bridge 网络 “docker_gwbridge”,为所有连接到 overlay 网络的容器提供访问外网的能力。

[root@ubuntu ~ [host1]]# docker network ls
NETWORK ID NAME DRIVER SCOPE
74bdaebd8ae5 bridge bridge local
604a0b967e13 docker_gwbridge bridge local
f59af6b0b523 host host local
2613e0c2029e none null local
49a8ea9add6a ov_net1 overlay global

docker network inspect docker_gwbridge 输出可确认 docker_gwbridge 的 IP 地址范围是 172.18.0.0/16,当前连接的容器就是 bbox1(172.18.0.2)。

[root@ubuntu ~ [host1]]# docker network inspect docker_gwbridge
[
{
"Name": "docker_gwbridge",
"Id": "604a0b967e135d41c605547b65853a7a1315fceefe99c051d7a001e4e1207c1c",
"Created": "2018-05-03T11:40:44.426460442+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"eba09cf91fa34e3a7eb1ab20047ce08ed8fb0ac4d8f2dc9ddf9a08116575eba2": {
"Name": "gateway_eba09cf91fa3",
"EndpointID": "3dd836e9db9ec3250cfa3bc1662ab8822918a7ea3a30b9e24e2ee7151f5f75b0",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.enable_icc": "false",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.name": "docker_gwbridge"
},
"Labels": {}
}
]

而且此网络的网关就是网桥 docker_gwbridge 的 IP 172.18.0.1,在 host1 上面查看。

root@host1:~# ifconfig docker_gwbridge
docker_gwbridge Link encap:Ethernet HWaddr 02:42:95:80:cf:70
inet addr:172.18.0.1 Bcast:172.18.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:95ff:fe80:cf70/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:648 (648.0 B)

这样容器 bbox1 就可以通过 docker_gwbridge 访问外网。

五、overlay 网络连通性

1、host2 中运行 bbox2

[root@ubuntu ~ [host2]]# docker run -itd --name bbox2 --network ov_net1 busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
f70adabe43c0: Pull complete
Digest: sha256:58ac43b2cc92c687a32c8be6278e50a063579655fe3090125dcb2af0ff9e1a64
Status: Downloaded newer image for busybox:latest
457e0e4363216d3fe70ea471f3c671863f166bf6d64edf1a92232d0cb585bd85

2、查看 bbox2 路由情况

[root@ubuntu ~ [host2]]# docker exec bbox2 ip r
default via 172.18.0.1 dev eth1
10.0.0.0/24 dev eth0 scope link src 10.0.0.3
172.18.0.0/16 dev eth1 scope link src 172.18.0.2

3、互通测试

bbox2 IP 为 10.0.0.3,可以直接 ping bbox1:

[root@ubuntu ~ [host2]]# docker exec bbox2 ping -c 2 bbox1
PING bbox1 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=24.710 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.524 ms --- bbox1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.524/12.617/24.710 ms

可见 overlay 网络中的容器可以直接通信,同时 docker 也实现了 DNS 服务。

4、实现原理

docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 linux bridge br0, veth pair 一端连接到容器中(即 eth0),另一端连接到 namespace 的 br0 上。

br0 除了连接所有的 veth pair,还会连接一个 vxlan 设备,用于与其他 host 建立 vxlan tunnel。容器之间的数据就是通过这个 tunnel 通信的。逻辑网络拓扑结构如图所示:

root@host1:~# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242cf3d50df no
docker_gwbridge 8000.02429580cf70 no vethb08d6be
root@host2:~# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242303d222f no
docker_gwbridge 8000.02423eb55e58 no vethdb98439

要查看 overlay 网络的 namespace 可以在 host1 和 host2 上执行 ip netns(请确保在此之前执行过 ln -s /var/run/docker/netns /var/run/netns),可以看到两个 host 上有一个相同的 namespace "1-49a8ea9add":

root@host1:~# ip netns
c0052da621d7 (id: 1)
1-49a8ea9add (id: 0)
root@host2:~# ip netns
e486246b39d9 (id: 1)
1-49a8ea9add (id: 0)

"1-49a8ea9add" 这就是 ov_net1 的 namespace,查看 namespace 中的 br0 上的设备。

root@host1:~# ip netns exec 1-49a8ea9add brctl show
bridge name bridge id STP enabled interfaces
br0 8000.767c8828d7b0 no veth0
vxlan0

六、overlay 网络隔离

1、创建网络 ov_net2

不同的 overlay 网络是相互隔离的。我们创建第二个 overlay 网络 ov_net2 并运行容器 bbox3。

root@host1:~# docker network create -d overlay ov_net2
7c2ac9ec1a0ec477aa9230bcfffd91b1b79bee6ea7007a7a5de20ccae0b3d91c

2、启动容器 bbox3

root@host1:~# docker run -itd --name bbox3 --network ov_net2 busybox
1a3d81915a57b195a8b0baa2d1444bbeb5c947e7e203752ed975d6a900dbb141

3、查看 bbox3 网络

bbox3 分配到的 IP 是 10.0.1.2,尝试 ping bbox1(10.0.0.2)。

root@host1:~# docker exec -it bbox3 ip r
default via 172.18.0.1 dev eth1
10.0.1.0/24 dev eth0 scope link src 10.0.1.2
172.18.0.0/16 dev eth1 scope link src 172.18.0.3

ping 失败,可见不同 overlay 网络之间是隔离的。即便是通过 docker_gwbridge 也不能通信。

如果要实现 bbox3 与 bbox1 通信,可以将 bbox3 也连接到 ov_net1。

docker network connect ov_net1 bbox3

docker 默认为 overlay 网络分配 24 位掩码的子网(10.0.X.0/24),所有主机共享这个 subnet,容器启动时会顺序从此空间分配 IP。当然我们也可以通过 --subnet 指定 IP 空间。

docker network create -d overlay --subnet 10.22.1.0/24 ov_net3

Docker 跨主机网络 overlay(十六)的更多相关文章

  1. Docker跨主机网络——overlay

    前言 在Docker网络--单host网络一文中,我为大家总结了Docker的单机网络相关知识和操作,单机网络比较容易.本文我为大家总结Docker跨主机通信相关知识.同样本文大部分内容以CloudM ...

  2. centos7下安装docker(15.2跨主机网络-overlay)

    为支持容器跨主机通信,Docker提供了overlay driver,使用户可以创建基于VxLAN的overlay网络.VxLAN可将二层数据封装到UDP进行传输,VxLAN提供与VLAN相同的以太网 ...

  3. Docker 跨主机网络

    Docker提供两种原生的跨主机网络: Overlay  和  Macvlan libnetwork & CNM libnetwork 是 docker 容器网络库,最核心的内容是其定义的 C ...

  4. Docker跨主机网络实践

    Docker使用中网络管理是最麻烦的,在项目初始化前期就需要进行合理的规划,如果在比较理想的单主机的网络通信是比较简单的,但如果涉及到跨主机的网络就需要使用docker自带的overlay netwo ...

  5. 跨主机网络-overlay(18)

    docker overlay跨主机网络 .环境 docker版本 Docker version -ce, build fc4de44 3台主机 192.168.55.51 host1 192.168. ...

  6. docker 跨主机网络:overlay 简介

    简介 docker 在早前的时候没有考虑跨主机的容器通信,这个特性直到 docker 1.9 才出现.在此之前,如果希望位于不同主机的容器能够通信,一般有几种方法: 使用端口映射:直接把容器的服务端口 ...

  7. docker容器跨主机网络overlay

    前提:已部署好docker服务服务预计部署情况如下10.0.0.134 Consul服务10.0.0.135 host1  主机名mcw510.0.0.134 host2  主机名mcw6host1与 ...

  8. Docker 跨主机网络方案分析

    PS:文章首发公众号,欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多 ...

  9. Docker跨主机网络解决方案

    前言:前面的部分一直都是单机跑docker,但实际生产环境不可能只用一台来跑.肯定会用到多台,因为他们都是内部私有ip,那么多台主机之间的容器如何通信?这个是个很头疼的问题!目前主流几种方法如下:1. ...

随机推荐

  1. electron中引入jquery

    <!-- Insert this line above script imports --> <script>if (typeof module === 'object') { ...

  2. waitgroup等待退出

    等待一组协程结束,用sync.WaitGroup操作 package main import ( "fmt" "sync" "time" ) ...

  3. SQL Server 表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  4. soap1.1与soap1.2

    1.soap1.2 如果加上jar包后,项目启动报错,有可能是jar包没起作用, 解决方法:把jar包移除,重新加入jar包 TCP/IP Monitor监测到的内容: soap1.2请求与soap1 ...

  5. java+上传一个文件夹

    在web项目中上传文件夹现在已经成为了一个主流的需求.在OA,或者企业ERP系统中都有类似的需求.上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便.能够提供更高级的应用支撑. ...

  6. 重载new和delete运算符

    内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...

  7. 【HTTP】协议详解

    什么是HTTP协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端 ...

  8. Linux存储在线管理(一)FC磁盘设备管理

    由 Jun_Tan 在 2013-1-28 上午12:08 上创建,最后由 Jun_Tan 在 2013-1-28 上午12:13 上修改 版本 1 Linux存储在线管理(一)FC磁盘设备管理 转载 ...

  9. P3802 小魔女帕琪 期望

    P3802 小魔女帕琪 期望 题面 题意稍微不清楚,题中的a[i]指的是属性i的魔法有a[i]个. 题目大意:有7种魔法,每种数量a[i],每次随机放出一个魔法,问放完为止出现7次魔法都不相同的期望次 ...

  10. testdisk修复磁盘文件

    使用testdisk,分析之后,使用:P ,list文件,然后使用如下方法恢复文件 Use Right to change directory, h to hide Alternate Data St ...