会社のプライベートクラウドで、SNATルーターが度々不調になるということに出くわした…。 調べていくとネットワークノードで以下のメッセージが出ていた。
neighbour: arp_cache: neighbor table overflow!
このメッセージはARPキャッシュエントリーの数が設定値を超えると発生するらしい。 ARPエントリが追加できないので、通信ができなくなるということらしい。 プライベートクラウドのSNATルーターはHA構成になっているため、通信断になるとフェイルオーバーするのだが、フェイルオーバーしたことを検知することもできないし、即時にARPテーブルの空きができてフェイルバックするために、通信断の状態が長くなるのであった…。
これを解決するには以下のカーネルパラメータを変更すればよい
- net.ipv4.neigh.default.gc_thresh1
- net.ipv4.neigh.default.gc_thresh2
- net.ipv4.neigh.default.gc_thresh3
それぞれのデフォルト値とパラメータの意味は以下を参照。 Man page of ARP
どうしたらneighbor table overflow!が発生するのか?
例の如く id:hiboma がどういう実装になっているのかを調べてくれた。hiboma++
static struct neighbour *neigh_alloc(struct neigh_table *tbl, struct net_device *dev) { struct neighbour *n = NULL; unsigned long now = jiffies; int entries; entries = atomic_inc_return(&tbl->entries) - 1; if (entries >= tbl->gc_thresh3 || (entries >= tbl->gc_thresh2 && time_after(now, tbl->last_flush + 5 * HZ))) { if (!neigh_forced_gc(tbl) && entries >= tbl->gc_thresh3) { net_info_ratelimited("%s: neighbor table overflow!\n", tbl->id); NEIGH_CACHE_STAT_INC(tbl, table_fulls); goto out_entries; } } -- -- snip -- --
上記を見ると gc_thresh3
を超えると発生するようだ。
ARPキャッシュエントリー数は lnstat
コマンドで確認できる。
これも id:hiboma に教えてもらった。 hiboma++
$ lnstat -c 1 -k arp_cache:entries arp_cach| entries| 4162|
このエントリ数を見て gc_treshX
を設定するのが良いと思う。
会社のプライベートクラウドでは、インスタンス数600、ポート数1600弱だったが上記の通りそこそこのエントリ数だったので以下のように設定し回避した。
echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh1 echo 8192 > /proc/sys/net/ipv4/neigh/default/gc_thresh2 echo 8192 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
また、エントリ数をMackerelに投稿するやーつを @r_takaishi が作ったのでまたエントリ数が増えてきたら設定を増やすような運用にしたい。
(追記)各パラメータの設定値について、OpenStack-Ansibleでは8GBメモリ以上なら 4096 8192 16384
で設定しているように見受けられた。
搭載メモリが多ければなるべく大きめに設定しておくと良さそうだ。
OpenStack Docs: OpenStack-Ansible openstack_hosts