👹
Dockerコンテナ間の通信を遅延させる(ingress用制御つき)
この記事
早稲田大学コンピュータ研究会のアドベントカレンダーとして書いた記事です。
やりたいこと
Dockerコンテナを二つ用意し、Linux traffic controllerを利用しコンテナ間のトラフィックに障害(遅延)を発生させる。
デフォルトの設定だと外向き(egress)のパケットのみに遅延が発生するため、擬似デバイスをロードして内向き(ingress)のパケットをフィルターしリダイレクトさせ、遅延を発生させる。
cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
実際に遅延を発生させる
Dockerつくる
composeファイルを用意する
docker-compose.yml
version: "3.9"
services:
server:
image: ubuntu:latest
command: sleep infinity
networks:
- tc-test
client:
image: ubuntu:latest
command: sleep infinity
networks:
- tc-test
networks:
tc-test:
external: true
コマンド
$ docker network create tc-test
55d87a017adcf714e820723fead9af950816be363bd79feedd2a5637993ac89a
$ docker compose up -d
[+] Running 2/2
⠿ Container trafficcontrol_sample-server-1 Started 0.6s
⠿ Container trafficcontrol_sample-client-1 Started
仮想NICの名前を確認する
$ ip a | grep 55d87 # bridgeを作った時の出力
2917: br-55d87a017adc: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
inet 172.23.0.1/16 brd 172.23.255.255 scope global br-55d87a017adc
2923: vethc780b05@if2922: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-55d87a017adc state UP group default
2925: veth4f88b36@if2924: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-55d87a017adc state UP group default
カーネルモジュールのロード
$ sudo modprobe ifb numifbs=1
$ sudo modprobe act_mirred
ifbは仮想通信ポートです。act_mirredはパケットのリダイレクトをしてくれるやつです。
仮想通信ポートの有効化
$ sudo ip link set dev ifb0 up
複数使いたい時はnumifbsの数を増やしてifb1,ifb2と順番に有効化してください
ifb0にパケットを回す設定
さっきゲットしたvethc780b05を使います
$ sudo tc qdisc add dev vethc780b05 handle ffff: ingress
$ sudo tc filter add dev vethc780b05 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
障害の発生
$ sudo tc qdisc add dev vethc780b05 root handle 1: netem delay 200ms 20ms distribution normal loss 10%
$ sudo tc qdisc add dev ifb0 root handle 1: netem delay 200ms 20ms distribution normal loss 10%
これが遅延の設定です。内容は
- 200msの遅延x2
- 正規分布に従った10%(20ms)のジッタ
- パケロス10%(ingress,egress双方に発生してるのでこれを2乗した値が発生します)
帯域制限をかけたいなら
$ sudo tc qdisc add dev vethc780b05 root handle 1: htb default 10
$ sudo tc class add dev vethc780b05 parent 1: classid 1:1 htb rate 1mbit
$ sudo tc class add dev vethc780b05 parent 1:1 classid 1:10 htb rate 1mbit
$ sudo tc qdisc add dev ifb0 root handle 1: htb default 10
$ sudo tc class add dev ifb0 parent 1: classid 1:1 htb rate 1mbit
$ sudo tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 1mbit
こんな感じです。細かい設定についてはまた次の機会に記事を書こうと思います。
遅延が発生しているか確認
コンテナに入る
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59b053cead41 ubuntu:latest "sleep infinity" About an hour ago Up About an hour trafficcontrol_sample-server-1
2cfb9d91effe ubuntu:latest "sleep infinity" About an hour ago Up About an hour trafficcontrol_sample-client-1
$ docker inspect 59b053cead41 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.23.0.3",
$ docker compose exec client bash
# apt update
# apt install -y iputils-ping
# ping 172.23.0.3
PING 172.23.0.3 (172.23.0.3) 56(84) bytes of data.
64 bytes from 172.23.0.3: icmp_seq=2 ttl=64 time=411 ms
64 bytes from 172.23.0.3: icmp_seq=3 ttl=64 time=406 ms
64 bytes from 172.23.0.3: icmp_seq=4 ttl=64 time=380 ms
~~~ 略 ~~~
^C
--- 172.23.0.3 ping statistics ---
30 packets transmitted, 23 received, 23.3333% packet loss, time 29128ms
rtt min/avg/max/mdev = 330.492/395.859/441.963/23.431 ms
後片付け
$ sudo tc qdisc del dev vethc780b05 root
$ sudo tc qdisc del dev ifb 0 root
$ sudo modprobe -r ifb
Discussion