一、跨主机网络概述

前面已经学习了 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 跨主机网络方案分析

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

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

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

  9. 安装docker跨主机网络flannel

    一.实验环境 机器 操作系统 安装服务 172.16.4.36 centos7 docker etcd flannel 172.16.4.37 centos7 docker etcd flanne ( ...

随机推荐

  1. CentOS6.5 (64bit) 光盘内部FTP源

    一.启动系统,用ISO镜像挂载[root@yum ~]# mkdir -p /mnt/cdrom01[root@yum ~]# mkdir -p /mnt/cdrom02 [root@yum ~]# ...

  2. java-冒泡排序

    1.打印 print--打印,不换行,根据要求加上换行符 println--打印一次就换行 printf--打印,继承C语音的格式,可以进行格式化输出 换行符 '\r'是回车,'\n'是换行,‘\t' ...

  3. JSP:useBean,setProperty的使用

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  4. [Computer Vision] SIFT特征学习笔记

    SIFT(Scale Invariant Feature Transform),尺度空间不变特征,目前手工设计的最好vision特征. 以下是学习http://blog.csdn.net/zddblo ...

  5. post get

    /// <summary> /// Get方法 /// </summary> /// <param name="serverUrl">url地址 ...

  6. sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决)

    sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决) 出现此错误主要是因为.sql的脚本文件过大(一般都超过100M)造成内存无法 ...

  7. DevExpress ASP.NET 使用经验谈(3)-XPO对象的使用(使用指定数据连接)

    首先,我们贴出上一节Users类XPO对象的保存代码,直接建立的XPO Session会话,因为没有与我们所期望的数据层建立绑定, 所以程序自动创建了一个Access数据库,作为默认数据库操作对象来使 ...

  8. transform和transition

    作者:zccst 例如:图片墙  .另外还有,便签墙 使用的样式: 1,正常情况下 ul#index_cards li {     background: url("../images/ca ...

  9. IO 模型

    常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求soc ...

  10. ionic中应用sass

    在学习ionic过程中看到sass,总结了一下基本用法和问题解决办法1.首先需要一个ionic项目,并执行下面的命令ionic start CustomSass blank && cd ...