don't stop believing

Traffic Control (tc) - delay 본문

Network

Traffic Control (tc) - delay

Tongchun 2019. 1. 10. 18:51

Linux에서 네트워크 제어(Traffic Shaping)를 위해 tc를 한참 보게되었습니다.

음... tc의 구조와 사용법을 다 이해하지는 못했지만 우선 사용법을 정리해 보겠습니다.

tc(traffic control)에 대해 자세히 확인하고 싶다면 아래 링크를 확인하거나 tc 또는 traffic shaping으로 검색해 보기 바랍니다.

https://www.tldp.org/HOWTO/html_single/Traffic-Control-HOWTO/


tc를 사용하려면 iproute2를 설치해야 합니다.

1
$ sudo apt-get install iproute2
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

먼저 network interface에 대해 확인해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ifconfig
enp3s0: flags=4163 mtu 1500
inet 192.168.10.1 netmask 255.255.255.0 broadcast 192.168.10.255
ether 00:e0:63:36:15:1c txqueuelen 1000 (Ethernet)
RX packets 268746 bytes 204086666 (204.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 340979 bytes 365557779 (365.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 147
enp4s0: flags=4163 mtu 1500
inet 10.10.1.168 netmask 255.255.248.0 broadcast 10.10.7.255
inet6 fe80::60c9:1ec3:f9c1:b8f0 prefixlen 64 scopeid 0x20
ether 30:5a:3a:07:5c:6d txqueuelen 1000 (Ethernet)
RX packets 5298403 bytes 4292652377 (4.2 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1871916 bytes 555633283 (555.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1000 (Local Loopback)
RX packets 4632 bytes 377381 (377.3 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4632 bytes 377381 (377.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

테스트에 사용되는 Ubuntu에는 두 개의 interface가 있습니다. 이중 enp4s0를 사용해 tc를 확인해 보겠습니다.

그리고 현재의 네트워크 상태를 확인합니다. 테스트용 측적이니 변동성을 줄이기 위해 사내 PC로 Ping을 보냅니다.

(초기 google dns: 8.8.8.8로 ping을 보내 측정했는데 외부 영향으로 원하는 측정 데이터보다 변동성이 컸습니다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ping 10.10.0.78 -c 20
PING 10.10.0.78 (10.10.0.78) 56(84) bytes of data.
64 bytes from 10.10.0.78: icmp_seq=1 ttl=64 time=0.354 ms
64 bytes from 10.10.0.78: icmp_seq=2 ttl=64 time=0.343 ms
64 bytes from 10.10.0.78: icmp_seq=3 ttl=64 time=0.345 ms
64 bytes from 10.10.0.78: icmp_seq=4 ttl=64 time=0.346 ms
64 bytes from 10.10.0.78: icmp_seq=5 ttl=64 time=0.347 ms
64 bytes from 10.10.0.78: icmp_seq=6 ttl=64 time=0.345 ms
64 bytes from 10.10.0.78: icmp_seq=7 ttl=64 time=0.342 ms
64 bytes from 10.10.0.78: icmp_seq=8 ttl=64 time=0.345 ms
64 bytes from 10.10.0.78: icmp_seq=9 ttl=64 time=0.353 ms
64 bytes from 10.10.0.78: icmp_seq=10 ttl=64 time=0.353 ms
64 bytes from 10.10.0.78: icmp_seq=11 ttl=64 time=0.347 ms
64 bytes from 10.10.0.78: icmp_seq=12 ttl=64 time=0.345 ms
64 bytes from 10.10.0.78: icmp_seq=13 ttl=64 time=0.347 ms
64 bytes from 10.10.0.78: icmp_seq=14 ttl=64 time=0.344 ms
64 bytes from 10.10.0.78: icmp_seq=15 ttl=64 time=0.347 ms
64 bytes from 10.10.0.78: icmp_seq=16 ttl=64 time=0.344 ms
64 bytes from 10.10.0.78: icmp_seq=17 ttl=64 time=0.346 ms
64 bytes from 10.10.0.78: icmp_seq=18 ttl=64 time=0.346 ms
64 bytes from 10.10.0.78: icmp_seq=19 ttl=64 time=0.346 ms
64 bytes from 10.10.0.78: icmp_seq=20 ttl=64 time=0.346 ms
--- 10.10.0.78 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19430ms
rtt min/avg/max/mdev = 0.342/0.346/0.354/0.019 ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

평균 딜레이 타임은 0.346ms로 나옵니다. packet loss는 0% 이구요.


가장먼저 enp4s0에 delay 100ms를 적용합니다.

1
$ sudo tc qdisc add dev enp4s0 root netem delay 100ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

위 명령을 해석하면 아래와 같습니다.

qdisc: modify the scheduler (aka queuing discipline)

add: add a new rule

dev enp4s0: rules will be applied on device enp4s0

root: modify the outbound traffic scheduler (aka known as the egress qdisc)

netem: use the network emulator to emulate a WAN property

delay: the network property that is modified

200ms: introduce delay of 200 ms


적용된 rule을 확인하기위해 아래와 같이 실행합니다.

1
2
$ sudo tc qdisc show dev enp4s0
qdisc netem 8009: root refcnt 2 limit 1000 delay 100.0ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

delay 100.0ms가 적용된 것이 보입니다.

이제 다시 ping을 날려봅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ping 10.10.0.78 -c 20
PING 10.10.0.78 (10.10.0.78) 56(84) bytes of data.
64 bytes from 10.10.0.78: icmp_seq=1 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=2 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=3 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=4 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=5 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=6 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=7 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=8 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=9 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=10 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=11 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=12 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=13 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=14 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=15 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=16 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=17 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=18 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=19 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=20 ttl=64 time=100 ms
--- 10.10.0.78 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19027ms
rtt min/avg/max/mdev = 100.374/100.379/100.396/0.361 ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

사내 PC인 10.100.78까지 갔다오는데 전에는 0.3ms 정도였는데, tc로 delay 100ms를 설정한 후 rtt가 100ms가 되었습니다.


이번에는 delay를 100ms를 기본으로하고 +-10ms로 랜덤하게 변경합니다.

1
$ sudo tc qdisc change dev enp4s0 root netem delay 100ms 10ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

기존에 적용되었던 설정을 수정하는 것이기 때문에 add가 아닌 change로 했습니다.

명령에 delay 100ms 10ms로 수정하면 100 ms의 기본 delay에 +- 10 ms까지 랜덤하게 적용됩니다. (90ms ~ 110ms)

설정된 rule을 확인해 보겠습니다.

1
2
$ sudo tc qdisc show dev enp4s0
qdisc netem 8005: root refcnt 2 limit 1000 delay 100.0ms 10.0ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

이제 다시 Google DNS로 ping을 날려 봅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ping 10.10.0.78 -c 20
PING 10.10.0.78 (10.10.0.78) 56(84) bytes of data.
64 bytes from 10.10.0.78: icmp_seq=2 ttl=64 time=101 ms
64 bytes from 10.10.0.78: icmp_seq=3 ttl=64 time=106 ms
64 bytes from 10.10.0.78: icmp_seq=4 ttl=64 time=106 ms
64 bytes from 10.10.0.78: icmp_seq=5 ttl=64 time=109 ms
64 bytes from 10.10.0.78: icmp_seq=1 ttl=64 time=4393 ms
64 bytes from 10.10.0.78: icmp_seq=6 ttl=64 time=109 ms
64 bytes from 10.10.0.78: icmp_seq=7 ttl=64 time=101 ms
64 bytes from 10.10.0.78: icmp_seq=8 ttl=64 time=104 ms
64 bytes from 10.10.0.78: icmp_seq=9 ttl=64 time=106 ms
64 bytes from 10.10.0.78: icmp_seq=10 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=15 ttl=64 time=109 ms
64 bytes from 10.10.0.78: icmp_seq=11 ttl=64 time=4393 ms
64 bytes from 10.10.0.78: icmp_seq=12 ttl=64 time=4386 ms
64 bytes from 10.10.0.78: icmp_seq=13 ttl=64 time=4387 ms
64 bytes from 10.10.0.78: icmp_seq=17 ttl=64 time=602 ms
64 bytes from 10.10.0.78: icmp_seq=18 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=14 ttl=64 time=4386 ms
64 bytes from 10.10.0.78: icmp_seq=20 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=16 ttl=64 time=4388 ms
64 bytes from 10.10.0.78: icmp_seq=19 ttl=64 time=4386 ms
--- 10.10.0.78 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19118ms
rtt min/avg/max/mdev = 101.573/1629.445/4393.975/2027.818 ms, pipe 5
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

간혹 4388ms까지 튀는 구간이 발생합니다.


설정될 rule을 삭제해 보겠습니다.

1
$ sudo tc qdisc del dev enp4s0 root
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


이번에는 기본으로 100ms의 딜레이를 주고 25%의 비율로 10ms 딜레이로 적용하도록 합니다.

rule을 다시 추가하는 것이니 add로 주고 delay 100ms 10ms 25%를 추가합니다.

1
$ sudo tc qdisc add dev enp4s0 root netem delay 100ms 10ms 25%
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

적용된 rule을 확인해 봅니다.

1
2
$ sudo tc qdisc show dev enp4s0
qdisc netem 8006: root refcnt 2 limit 1000 delay 100.0ms 10.0ms 25%
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

다시 사내 PC로 ping을 날려 적용된 것을 확인합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ping 10.10.0.78 -c 20
PING 10.10.0.78 (10.10.0.78) 56(84) bytes of data.
64 bytes from 10.10.0.78: icmp_seq=2 ttl=64 time=101 ms
64 bytes from 10.10.0.78: icmp_seq=5 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=1 ttl=64 time=4391 ms
64 bytes from 10.10.0.78: icmp_seq=6 ttl=64 time=103 ms
64 bytes from 10.10.0.78: icmp_seq=7 ttl=64 time=101 ms
64 bytes from 10.10.0.78: icmp_seq=3 ttl=64 time=4387 ms
64 bytes from 10.10.0.78: icmp_seq=4 ttl=64 time=4393 ms
64 bytes from 10.10.0.78: icmp_seq=9 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=10 ttl=64 time=108 ms
64 bytes from 10.10.0.78: icmp_seq=11 ttl=64 time=105 ms
64 bytes from 10.10.0.78: icmp_seq=8 ttl=64 time=4387 ms
64 bytes from 10.10.0.78: icmp_seq=13 ttl=64 time=101 ms
64 bytes from 10.10.0.78: icmp_seq=15 ttl=64 time=103 ms
64 bytes from 10.10.0.78: icmp_seq=12 ttl=64 time=4387 ms
64 bytes from 10.10.0.78: icmp_seq=17 ttl=64 time=104 ms
64 bytes from 10.10.0.78: icmp_seq=14 ttl=64 time=4386 ms
64 bytes from 10.10.0.78: icmp_seq=19 ttl=64 time=107 ms
64 bytes from 10.10.0.78: icmp_seq=20 ttl=64 time=109 ms
64 bytes from 10.10.0.78: icmp_seq=16 ttl=64 time=4392 ms
64 bytes from 10.10.0.78: icmp_seq=18 ttl=64 time=4394 ms
--- 10.10.0.78 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19076ms
rtt min/avg/max/mdev = 101.237/1818.557/4394.391/2099.673 ms, pipe 5
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


이번에는 delay를 기본 100ms로 주고 +- 20ms의 delay를 균일하게 적용합니다. 

위 적용된 rule을 수정하는 것이니 change로 주고, delay 100ms 20ms distribution normal을 적용합니다.

균일한 적용이라 튀는 현상 없이 80ms ~ 120ms까지 delay가 발생합니다.

1
$ sudo tc qdisc add dev enp4s0 root netem delay 100ms 20ms distribution normal
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

적용인 rule을 확인해 봅니다.

1
2
$ sudo tc qdisc show dev enp4s0
qdisc netem 8007: root refcnt 2 limit 1000 delay 100.0ms 20.0ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

다시 사내 PC로 ping을 날려 확인합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ping 10.10.0.78 -c 20
PING 10.10.0.78 (10.10.0.78) 56(84) bytes of data.
64 bytes from 10.10.0.78: icmp_seq=1 ttl=64 time=116 ms
64 bytes from 10.10.0.78: icmp_seq=2 ttl=64 time=97.9 ms
64 bytes from 10.10.0.78: icmp_seq=3 ttl=64 time=78.3 ms
64 bytes from 10.10.0.78: icmp_seq=4 ttl=64 time=97.7 ms
64 bytes from 10.10.0.78: icmp_seq=5 ttl=64 time=92.5 ms
64 bytes from 10.10.0.78: icmp_seq=6 ttl=64 time=95.3 ms
64 bytes from 10.10.0.78: icmp_seq=7 ttl=64 time=69.8 ms
64 bytes from 10.10.0.78: icmp_seq=8 ttl=64 time=109 ms
64 bytes from 10.10.0.78: icmp_seq=9 ttl=64 time=115 ms
64 bytes from 10.10.0.78: icmp_seq=10 ttl=64 time=115 ms
64 bytes from 10.10.0.78: icmp_seq=11 ttl=64 time=140 ms
64 bytes from 10.10.0.78: icmp_seq=12 ttl=64 time=123 ms
64 bytes from 10.10.0.78: icmp_seq=13 ttl=64 time=107 ms
64 bytes from 10.10.0.78: icmp_seq=14 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=15 ttl=64 time=105 ms
64 bytes from 10.10.0.78: icmp_seq=16 ttl=64 time=87.7 ms
64 bytes from 10.10.0.78: icmp_seq=17 ttl=64 time=88.5 ms
64 bytes from 10.10.0.78: icmp_seq=18 ttl=64 time=90.5 ms
64 bytes from 10.10.0.78: icmp_seq=19 ttl=64 time=94.8 ms
64 bytes from 10.10.0.78: icmp_seq=20 ttl=64 time=130 ms
--- 10.10.0.78 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19028ms
rtt min/avg/max/mdev = 69.896/102.975/140.586/16.928 ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

튀는 현상 없이 균일하게 적용되고 있습니다.


이번에는 delay 100ms에 +- 20ms, 연관성 25%를 주고 균일하게 적용해 봅니다.

rule을 지우고 적용합니다.

1
2
3
4
$ sudo tc qdisc del dev enp4s0 root
$ sudo tc qdisc add dev enp4s0 root netem delay 100ms 20ms 25% distribution normal
$ sudo tc qdisc show dev enp4s0
qdisc netem 800e: root refcnt 2 limit 1000 delay 100.0ms 10.0ms 25%
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

다시 사내 PC로 ping을 날려 확인합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ping 10.10.0.78 -c 20
PING 10.10.0.78 (10.10.0.78) 56(84) bytes of data.
64 bytes from 10.10.0.78: icmp_seq=1 ttl=64 time=105 ms
64 bytes from 10.10.0.78: icmp_seq=2 ttl=64 time=120 ms
64 bytes from 10.10.0.78: icmp_seq=3 ttl=64 time=91.6 ms
64 bytes from 10.10.0.78: icmp_seq=4 ttl=64 time=87.9 ms
64 bytes from 10.10.0.78: icmp_seq=5 ttl=64 time=100 ms
64 bytes from 10.10.0.78: icmp_seq=6 ttl=64 time=81.6 ms
64 bytes from 10.10.0.78: icmp_seq=7 ttl=64 time=128 ms
64 bytes from 10.10.0.78: icmp_seq=8 ttl=64 time=105 ms
64 bytes from 10.10.0.78: icmp_seq=9 ttl=64 time=87.4 ms
64 bytes from 10.10.0.78: icmp_seq=10 ttl=64 time=97.4 ms
64 bytes from 10.10.0.78: icmp_seq=11 ttl=64 time=92.4 ms
64 bytes from 10.10.0.78: icmp_seq=12 ttl=64 time=81.1 ms
64 bytes from 10.10.0.78: icmp_seq=13 ttl=64 time=58.3 ms
64 bytes from 10.10.0.78: icmp_seq=14 ttl=64 time=93.6 ms
64 bytes from 10.10.0.78: icmp_seq=15 ttl=64 time=107 ms
64 bytes from 10.10.0.78: icmp_seq=16 ttl=64 time=65.2 ms
64 bytes from 10.10.0.78: icmp_seq=17 ttl=64 time=79.2 ms
64 bytes from 10.10.0.78: icmp_seq=18 ttl=64 time=102 ms
64 bytes from 10.10.0.78: icmp_seq=19 ttl=64 time=81.8 ms
64 bytes from 10.10.0.78: icmp_seq=20 ttl=64 time=99.8 ms
--- 10.10.0.78 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19026ms
rtt min/avg/max/mdev = 58.353/93.406/128.446/16.348 ms
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

ping 출력때문에 페이지가 길어지는 것 같습니다.

packet loss에 대해서는 다음 페이지에서 확인해 보겠습니다.



Comments