メインコンテンツへスキップ

Linux上でネットワークの帯域制限と遅延を設定する

NOTE
この記事は最終更新日から1年以上が経過しています。内容が古くなっている可能性があります。

無線通信をするアプリケーションのテストのために、帯域や遅延といった、ネットワークの状態をシミュレートしたいことがあると思います。 本記事では、Linux上で、ネットワークインタフェースに対する帯域制限と遅延の設定方法を説明します。

設定にはtcコマンドを使います。 tcコマンドとは、Traffic Controlコマンドのことで、Linux Kernel内の通信を制御します。

動作環境
#

本記事での動作環境を以下に示します。

ディストリビューション

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"

Linux Kernel

$ uname -sr
Linux 3.16.0-30-generic

tcコマンド

Ubuntu14.04にデフォルトでインストールされているものを使います。

設定方法
#

最初にコマンドを示します。各コマンドの解説は後述します。

帯域制限のみ

出力帯域を50Mbpsに制限します。

$ sudo tc qdisc add dev eth0 root handle 1:0 tbf rate 50mbit burst 25kb limit 250kb

遅延のみ

50msの遅延と10msのジッタを発生させます。ジッタとは、遅延量の揺らぎのことです。

$ sudo tc qdisc add dev root handle 1:0 netem delay 50ms 10ms distribution normal

帯域制限と遅延

帯域制限と遅延の両方を設定します。

$ sudo tc qdisc add dev eth0 root handle 1:0 tbf rate 50mbit burst 25kb limit 250kb
$ sudo tc qdisc add dev eth0 parent 1:1 handle 10:1 netem delay 50ms 10ms distribution normal

解説
#

帯域制限
#

以下のコマンドを実行すると、eth0の出力帯域を50Mbpsに制限します。

$ sudo tc qdisc add dev eth0 root handle 1:0 tbf rate 50mbit burst 25kb limit 250kb

以下から、このコマンドの詳細について説明します。 rate

帯域を指定します。50Mbpsに設定する場合は50mbitと指定します。 50mbpsと指定すると、50Mbyte/secになります。単位に注意してください。

burst

バッファサイズを指定します。tc-tbf(8)のManページによると、

The minimum buffer size can be calculated by dividing the rate by HZ.

とのことなので、以下の式で設定値を計算します。

burst(byte) = rate(byte) / HZ

HZはタイマー割り込み周波数です。 HZの値は以下のコマンドで確認できます。

$ cat /boot/config-\`uname -r\` | grep 'CONFIG_HZ='
CONFIG_HZ=250

rateが50mbit、HZが250HZの場合、以下のように計算します。 burst = (50 * 10^6 / 8) / 250 = 25 * 10^3

limit

burstと比較して十分に大きな値を設定します。 十分に大きな値を設定することで、帯域制限の方式をシェーピングに設定します。 帯域制限の方式及びシェーピングについては「 ポリシングとシェーピングの概要」を参照してください。

遅延の設定
#

以下のコマンドを実行すると、eth0に遅延50msとジッタ10msを設定します。

$ sudo tc qdisc add dev eth0 parent 1:1 handle 10:1 netem delay 50ms 10ms distribution normal

以下から、このコマンドの詳細について説明します。 delay

遅延を指定します。 1つ目の引数で遅延を指定して、2つ目の引数でジッタを指定します。 例えば、delay 50ms 10msなら、遅延は50ms、ジッタは10msとなります。 その後の、distribution normalで、ジッタの分布を正規分布に指定します。 以下に、distribution normalを指定した場合と、指定しなかった場合の、遅延の確率分布図を示します。

dist_normal
no_dist

オプションを指定すると、遅延が正規分布に近い分布になることががわかります。 また、オプションを指定しなかった場合には、遅延が一様分布に近い分布になることがわかります。

parent

parent 1:1で、既に設定してある帯域制限の設定と紐づけをします。 詳細は「 クラスフルなキューイング規則」を参照してください。

設定確認
#

tcコマンドで確認
#

$ sudo tc qdisc show dev eth0
qdisc tbf 1: root refcnt 2 rate 50000Kbit burst 25Kb lat 36.9ms
qdisc netem 10: parent 1:1 limit 1000 delay 50.0ms 10.0ms

遅延の確認
#

pingで遅延を確認します。

$ ping 192.168.1.37 -c 100
PING 192.168.1.37 (192.168.1.37) 56(84) bytes of data.
64 bytes from 192.168.1.37: icmp_seq=1 ttl=64 time=42.3 ms
64 bytes from 192.168.1.37: icmp_seq=2 ttl=64 time=47.9 ms
64 bytes from 192.168.1.37: icmp_seq=3 ttl=64 time=43.2 ms
64 bytes from 192.168.1.37: icmp_seq=4 ttl=64 time=53.5 ms
64 bytes from 192.168.1.37: icmp_seq=5 ttl=64 time=43.6 ms

~~~snip~~~

64 bytes from 192.168.1.37: icmp_seq=98 ttl=64 time=42.0 ms
64 bytes from 192.168.1.37: icmp_seq=99 ttl=64 time=63.4 ms
64 bytes from 192.168.1.37: icmp_seq=100 ttl=64 time=45.4 ms

--- 192.168.1.37 ping statistics ---
100 packets transmitted, 100 received, 0% packet loss, time 99191ms
rtt min/avg/max/mdev = 22.033/50.743/73.850/10.505 ms

50msの遅延と10msのジッタが入っていることが確認できます。

帯域の確認
#

iperf3で帯域を確認します。 iperf3とは、IPネットワーク上で帯域を測定するアプリケーションのことです。 クライアント/サーバアプリケーションとして動作します。

クライアント

$ iperf3 -c 192.168.1.37
Connecting to host 192.168.1.37, port 5201
[ 4] local 192.168.1.10 port 55652 connected to 192.168.1.37 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 4.61 MBytes 38.7 Mbits/sec 0 277 KBytes
[ 4] 1.00-2.00 sec 5.40 MBytes 45.3 Mbits/sec 2 290 KBytes
[ 4] 2.00-3.00 sec 5.56 MBytes 46.6 Mbits/sec 1 300 KBytes
[ 4] 3.00-4.00 sec 5.88 MBytes 49.3 Mbits/sec 0 307 KBytes
[ 4] 4.00-5.00 sec 5.45 MBytes 45.7 Mbits/sec 1 315 KBytes
[ 4] 5.00-6.00 sec 5.75 MBytes 48.2 Mbits/sec 2 322 KBytes
[ 4] 6.00-7.00 sec 5.70 MBytes 47.8 Mbits/sec 3 328 KBytes
[ 4] 7.00-8.00 sec 5.83 MBytes 48.9 Mbits/sec 1 335 KBytes
[ 4] 8.00-9.00 sec 5.78 MBytes 48.5 Mbits/sec 1 344 KBytes
[ 4] 9.00-10.00 sec 5.42 MBytes 45.4 Mbits/sec 1 348 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 55.4 MBytes 46.5 Mbits/sec 12 sender
[ 4] 0.00-10.00 sec 55.1 MBytes 46.2 Mbits/sec receiver

iperf Done.

サーバ

$ iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.1.10, port 55651
[ 5] local 192.168.1.37 port 5201 connected to 192.168.1.10 port 55652
[ ID] Interval Transfer Bandwidth
[ 5] 0.00-1.00 sec 3.76 MBytes 31.6 Mbits/sec
[ 5] 1.00-2.00 sec 5.45 MBytes 45.7 Mbits/sec
[ 5] 2.00-3.00 sec 5.64 MBytes 47.3 Mbits/sec
[ 5] 3.00-4.00 sec 5.71 MBytes 47.9 Mbits/sec
[ 5] 4.00-5.00 sec 5.64 MBytes 47.3 Mbits/sec
[ 5] 5.00-6.00 sec 5.68 MBytes 47.7 Mbits/sec
[ 5] 6.00-7.00 sec 5.74 MBytes 48.2 Mbits/sec
[ 5] 7.00-8.00 sec 5.73 MBytes 48.1 Mbits/sec
[ 5] 8.00-9.00 sec 5.68 MBytes 47.7 Mbits/sec
[ 5] 9.00-10.00 sec 5.65 MBytes 47.4 Mbits/sec
[ 5] 10.00-10.06 sec 363 KBytes 53.6 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 5] 0.00-10.06 sec 55.4 MBytes 46.2 Mbits/sec 12 sender
[ 5] 0.00-10.06 sec 55.1 MBytes 45.9 Mbits/sec receiver

帯域が50Mbit/secに制限されていることが確認できます。

以上、ネットワークインタフェースに対する帯域制限と遅延の設定方法でした。

関連記事

Containerlabを試してみた

弊社ではネットワーク系の開発案件が多く、開発中の動作検証環境は複数の仮想マシン(VM)を用いて構築しているのですが、少し前からコンテナで構築することも行っていました。

CPU Isolation

きょうは Linux カーネルがユーザーランドプロセスにスケジューリングしないCPUを確保しておく方法についてです。これによってコンテナやVMに割り当てるためのCPUが、ホストOSのユーザランドプロセスに使われてしまうことを回避できます。