前回まではmod_proxy_balancerで中〜大規模サーバーを運用するときの勘所をお話ししてきました。
これ以外にもmod_proxy_balancerな中〜大規模サーバーで気をつけるべき点はあります。それがiptablesとip_conntrack。
外部に直接晒されているサーバーはセキュリティーを確保するためにiptablesなどのファイヤウォールを導入しているかと思います。アクセス数がある程度以上になってくると、そのファイヤウォールが思わぬ足かせになってしまうと言うお話です。
iptablesはパケットフィルタリングを行うソフトウェアです。PCに入ってきたり、逆にPCから出て行くパケットを監視し、ルールに従い適宜フィルタリングを行います。
さて、iptablesでは、関連したパケットを追跡するために/proc/net/ip_conntrackというファイルを作り、パケットの情報を記録しておきます。
このip_conntrackに記録できる上限数を決めているのが/proc/sys/net/ipv4/ip_conntrack_max。システムで自動的に設定されるデフォルト値は搭載されているメモリーによって異なり、1GBで30000強、2GB以上で65536ぐらいになります。
1GBのメモリーを積んでいる場合、1時間あたりのアクセス数が100,000ページビュー程度までならデフォルト値でも問題ないのですが、ぞれ以上になってくるとip_conntrack_maxの値を超えてしまい、パケットが捨てられてしまうという事態に陥ります。ip_conntrack_maxの値を超えると、コンソールに以下のようなメッセージが出力されます。
ip_conntrack: maximum limit of 65536 entries exceeded
こうなってしまった場合の対処方法はただ一つ。ip_conntrack_maxの値を上げることです。変更の仕方は、rootユーザになって以下のようにすればOK。
echo '100000' > /proc/sys/net/ipv4/ip_conntrack_max
ip_conntrack_maxの値の上限は、搭載しているメモリーに依るらしく、64MBあたり4096になるそうです(See: netfilter/iptables FAQ: 実行時の問題)。なお、追跡するコネクションが一つ増えるごとに(ip_conntrackの値が一つ増えるごとに)swapできないメモリー約350バイトが必要になると言う点に注意が必要です。
ちなみに、現在使用しているip_conntrackの値を知りたかったらrootユーザで以下のようにすればOK。
cat /proc/net/ip_conntrack | wc -l
ところで、iptablesを再起動するとip_conntrack_maxがデフォルト値に戻ってしまうのですが、これを回避する方法をご存じでしたら、是非コメント欄などでお知らせください。よろしくお願いします。
/etc/rc.d/rc.local
に
echo ‘100000’ > /proc/sys/net/ipv4/ip_conntrack_max
を記載すると
良いかと思われます。
というのでもよいですか?
なるほど、rc.localならランレベル2〜5の時に実行されるので、そこに記述すれば良さそうですね。
# vi /etc/sysctl.conf
net.ipv4.ip_conntrack_max = ******
# sysctl -p
通りすがりさん
/etc/sysctl.confがありましたね。ありがとうございます。
#vi /etc/modprobe.conf
options ip_conntrack hashsize=12500
options ip_conntrack hashsize ×8 が設定されるので上記設定で
ip_conntrack_max=100000
が設定されると思います。