Ns3与Docker之间实现数据通信

一、整体架构

在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

7、在Linux中允许操作系统将以太网帧转发到新创建的网桥(可以忽略这步的错误)

sudo iptables -I FORWARD -m physdev --physdev-is-bridged -i ${bridges[0]} -p tcp -j ACCEPT
sudo iptables -I FORWARD -m physdev --physdev-is-bridged -i ${bridges[0]} -p arp -j ACCEPT
sudo iptables -I FORWARD -m physdev --physdev-is-bridged -i ${bridges[1]} -p tcp -j ACCEPT
sudo iptables -I FORWARD -m physdev --physdev-is-bridged -i ${bridges[1]} -p arp -j ACCEPT

8、分别获取Docker容器进程 ID (PID) ---容器一定要启动状态

pid_left=$(docker inspect --format '{{ .State.Pid }}' left)

pid_right=$(docker inspect --format '{{ .State.Pid }}' right)

9、创建一个新的网络命名空间,该命名空间将以符号方式链接到第一个Docker容器left

mkdir -p /var/run/netns sudo

ln -s /proc/$pid_left/ns/net /var/run/netns/$pid_left

10、创建 veth pair将容器连接到自定义网桥

sudo ip link add internal-left type veth peer name external-left
sudo ip link set internal-left master ${bridges[0]}
sudo ip link set internal-left up

11、为容器left分配 IP 地址和 MAC 地址

sudo ip link set external-left netns $pid_left
sudo ip netns exec $pid_left ip link set dev external-left name eth0
sudo ip netns exec $pid_left ip link set eth0 address 12:34:88:5D:61:BD
sudo ip netns exec $pid_left ip link set eth0 up
sudo ip netns exec $pid_left ip addr add 10.0.0.1/16 dev eth0

12、right容器配置

sudo ln -s /proc/$pid_right/ns/net /var/run/netns/$pid_right
sudo ip link add internal-right type veth peer name external-right
sudo ip link set internal-right master ${bridges[1]}
sudo ip link set internal-right up

sudo ip link set external-right netns $pid_right
sudo ip netns exec $pid_right ip link set dev external-right name eth0
sudo ip netns exec $pid_right ip link set eth0 address 12:34:88:5D:62:BD
sudo ip netns exec $pid_right ip link set eth0 up
sudo ip netns exec $pid_right ip addr add 10.0.0.2/16 dev eth0

2.2、在root权限下运行ns3

添加图片注释,不超过 140 字(可选)

2.3、进入docker中相互ping

添加图片注释,不超过 140 字(可选)

三、多个容器与ns3通信

通过 docker Compose,可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

3.1、安装docker compose

1.安装curl(可选)

sudo apt update

sudo apt install curl

2.下载Docker Compose二进制文件

sudo curl -L "https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

3.设置权限

sudo chmod +x /usr/local/bin/docker-compose

4.检查

docker-compose version

3.2、使用docker compose管理多个docker

yaml文件

Docker Compose 是一个用于定义和运行多容器Docker应用程序的工具。可以使用YAML文件来配置docker的服务。

services:
  node1:
    container_name: node1
    build:
      dockerfile: images/ueDevice.Dockerfile
      context: .
    networks:
        - net-node1
    tty: true
  node2:
    container_name: node2
    build:
      dockerfile: images/Device.Dockerfile
      context: .
    networks:
      - net-node2
    tty: true
networks:
 net-node1:
  external: true
 net-node2:
  external: true
#create nodes

dockerfile文件

用于自动构建 Docker 镜像

FROM ubuntu

RUN apt-get update && apt-get install -y \
	iputils-ping 	\
	iproute2     	\
	netcat		\
  traceroute \
  curl \
	&& rm -rf /var/lib/apt/lists/*

CMD ["/bin/bash"]

其他配置

在这里使用一个脚本文件配置两个docker分别为node1和node2(用于和上面区分),bridges变量会获取到所有的br-****的bridge(因为我系统中只有两个br-***的bridge所以我使用的是 ${bridges[0]} 和 ${bridges[1]})。

在文件没有创建新的veth pair互联接口使用docker自带的互联接口

#创建tap
echo "Create tap ..."
ip tuntap add tap-node1 mode tap
ip tuntap add tap-node2 mode tap
#将tap设备设为混杂模式并启动   
sudo ifconfig tap-node1 0.0.0.0 promisc up
sudo ifconfig tap-node2 0.0.0.0 promisc up
echo "Done."
#创建docker网桥
echo "Create docker bridge ..."
docker network create --driver bridge net-node1
docker network create --driver bridge net-node2
# 获取所有网络桥接的名称  
readarray -t bridges < <(ip link show type bridge | awk -F': ' '{print $2}'| grep -i 'br-')
echo ${bridges[0]}
echo ${bridges[1]}
#将tap绑定到相应的网桥上并启动
sudo brctl addif ${bridges[0]} tap-node1
sudo brctl addif ${bridges[1]} tap-node2
ip link set dev ${bridges[0]} up
ip link set dev ${bridges[1]} up
echo "Done."
#创建两个docker容器并指定容器挂载在不同的docker网桥上
echo "Create docker bridge ..."
docker-compose -f test.yaml up -d
echo "Done."
#分别获取Docker容器进程 ID (PID)   ---容器一定要启动状态
echo "get pid  ..."
pid_node1=$(docker inspect --format '{{ .State.Pid }}' node1)
pid_node2=$(docker inspect --format '{{ .State.Pid }}' node2)
echo "Done."
#创建一个新的网络命名空间,该命名空间将以符号方式链接到第一个Docker容器left
echo "set node1..."
mkdir -p /var/run/netns
sudo ln -s /proc/$pid_node1/ns/net /var/run/netns/$pid_node1
echo "set node1..."
#为容器node1分配 IP 地址和 MAC 地址
sudo ip netns exec $pid_node1 ip link set eth0 up
sudo ip netns exec $pid_node1 ip addr add 10.0.0.3/16 dev eth0
echo "Done."
#容器node2
echo "set node2..."
sudo ln -s /proc/$pid_node2/ns/net /var/run/netns/$pid_node2
sudo ip link set external-node2 netns $pid_node2
sudo ip netns exec $pid_node2 ip link set eth0 up
sudo ip netns exec $pid_node2 ip addr add 10.0.0.4/16 dev eth0
echo "Done."

添加图片注释,不超过 140 字(可选)

参考文献:

Docker与NS3之间实现数据通信_ns3 能否给外面设备发数据-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_50881817/article/details/134154970

How to Use Docker and NS-3 to Create Realistic Network Simulations (cmu.edu)icon-default.png?t=N7T8https://insights.sei.cmu.edu/blog/how-to-use-docker-and-ns-3-to-create-realistic-network-simulations/相关的脚本文件下载:

NS3与docker数据通信相关脚本文件资源-CSDN文库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值