web-dev-qa-db-ja.com

「nf_conntrack:テーブルがいっぱいです。パケットをドロップしています」nf_conntrack_countがnf_conntrack_maxよりはるかに小さい場合でも

クラスター内に、syslogで大量の「nf_conntrack:テーブルがいっぱいです。パケットをドロップしています」というメッセージを受け取るノードがあります。 nf_conntrack_countを確認したところ、nf_conntrack_maxに対して実行されていました。テーブルを調べると、ほとんどのエントリがDNS要求であることがわかったので、これらのルールを「生の」netfilterテーブルに追加しました。

$ Sudo iptables -t raw -vnL
Chain PREROUTING (policy ACCEPT 146M packets, 19G bytes)
pkts bytes target     prot opt in     out     source               destination
33M 4144M CT         udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 CT notrack
33M 2805M CT         udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 CT notrack
Chain OUTPUT (policy ACCEPT 73M packets, 8311M bytes)
pkts bytes target     prot opt in     out     source               destination         
10785  882K CT         udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 CT notrack
0     0 CT         udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 CT notrack

そのため、カウントは13000程度に留まり、nf_conntrack_maxは65535に設定されています。ただし、ドロップされたパケットメッセージが引き続き表示されます。残りのパケットのほとんどはUDPであり、nf_conntrack_udp_timeoutを1秒に設定し、nf_conntrack_countを約1000のままにします。ただし、ドロップされたパックメッセージが表示されます。

ここから、最大値を上げると、ドロップされたパケットメッセージが停止しますが、なぜそれが必要なのかわかりません。

Dockerを実行していますが、elasticsearchコンテナーがあります(この問題は、elasticsearchを実行しているノードで発生するようです)。関連性があるかどうかはわかりませんが、ノードには48個のコアがあります。

$ uname -a
Linux qtausc-pphd0128 3.19.0-26-generic #28~14.04.1-Ubuntu SMP Wed Aug 12 14:09:17 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

では、カウントが最大値よりはるかに少ないのに、なぜパケットをドロップするのでしょうか。

2
Matthew Sharp

しばらく前にSquidシステムで同じ問題が発生しました。

Conntrackのサイズを減らすために私が見つけた最も効果的な方法の1つは、カーネルのデフォルトのTCPタイムアウトを減らすことでした。

net.netfilter.nf_conntrack_tcp_timeout_establishedはデフォルトで432000に設定されています。そうです...それは5日です。

値を設定するには、次のコマンドを発行できます。

sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=X

また、その変更を永続的にしたい場合は、/etc/sysctl.confに行を追加する必要があります。

その値を600に減らした後、conntrackカウントは数日にわたって着実に減少していました。

Conntrackテーブルのカウントと最大設定をどのように確認したかはわかりませんが、値を取得するためにsysctl netfilter.nf_conntrack_maxsysctl net.netfilter.nf_conntrack_countを使用しました。

4
Alex