いまさらながらLinux Network Namespaceに触れたみた
Linux Network Namespaceを使ってみた。CUIベースとは言え、VirtualBoxやGNS3なしで、仮想ネットワークを構築できるというメリットあり。インターネット上に多数の情報が見つかる。
tc(traffic control)+iperfと組み合わせ
Network Namespace(以降「netns」)を用いて、仮想ネットワーク構築する。仮想ネットワークとのインターフェースにtcコマンドを適用する。ネットワーク的には下記となる。
右側が作成した仮想ネットワーク”Guest”であり、iperfサーバーを実行し、仮想ネットワークを作成した左側にて、netns "Guest"に対してiperf(クライアント)およびpingを実行する。(”1st space”とはログイン後のシェルが動作している空間である。)
仮想ネットワーク構築
記事「ip netnsコマンドで学ぶNetwork Namespace」を参考にして、仮想ネットワークを作成。
$ sudo ip netns add guest
$ sudo ip link add name veth type veth peer name guest-veth
$ sudo ip link set guest-veth netns guest
$ sudo ip addr add 10.0.0.1/24 dev veth
$ sudo ip link set veth up
$ sudo ip netns exec guest bash
(ここから、"Guest" netnsでの実行)
# ip addr add 10.0.0.2/24 dev guest-veth
# ip link set guest-veth up
# ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.050 ms
"Guest"からのping疎通を確認。
tc+iperfによる検証
"Guest" netnsで、iperfサーバーを実行。
# iperf3 -s
フィルターなし(tcなし)
左側にコマンド実行(以降同様)。
$ iperf3 -c 10.0.0.2 -u -b 100m -t 100
...
[ 5] 99.00-100.00 sec 11.9 MBytes 100 Mbits/sec 8632
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-100.00 sec 1.16 GBytes 100 Mbits/sec 0.000 ms 0/863252 (0%) sender
[ 5] 0.00-100.00 sec 1.16 GBytes 100 Mbits/sec 0.002 ms 0/863252 (0%) receiver
100Mbpsで送れば、100Mbpsの結果が出る。
10%パケットドロップ
作成した仮想ネットワークインターフェースである”veth”に対して制御を実行。ここでは、10%のパケットドロップ実施。
$ sudo tc qdisc add dev veth root netem drop 10%
$ tc qdisc show dev veth
qdisc netem 8004: root refcnt 5 limit 1000 loss 10%
$ iperf3 -c 10.0.0.2 -u -b 100m -t 100
...
[ 5] 97.00-98.00 sec 11.9 MBytes 100 Mbits/sec 8632
[ 5] 98.00-99.00 sec 11.9 MBytes 100 Mbits/sec 8633
[ 5] 99.00-100.00 sec 11.9 MBytes 100 Mbits/sec 8632
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-100.00 sec 1.16 GBytes 100 Mbits/sec 0.000 ms 0/863252 (0%) sender
[ 5] 0.00-100.00 sec 1.05 GBytes 90.0 Mbits/sec 0.003 ms 86294/863252 (10%) receiver
設定どおり10%ロストしている。
帯域90Mbps指定
$ sudo tc qdisc add dev veth root netem rate 90mbit
$ tc qdisc show dev veth
qdisc netem 8005: root refcnt 5 limit 1000 rate 90Mbit
$ iperf3 -c 10.0.0.2 -u -b 100m -t 100
...
[ 5] 98.00-99.00 sec 11.9 MBytes 100 Mbits/sec 8633
[ 5] 99.00-100.00 sec 11.9 MBytes 100 Mbits/sec 8632
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-100.00 sec 1.16 GBytes 100 Mbits/sec 0.000 ms 0/863252 (0%) sender
[ 5] 0.00-100.13 sec 1.02 GBytes 87.5 Mbits/sec 0.209 ms 107229/863251 (12%) receiver
87.5Mbps。若干だが指定値(90Mbps)より小さい。こんなものか。
tc+pingによる検証
tcによる遅延を確認するため、pingを実行。
フィルターなし(tcなし)
$ ping 10.0.0.2 -c 100
...
--- 10.0.0.2 ping statistics ---
100 packets transmitted, 100 received, 0% packet loss, time 101395ms
rtt min/avg/max/mdev = 0.023/0.065/0.095/0.007 ms
100ms遅延+10msジッター
$ ping 10.0.0.2 -c 100
...
$ sudo tc qdisc add dev veth root netem delay 100ms 10ms
$ tc qdisc show dev veth
qdisc netem 8003: root refcnt 5 limit 1000 delay 100ms 10ms
64 bytes from 10.0.0.2: icmp_seq=90 ttl=64 time=104 ms
64 bytes from 10.0.0.2: icmp_seq=91 ttl=64 time=96.1 ms
64 bytes from 10.0.0.2: icmp_seq=92 ttl=64 time=93.0 ms
64 bytes from 10.0.0.2: icmp_seq=93 ttl=64 time=107 ms
64 bytes from 10.0.0.2: icmp_seq=94 ttl=64 time=97.0 ms
64 bytes from 10.0.0.2: icmp_seq=95 ttl=64 time=103 ms
64 bytes from 10.0.0.2: icmp_seq=96 ttl=64 time=91.8 ms
64 bytes from 10.0.0.2: icmp_seq=97 ttl=64 time=99.5 ms
64 bytes from 10.0.0.2: icmp_seq=98 ttl=64 time=107 ms
64 bytes from 10.0.0.2: icmp_seq=99 ttl=64 time=91.2 ms
64 bytes from 10.0.0.2: icmp_seq=100 ttl=64 time=107 ms
--- 10.0.0.2 ping statistics ---
100 packets transmitted, 100 received, 0% packet loss, time 99144ms
rtt min/avg/max/mdev = 90.204/100.949/110.064/5.675 ms
90-110msの遅延が発生していることがわかる。
終わりに
簡単に仮想ネットワークを構築して、ルーター/L3SwitchやL2Switchなどいろいろと検証できそう(いまさらながら)。簡単なものであれば、GNS3に頼らず、使ってみることにした。