一、整体架构
在ubuntu系统中创建了两个Docker容器,即left和right。在创建Docker容器的同时会创建一对veth pair的互联接口,这对互联接口类似于一根通信管道,当向任意一端发送数据包时,另一端都能自动收到相同的包。互联接口的一端与容器内的网卡eth0相连,另一端则是veth(Virtual ethernet)接口master在bridge上。网桥的另一端连接的是用户或者程序创建的Tap设备。Tap设备是链路层的虚拟网络设备,其作用等同于一个以太网设备,它可以收/发链路层的第二层数据报文包,如以太网数据帧。Tap设备的另一端则连接着我们在NS3脚本中创建的TapBridge网络设备,TapBridge网络设备存在于NS3的用户空间。
通过以上这些网络设备,从容器内应用产生的数据包最终可以进入NS3的用户空间,这些数据包最终通过TapBridge网络设备被转发到相应的CSMA网络设备,同理NS3中CSMA网络设备产生的数据包也可以通过同样的方式传递到容器内。最终实现容器与NS3之间互联互通如图1所示(第二部分案例实现完全按照图1 实现)。
图1
二、案例实现
2.1、环境配置
1、创建tap
ip tuntap add tap-left mode tap
ip tuntap add tap-right mode tap
2、将tap设备设为混杂模式并启动
设置混杂模式是为了使tap能够监听系统中所有正在发送的数据包以及允许docker容器之间通过虚拟网络通信
sudo ifconfig tap-left 0.0.0.0 promisc up
sudo ifconfig tap-right 0.0.0.0 promisc up
3、创建docker网桥
docker network create net-left
docker network create net-right
4、根据docker网桥的命名规则获取所有bridg
# 获取所有网络桥接的名称
readarray -t bridges < <(ip link show type bridge | awk -F': ' '{print $2}'| grep -i 'br-')
5、将tap绑定到相应的bridge上并启动
sudo brctl addif ${bridges[0]} tap-left
sudo brctl addif ${bridges[1]} tap-right
ip link set dev ${bridges[0]} up
ip link set dev ${bridges[1]} up
6、创建两个docker容器并指定容器挂载在不同的docker网桥上
docker run -id --name left --network net-left ubuntu /bin/bash
docker run -id --name right --network net-right ubuntu /bin/bash