Linux Network Namespace（その１：tcとの組み合わせ）

# いまさらながらLinux Network Namespaceに触れたみた
Linux Network Namespaceを使ってみた。CUIベースとは言え、VirtualBoxやGNS3なしで、仮想ネットワークを構築できるというメリットあり。インターネット上に多数の情報が見つかる。

## tc(traffic control)+iperfと組み合わせ
Network Namespace（以降「netns」）を用いて、仮想ネットワーク構築する。仮想ネットワークとのインターフェースにtcコマンドを適用する。ネットワーク的には下記となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/11c49154-98d0-dbe8-4538-35965d7b2892.png)
右側が作成した仮想ネットワーク”Guest”であり、iperfサーバーを実行し、仮想ネットワークを作成した左側にて、netns "Guest"に対してiperf（クライアント）およびpingを実行する。（”1st space”とはログイン後のシェルが動作している空間である。）

## 仮想ネットワーク構築
記事「[ip netnsコマンドで学ぶNetwork Namespace](https://christina04.hatenablog.com/entry/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に頼らず、使ってみることにした。