本文介绍如何使用 OpenvSwitch 连接 Docker 容器。实现思路:为 docker 默认创建的 docker0 网桥分配网段,通过在 OpenvSwitch 网桥建立 gre 隧道连接多个主机,并将 docker0 网桥和 OpenvSwitch 连接实现跨主机连接 docker 容器。
环境说明
- vm1
- IP: 172.20.0.134
- docker0 网桥网段:172.17.4.1/24
- vm2
- IP: 172.20.0.135
- docker0 网桥网段:172.17.5.1/24
示例
环境初始化
root@vm1:~# ip a show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:38:1a:47:15 brd ff:ff:ff:ff:ff:ff
inet 172.17.4.1/24 brd 172.17.4.255 scope global docker0
valid_lft forever preferred_lft forever
root@vm2:~# ip a show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:35:51:08:f8 brd ff:ff:ff:ff:ff:ff
inet 172.17.5.1/24 brd 172.17.5.255 scope global docker0
valid_lft forever preferred_lft forever
- 为2个主机分别安装 OpenvSwitch
- Ubuntu 使用命令:
apt update && apt install openvswitch-switch -y && systemctl enable openvswitch-switch && systemctl start openvswitch-switch
创建网桥
在 vm1 和 vm2 分别执行:
# vm1
root@vm1:~# ovs-vsctl add-br br0
root@vm1:~# ip link set dev br0 up
root@vm1:~# ip a show br0
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether 8e:10:d6:2c:5b:43 brd ff:ff:ff:ff:ff:ff
inet6 fe80::8c10:d6ff:fe2c:5b43/64 scope link
valid_lft forever preferred_lft forever
root@vm1:~# ovs-vsctl show
6dfd67c6-29b3-43fd-bfe6-83a41e73230e
Bridge br0
Port br0
Interface br0
type: internal
ovs_version: "2.13.5"
# vm2
root@vm2:~# ovs-vsctl add-br br0
root@vm2:~# ip link set dev br0 up
root@vm2:~# ip a show br0
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether 8a:cb:e2:de:ee:4a brd ff:ff:ff:ff:ff:ff
inet6 fe80::88cb:e2ff:fede:ee4a/64 scope link
valid_lft forever preferred_lft forever
root@vm2:~# ovs-vsctl show
ad871957-28d4-4dd2-ae2a-d71fe70b8f8e
Bridge br0
Port br0
Interface br0
type: internal
ovs_version: "2.13.5"
建立 GRE 隧道
# vm1
root@vm1:~# ovs-vsctl add-port br0 gre0 -- set Interface gre0 type=gre options:remote_ip=172.20.0.135
root@vm1:~# apt install bridge-utils
# 将 br0 添加到 docker0,使容器流量通过 OVS 到 gre0
root@vm1:~# brctl addif docker0 br0
root@vm1:~# ovs-vsctl show
6dfd67c6-29b3-43fd-bfe6-83a41e73230e
Bridge br0
Port gre0
Interface gre0
type: gre
options: {remote_ip="172.20.0.135"}
Port br0
Interface br0
type: internal
ovs_version: "2.13.5"
root@vm1:~# ip a show br0
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UNKNOWN group default qlen 1000
link/ether 8e:10:d6:2c:5b:43 brd ff:ff:ff:ff:ff:ff
inet6 fe80::8c10:d6ff:fe2c:5b43/64 scope link
valid_lft forever preferred_lft forever
# vm2
root@vm2:~# ovs-vsctl add-port br0 gre0 -- set Interface gre0 type=gre options:remote_ip=172.20.0.134
root@vm2:~# apt install bridge-utils
root@vm2:~# brctl addif docker0 br0
root@vm2:~# ovs-vsctl show
ad871957-28d4-4dd2-ae2a-d71fe70b8f8e
Bridge br0
Port br0
Interface br0
type: internal
Port gre0
Interface gre0
type: gre
options: {remote_ip="172.20.0.134"}
ovs_version: "2.13.5"
root@vm2:~# ip a show br0
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UNKNOWN group default qlen 1000
link/ether 8a:cb:e2:de:ee:4a brd ff:ff:ff:ff:ff:ff
inet6 fe80::88cb:e2ff:fede:ee4a/64 scope link
valid_lft forever preferred_lft forever
添加静态路由
在 vm1 和 vm2 均执行:
ip route add 172.17.0.0/16 dev docker0
验证
# vm1
root@vm1:~# docker run -it busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
/ # ip a show eth0
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:04:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.4.2/24 brd 172.17.4.255 scope global eth0
valid_lft forever preferred_lft forever
# vm2
root@vm2:~# docker run -it busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
/ # ip a show eth0
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:05:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.5.2/24 brd 172.17.5.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping -c1 172.17.4.2
PING 172.17.4.2 (172.17.4.2): 56 data bytes
64 bytes from 172.17.4.2: seq=0 ttl=63 time=1.004 ms
--- 172.17.4.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.004/1.004/1.004 ms
/ #
此时,vm1 和 vm2 分别创建的容器实现网络互通。
开机启动
将如下脚本添加到 /etc/rc.local
中,实现开机启动:
ip link set dev br0 up
brctl addif docker0 br0
ip route add 172.17.0.0/16 dev docker0