iptables ip_conntrack/nf_conntrack 拡張
中規模/大規模なサイトや、proxy/NAT/ロードバランサ等で使用していると、以下のようなログを目にする/した事があるかもしれません。
ip_conntrack: table full, dropping packet
この場合、iptablesによって管理されているコネクションのテーブルが不足しているかもしれません。
(iptablesのルールによっては、そちらの整理で回避出来る場合もあります。)
必要に応じて(出来れば予め)確認/拡張しましょう。
ip_conntrack/nf_conntrack確認
現在値/最大値を確認します。現在値については、監視システム等で定常的に取得しておくと良いでしょう。
- CentOS5の場合
$ cat /proc/net/stat/ip_conntrack entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete 00000001 00000000 000158e5 0000544b 00000002 00000000 000054a7 000054a7 0000544b 00000000 00000000 00000000 00000000 00000000 00000000 00000000
$ cat /proc/sys/net/ipv4/ip_conntrack_max 65536
entriesの項が示す値(16進)が現在値です。
/proc/net/stat/ip_conntrackはインターフェース設定次第で複数行ある場合がありますが、特に設定しなければentriesの項は同じ値(テーブルが共通)のはずです。
- CentOS6/CentOS7の場合
$ cat /proc/sys/net/netfilter/nf_conntrack_count 5
$ cat /proc/sys/net/netfilter/nf_conntrack_max 65536
CentOS3の時代辺りでは、/proc下でテーブルのカウンタ値を取得出来なかったせいか、テーブルのエントリを直接参照するような集計方法を見掛けますが、このような方法は避けるべきでしょう。
理由は、root権限でなければ実行出来ないことからも想像できるかと思いますが、テーブルへのアクセスが競合するためです。
- CentOS5の場合(実行は要注意)
# cat /proc/net/ip_conntrack | wc -l 1
- CentOS6/CentOS7の場合(実行は要注意)
# cat /proc/net/nf_conntrack | wc -l 5
テーブルの不足が確認出来た場合、メモリに余裕があれば単純に拡張してしまうのが最善ですが、拡張が困難/iptablesのルールを精査する場合は、上記のエントリを(サービスへの影響を覚悟の上)テキストで取得しておき、設定されているルールを見直す事になるでしょう。
ip_conntrack_max/nf_conntrack_max拡張設定
sysctlコマンドで値を設定してもいいのですが、hashsizeを変更して関連するパラメータにも反映されるようにした方が良いでしょう。
confファイルに記述する場合は再起動が必要です。一時的に拡張する場合はmodprobeコマンドで適用します。
- CentOS5の場合
$ sysctl net.ipv4.ip_conntrack_max net.ipv4.ip_conntrack_max = 65536
--- a/modprobe.conf
+++ b/modprobe.conf
@@ -17,0 +18 @@
+options ip_conntrack hashsize=32768
再起動後。
$ sysctl net.ipv4.ip_conntrack_max net.ipv4.ip_conntrack_max = 262144
- CentOS6/CentOS7の場合
$ sysctl net.nf_conntrack_max net.nf_conntrack_max = 65536
--- /dev/null
+++ /etc/modprobe.d/nf_conntrack.conf
@@ -0,0 +1 @@
+options nf_conntrack hashsize=32768
再起動後。
$ sysctl net.nf_conntrack_max net.nf_conntrack_max = 262144
hashsize の変更適用により、以下のパラメータが変動します。
-net.netfilter.nf_conntrack_max = 65536
-net.netfilter.nf_conntrack_buckets = 16384
+net.netfilter.nf_conntrack_max = 262144
+net.netfilter.nf_conntrack_buckets = 32768
-net.netfilter.nf_conntrack_expect_max = 256
+net.netfilter.nf_conntrack_expect_max = 512
-net.nf_conntrack_max = 65536
+net.nf_conntrack_max = 262144
- 動的に適用する場合
# modprobe nf_conntrack hashsize=32768
使用メモリ算出
オブジェクトサイズ * エントリ数のメモリを必要とします。
slab のため swap 不可なので、拡張の際には、余裕がある事を計算/確認しておきましょう。
オブジェクトサイズは /proc/slabinfo 内のエントリで確認出来ます。カーネルによって微妙にサイズが変わりますが、概ね200バイトから400バイト程度です。
$ grep conntrack /proc/slabinfo | grep -v expect | tr -s " " | cut -d" " -f4 304