Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

๋ช‡ ๋…„ ์ „ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ด๋ฏธ ๋…ผ์˜ ๊ณต์‹ GitHub ๋ธ”๋กœ๊ทธ์—์„œ. ์ดํ›„ ์„œ๋น„์Šค ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ํ‘œ์ค€ ๊ธฐ์ˆ ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Kubernetes๋Š” ์ด์ œ ๋‚ด๋ถ€ ๋ฐ ๊ณต์šฉ ์„œ๋น„์Šค์˜ ์ƒ๋‹น ๋ถ€๋ถ„์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์„ฑ์žฅํ•˜๊ณ  ์„ฑ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ์ด ๋”์šฑ ์—„๊ฒฉํ•ด์ง์— ๋”ฐ๋ผ Kubernetes์˜ ์ผ๋ถ€ ์„œ๋น„์Šค์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž์ฒด์˜ ๋กœ๋“œ๋กœ๋Š” ์„ค๋ช…ํ•  ์ˆ˜ ์—†๋Š” ์ง€์—ฐ ์‹œ๊ฐ„์ด ์‚ฐ๋ฐœ์ ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฐœ๊ฒฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ตœ๋Œ€ 100ms ์ด์ƒ์˜ ๋ฌด์ž‘์œ„ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๊ฒฝํ—˜ํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋˜๋Š” ์žฌ์‹œ๋„๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค๋Š” 100ms๋ณด๋‹ค ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์š”์ฒญ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฐ๊ฒฐ ์ž์ฒด์— ๋„ˆ๋ฌด ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฉด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด์™€ ๋ณ„๋„๋กœ ์šฐ๋ฆฌ๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ์†Œ์š”๋˜๋Š” ๋งค์šฐ ๋น ๋ฅธ MySQL ์ฟผ๋ฆฌ๋ฅผ ๊ด€์ฐฐํ–ˆ์œผ๋ฉฐ MySQL์€ ๋ฐ€๋ฆฌ์ดˆ ๋งŒ์— ์™„๋ฃŒ๋˜์—ˆ์ง€๋งŒ ์š”์ฒญ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ด€์ ์—์„œ๋Š” ์‘๋‹ต์— 100ms ์ด์ƒ์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

ํ˜ธ์ถœ์ด Kubernetes ์™ธ๋ถ€์—์„œ ์™”๋”๋ผ๋„ Kubernetes ๋…ธ๋“œ์— ์—ฐ๊ฒฐํ•  ๋•Œ๋งŒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ๊ฒƒ์ด ์ฆ‰์‹œ ๋ถ„๋ช…ํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. ๋‹จ์กฐ๋กœ์šด ์ƒํ™œ์„ํ•˜๋‹ค๋Š” ๋‚ด๋ถ€ ํ˜ธ์ŠคํŠธ์—์„œ ์‹คํ–‰๋˜๋ฉฐ ํŠน์ • ํฌํŠธ์—์„œ Kubernetes ์„œ๋น„์Šค๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‚ฐ๋ฐœ์ ์œผ๋กœ ๋†’์€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ด ๋ฌธ์ œ์˜ ์›์ธ์„ ์–ด๋–ป๊ฒŒ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹คํŒจ๋กœ ์ด์–ด์ง€๋Š” ์ฒด์ธ์˜ ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ ์ œ๊ฑฐ

๋™์ผํ•œ ์˜ˆ๋ฅผ ์žฌํ˜„ํ•จ์œผ๋กœ์จ ๋ฌธ์ œ์˜ ์ดˆ์ ์„ ์ขํžˆ๊ณ  ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ ๊ณ„์ธต์„ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” Vegeta์™€ Kubernetes ํฌ๋“œ ์‚ฌ์ด์˜ ํ๋ฆ„์— ์š”์†Œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ๋” ๊นŠ์€ ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•˜๋ ค๋ฉด ๊ทธ ์ค‘ ์ผ๋ถ€๋ฅผ ๋ฐฐ์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

ํด๋ผ์ด์–ธํŠธ(Vegeta)๋Š” ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ชจ๋“  ๋…ธ๋“œ์™€ TCP ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. Kubernetes๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ค๋ฒ„๋ ˆ์ด ๋„คํŠธ์›Œํฌ(๊ธฐ์กด ๋ฐ์ดํ„ฐ ์„ผํ„ฐ ๋„คํŠธ์›Œํฌ ์œ„์—)๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. IPIP์ฆ‰, ๋ฐ์ดํ„ฐ ์„ผํ„ฐ์˜ IP ํŒจํ‚ท ๋‚ด๋ถ€์— ์˜ค๋ฒ„๋ ˆ์ด ๋„คํŠธ์›Œํฌ์˜ IP ํŒจํ‚ท์„ ์บก์Šํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ์— ์—ฐ๊ฒฐํ•  ๋•Œ ๋„คํŠธ์›Œํฌ ์ฃผ์†Œ ๋ณ€ํ™˜์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์ฃผ์†Œ ๋ณ€ํ™˜ (NAT) ์ƒํƒœ ์ €์žฅ์„ ํ†ตํ•ด Kubernetes ๋…ธ๋“œ์˜ IP ์ฃผ์†Œ ๋ฐ ํฌํŠธ๋ฅผ ์˜ค๋ฒ„๋ ˆ์ด ๋„คํŠธ์›Œํฌ(ํŠนํžˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ๋Š” Pod)์˜ IP ์ฃผ์†Œ ๋ฐ ํฌํŠธ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ํŒจํ‚ท์˜ ๊ฒฝ์šฐ ๋ฐ˜๋Œ€ ์ˆœ์„œ์˜ ์ž‘์—…์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค๊ฐ€ ๋ฐฐํฌ๋˜๊ณ  ์ด๋™๋จ์— ๋”ฐ๋ผ ์ง€์†์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๊ณ  ๋ณ€๊ฒฝ๋˜๋Š” ๋งŽ์€ ์ƒํƒœ์™€ ๋งŽ์€ ์š”์†Œ๊ฐ€ ํฌํ•จ๋œ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.

๊ณต์ต ์‚ฌ์—… tcpdump Vegeta ํ…Œ์ŠคํŠธ์—์„œ๋Š” TCP ํ•ธ๋“œ์…ฐ์ดํฌ(SYN๊ณผ SYN-ACK ๊ฐ„) ์ค‘์— ์ง€์—ฐ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ์„ ์ œ๊ฑฐํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. hping3 SYN ํŒจํ‚ท์„ ์‚ฌ์šฉํ•œ ๊ฐ„๋‹จํ•œ "ํ•‘"์šฉ์ž…๋‹ˆ๋‹ค. ์‘๋‹ต ํŒจํ‚ท์— ์ง€์—ฐ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ ํ›„ ์—ฐ๊ฒฐ์„ ์žฌ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. 100ms๋ณด๋‹ค ํฐ ํŒจํ‚ท๋งŒ ํฌํ•จํ•˜๋„๋ก ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๊ณ  Vegeta์˜ ์ „์ฒด ๋„คํŠธ์›Œํฌ ๊ณ„์ธต 7 ํ…Œ์ŠคํŠธ๋ณด๋‹ค ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋Š” ๋” ์‰ฌ์šด ๋ฐฉ๋ฒ•์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ฐ€์žฅ ๋Š๋ฆฐ ์‘๋‹ต์œผ๋กœ ํ•„ํ„ฐ๋ง๋œ 30927ms ๊ฐ„๊ฒฉ์œผ๋กœ ์„œ๋น„์Šค "๋…ธ๋“œ ํฌํŠธ"(10)์—์„œ TCP SYN/SYN-ACK๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Kubernetes ๋…ธ๋“œ "ping"์ž…๋‹ˆ๋‹ค.

theojulienne@shell ~ $ sudo hping3 172.16.47.27 -S -p 30927 -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1485 win=29200 rtt=127.1 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1486 win=29200 rtt=117.0 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1487 win=29200 rtt=106.2 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1488 win=29200 rtt=104.1 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=5024 win=29200 rtt=109.2 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=5231 win=29200 rtt=109.2 ms

์ฆ‰์‹œ ์ฒซ ๋ฒˆ์งธ ๊ด€์ฐฐ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œํ€€์Šค ๋ฒˆํ˜ธ์™€ ํƒ€์ด๋ฐ์œผ๋กœ ํŒ๋‹จํ•˜๋ฉด ์ด๋Š” ์ผํšŒ์„ฑ ์ •์ฒด๊ฐ€ ์•„๋‹˜์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ง€์—ฐ์€ ์ข…์ข… ๋ˆ„์ ๋˜์–ด ๊ฒฐ๊ตญ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ, ํ˜ผ์žก ๋ฐœ์ƒ์— ์–ด๋–ค ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ด€๋ จ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๊ฒƒ์ด NAT์— ์žˆ๋Š” ์ˆ˜๋ฐฑ ๊ฐœ์˜ iptables ๊ทœ์น™ ์ค‘ ์ผ๋ถ€์ผ๊นŒ์š”? ์•„๋‹ˆ๋ฉด ๋„คํŠธ์›Œํฌ์˜ IPIP ํ„ฐ๋„๋ง์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๋ฅผ ํ™•์ธํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์‹œ์Šคํ…œ์˜ ๊ฐ ๋‹จ๊ณ„๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. NAT ๋ฐ ๋ฐฉํ™”๋ฒฝ ๋…ผ๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  IPIP ๋ถ€๋ถ„๋งŒ ๋‚จ๊ฒจ๋‘๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ Linux์—์„œ๋Š” ์‹œ์Šคํ…œ์ด ๋™์ผํ•œ ๋„คํŠธ์›Œํฌ์— ์žˆ๋Š” ๊ฒฝ์šฐ IP ์˜ค๋ฒ„๋ ˆ์ด ๊ณ„์ธต์— ์ง์ ‘ ์‰ฝ๊ฒŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

theojulienne@kube-node-client ~ $ sudo hping3 10.125.20.64 -S -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=40 ip=10.125.20.64 ttl=64 DF id=0 sport=0 flags=RA seq=7346 win=0 rtt=127.3 ms

len=40 ip=10.125.20.64 ttl=64 DF id=0 sport=0 flags=RA seq=7347 win=0 rtt=117.3 ms

len=40 ip=10.125.20.64 ttl=64 DF id=0 sport=0 flags=RA seq=7348 win=0 rtt=107.2 ms

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ๋‚จ์•„์žˆ์Šต๋‹ˆ๋‹ค! iptables์™€ NAT๋Š” ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋ฌธ์ œ๋Š” TCP์ธ๊ฐ€? ์ผ๋ฐ˜ ICMP ํ•‘์ด ์–ด๋–ป๊ฒŒ ์ง„ํ–‰๋˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

theojulienne@kube-node-client ~ $ sudo hping3 10.125.20.64 --icmp -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=28 ip=10.125.20.64 ttl=64 id=42594 icmp_seq=104 rtt=110.0 ms

len=28 ip=10.125.20.64 ttl=64 id=49448 icmp_seq=4022 rtt=141.3 ms

len=28 ip=10.125.20.64 ttl=64 id=49449 icmp_seq=4023 rtt=131.3 ms

len=28 ip=10.125.20.64 ttl=64 id=49450 icmp_seq=4024 rtt=121.2 ms

len=28 ip=10.125.20.64 ttl=64 id=49451 icmp_seq=4025 rtt=111.2 ms

len=28 ip=10.125.20.64 ttl=64 id=49452 icmp_seq=4026 rtt=101.1 ms

len=28 ip=10.125.20.64 ttl=64 id=50023 icmp_seq=4343 rtt=126.8 ms

len=28 ip=10.125.20.64 ttl=64 id=50024 icmp_seq=4344 rtt=116.8 ms

len=28 ip=10.125.20.64 ttl=64 id=50025 icmp_seq=4345 rtt=106.8 ms

len=28 ip=10.125.20.64 ttl=64 id=59727 icmp_seq=9836 rtt=106.1 ms

๊ฒฐ๊ณผ๋Š” ๋ฌธ์ œ๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š์•˜์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๊ฒƒ์€ IPIP ํ„ฐ๋„์ผ๊นŒ์š”? ํ…Œ์ŠคํŠธ๋ฅผ ๋”์šฑ ๋‹จ์ˆœํ™”ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

์ด ๋‘ ํ˜ธ์ŠคํŠธ ๊ฐ„์— ๋ชจ๋“  ํŒจํ‚ท์ด ์ „์†ก๋ฉ๋‹ˆ๊นŒ?

theojulienne@kube-node-client ~ $ sudo hping3 172.16.47.27 --icmp -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=46 ip=172.16.47.27 ttl=61 id=41127 icmp_seq=12564 rtt=140.9 ms

len=46 ip=172.16.47.27 ttl=61 id=41128 icmp_seq=12565 rtt=130.9 ms

len=46 ip=172.16.47.27 ttl=61 id=41129 icmp_seq=12566 rtt=120.8 ms

len=46 ip=172.16.47.27 ttl=61 id=41130 icmp_seq=12567 rtt=110.8 ms

len=46 ip=172.16.47.27 ttl=61 id=41131 icmp_seq=12568 rtt=100.7 ms

len=46 ip=172.16.47.27 ttl=61 id=9062 icmp_seq=31443 rtt=134.2 ms

len=46 ip=172.16.47.27 ttl=61 id=9063 icmp_seq=31444 rtt=124.2 ms

len=46 ip=172.16.47.27 ttl=61 id=9064 icmp_seq=31445 rtt=114.2 ms

len=46 ip=172.16.47.27 ttl=61 id=9065 icmp_seq=31446 rtt=104.2 ms

๋‘ ๊ฐœ์˜ Kubernetes ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ํŒจํ‚ท, ์‹ฌ์ง€์–ด ICMP ping์„ ๋ณด๋‚ด๋Š” ์ƒํ™ฉ์„ ๋‹จ์ˆœํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์ƒ ํ˜ธ์ŠคํŠธ๊ฐ€ "๋ถˆ๋Ÿ‰"(์ผ๋ถ€๋Š” ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ๋” ๋‚˜์จ)์ธ ๊ฒฝ์šฐ์—๋„ ์—ฌ์ „ํžˆ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ๋งˆ์ง€๋ง‰ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ์™œ ์ง€์—ฐ์ด kube-node ์„œ๋ฒ„์—์„œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  kube-node๊ฐ€ ๋ฐœ์‹ ์ž์ผ ๋•Œ๋‚˜ ์ˆ˜์‹ ์ž์ผ ๋•Œ ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜๋‚˜์š”? ์šด ์ข‹๊ฒŒ๋„ ์ด๋Š” Kubernetes ์™ธ๋ถ€์˜ ํ˜ธ์ŠคํŠธ์—์„œ ๋™์ผํ•œ "์•Œ๋ ค์ง„ ๋ถˆ๋Ÿ‰" ์ˆ˜์‹ ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒจํ‚ท์„ ๋ณด๋‚ด๋ฉด ์‰ฝ๊ฒŒ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณด์‹œ๋‹ค์‹œํ”ผ ๋ฌธ์ œ๋Š” ์‚ฌ๋ผ์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

theojulienne@shell ~ $ sudo hping3 172.16.47.27 -p 9876 -S -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=312 win=0 rtt=108.5 ms

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=5903 win=0 rtt=119.4 ms

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=6227 win=0 rtt=139.9 ms

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=7929 win=0 rtt=131.2 ms

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด์ „ ์†Œ์Šค kube-node์—์„œ ์™ธ๋ถ€ ํ˜ธ์ŠคํŠธ๋กœ ๋™์ผํ•œ ์š”์ฒญ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค(ping์— RX ๋ฐ TX ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋˜๋ฏ€๋กœ ์†Œ์Šค ํ˜ธ์ŠคํŠธ๋Š” ์ œ์™ธ๋จ).

theojulienne@kube-node-client ~ $ sudo hping3 172.16.33.44 -p 9876 -S -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'
^C
--- 172.16.33.44 hping statistic ---
22352 packets transmitted, 22350 packets received, 1% packet loss
round-trip min/avg/max = 0.2/7.6/1010.6 ms

๋Œ€๊ธฐ ์‹œ๊ฐ„ ํŒจํ‚ท ์บก์ฒ˜๋ฅผ ์กฐ์‚ฌํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฐœ์‹ ์ž(ํ•˜๋‹จ)๋Š” ์ด ์‹œ๊ฐ„ ์ดˆ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ˆ˜์‹ ์ž(์ƒ๋‹จ)๋Š” ์ด๋ฅผ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ธํƒ€ ์—ด(์ดˆ)์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

๋˜ํ•œ ์ˆ˜์‹ ์ž ์ธก์—์„œ TCP์™€ ICMP ํŒจํ‚ท์˜ ์ˆœ์„œ(์‹œํ€€์Šค ๋ฒˆํ˜ธ ๊ธฐ์ค€) ์ฐจ์ด๋ฅผ ์‚ดํŽด๋ณด๋ฉด ICMP ํŒจํ‚ท์€ ํ•ญ์ƒ ์ „์†ก๋œ ์ˆœ์„œ์™€ ๋™์ผํ•˜์ง€๋งŒ ํƒ€์ด๋ฐ์ด ๋‹ค๋ฅด๊ฒŒ ๋„์ฐฉํ•ฉ๋‹ˆ๋‹ค. ๋™์‹œ์— TCP ํŒจํ‚ท์ด ๋•Œ๋•Œ๋กœ ์ธํ„ฐ๋ฆฌ๋ธŒ๋˜๊ณ  ์ผ๋ถ€๋Š” ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ํŠนํžˆ SYN ํŒจํ‚ท์˜ ํฌํŠธ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์†ก์‹ ์ž ์ธก์—์„œ๋Š” ์ˆœ์„œ๊ฐ€ ์žˆ์ง€๋งŒ ์ˆ˜์‹ ์ž ์ธก์—์„œ๋Š” ์ˆœ์„œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ•์—๋Š” ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ๋„คํŠธ์›Œํฌ ์นด๋“œ ๋ฐ์ดํ„ฐ ์„ผํ„ฐ์™€ ๊ฐ™์€ ์ตœ์‹  ์„œ๋ฒ„๋Š” TCP ๋˜๋Š” ICMP๊ฐ€ ํฌํ•จ๋œ ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํŒจํ‚ท์ด ๋„์ฐฉํ•˜๋ฉด ๋„คํŠธ์›Œํฌ ์–ด๋Œ‘ํ„ฐ๋Š” "์—ฐ๊ฒฐ๋‹น ํ•ด์‹œ"ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์—ฐ๊ฒฐ์„ ๋Œ€๊ธฐ์—ด๋กœ ๋‚˜๋ˆ„๊ณ  ๊ฐ ๋Œ€๊ธฐ์—ด์„ ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์„œ ์ฝ”์–ด๋กœ ๋ณด๋‚ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. TCP์˜ ๊ฒฝ์šฐ ์ด ํ•ด์‹œ์—๋Š” ์†Œ์Šค ๋ฐ ๋Œ€์ƒ IP ์ฃผ์†Œ์™€ ํฌํŠธ๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐ ์—ฐ๊ฒฐ์€ (์ž ์žฌ์ ์œผ๋กœ) ๋‹ค๋ฅด๊ฒŒ ํ•ด์‹œ๋ฉ๋‹ˆ๋‹ค. ICMP์˜ ๊ฒฝ์šฐ ํฌํŠธ๊ฐ€ ์—†์œผ๋ฏ€๋กœ IP ์ฃผ์†Œ๋งŒ ํ•ด์‹œ๋ฉ๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ์ƒˆ๋กœ์šด ๊ด€์ฐฐ: ์ด ๊ธฐ๊ฐ„ ๋™์•ˆ ๋‘ ํ˜ธ์ŠคํŠธ ๊ฐ„์˜ ๋ชจ๋“  ํ†ต์‹ ์—์„œ ICMP๊ฐ€ ์ง€์—ฐ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ TCP๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์›์ธ์ด RX ๋Œ€๊ธฐ์—ด ํ•ด์‹ฑ๊ณผ ๊ด€๋ จ์ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ์ •์ฒด๋Š” ๊ฑฐ์˜ ํ™•์‹คํ•˜๊ฒŒ ์‘๋‹ต ์ „์†ก์ด ์•„๋‹ˆ๋ผ RX ํŒจํ‚ท ์ฒ˜๋ฆฌ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ€๋Šฅํ•œ ์›์ธ ๋ชฉ๋ก์—์„œ ํŒจํ‚ท ์ „์†ก์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๋Š” ์ผ๋ถ€ kube-node ์„œ๋ฒ„์˜ ์ˆ˜์‹  ์ธก์—์„œ ํŒจํ‚ท ์ฒ˜๋ฆฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Linux ์ปค๋„์˜ ํŒจํ‚ท ์ฒ˜๋ฆฌ ์ดํ•ด

์ผ๋ถ€ kube-node ์„œ๋ฒ„์˜ ์ˆ˜์‹ ์ž์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด Linux ์ปค๋„์ด ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๊ธฐ์กด ๊ตฌํ˜„์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ๋„คํŠธ์›Œํฌ ์นด๋“œ๋Š” ํŒจํ‚ท์„ ์ˆ˜์‹ ํ•˜๊ณ  ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉํ•ดํ•˜๋‹ค ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ํŒจํ‚ค์ง€๊ฐ€ ์žˆ๋‹ค๋Š” Linux ์ปค๋„. ์ปค๋„์€ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ค‘์ง€ํ•˜๊ณ  ์ปจํ…์ŠคํŠธ๋ฅผ ์ธํ„ฐ๋ŸฝํŠธ ์ฒ˜๋ฆฌ๊ธฐ๋กœ ์ „ํ™˜ํ•˜๊ณ  ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ ํ˜„์žฌ ์ž‘์—…์œผ๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

์ด๋Ÿฌํ•œ ์ปจํ…์ŠคํŠธ ์ „ํ™˜์€ ๋Š๋ฆฝ๋‹ˆ๋‹ค. 10๋…„๋Œ€์—๋Š” 90Mbps ๋„คํŠธ์›Œํฌ ์นด๋“œ์—์„œ๋Š” ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๋ˆˆ์— ๋„์ง€ ์•Š์•˜์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ดˆ๋‹น ์ตœ๋Œ€ ์ฒ˜๋ฆฌ๋Ÿ‰์ด 10๋งŒ ํŒจํ‚ท์ธ ์ตœ์‹  15G ์นด๋“œ์—์„œ๋Š” ์†Œํ˜• XNUMX์ฝ”์–ด ์„œ๋ฒ„์˜ ๊ฐ ์ฝ”์–ด๊ฐ€ ์ˆ˜๋ฐฑ๋งŒ ๋ฒˆ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๋‹น ํšŸ์ˆ˜.

์ง€์†์ ์œผ๋กœ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๋ช‡ ๋…„ ์ „์— Linux์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜ํ”ผ: ๋ชจ๋“  ์ตœ์‹  ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๊ณ ์†์—์„œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋„คํŠธ์›Œํฌ API์ž…๋‹ˆ๋‹ค. ๋‚ฎ์€ ์†๋„์—์„œ๋„ ์ปค๋„์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์˜ˆ์ „ ๋ฐฉ์‹์œผ๋กœ ๋„คํŠธ์›Œํฌ ์นด๋“œ๋กœ๋ถ€ํ„ฐ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ž„๊ณ„๊ฐ’์„ ์ดˆ๊ณผํ•˜๋Š” ์ถฉ๋ถ„ํ•œ ํŒจํ‚ท์ด ๋„์ฐฉํ•˜๋ฉด ์ปค๋„์€ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ๋Œ€์‹  ๋„คํŠธ์›Œํฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ํด๋งํ•˜๊ณ  ํŒจํ‚ท์„ ์ฒญํฌ ๋‹จ์œ„๋กœ ์ˆ˜์ง‘ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜๋ฆฌ๋Š” Softirq์—์„œ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์†Œํ”„ํŠธ์›จ์–ด ์ธํ„ฐ๋ŸฝํŠธ์˜ ์ปจํ…์ŠคํŠธ ์‹œ์Šคํ…œ ํ˜ธ์ถœ ๋ฐ ํ•˜๋“œ์›จ์–ด ์ค‘๋‹จ ํ›„ ์ปค๋„(์‚ฌ์šฉ์ž ๊ณต๊ฐ„๊ณผ ๋ฐ˜๋Œ€)์ด ์ด๋ฏธ ์‹คํ–‰ ์ค‘์ผ ๋•Œ.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

์ด๋Š” ํ›จ์”ฌ ๋น ๋ฅด์ง€๋งŒ ๋‹ค๋ฅธ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ํŒจํ‚ท์ด ๋„ˆ๋ฌด ๋งŽ์œผ๋ฉด ๋„คํŠธ์›Œํฌ ์นด๋“œ์—์„œ ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๋ชจ๋“  ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๊ณ  ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ํ”„๋กœ์„ธ์Šค์—๋Š” ์‹ค์ œ๋กœ ์ด๋Ÿฌํ•œ ๋Œ€๊ธฐ์—ด์„ ๋น„์šธ ์‹œ๊ฐ„์ด ์—†์Šต๋‹ˆ๋‹ค(TCP ์—ฐ๊ฒฐ์—์„œ ์ฝ๊ธฐ ๋“ฑ). ๊ฒฐ๊ตญ ๋Œ€๊ธฐ์—ด์ด ์ฑ„์›Œ์ง€๊ณ  ํŒจํ‚ท ์‚ญ์ œ๊ฐ€ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ๊ท ํ˜•์„ ์ฐพ๊ธฐ ์œ„ํ•ด ์ปค๋„์€ Softirq ์ปจํ…์ŠคํŠธ์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ์ตœ๋Œ€ ํŒจํ‚ท ์ˆ˜์— ๋Œ€ํ•œ ์˜ˆ์‚ฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‚ฐ์ด ์ดˆ๊ณผ๋˜๋ฉด ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ksoftirqd (๊ทธ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ps ์ฝ”์–ด๋‹น) ์ผ๋ฐ˜์ ์ธ syscall/์ธํ„ฐ๋ŸฝํŠธ ๊ฒฝ๋กœ ์™ธ๋ถ€์—์„œ ์ด๋Ÿฌํ•œ Softirq๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์ •ํ•˜๊ฒŒ ํ• ๋‹นํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ํ‘œ์ค€ ํ”„๋กœ์„ธ์Šค ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

์ปค๋„์ด ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์—ฐ๊ตฌํ•œ ๊ฒฐ๊ณผ ํ˜ผ์žก์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Softirq ํ˜ธ์ถœ์˜ ์ˆ˜์‹  ๋นˆ๋„๊ฐ€ ๋‚ฎ์•„์ง€๋ฉด ํŒจํ‚ท์€ ๋„คํŠธ์›Œํฌ ์นด๋“œ์˜ RX ๋Œ€๊ธฐ์—ด์—์„œ ์ฒ˜๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ถ€ ์ž‘์—…์ด ํ”„๋กœ์„ธ์„œ ์ฝ”์–ด๋ฅผ ์ฐจ๋‹จํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์š”์ธ์œผ๋กœ ์ธํ•ด ์ฝ”์–ด๊ฐ€ Softirq๋ฅผ ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒ˜๋ฆฌ ๋ฒ”์œ„๋ฅผ ํ•ต์‹ฌ ๋˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ขํžˆ๊ธฐ

Softirq ์ง€์—ฐ์€ ํ˜„์žฌ๋กœ์„œ๋Š” ์ถ”์ธก์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๊ฒƒ์€ ๋ง์ด ๋˜๊ณ , ์šฐ๋ฆฌ๋Š” ๋งค์šฐ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ๋ณด๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ ๋‹จ๊ณ„๋Š” ์ด ์ด๋ก ์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ™•์ธ๋œ ๊ฒฝ์šฐ ์ง€์—ฐ ์ด์œ ๋ฅผ ์ฐพ์œผ์‹ญ์‹œ์˜ค.

๋Š๋ฆฐ ํŒจํ‚ท์œผ๋กœ ๋Œ์•„๊ฐ€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

len=46 ip=172.16.53.32 ttl=61 id=29573 icmp_seq=1953 rtt=99.3 ms

len=46 ip=172.16.53.32 ttl=61 id=29574 icmp_seq=1954 rtt=89.3 ms

len=46 ip=172.16.53.32 ttl=61 id=29575 icmp_seq=1955 rtt=79.2 ms

len=46 ip=172.16.53.32 ttl=61 id=29576 icmp_seq=1956 rtt=69.1 ms

len=46 ip=172.16.53.32 ttl=61 id=29577 icmp_seq=1957 rtt=59.1 ms

len=46 ip=172.16.53.32 ttl=61 id=29790 icmp_seq=2070 rtt=75.7 ms

len=46 ip=172.16.53.32 ttl=61 id=29791 icmp_seq=2071 rtt=65.6 ms

len=46 ip=172.16.53.32 ttl=61 id=29792 icmp_seq=2072 rtt=55.5 ms

์•ž์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ด๋Ÿฌํ•œ ICMP ํŒจํ‚ท์€ ๋‹จ์ผ RX NIC ๋Œ€๊ธฐ์—ด๋กœ ํ•ด์‹œ๋˜๊ณ  ๋‹จ์ผ CPU ์ฝ”์–ด์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. Linux ์ž‘๋™ ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๋ ค๋ฉด ํ”„๋กœ์„ธ์Šค๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋Ÿฌํ•œ ํŒจํ‚ค์ง€๊ฐ€ ์–ด๋””์—์„œ(์–ด๋–ค CPU ์ฝ”์–ด์—์„œ) ์–ด๋–ป๊ฒŒ(softirq, ksoftirqd) ์ฒ˜๋ฆฌ๋˜๋Š”์ง€ ์•„๋Š” ๊ฒƒ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์‹ค์‹œ๊ฐ„์œผ๋กœ Linux ์ปค๋„์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๋Š” ์ˆจ์€ ์ฐธ์กฐ. ์ด ๋„๊ตฌ ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปค๋„์—์„œ ์ž„์˜์˜ ํ•จ์ˆ˜๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ Python ํ”„๋กœ๊ทธ๋žจ์— ๋ฒ„ํผ๋งํ•˜๋Š” ์ž‘์€ C ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปค๋„์— ์ž„์˜์˜ ๊ธฐ๋Šฅ์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์€ ๋ณต์žกํ•œ ๋ฌธ์ œ์ด์ง€๋งŒ ์ด ์œ ํ‹ธ๋ฆฌํ‹ฐ๋Š” ๋ณด์•ˆ์„ ๊ทน๋Œ€ํ™”ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ ํ…Œ์ŠคํŠธ ๋˜๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์‰ฝ๊ฒŒ ์žฌํ˜„๋˜์ง€ ์•Š๋Š” ์ƒ์‚ฐ ๋ฌธ์ œ์˜ ์ข…๋ฅ˜๋ฅผ ์ •ํ™•ํžˆ ์ถ”์ ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ์˜ ๊ณ„ํš์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„์ด ์ด๋Ÿฌํ•œ ICMP ํ•‘์„ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ปค๋„ ๊ธฐ๋Šฅ์— ํ›„ํฌ๋ฅผ ๊ฒ๋‹ˆ๋‹ค. icmp_echo, ๋“ค์–ด์˜ค๋Š” ICMP ์—์ฝ” ์š”์ฒญ ํŒจํ‚ท์„ ์ˆ˜๋ฝํ•˜๊ณ  ICMP ์—์ฝ” ์‘๋‹ต ๋ณด๋‚ด๊ธฐ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. icmp_seq ๋ฒˆํ˜ธ๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ ํŒจํ‚ท์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. hping3 ์œ„.

์•”ํ˜ธ ์ˆจ์€ ์ฐธ์กฐ ์Šคํฌ๋ฆฝํŠธ ๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ ์ƒ๊ฐ๋งŒํผ ๋ฌด์„ญ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ icmp_echo ์ „์†กํ•˜๋‹ค struct sk_buff *skb: "์—์ฝ” ์š”์ฒญ"์ด ํฌํ•จ๋œ ํŒจํ‚ท์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์ถ”์ ํ•˜๊ณ  ์‹œํ€€์Šค๋ฅผ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ์–ด์š” echo.sequence (์ด๊ฒƒ์€ icmp_seq ์ž‘์„ฑ์ž: hping3 ะฒั‹ัˆะต), ์ด๋ฅผ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค ์ด๋ฆ„/ID๋ฅผ ์บก์ฒ˜ํ•˜๋Š” ๊ฒƒ๋„ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์ปค๋„์ด ํŒจํ‚ท์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋™์•ˆ ์ง์ ‘ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

TGID PID ํ”„๋กœ์„ธ์Šค ์ด๋ฆ„ ICMP_SEQ 0 0 swapper/11 770 0 0 swapper/11 771 0 0 swapper/11 772 0 0 swapper/11 773 0 0 swapper/11 774 20041 20086 prometheus 775 0 0 swapper/11 776 0 0 swapper/11 777 0 0 11 ์Šค์™‘ํผ/778 4512 4542 779 ์Šคํฌํฌ-๋ณด๊ณ ์„œ-s XNUMX

์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€ ๋ฌธ๋งฅ์ƒ softirq ์‹œ์Šคํ…œ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•œ ํ”„๋กœ์„ธ์Šค๋Š” ์‹ค์ œ๋กœ ์ปค๋„ ์ปจํ…์ŠคํŠธ์—์„œ ํŒจํ‚ท์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปค๋„์ธ ๊ฒฝ์šฐ "ํ”„๋กœ์„ธ์Šค"๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ด ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ํ”„๋กœ์„ธ์Šค๋ฅผ ์ง€์—ฐ์„ ๋‚˜ํƒ€๋‚ด๋Š” ํŠน์ • ํŒจํ‚ค์ง€์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. hping3. ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž grep ํŠน์ • ๊ฐ’์— ๋Œ€ํ•œ ์ด ์บก์ฒ˜์— ๋Œ€ํ•ด icmp_seq. ์œ„์˜ icmp_seq ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š” ํŒจํ‚ท์€ ์œ„์—์„œ ๊ด€์ฐฐํ•œ RTT์™€ ํ•จ๊ป˜ ๊ธฐ๋ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค(๊ด„ํ˜ธ ์•ˆ์€ 50ms ๋ฏธ๋งŒ์˜ RTT ๊ฐ’์œผ๋กœ ์ธํ•ด ํ•„ํ„ฐ๋งํ•œ ํŒจํ‚ท์— ๋Œ€ํ•œ ์˜ˆ์ƒ RTT ๊ฐ’์ž…๋‹ˆ๋‹ค).

TGID PID ํ”„๋กœ์„ธ์Šค ์ด๋ฆ„ ICMP_SEQ ** RTT -- 10137 10436 cadvisor 1951 10137 10436 cadvisor 1952 76 76 ksoftirqd/11 1953 ** 99ms 76 76 ksoftirqd/11 1954 ** 89ms 76 76 ksoftir qd/11 1955 79 ** 76ms 76 11 ksoftirqd/ 1956 69 ** 76ms 76 11 ksoftirqd/1957 59 ** 76ms 76 11 ksoftirqd/1958 49 ** (76ms) 76 11 ksoftirqd/1959 39 ** (76ms) 76 11 ksoftirqd/1960 29 ** (76ms) 76 11 ksoft irqd/ 1961 19 ** (76ms) 76 11 ksoftirqd/1962 9 ** (10137ms) -- 10436 2068 cadvisor 10137 10436 2069 cadvisor 76 76 11 ksoftirqd/2070 75 ** 76ms 76 11 ksoftirqd/2071 65 76 ** 76ms 11 2072 ksoftirqd/55 76 ** 76ms 11 2073 ksoftirqd/45 76 ** (76ms) 11 2074 ksoftirqd/35 76 ** (76ms) 11 2075 ksoftirqd/25 76 ** (76ms) 11 2076 ksoftirqd/15 76 ** (76ms) ) 11 2077 ksoftirqd/5 XNUMX ** (XNUMXms)

๊ฒฐ๊ณผ๋Š” ์šฐ๋ฆฌ์—๊ฒŒ ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์‹ค์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ์ฒซ์งธ, ์ด๋Ÿฌํ•œ ๋ชจ๋“  ํŒจํ‚ค์ง€๋Š” ์ปจํ…์ŠคํŠธ์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ksoftirqd/11. ์ด๋Š” ์ด ํŠน์ • ์ปดํ“จํ„ฐ ์Œ์˜ ๊ฒฝ์šฐ ICMP ํŒจํ‚ท์ด ์ˆ˜์‹  ์ธก์˜ ์ฝ”์–ด 11๋กœ ํ•ด์‹œ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์žผ์ด ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์‹œ์Šคํ…œ ํ˜ธ์ถœ์˜ ๋งฅ๋ฝ์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ํŒจํ‚ท์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. cadvisor. ๊ทธ๋Ÿฐ ๋‹ค์Œ ksoftirqd ์ž‘์—…์„ ์ธ๊ณ„๋ฐ›์•„ ๋ˆ„์ ๋œ ๋Œ€๊ธฐ์—ด์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ ๊ทธ ์ดํ›„์— ๋ˆ„์ ๋œ ํŒจํ‚ท ์ˆ˜์ž…๋‹ˆ๋‹ค. cadvisor.

์ง์ „์— ํ•ญ์ƒ ์ž‘๋™ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค cadvisor, ๋ฌธ์ œ์— ๊ทธ๊ฐ€ ๊ด€์—ฌํ–ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ๊ทธ ๋ชฉ์ ์€ ์บ๋“œ๋ฐ”์ด์ € - ์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๊ธฐ๋ณด๋‹ค๋Š” "์‹คํ–‰ ์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ์˜ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ๋ฐ ์„ฑ๋Šฅ ํŠน์„ฑ์„ ๋ถ„์„"ํ•ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ์˜ ๋‹ค๋ฅธ ์ธก๋ฉด๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋“ค์€ ๋ชจ๋‘ ๊ณ ๋„๋กœ ๋ฐœ์ „๋œ ๋„๊ตฌ์ด๋ฏ€๋กœ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ƒํ™ฉ์—์„œ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒจํ‚ท ๋Œ€๊ธฐ์—ด ์†๋„๋ฅผ ๋Šฆ์ถ”๊ธฐ ์œ„ํ•ด cadvisor๋Š” ๋ฌด์—‡์„ ํ•ฉ๋‹ˆ๊นŒ?

์ด์ œ ์šฐ๋ฆฌ๋Š” ์ถฉ๋Œ์ด ์–ด๋–ป๊ฒŒ ๋ฐœ์ƒํ•˜๋Š”์ง€, ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ถฉ๋Œ์„ ์ผ์œผํ‚ค๋Š”์ง€, ์–ด๋–ค CPU์—์„œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ๊ฝค ์ž˜ ์ดํ•ดํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋“œ ๋ธ”๋กœํ‚น์œผ๋กœ ์ธํ•ด Linux ์ปค๋„์ด ์˜ˆ์•ฝํ•  ์‹œ๊ฐ„์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ksoftirqd. ๊ทธ๋ฆฌ๊ณ  ํŒจํ‚ท์ด ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. cadvisor. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด ๋…ผ๋ฆฌ์ ์ด๋‹ค. cadvisor ๋Š๋ฆฐ syscall์„ ์‹คํ–‰ํ•œ ํ›„ ํ•ด๋‹น ์‹œ๊ฐ„์— ๋ˆ„์ ๋œ ๋ชจ๋“  ํŒจํ‚ท์ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

์ด๊ฒƒ์€ ์ด๋ก ์ด์ง€๋งŒ ์–ด๋–ป๊ฒŒ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์€ ์ด ํ”„๋กœ์„ธ์Šค ์ „๋ฐ˜์— ๊ฑธ์ณ CPU ์ฝ”์–ด๋ฅผ ์ถ”์ ํ•˜๊ณ , ํŒจํ‚ท ์ˆ˜๊ฐ€ ์˜ˆ์‚ฐ์„ ์ดˆ๊ณผํ•˜๊ณ  ksoftirqd๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์ง€์ ์„ ์ฐพ์€ ๋‹ค์Œ ์กฐ๊ธˆ ๋” ๋˜๋Œ์•„๊ฐ€ ๊ทธ ์ง€์  ์ง์ „์— CPU ์ฝ”์–ด์—์„œ ์ •ํ™•ํžˆ ๋ฌด์—‡์ด ์‹คํ–‰๋˜๊ณ  ์žˆ์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. . ์ด๋Š” ๋ช‡ ๋ฐ€๋ฆฌ์ดˆ๋งˆ๋‹ค CPU๋ฅผ ์—‘์Šค๋ ˆ์ด๋กœ ์ดฌ์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

Kubernetes์—์„œ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋””๋ฒ„๊น…

ํŽธ๋ฆฌํ•˜๊ฒŒ๋„ ์ด ๋ชจ๋“  ์ž‘์—…์€ ๊ธฐ์กด ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์„ฑ๋Šฅ ๊ธฐ๋ก ์ง€์ •๋œ ๋นˆ๋„๋กœ ์ง€์ •๋œ CPU ์ฝ”์–ด๋ฅผ ํ™•์ธํ•˜๊ณ  ์‚ฌ์šฉ์ž ๊ณต๊ฐ„๊ณผ Linux ์ปค๋„์„ ๋ชจ๋‘ ํฌํ•จํ•˜์—ฌ ์‹คํ–‰ ์ค‘์ธ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ํ˜ธ์ถœ ์ผ์ •์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ก์„ ๊ฐ€์ ธ์™€ ํ”„๋กœ๊ทธ๋žจ์˜ ์ž‘์€ ํฌํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”Œ๋ ˆ์ž„๊ทธ๋ž˜ํ”„ ์Šคํƒ ์ถ”์ ์˜ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋Š” Brendan Gregg์˜ ๊ธ€์ž…๋‹ˆ๋‹ค. 1ms๋งˆ๋‹ค ํ•œ ์ค„ ์Šคํƒ ์ถ”์ ์„ ์ €์žฅํ•œ ๋‹ค์Œ ์ถ”์ ์ด ๋ฐœ์ƒํ•˜๊ธฐ 100๋ฐ€๋ฆฌ์ดˆ ์ „์— ์ƒ˜ํ”Œ์„ ๊ฐ•์กฐ ํ‘œ์‹œํ•˜๊ณ  ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ksoftirqd:

# record 999 times a second, or every 1ms with some offset so not to align exactly with timers
sudo perf record -C 11 -g -F 999
# take that recording and make a simpler stack trace.
sudo perf script 2>/dev/null | ./FlameGraph/stackcollapse-perf-ordered.pl | grep ksoftir -B 100

๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

(ัะพั‚ะฝะธ ัะปะตะดะพะฒ, ะบะพั‚ะพั€ั‹ะต ะฒั‹ะณะปัะดัั‚ ะฟะพั…ะพะถะธะผะธ)

cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_iter cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages ksoftirqd/11;ret_from_fork;kthread;kthread;smpboot_thread_fn;smpboot_thread_fn;run_ksoftirqd;__do_softirq;net_rx_action;ixgbe_poll;ixgbe_clean_rx_irq;napi_gro_receive;netif_receive_skb_internal;inet_gro_receive;bond_handle_frame;__netif_receive_skb_core;ip_rcv_finish;ip_rcv;ip_forward_finish;ip_forward;ip_finish_output;nf_iterate;ip_output;ip_finish_output2;__dev_queue_xmit;dev_hard_start_xmit;ipip_tunnel_xmit;ip_tunnel_xmit;iptunnel_xmit;ip_local_out;dst_output;__ip_local_out;nf_hook_slow;nf_iterate;nf_conntrack_in;generic_packet;ipt_do_table;set_match_v4;ip_set_test;hash_net4_kadt;ixgbe_xmit_frame_ring;swiotlb_dma_mapping_error;hash_net4_test ksoftirqd/11;ret_from_fork;kthread;kthread;smpboot_thread_fn;smpboot_thread_fn;run_ksoftirqd;__do_softirq;net_rx_action;gro_cell_poll;napi_gro_receive;netif_receive_skb_internal;inet_gro_receive;__netif_receive_skb_core;ip_rcv_finish;ip_rcv;ip_forward_finish;ip_forward;ip_finish_output;nf_iterate;ip_output;ip_finish_output2;__dev_queue_xmit;dev_hard_start_xmit;dev_queue_xmit_nit;packet_rcv;tpacket_rcv;sch_direct_xmit;validate_xmit_skb_list;validate_xmit_skb;netif_skb_features;ixgbe_xmit_frame_ring;swiotlb_dma_mapping_error;__dev_queue_xmit;dev_hard_start_xmit;__bpf_prog_run;__bpf_prog_run

์—ฌ๊ธฐ์—๋Š” ๋งŽ์€ ๊ฒƒ๋“ค์ด ์žˆ์ง€๋งŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์•ž์„œ ICMP ์ถ”์  ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ณธ "ksoftirqd ์ด์ „์˜ cadvisor" ํŒจํ„ด์„ ๋ฐœ๊ฒฌํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌด์Šจ ๋œป์ด์—์š”?

๊ฐ ๋ผ์ธ์€ ํŠน์ • ์‹œ์ ์˜ CPU ์ถ”์ ์ž…๋‹ˆ๋‹ค. ํ•œ ์ค„์˜ ์Šคํƒ ์•„๋ž˜๋กœ ํ˜ธ์ถœ๋˜๋Š” ๊ฐ ํ˜ธ์ถœ์€ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. ์ค„ ์ค‘๊ฐ„์— syscall์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. read(): .... ;do_syscall_64;sys_read; .... ๊ทธ๋ž˜์„œ Cadvisor๋Š” ์‹œ์Šคํ…œ ํ˜ธ์ถœ์— ๋งŽ์€ ์‹œ๊ฐ„์„ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค. read()๊ธฐ๋Šฅ๊ณผ ๊ด€๋ จ๋œ mem_cgroup_* (ํ˜ธ์ถœ ์Šคํƒ์˜ ๋งจ ์œ„/์ค„ ๋).

ํ˜ธ์ถœ ์ถ”์ ์—์„œ ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์ฝ๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํŽธํ•˜๋ฏ€๋กœ ๋‹ค์Œ์„ ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. strace cadvisor๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์„ ์‚ดํŽด๋ณด๊ณ  100ms๋ณด๋‹ค ๊ธด ์‹œ์Šคํ…œ ํ˜ธ์ถœ์„ ์ฐพ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

theojulienne@kube-node-bad ~ $ sudo strace -p 10137 -T -ff 2>&1 | egrep '<0.[1-9]'
[pid 10436] <... futex resumed> ) = 0 <0.156784>
[pid 10432] <... futex resumed> ) = 0 <0.258285>
[pid 10137] <... futex resumed> ) = 0 <0.678382>
[pid 10384] <... futex resumed> ) = 0 <0.762328>
[pid 10436] <... read resumed> "cache 154234880nrss 507904nrss_h"..., 4096) = 658 <0.179438>
[pid 10384] <... futex resumed> ) = 0 <0.104614>
[pid 10436] <... futex resumed> ) = 0 <0.175936>
[pid 10436] <... read resumed> "cache 0nrss 0nrss_huge 0nmapped_"..., 4096) = 577 <0.228091>
[pid 10427] <... read resumed> "cache 0nrss 0nrss_huge 0nmapped_"..., 4096) = 577 <0.207334>
[pid 10411] <... epoll_ctl resumed> ) = 0 <0.118113>
[pid 10382] <... pselect6 resumed> ) = 0 (Timeout) <0.117717>
[pid 10436] <... read resumed> "cache 154234880nrss 507904nrss_h"..., 4096) = 660 <0.159891>
[pid 10417] <... futex resumed> ) = 0 <0.917495>
[pid 10436] <... futex resumed> ) = 0 <0.208172>
[pid 10417] <... futex resumed> ) = 0 <0.190763>
[pid 10417] <... read resumed> "cache 0nrss 0nrss_huge 0nmapped_"..., 4096) = 576 <0.154442>

์˜ˆ์ƒํ•œ ๋Œ€๋กœ ์—ฌ๊ธฐ์„œ๋Š” ๋Š๋ฆฐ ํ˜ธ์ถœ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. read(). ์ฝ๊ธฐ ์ž‘์—… ๋ฐ ์ปจํ…์ŠคํŠธ ๋‚ด์šฉ์—์„œ mem_cgroup ์ด๋Ÿฌํ•œ ๋„์ „์€ ๋ถ„๋ช…ํ•˜๋‹ค read() ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š” memory.stat, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ฐ cgroup ์ œํ•œ(Docker์˜ ๋ฆฌ์†Œ์Šค ๊ฒฉ๋ฆฌ ๊ธฐ์ˆ )์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. cadvisor ๋„๊ตฌ๋Š” ์ด ํŒŒ์ผ์„ ์ฟผ๋ฆฌํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ์— ๋Œ€ํ•œ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ์ •๋ณด๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ์ปค๋„์ด๋‚˜ ์บ๋“œ๋ฐ”์ด์ €๊ฐ€ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ผ์„ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

theojulienne@kube-node-bad ~ $ time cat /sys/fs/cgroup/memory/memory.stat >/dev/null

real 0m0.153s
user 0m0.000s
sys 0m0.152s
theojulienne@kube-node-bad ~ $

์ด์ œ ์šฐ๋ฆฌ๋Š” ๋ฒ„๊ทธ๋ฅผ ์žฌํ˜„ํ•˜๊ณ  Linux ์ปค๋„์ด ๋ณ‘๋ฆฌ ํ˜„์ƒ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Œ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ๊ธฐ ์ž‘์—…์ด ์™œ ๊ทธ๋ ‡๊ฒŒ ๋Š๋ฆฐ๊ฐ€์š”?

์ด ๋‹จ๊ณ„์—์„œ๋Š” ์œ ์‚ฌํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ, Cadvisor ์ถ”์ ๊ธฐ์—์„œ ์ด ๋ฒ„๊ทธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด๊ณ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณผ๋„ํ•œ CPU ์‚ฌ์šฉ ๋ฌธ์ œ, ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๋„คํŠธ์›Œํฌ ์Šคํƒ์— ๋ฌด์ž‘์œ„๋กœ ๋ฐ˜์˜๋œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•„๋ฌด๋„ ์•Œ์•„์ฐจ๋ฆฌ์ง€ ๋ชปํ–ˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ cadvisor๊ฐ€ ์˜ˆ์ƒ๋ณด๋‹ค ๋” ๋งŽ์€ CPU ์‹œ๊ฐ„์„ ์†Œ๋น„ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ํ™•์ธ๋˜์—ˆ์ง€๋งŒ ์ด๋Š” ๊ทธ๋‹ค์ง€ ์ค‘์š”ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ์„œ๋ฒ„์—๋Š” ๋งŽ์€ CPU ๋ฆฌ์†Œ์Šค๊ฐ€ ์žˆ์–ด์„œ ๋ฌธ์ œ๋ฅผ ์ฃผ์˜ ๊นŠ๊ฒŒ ์กฐ์‚ฌํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” cgroup์ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค(์ปจํ…Œ์ด๋„ˆ) ๋‚ด์˜ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ๊ณ ๋ คํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด cgroup์˜ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด Docker๋Š” ๋ฉ”๋ชจ๋ฆฌ cgroup์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "๋ฉ”๋ชจ๋ฆฌ"๋Š” ๋‹จ์ˆœํ•œ ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ ์ž์ฒด๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์ง€๋งŒ ์ปค๋„์€ ๋ฉ”๋ชจ๋ฆฌ cgroup์— ์บ์‹œ๋œ dentries ๋ฐ inode(๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฐ ํŒŒ์ผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ)์™€ ๊ฐ™์€ ์บ์‹œ๋œ ์ฝ˜ํ…์ธ ๋ฅผ ์—ฌ์ „ํžˆ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ ์„ค๋ช…์—์„œ:

์ข€๋น„ cgroups: ํ”„๋กœ์„ธ์Šค๊ฐ€ ์—†๊ณ  ์‚ญ์ œ๋˜์—ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ cgroup์ž…๋‹ˆ๋‹ค(์ œ ๊ฒฝ์šฐ์—๋Š” dentry ์บ์‹œ์—์„œ, ํŽ˜์ด์ง€ ์บ์‹œ๋‚˜ tmpfs์—์„œ ํ• ๋‹นํ•  ์ˆ˜๋„ ์žˆ์Œ).

cgroup์„ ํ•ด์ œํ•  ๋•Œ ์บ์‹œ์— ์žˆ๋Š” ๋ชจ๋“  ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์ปค๋„์˜ ํ™•์ธ์€ ๋งค์šฐ ๋Š๋ฆด ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ง€์—ฐ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„ ํƒ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค์‹œ ์š”์ฒญ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ํ•„์š”ํ•  ๋•Œ ๋งˆ์ง€๋ง‰์œผ๋กœ cgroup์„ ์ง€์›๋‹ˆ๋‹ค. ์ด ์‹œ์ ๊นŒ์ง€๋Š” ํ†ต๊ณ„๋ฅผ ์ˆ˜์ง‘ํ•  ๋•Œ cgroup์ด ๊ณ„์† ๊ณ ๋ ค๋ฉ๋‹ˆ๋‹ค.

์„ฑ๋Šฅ ๊ด€์ ์—์„œ ๋ณด๋ฉด ์„ฑ๋Šฅ์„ ์œ„ํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํฌ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์บ์‹œ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ผ๋ถ€ ๋‚จ๊ฒจ๋‘์–ด ์ดˆ๊ธฐ ์ •๋ฆฌ ์†๋„๋ฅผ ๋†’์˜€์Šต๋‹ˆ๋‹ค. ์ด๊ฑด ๊ดœ์ฐฎ์•„. ์ปค๋„์ด ์บ์‹œ๋œ ๋ฉ”๋ชจ๋ฆฌ ์ค‘ ๋งˆ์ง€๋ง‰ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฐ๊ตญ cgroup์ด ์ง€์›Œ์ง€๋ฏ€๋กœ ์ด๋ฅผ "๋ˆ„์ถœ"์ด๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ๊ฒ€์ƒ‰ ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์€ memory.stat ์ด ์ปค๋„ ๋ฒ„์ „(4.9)์—์„œ๋Š” ์šฐ๋ฆฌ ์„œ๋ฒ„์˜ ์—„์ฒญ๋‚œ ์–‘์˜ ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ฒฐํ•ฉ๋˜์–ด ์ตœ์‹  ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์›ํ•˜๊ณ  cgroup ์ข€๋น„๋ฅผ ์ง€์šฐ๋Š” ๋ฐ ํ›จ์”ฌ ๋” ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ๋…ธ๋“œ ์ค‘ ์ผ๋ถ€์—๋Š” cgroup ์ข€๋น„๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์„œ ์ฝ๊ธฐ ๋ฐ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด XNUMX์ดˆ๋ฅผ ์ดˆ๊ณผํ•œ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.

Cadvisor ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์‹œ์Šคํ…œ ์ „์ฒด์—์„œ dentries/inodes ์บ์‹œ๋ฅผ ์ฆ‰์‹œ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ˜ธ์ŠคํŠธ์˜ ์ฝ๊ธฐ ๋Œ€๊ธฐ ์‹œ๊ฐ„๊ณผ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ์ฆ‰์‹œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์บ์‹œ๋ฅผ ์ง€์šฐ๋ฉด ์บ์‹œ๋œ ์ข€๋น„ cgroup ํŽ˜์ด์ง€๋„ ์ผœ์ง€๊ณ  ํ•ด์ œ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํ•ด๊ฒฐ์ฑ…์€ ์•„๋‹ˆ์ง€๋งŒ ๋ฌธ์ œ์˜ ์›์ธ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ตœ์‹  ์ปค๋„ ๋ฒ„์ „(4.19+)์—์„œ๋Š” ํ˜ธ์ถœ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋œ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. memory.stat์ด๋ฏ€๋กœ ์ด ์ปค๋„๋กœ ์ „ํ™˜ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋™์‹œ์— ์šฐ๋ฆฌ๋Š” Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , ์ ์ ˆํ•˜๊ฒŒ ๋“œ๋ ˆ์ด๋‹ํ•˜๊ณ  ์žฌ๋ถ€ํŒ…ํ•˜๋Š” ๋„๊ตฌ๋ฅผ ๋ณด์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์กฐ์‚ฌํ•˜์—ฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ์ถฉ๋ถ„ํžˆ ๋†’์€ ๋…ธ๋“œ๋ฅผ ์ฐพ์•„ ์žฌ๋ถ€ํŒ…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ์จ ๋‚˜๋จธ์ง€ ์„œ๋ฒ„์˜ OS๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์‹œ๊ฐ„์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.

์ตœ๋Œ€ ํ•ฉ๊ณ„

์ด ๋ฒ„๊ทธ๋กœ ์ธํ•ด ์ˆ˜๋ฐฑ ๋ฐ€๋ฆฌ์ดˆ ๋™์•ˆ RX NIC ๋Œ€๊ธฐ์—ด ์ฒ˜๋ฆฌ๊ฐ€ ์ค‘๋‹จ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์งง์€ ์—ฐ๊ฒฐ์—์„œ ๋†’์€ ๋Œ€๊ธฐ ์‹œ๊ฐ„๊ณผ MySQL ์š”์ฒญ ๋ฐ ์‘๋‹ต ํŒจํ‚ท ์‚ฌ์ด์™€ ๊ฐ™์€ ์ค‘๊ฐ„ ์—ฐ๊ฒฐ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๋™์‹œ์— ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Kubernetes์™€ ๊ฐ™์€ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์‹œ์Šคํ…œ์˜ ์„ฑ๋Šฅ์„ ์ดํ•ดํ•˜๊ณ  ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์€ ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋ชจ๋“  ์„œ๋น„์Šค์˜ ์•ˆ์ •์„ฑ๊ณผ ์†๋„์— ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ํ•˜๋Š” ๋ชจ๋“  ์‹œ์Šคํ…œ์€ Kubernetes ์„ฑ๋Šฅ ํ–ฅ์ƒ์˜ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€