mahimahi介绍
Mahimahi是MIT提出的一套用于网络仿真和分析的用户空间工具,可记录来自基于HTTP的应用程序流量,并在模拟的网络条件下重放流量内容进行准确的测量。
Docker
我是在docker上面搭的环境,容器的操作系统用的是Ubuntu 22.04。特别注意,mahimahi运行的时候需要访问到/dev/net/tun,一般方式运行起来的容器找不到这个文件,必须在创建容器的时候就使用–privileged来允许容器映射宿主机/dev中的全部文件!(血泪教训啊……第一次搭的环境本来都已经成功编译了,结果跑不起来,尝试了半天也没能让当前容器访问到宿主机的/dev,只好又创建了一个新容器,重新搭了一遍)
创建并启动容器命令:
docker run --privileged -v /path/in/host:/path/in/container --name container_name -it ubuntu:22.04 bash
其中,--privileged选项会给Docker容器提供额外的权限;-v指定宿主机和容器目录的映射关系,就是说,在容器内/path/in/container目录是宿主机/path/in/host目录的映射,这样便于在宿主机和容器间传递文件;--name指定容器的名字,如果不指定,系统就会分配一个随机的(很搞笑的)名字,比如“silly_varahamihira”;-it选项会让Docker容器在交互模式下运行;bash是你想在容器中运行的指令,这里我希望获得一个bash。
执行完上述命令,你就创建并启动了一个容器,并且此时你已经在容器内部了。如果此时在宿主机上开另一个bash并执行docker ps,你的容器应该在列。可以在容器内部使用exit退出容器,退出后再执行docker ps就看不到这个容器了,但执行docker ps -a能看到所有存在的容器,可以在此看到你的容器。如果想再次启动容器,可以使用docker start container_id_or_name命令,然后用docker exec -it container_name bash进入容器命令行。
Mahimahi安装
我这里无法使用apt-get直接安装mahimahi,报错找不到mahimahi包。所以我直接源码安装。
两个很好的教程:网络模拟和分析工具–Mahimahi的安装教程 和 网络仿真工具Mahimahi的安装和基础用法
我的docker刚创建,环境非常的干净,连vim都没有,正好可以记录一下mahimahi依赖的所有包。
首先要更新一下apt:apt update,但获得报错:
Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
Err:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
Couldn't create temporary file /tmp/apt.conf.XXLh0Z for passing config to apt-key
Err:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Couldn't create temporary file /tmp/apt.conf.Y0klwg for passing config to apt-key
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
Err:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Couldn't create temporary file /tmp/apt.conf.FVVrOZ for passing config to apt-key
Get:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease [127 kB]
Err:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Couldn't create temporary file /tmp/apt.conf.2CBY68 for passing config to apt-key
Reading package lists... Done
W: GPG error: http://security.ubuntu.com/ubuntu jammy-security InRelease: Couldn't create temporary file /tmp/apt.conf.XXLh0Z for passing config to apt-key
E: The repository 'http://security.ubuntu.com/ubuntu jammy-security InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
W: GPG error: http://archive.ubuntu.com/ubuntu jammy InRelease: Couldn't create temporary file /tmp/apt.conf.Y0klwg for passing config to apt-key
E: The repository 'http://archive.ubuntu.com/ubuntu jammy InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
W: GPG error: http://archive.ubuntu.com/ubuntu jammy-updates InRelease: Couldn't create temporary file /tmp/apt.conf.FVVrOZ for passing config to apt-key
E: The repository 'http://archive.ubuntu.com/ubuntu jammy-updates InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
W: GPG error: http://archive.ubuntu.com/ubuntu jammy-backports InRelease: Couldn't create temporary file /tmp/apt.conf.2CBY68 for passing config to apt-key
E: The repository 'http://archive.ubuntu.com/ubuntu jammy-backports InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
解决方案:先执行chmod 1777 /tmp,再执行apt update就不报错了。(这部分我在博客中有所记录)
然后开始安装依赖包:
apt install autoconf automake libtool
apt install libprotobuf-dev
apt install apache2-dev
apt install openssl #这个好像系统会自带
apt install libssl-dev
apt install "^libxcb.*" libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev
apt install libcairo2-dev
apt install libpango1.0-dev
apt install protobuf-compiler
apt install libprotobuf-dev
apt install iptables
apt install iproute2
apt install dnsmasq
依赖安装好了之后,开始编译安装Mahimahi:
# 掠过git clone环节,假设已经clone好了
cd mahimahi
./autogen.sh
./configure #这一步会检查依赖包是否全部安装完成,如有缺漏,安装好相应依赖包后再次执行本命令
make
make install #官方要求用sudo,但因为我在docker中天然是root,就不用sudo了
如果前面依赖安装的没问题,至此mahimahi安装完成。我第一次配环境的时候遇到./configure检查通过,但make的时候报错src/protobufs/下http_record.pb.cc和http_record.pb.h引入的google/protobuf/下部分头文件找不到的情况。检查发现这两个文件是在make过程中自动生成的,因此怀疑是libprotobuf-dev和protobuf-compiler版本不匹配造成,因为当时我的libprotobuf-dev是通过apt安装的,版本是3.12.4,而protobuf-compiler是通过发行版安装的,版本是3.7.0,后来通过将protobuf-compiler换成3.12.4解决了此问题。不过如果二者都是通过apt安装应该就不会遇到这个问题。
检查是否安装成功:在mahimahi目录下执行mm-delay 20,执行后命令行开头出现[delay 20 ms]就说明Mahimahi安装成功。
但这一步我还遇到了报错:
Died on std::runtime_error: mm-delay: please run as non-root
竟然不允许我用root权限运行这个指令……于是我只好在docker上用adduser usrname命令给自己开了一个非root用户。(小知识,用adduser创建新用户会自动在/home中创建一个以该用户名为文件名的目录,而用useradd创建用户则不会)
另外,如果创建docker的时候没有用--privileged选项,这一步也会报错:
Died on unix_error: open /dev/net/tun: No such file or directory
这我确实无力挽救,从头再配一遍吧哈哈哈哈哈哈哈orz
Mahimahi运行
Mahimahi官方手册在:https://manpages.debian.org/testing/mahimahi/
我们使用网络测试工具iperf3进行自动收发包和记录网络状态。apt install iperf3即可安装,iperf3使用方式可以参考iperf3网络测试工具使用方法。以下实验参考网络仿真工具Mahimahi的安装和基础用法。
在当前终端(Terminal 1)中运行ifconfig,记录IP地址。然后运行iperf3服务端:
iperf3 -s -p 12345 -i 1
-s表示以服务器模式运行,-p指定监听端口号,-i指定监控报告时间间隔,单位秒(s)。
在使用Mahimahi设置网络状态前先看一下原始状态。 这里我们再打开一个终端(Terminal 2)(可以通过在宿主机终端中运行docker exec -it container_name bash实现),运行
iperf3 -c server_ip -p 12345 -i 1
-c指定服务端IP,就是刚才从ifconfig中记录下的IP,-p指定目的端口,要与服务端监听端口一致,-i同上。
测试结果:
Connecting to host 172.17.0.3, port 12345
[ 5] local 172.17.0.3 port 56350 connected to 172.17.0.3 port 12345
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 2.58 GBytes 22.1 Gbits/sec 0 7.93 MBytes
[ 5] 1.00-2.00 sec 2.73 GBytes 23.4 Gbits/sec 0 7.93 MBytes
[ 5] 2.00-3.00 sec 3.20 GBytes 27.5 Gbits/sec 0 7.93 MBytes
[ 5] 3.00-4.00 sec 3.42 GBytes 29.3 Gbits/sec 0 7.93 MBytes
[ 5] 4.00-5.00 sec 3.35 GBytes 28.8 Gbits/sec 0 7.93 MBytes
[ 5] 5.00-6.00 sec 3.41 GBytes 29.3 Gbits/sec 0 7.93 MBytes
[ 5] 6.00-7.00 sec 3.63 GBytes 31.1 Gbits/sec 0 7.93 MBytes
[ 5] 7.00-8.00 sec 3.10 GBytes 26.6 Gbits/sec 0 7.93 MBytes
[ 5] 8.00-9.00 sec 3.31 GBytes 28.4 Gbits/sec 0 7.93 MBytes
[ 5] 9.00-10.00 sec 3.27 GBytes 28.1 Gbits/sec 0 7.93 MBytes
[ 5] 10.00-11.00 sec 3.54 GBytes 30.4 Gbits/sec 0 7.93 MBytes
[ 5] 11.00-12.00 sec 3.28 GBytes 28.2 Gbits/sec 0 7.93 MBytes
[ 5] 12.00-13.00 sec 2.98 GBytes 25.6 Gbits/sec 0 7.93 MBytes
然后设置传播时延:mm-delay 20(单位:ms),再次运行iperf3(不需要停止服务端,只要重新运行客户端即可),测试结果:
Connecting to host 172.17.0.3, port 12345
[ 5] local 100.64.0.2 port 53638 connected to 172.17.0.3 port 12345
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 25.1 MBytes 210 Mbits/sec 560 1.16 MBytes
[ 5] 1.00-2.00 sec 28.8 MBytes 241 Mbits/sec 0 1.24 MBytes
[ 5] 2.00-3.00 sec 28.8 MBytes 241 Mbits/sec 0 1.29 MBytes
[ 5] 3.00-4.00 sec 30.0 MBytes 252 Mbits/sec 0 1.33 MBytes
[ 5] 4.00-5.00 sec 31.2 MBytes 262 Mbits/sec 0 1.35 MBytes
[ 5] 5.00-6.00 sec 30.0 MBytes 252 Mbits/sec 0 1.36 MBytes
[ 5] 6.00-7.00 sec 31.2 MBytes 262 Mbits/sec 0 1.37 MBytes
[ 5] 7.00-8.00 sec 30.0 MBytes 252 Mbits/sec 0 1.37 MBytes
[ 5] 8.00-9.00 sec 31.2 MBytes 262 Mbits/sec 0 1.37 MBytes
[ 5] 9.00-10.00 sec 31.2 MBytes 262 Mbits/sec 0 1.37 MBytes
[ 5] 10.00-11.00 sec 32.5 MBytes 273 Mbits/sec 0 1.38 MBytes
[ 5] 11.00-12.00 sec 27.5 MBytes 231 Mbits/sec 0 1.40 MBytes
[ 5] 12.00-13.00 sec 25.0 MBytes 210 Mbits/sec 52 1.08 MBytes
再设置上行链路丢包率:mm-loss uplink 0.01,再次运行iperf3,测试结果:
Connecting to host 172.17.0.3, port 12345
[ 5] local 100.64.0.4 port 36152 connected to 172.17.0.3 port 12345
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 1.55 MBytes 13.0 Mbits/sec 8 15.6 KBytes
[ 5] 1.00-2.00 sec 255 KBytes 2.08 Mbits/sec 4 8.48 KBytes
[ 5] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec 2 15.6 KBytes
[ 5] 3.00-4.00 sec 509 KBytes 4.17 Mbits/sec 1 22.6 KBytes
[ 5] 4.00-5.00 sec 509 KBytes 4.17 Mbits/sec 5 9.90 KBytes
[ 5] 5.00-6.00 sec 0.00 Bytes 0.00 bits/sec 2 11.3 KBytes
[ 5] 6.00-7.00 sec 509 KBytes 4.17 Mbits/sec 2 11.3 KBytes
[ 5] 7.00-8.00 sec 255 KBytes 2.08 Mbits/sec 0 29.7 KBytes
[ 5] 8.00-9.00 sec 764 KBytes 6.26 Mbits/sec 2 24.0 KBytes
[ 5] 9.00-10.00 sec 509 KBytes 4.17 Mbits/sec 3 19.8 KBytes
[ 5] 10.00-11.00 sec 509 KBytes 4.17 Mbits/sec 2 21.2 KBytes
[ 5] 11.00-12.00 sec 509 KBytes 4.17 Mbits/sec 1 22.6 KBytes
[ 5] 12.00-13.00 sec 255 KBytes 2.08 Mbits/sec 7 9.90 KBytes
最后设置链路带宽:mm-link traces/Verizon-LTE-short.up traces/Verizon-LTE-short.down,这里面traces/Verizon-LTE-short.up和traces/Verizon-LTE-short.down都是mahimahi源码中就包含的文件,这两个文件中记录了收集该数据时的动态链路带宽。再次运行iperf3,测试结果:
Connecting to host 172.17.0.3, port 12345
[ 5] local 100.64.0.5 port 52262 connected to 172.17.0.3 port 12345
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 614 KBytes 5.03 Mbits/sec 5 28.3 KBytes
[ 5] 1.00-2.00 sec 255 KBytes 2.08 Mbits/sec 0 28.3 KBytes
[ 5] 2.00-3.00 sec 382 KBytes 3.13 Mbits/sec 3 14.1 KBytes
[ 5] 3.00-4.00 sec 255 KBytes 2.09 Mbits/sec 4 7.07 KBytes
[ 5] 4.00-5.00 sec 0.00 Bytes 0.00 bits/sec 1 12.7 KBytes
[ 5] 5.00-6.00 sec 255 KBytes 2.09 Mbits/sec 1 14.1 KBytes
[ 5] 6.00-7.00 sec 127 KBytes 1.04 Mbits/sec 0 22.6 KBytes
[ 5] 7.00-8.00 sec 255 KBytes 2.09 Mbits/sec 0 28.3 KBytes
[ 5] 8.00-9.00 sec 509 KBytes 4.17 Mbits/sec 2 21.2 KBytes
[ 5] 9.00-10.00 sec 255 KBytes 2.08 Mbits/sec 3 12.7 KBytes
[ 5] 10.00-11.00 sec 255 KBytes 2.09 Mbits/sec 3 9.90 KBytes
[ 5] 11.00-12.00 sec 127 KBytes 1.04 Mbits/sec 3 7.07 KBytes
[ 5] 12.00-13.00 sec 127 KBytes 1.04 Mbits/sec 2 11.3 KBytes
注意,以上设置是叠加的。也可以通过命令mm-delay 20 mm-loss uplink 0.01 mm-link traces/Verizon-LTE-short.up traces/Verizon-LTE-short.down --meter-all来一次性设置好。这里面--meter-all表示可视化数据传输过程中的带宽和时延动态变化情况,但因为我做实验的Ubuntu不是桌面版,无法可视化,所以去掉了这一参数。
退出仿真网络环境可以运行exit,一次性设置好的话运行一次即可,逐层设置的话要逐层退出。
Mahimahi网络仿真实现原理可以读这篇博客:链路仿真工具 - Mahimahi使用教程

4982

被折叠的 条评论
为什么被折叠?



