docker+openvswitch实现主机与容器的网络通信

时间:2022-04-25 18:11:48

主要用到openvswitch和netns网络名称空间的相关知识还有ip命令的使用。

实验环境的结构图如下:

docker+openvswitch实现主机与容器的网络通信

思路如下:

  1. 安装openvswitch
  2. ovs创建br0,br1,并启动两个不加载网络的docker容器
  3. 将容器关联网桥br0,并设置ip、vlan
  4. 创建veth0与veth1网卡对
  5. 创建netns名称空间,并添加veth0.0和veth1.0接口,并配置相关信息
  6. 将veth0.1和veth1.1分别桥接至br0,br1,并配置相关信息
  7. 添加SNAT和DNAT规则
  8. 给br1配置ip测试连通

具体步骤如下

1.安装openvswitch

# yum install -y openvswitch

下载OpenvSwitch项目提供的支持Docker容器的辅助脚本ovs-docker:

# wget https://github.com/openvswitch/ovs/raw/master/utilities/ovs-docker

# chmod a+x ovs-docker

此处脚本最好放在/root目录下,后续使用ovs-docker命令需要用到

docker+openvswitch实现主机与容器的网络通信

2.ovs创建br0,br1,并启动两个不加载网络的docker容器

# ovs-vsctl add-br br0

# ovs-vsctl add-br br0

# ip link set br0 up

# ip link set br1 up

# docker run –it –privileged=true –net=none –name box1 busybox:latest /bin/sh

# docker run –it –privileged=true –net=none –name box2 busybox:latest /bin/sh

通过ctrl p+ctrl q可以退出容器并且不关闭容器

docker+openvswitch实现主机与容器的网络通信

3.将容器关联网桥br0,并设置ip、vlan

# ./ovs-docker add-port br0 eth0 box1 –ipaddress=10.0.0.1/24 –gateway=10.0.0.253

# ./ovs-docker set-vlan br0 eth0 box1 5

# ./ovs-docker add-port br0 eth0 box2 –ipaddress=10.0.0.2/24 –gateway=10.0.0.253

# ./ovs-docker set-vlan br0 eth0 box2 5

此时可以先测试容器的互通性,两容器相互ping测试。

docker+openvswitch实现主机与容器的网络通信

4.创建veth0与veth1网卡对

# ip link add veth0.0 type veth peer name veth0.1

# ip link add veth1.0 type veth peer name veth1.1

注意开启:net.ipv4.ip_forward=1

5.创建netns名称空间,并添加veth0.0和veth1.0接口,并配置相关信息

# ip netns add r1               创建netns名称空间r1

# ip link set veth0.0 netns r1          添加两个接口

# ip link set veth1.0 netns r1

# ip netns exec r1 ip link set veth0.0 up   启动两个接口

# ip netns exec r1 ip link set veth1.0 up

# ip netns exec r1 ip addr add 192.168.2.221/24 dev veth1.0        给veth1.0添加ip

# ip netns exec r1 ifconfig veth1.0:1 192.168.1.223/24 up        配置两个浮动ip

# ip netns exec r1 ifconfig veth1.0:2 192.168.1.224/24 up

# ip netns exec r1 ip addr add 10.0.0.253/24 dev veth0.1        配置容器的网关地址

6.将veth0.1和veth1.1分别桥接至br0,br1,并配置相关信息

# ovs-vsctl add-port br0 veth0.1

# ovs-vsctl add-port br1 veth1.1

# ip link set veth0.1 up

# ip link set veth1.1 up

# ovs-vsctl set port veth0.1 tag=5        tag实际就是配置vlan,否则在vlan 5的容器内流量不会经过此接口

docker+openvswitch实现主机与容器的网络通信

此时可以测试容器的通信(容器内ping 10.0.0.253,ping 192.168.1.221)

7.添加SNAT和DNAT规则

SNAT:使得容器box1和box2能访问外网

# ip netns exec r1 iptables –t nat –A POSTROUTING –s 10.0.0.1/32 –j SNAT –-to-source 192.168.2.223

# ip netns exec r1 iptables –t nat –A POSTROUTING –s 10.0.0.2/32 –j SNAT –-to-source 192.168.2.224

DNAT:使得外网能够访问容器

# ip netns exec r1 iptables –t nat –A PREROUTING –d 192.168.2.223/32 –j DNAT –-to-destination 10.0.0.1

# ip netns exec r1 iptables –t nat –A PREROUTING –d 192.168.2.224/32 –j DNAT -–to-destination 10.0.0.2

 
8.给br1配置IP并测试整个通信

# ifconfig br1 192.168.1.122

docker+openvswitch实现主机与容器的网络通信

最后网桥br0和br1的接口信息:

docker+openvswitch实现主机与容器的网络通信

测试整个网络的通信

在容器中(box1):ping 10.0.0.2,ping 10.0.0.253,ping 192.168.1.221,ping 192.168.1.223,ping 192.168.1.224,ping 192.168.1.122,ping 192.168.1.222(本机ip)

在本机中(192.168.1.222):ping 192.168.1.122,ping 192.168.1.223,ping 192.168.1.224,ping 192.168.1.221

docker+openvswitch实现主机与容器的网络通信

docker+openvswitch实现主机与容器的网络通信

以上