Jusene's Blog

Docker overlay跨主机通信

字数统计: 931阅读时长: 4 min
2018/04/12 Share

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
CATALOG
  1. 1. driver
  2. 2. overlay
  3. 3. 环境准备