设为首页 收藏本站
查看: 1317|回复: 0

[经验分享] Docker 跨主机网络 overlay(十六)

[复制链接]

尚未签到

发表于 2019-2-21 12:57:19 | 显示全部楼层 |阅读模式
一、跨主机网络概述
  前面已经学习了 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



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-675383-1-1.html 上篇帖子: Docker(十八)基于python3.5 以apline 为系统的python 环境 下篇帖子: Docker 容器日志管理Fluentd
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表