Linuxサーバ上でホスト間コネクションを集約表示するツール lstf をつくった - ゆううきメモ ã«ã¦ç´¹ä»‹ã—ãŸlstfã®ãƒ›ã‚¹ãƒˆä¸Šã®TCPコãƒã‚¯ã‚·ãƒ§ãƒ³æƒ…å ±ã®å–得処ç†ã«ãŠã„ã¦ã€
/proc/net/tcp
ã‚’èªã¿ã ã™ä»£ã‚ã‚Šã«ã€Netlinkソケットを利用ã™ã‚‹ã“ã¨ã§ã€å®Ÿè¡Œé€Ÿåº¦ãŒ1.6å€ã«ãªã£ãŸã€‚lstfã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³0.4.0ã§ä½¿ãˆã‚‹ã‚ˆã†ã«ãªã‚‹ã€‚
実験
ç´„40,000接続ã‚ã‚‹Webサーãƒä¸Šã«ã¦ã€lstfコマンドã®å®Ÿè¡Œæ™‚é–“ã‚’åå‰è§£æ±ºæ™‚é–“ã‚’å«ã¾ãšã«æ¯”較ã™ã‚‹ã€‚ 実験環境ã¯EC2ã®c4.2xlargeã€Debian 8.10ã€Linuxカーãƒãƒ«3.16ã§ã‚ã‚Šã€ãƒªãƒãƒ¼ã‚¹ãƒ—ãƒã‚ã‚·ã¨ã—ã¦nginxãŒå‹•ä½œã—ã¦ã„る。
接続数ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã‚ˆã‚Šã ã„ãŸã„40,000接続ã§ã‚ã‚‹ã“ã¨ã‚’確èªã™ã‚‹ã€‚
[y_uuki@hoge ~]$ ss -tan | wc -l 39264
/proc/net/tcp
ã‚’èªã‚€å®Ÿè£…ã§ã¯ã€æ¬¡ã®ã‚ˆã†ã«å®Ÿè¡Œæ™‚é–“ã¯ç´„500msã§ã‚ã‚Šã€
[y_uuki@hoge ~]$ time ./lstf_old -n >/dev/null real 0m0.532s user 0m0.432s sys 0m0.140s
Netlinkソケットを利用ã™ã‚‹å®Ÿè£…ã§ã¯ã€æ¬¡ã®ã‚ˆã†ã«å®Ÿè¡Œæ™‚é–“ã¯ç´„300msã¨ãªã£ã¦ãŠã‚Šã€ç´„1.6å€ã®é€Ÿåº¦å‘上ã§ã‚る。10回実行ã®å¹³å‡å€¤ã‚’ã¨ã£ã¦ã‚‚ã€1.68å€ã®é€Ÿåº¦å‘上ã¨ãªã£ãŸã€‚
[y_uuki@hoge ~]$ time ./lstf -n > /dev/null real 0m0.318s user 0m0.272s sys 0m0.052s
netlinkを使ã£ãŸåŒæ§˜ã®ãƒ‘フォーマンス改善ã«ã¤ã„ã¦ã¯ã€kernel: add a netlink interface to get information about processes (v2) [LWN.net]ãŒå‚考ã«ãªã‚‹ã€‚ ã“ã®è¨˜äº‹ã‚’真似ã¦ã€perfã«ã‚ˆã‚Šè§£æžã—ãŸãŒã€æœ‰æ„ãªçµæžœãŒå¾—られãŸãªã‹ã£ãŸãŸã‚ã€å®¿é¡Œã¨ã—ãŸã„。
実装
Netlinkã¯ã€ãƒ¦ãƒ¼ã‚¶ç©ºé–“ã®ãƒ—ãƒã‚»ã‚¹ã¨ã‚«ãƒ¼ãƒãƒ«ã¨ã®é€šä¿¡ã‚’ソケットインタフェースã«ã‚ˆã‚Šæä¾›ã™ã‚‹ã€‚ ssコマンドやipコマンドをå«ã‚€iproute2パッケージã§ã¯ã€netlinkを利用ã™ã‚‹ã“ã¨ã§ã€ãƒ‡ãƒã‚¤ã‚¹ã‚’æ“作ã—ã€ã‚«ãƒ¼ãƒãƒ«å†…ã®æƒ…å ±ã‚’å–å¾—ã—ã¦ã„る。*1 Netlinkソケットã‹ã‚‰ã‚½ã‚±ãƒƒãƒˆã®é–¢ã™ã‚‹æƒ…å ±ã‚’å–å¾—ã™ã‚‹ã«ã¯ã€Socket Monitoring Interfaceを使ã†ã€‚*2
Socket Monitoring Interfaceã¯ã€æ˜”ã¯inetファミリーã®ã¿ã®ã‚µãƒãƒ¼ãƒˆã ã£ãŸãŒã€Linuxカーãƒãƒ«3.3ã‹ã‚‰æ§˜ã€…ãªã‚½ã‚±ãƒƒãƒˆã‚¿ã‚¤ãƒ—をサãƒãƒ¼ãƒˆã™ã‚‹ã‚ˆã†ã«ãªã£ãŸ(raw socketãªã©, 1,2,3) ã ã„ãŸã„æ–°ã—ã„ã‚‚ã®ã‚’sock_diagã€å¤ã„ã‚‚ã®ã‚’inet_diagã¨ã—ã¦ã„るよã†ã«ã¿ãˆã‚‹ã€‚ ãã‚Œã«ä¼´ã„ã€è‹¥å¹²ã‚¤ãƒ³ã‚¿ãƒ•ã‚§ãƒ¼ã‚¹ãŒå¤‰æ›´ã•ã‚Œã¦ãŠã‚Šã€netlinkファミリーã¨ã—ã¦ã€TCPDIAG_FAMILYを指定ã—ã¦ã„ãŸã¨ã“ã‚ã‚’SOCK_DIAG_BY_FAMILYã¨ã—ã¦æŒ‡å®šã—ãŸã‚Šã€ãƒ¦ãƒ¼ã‚¶ç©ºé–“ã‹ã‚‰ã‚«ãƒ¼ãƒãƒ«ã«é€ä¿¡ã™ã‚‹ãƒªã‚¯ã‚¨ã‚¹ãƒˆæ§‹é€ 体ãŒinet_diag_req, inet_diag_req_v2ã¨ãªã£ã¦ã„る。 CentOS5ãªã©ã®å¤ã„カーãƒãƒ«ã§ã¯ã€inet_diagã®ã¿åˆ©ç”¨ã§ãる。 lstfã§ã¯ã€å¤ã„OSをサãƒãƒ¼ãƒˆã—ãŸã„ãŸã‚ã€inet_diagを利用ã—ãŸã€‚
ユーザ空間ã®ãƒ—ãƒã‚°ãƒ©ãƒŸãƒ³ã‚°ãƒ¢ãƒ‡ãƒ«ã¯ã€å¤§é›‘把ã«ã¯ã€ã¾ãšnetlinkソケットを作æˆã—ã€Socket Monitoringã®ãŸã‚ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆæ§‹é€ 体を作æˆã—ã€netlinkãƒ¡ãƒƒã‚»ãƒ¼ã‚¸æ§‹é€ ä½“ã¨ã—ã¦ã€sendto
/sendmsg
システムコールã§ã‚«ãƒ¼ãƒãƒ«ã«é€ä¿¡ã™ã‚‹ã€‚次ã«recvmsg
ãªã©ã§å—ä¿¡ã—ã€ãƒã‚¤ãƒˆåˆ—をパースã—å¿…è¦ãªæƒ…å ±ã‚’å¾—ã‚‹ã¨ã„ã†æµã‚Œã«ãªã‚‹ã€‚
Go言語ã§ã¯ã€netlinkを扱ã†ãŸã‚ã®ãƒ©ã‚¤ãƒ–ラリã¨ã—㦠vishvananda/netlinkãŒæœ‰åã§ã‚る。
ãŸã ã—ã€vishvananda/netlinkã¯Socket Monitoring Interfaceã‚’æä¾›ã—ã¦ã„ãªã„ãŸã‚ã€ã‚½ã‚±ãƒƒãƒˆæƒ…å ±ã‚’å–å¾—ã—よã†ã¨æ€ã†ã¨ã€ã‚³ã‚¢éƒ¨åˆ†ã®ç”Ÿã«è¿‘ã„インタフェースã§ã‚³ãƒ¼ãƒ‰ã‚’書ãã“ã¨ã«ãªã‚‹ã€‚
vishvananda/netlinkã®ã‚³ã‚¢éƒ¨åˆ†(nl
パッケージ)を使ã„ã¤ã¤ã€inet_diagã‚’ã²ã¨ã—ãり実装ã—ãŸãŒã€
最終的ã«ã¯ã€Goã®elastic/gosigarã®linuxパッケージを発見ã—ãŸãŸã‚ã€ã“れを利用ã—実装ã—ãŸã€‚
ã¡ãªã¿ã«ã€lstfã®v0.4.0ã«ã¯ã€ã‚½ã‚±ãƒƒãƒˆæƒ…å ±ã®å–得処ç†ã‚’2回走らã›ã¦ã—ã¾ã£ã¦ã„ãŸãŸã‚ã€ãã®ç„¡é§„ã‚’çœã„ãŸæ”¹å–„ã‚‚å…¥ã£ã¦ã„る。ã“ã‚Œã¨netlinkã®æ”¹å–„ã‚’åˆã‚ã›ã‚‹ã¨ã€å…¨ä½“ã§3å€å¼·ã®é€Ÿåº¦æ”¹å–„ã«ãªã£ã¦ã„る。
å‚考文献
- RFC3549, Linux Netlink as an IP Services Protocol, 2003, https://tools.ietf.org/html/rfc3549
- Rami Rosen, Linux Kernel Networking: Implementation and Theory, Apress, 2014
- Christian Benvenuti, Understanding Linux Network Internals, O'Reilly Media, 2005
- Passive monitoring of sockets on Linux
- Using Netlink to Optimize Socket Statistics
- Linux, Netlink, and Go — Part 1: netlink – Matt Layher – Medium
- Linuxでcからnetstatっぽいことをしたかった - や
- Add support for tcp diags. by sebbov · Pull Request #199 · vishvananda/netlink · GitHub
- iproute2 misc/ss.c
ã„ãŸã ã„ãŸåå¿œ
procã®tcpを見るパターンもコãƒã‚¯ã‚·ãƒ§ãƒ³æ•°ãŒå°‘ãªã‘ã‚Œã°å½“然速ã„ã®ã§ã€ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³æ•°ã®å¤‰åŒ–ã«å¿œã˜ã¦ã©ã®ã‚ãŸã‚Šã§netlinkãŒä¸Šå›žã‚‹ã‹ã‚ã‹ã‚‹ã¨ä¾¿åˆ©ãã†ã€‚ãã„ã‚„netlinkã¯ãƒžãƒ«ãƒã‚¹ãƒ¬ãƒƒãƒ‰ã«å¯¾å¿œã—ã¦ã‚‹ã®ã‹ãªã / “TCP接続…†https://t.co/jcCoabYfWW
— æ¾æœ¬ 亮介 / ã¾ã¤ã‚‚ã¨ã‚Šãƒ¼ (@matsumotory) 2018å¹´6月17æ—¥
netlinkã®æ–¹ãŒæ—©ã„ã®æ„外ã ã£ãŸã€‚ã¡ã‚‡ã„å‰ã«ã“ã®è¾ºã‚Šè§¦ã£ã¦ãŸãªã。
— På±± (@pyama86) 2018å¹´6月17æ—¥
RT: TCP接続を集約表示ã™ã‚‹lstfã§Netlinkã«ã‚ˆã‚Šå®Ÿè¡Œé€Ÿåº¦ãŒ1.6å€ã«ãªã£ãŸ https://t.co/IbjvLYJKrb
ã™ã”ã„ã€lstfã ã‘ã§ã‚‚便利ã ã£ãŸã®ã«æ€§èƒ½å‘上嬉ã—ã„ https://t.co/eCaNCmQATn
— mook (@mookjp) 2018å¹´6月17æ—¥