driver
Docker Host内容器通信,none、host、bridge、joind容器解决了单个Docker Host内的容器通信问题,而multi host容器间的通信问题的解决方案:
- docker network: overlay,macvlan
- third part network: flannel、weave、calico
overlay
Docker提供了overlay driver,使用户可以创建基于VxLAN的overlay网络。VxLAN可将二层数据封装到UDP进行传输,VxLAN提供与VLAN相同的以太网二层服务。
Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,这里使用 Consul。
环境准备
1.安装consul
1 | ~]# docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap |
通过web界面访问http://10.211.55.16:8500访问consul
2.修改docker引擎启动参数
修改host主机上的docker启动配置参数:
host1:
1 | ~]# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
2 | ~]# cat /usr/lib/systemd/system/docker.service |
3 | ... |
4 | ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --cluster-store=consul://10.211.55.16:8500 --cluster-advertise=eth0:2376 |
5 | ... |
6 | ~]# systemctl daemon-reload |
7 | ~}# systemctl start docker |
host2:
1 | ~]# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
2 | ~]# cat /usr/lib/systemd/system/docker.service |
3 | ... |
4 | ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --cluster-store=consul://10.211.55.16:8500 --cluster-advertise=eth0:2376 |
5 | ... |
6 | ~]# systemctl daemon-reload |
7 | ~]# systemctl start docker |
host1和host2将自动注册到consul数据库中
3.创建overlay网络
host1:
1 | ~]# docker network create -d overlay ov_net1 |
2 | ~}# docker network ls |
3 | NETWORK ID NAME DRIVER SCOPE |
4 | ddc35d6da4af bridge bridge local |
5 | ebfc4303c3a4 host host local |
6 | 92896272268f none null local |
7 | 8150759bff36 ov_net1 overlay global |
host2将通过consul读取到新的网络数据,host2中也可以看见ov_net1:
1 | ~]# docker network ls |
2 | NETWORK ID NAME DRIVER SCOPE |
3 | 39bb2589cf0e bridge bridge local |
4 | eaa8d1a649ec host host local |
5 | adad60399696 none null local |
6 | 8150759bff36 ov_net1 overlay global |
4.创建容器
host1:
1 | ~]# docker run -itd --name bbox1 --network ov_net1 busybox |
2 | ~]# docker exec bbox1 ip a |
3 | 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1 |
4 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 |
5 | inet 127.0.0.1/8 scope host lo |
6 | valid_lft forever preferred_lft forever |
7 | 29: eth0@if30: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue |
8 | link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff |
9 | inet 10.0.0.3/24 brd 10.0.0.255 scope global eth0 |
10 | valid_lft forever preferred_lft forever |
11 | 31: eth1@if32: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue |
12 | link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff |
13 | inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1 |
14 | valid_lft forever preferred_lft forever |
bbox1上有两个网络接口,eth0连接的是overlay网络,eth1是默认路由,eth1通过docker自动创建的docker_gwbridge的bridge网络,为所有连接到overlay网络的容器提供外网访问能力。
1 | ~]# docker network ls |
2 | NETWORK ID NAME DRIVER SCOPE |
3 | ddc35d6da4af bridge bridge local |
4 | a6bad960e33f docker_gwbridge bridge local |
5 | ebfc4303c3a4 host host local |
6 | 92896272268f none null local |
7 | 8150759bff36 ov_net1 overlay global |
host2:
1 | ~]# docker run -itd --name bbox2 --network ov_net2 busybox |
2 | ~]# docker exec bbox2 ping bbox1 |
3 | PING bbox1 (10.0.0.3): 56 data bytes |
4 | 64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.539 ms |
5 | 64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.551 ms |
6 | 64 bytes from 10.0.0.3: seq=2 ttl=64 time=0.586 ms |
7 | 64 bytes from 10.0.0.3: seq=3 ttl=64 time=0.468 ms |
8 | ... |
docker dns只有通过自定义的网络才能生效,实现了跨主机网络通信。
docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 linux bridge br0,endpoint 还是由 veth pair 实现,一端连接到容器中(即 eth0),另一端连接到 namespace 的 br0 上。
br0 除了连接所有的 endpoint,还会连接一个 vxlan 设备,用于与其他 host 建立 vxlan tunnel。容器之间的数据就是通过这个 tunnel 通信的。逻辑网络拓扑结构上图所示:
host1:
1 | ~]# ln -s /var/run/docker/netns /var/run/netns |
2 | ~]# ip netns |
3 | 5fc3a49d5cb2 (id: 2) |
4 | 2-8150759bff (id: 1) |
5 | ~]# ip netns exec 2-8150759bff brctl show |
6 | bridge name bridge id STP enabled interfaces |
7 | br0 8000.029efe99de15 no veth0 |
8 | vxlan0 |
host2:
1 | ~]# ln -s /var/run/docker/netns /var/run/netns |
2 | ~]# ip netns |
3 | 9f899b43c3d4 (id: 1) |
4 | 1-8150759bff (id: 0) |
5 | ~]# ip netns exec 1-8150759bff brctl show |
6 | bridge name bridge id STP enabled interfaces |
7 | br0 8000.76bb86220cf9 no veth0 |
8 | vxlan0 |