読者です 読者をやめる 読者になる 読者になる

kernelをチューニングしてTIME_WAIT値を変更する

kernelのチューニングについて

まぁ個人的な所感なんですけど。。

10年前ぐらい前、とあるシステムで原因のリンクダウンが頻発するトラブルがあり、まったく原因がわからなかったのですが、当時の先輩がkernelのソースコードをいじくって直したことがありました(なんかパッチ送ってました)。

私はその頃ペーペーだったのですが、なにこの変態と思いつつも、その技術力にとても感動しました。

10年たった今はだいぶ安定しておりkernelレベルのチューニングはあまり必要性を感じていませんが、どうしてもって時はこうやるよって感じのメモです。

まぁTIME_WAIT値を変えるぐらいなら大したことないんですけどね。あのリンクダウンってどうやって解決したのかな。10年たった今でもさっぱりわからん。変態め

環境等

  • OS: CentOS 5.8 (64bit)
  • kernel: kernel-2.6.18-308

そして今回実験台となってくれるのは信頼と実績のさくらのVPSさんです。

TIME_WAITを5秒に変更

れっつらごー

src.rpmをおとしてインスト

# wget http://vault.centos.org/5.8/os/SRPMS/kernel-2.6.18-308.el5.src.rpm

おとして・・

# rpm -ivh kernel-2.6.18-308.el5.src.rpm 
   1:kernel                 ########################## [100%]
#

インストしておきます。

編集箇所

/usr/src/redhat/SOURCES配下(CentOS6からは~~/rpmbuild/SOURCES/らへん?)にある"linux-2.6.18.4.tar.bz2"のがkernelの本体です。
パッチを作っていればこのファイルをいじる必要はありませんが、初めて編集する場合は展開してコードを修正します。

# tar jxf linux-2.6.18.4.tar.bz2

で展開した後にできる

  • include/net/tcp.h
  • net/ipv4/ipvs/ip_vs_proto_tcp.c

の2ファイルにTIME_WAITの設定値があるのでviで開いて編集します。

# vi include/net/tcp.h 
# vi net/ipv4/ipvs/ip_vs_proto_tcp.c 

それぞれのdiffはこんな感じ

# diff include/net/tcp.h.bk include/net/tcp.h   
106c106
< #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
---
> #define TCP_TIMEWAIT_LEN (5*HZ) /* how long to wait to destroy TIME-WAIT
# 

# diff net/ipv4/ipvs/ip_vs_proto_tcp.c.bk net/ipv4/ipvs/ip_vs_proto_tcp.c   
269c269
<   [IP_VS_TCP_S_TIME_WAIT]      =     2*60*HZ,
---
>   [IP_VS_TCP_S_TIME_WAIT]      =     1*5*HZ,
# 


今後のためにここでpatchを作っておくと便利です。

編集がすんだら同じファイル名でアーカイブし直します

# tar jcf linux-2.6.18.4.tar.bz2 linux-2.6.18.4 

展開したファイルはいらないのでrm -rf linux-2.6.18.4で消しておきます。

リビルド

/usr/src/redhat/SPECS/に移ってspecファイルを編集します。
specファイルの中身をみると

# Polite request for people who spin their own kernel rpms:
# please modify the "buildid" define in a way that identifies
# that the kernel isn't the stock distribution kernel, for example,
# by setting the define to ".local" or ".bz123456"
#
#% define buildid

らしいので、こいつをちょろっと編集します

# vi kernel.spec
# diff kernel.spec.bk kernel.spec
74a75
> %define buildid .time_wait_5sec
# 

まぁ適当にかえる。
patchを作成している場合はspecファイルにパッチを追記します。

あとはリビルドしてやります。
これ結構時間がかかる

# rpmbuild -ba kernel.spec

(10年後…)

# cd /usr/src/redhat/RPMS/x86_64/
# 
# ls -1
kernel-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-debug-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-debug-debuginfo-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-debug-devel-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-debuginfo-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-debuginfo-common-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-devel-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-headers-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-xen-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-xen-debuginfo-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
kernel-xen-devel-2.6.18-308.el5.time_wait_5sec.x86_64.rpm
# 

できた/(^o^)\

ね、簡単でしょ(棒

ハマりどころ

TIME_WAIT値を5秒未満にするとTIME_WAIT値がなくなる

いろいろなバージョンで検証したのですが、64bitの場合、TIME_WAIT値を5未満にするとTIME_WAITがなくなりました。
上でだした値を10秒→9秒→8秒・・・と順に短くしていったのですが5秒未満になるととたんになくなります。

で、謎なのが32bitの場合は5秒未満でもその数値となります。
これは結構調べたのですが結局わからずじまいです。。

gpgのエントロピーが足りない

これはべつにkernelチューニングに限ったことではないのですが、rpmbuildを実行すると

Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 284 more bytes)

などと出て止まってしますことがあります。
(検証サーバとして新品のサーバ作ったりリブートしたてだったりするとエントロピーが足りなくてでる)

でググったりするとマウスをぐりぐりしたりキーボードを適当に叩いてみたりするといいよとか出てくるんだけどいまいち効果がない。
そんなときは

# /sbin/rngd -r /dev/urandom

としてエントロピーを供給してやると進めるようになります。

id:kenjiskywalker

これでいいだろ!さあ子供たちを開放しろ!