Docker容器基于OVS跨主机网络连接

摘要

利用OVS技术将位于不同物理主机中的docker容器的网络连通,使之能够相互访问。

前置条件

关闭 SELINUX

在配置文件中:

1
vi /etc/selinux/config

将其中的内容 SELINUX=enforcing 修改:

1
SELINUX=disabled

然后重启

安装 open-vswitch

参考【安装配置 Open-vSwitch-2.5.5】

启动 open-vSiwtch:

1
ovs-ctl start

配置 Docker 网桥IP

修改守护进程的配置文件:

1
vi /etc/docker/daemon.json

在其中添加网桥的IP设置:

1
"bip": "172.17.1.1/24"

重启docker:

1
2
systemctl stop docker
systemctl start docker

查看网桥IP:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.1.1 netmask 255.255.255.0 broadcast 172.17.1.255
ether 02:42:c7:7b:7d:28 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
...

确实变成了我们所设定的IP。

配置 Open-vSwitch

创建网桥

1
ovs-vsctl add-br br0

查看网桥

1
2
[root@localhost docker-data]# ovs-vsctl list-br
br0

创建端口

1
ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=192.168.0.125

查看端口

1
2
[root@localhost ~]# ovs-vsctl list-ports br0
gre0

查看详细配置信息

1
2
3
4
5
6
7
8
9
10
11
[root@localhost docker-data]# ovs-vsctl show      
840c2123-021b-4137-b1d5-8b0963c9e6ac
Bridge "br0"
Port "gre0"
Interface "gre0"
type: gre
options: {remote_ip="192.168.0.125"}
Port "br0"
Interface "br0"
type: internal
ovs_version: "2.5.5"

连接 br0 和 docker0

查看往前目前的连接情况:

1
2
3
4
[root@localhost docker-data]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024205ee36a6 no
virbr0 8000.525400249fb4 yes virbr0-nic

可以注意到,此时的 docker0 是没有接口连接的,我们将其与 br0 连接起来:

1
brctl addif docker0 br0

此时再查看时,会发现其与接口br0连接了:

1
2
3
4
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242c77b7d28 no br0
virbr0 8000.52540071bdcb yes virbr0-nic

挂载 docker0 和 br0

查看这两个网络连接的状态:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# ip link show
...
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 30:9c:23:e1:f0:d9 brd ff:ff:ff:ff:ff:ff
...
6: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master docker0 state DOWN mode DEFAULT group default qlen 1000
link/ether a2:37:3f:c1:46:4e brd ff:ff:ff:ff:ff:ff
...
10: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:c7:7b:7d:28 brd ff:ff:ff:ff:ff:ff
...

其中还有很多个其他连接的情况,这里省略不看,主要关注 br0 和 docker0,留着 eno1 主要是为了对比。
eno1 是本机物理网卡的连接,可以看到其状态 state UP,我们接下来要将 br0 和 docker0 也修改为 UP

1
ip link set dev br0 up

在将 br0 改为 UP 时,docker0 状态改为 up,而br0 为 UNKNOW:

1
2
3
4
5
6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether a2:37:3f:c1:46:4e brd ff:ff:ff:ff:ff:ff

10: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:c7:7b:7d:28 brd ff:ff:ff:ff:ff:ff

添加路由

查看当前路由规则:

1
2
3
4
5
[root@localhost ~]# ip route list
default via 192.168.0.1 dev eno1 proto static metric 100
172.17.1.0/24 dev docker0 proto kernel scope link src 172.17.1.2
192.168.0.0/24 dev eno1 proto kernel scope link src 192.168.0.125 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1

添加路由:

1
2
ip route add 172.17.0.0/16 dev docker0
route add -net 172.17.0.0/16 gw 192.168.0.125

检查确认:

1
2
3
4
5
6
7
8
[root@localhost ~]# ip route list
default via 192.168.0.1 dev enp0s31f6
169.254.0.0/16 dev enp0s31f6 scope link metric 1002
172.17.0.0/16 via 192.168.0.125 dev enp0s31f6
172.17.0.0/16 dev docker0 scope link
172.17.1.0/24 dev docker0 proto kernel scope link src 172.17.1.1
192.168.0.0/24 dev enp0s31f6 proto kernel scope link src 192.168.0.123
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1

网络结构

enter image description here