スプリットブレインが起きたら ARP フラッシュが必要になった

これまた誰かの役に立てばということで。

keepalivedVRRP)はその仕組み上、ネットワーク分断時にマスターが二つ以上できます。俗にいう、スプリットブレインというやつです。

ネットワーク分断が解消したのち、マスターは一つに収束します。ネットワークスイッチの類であれば大概の場合これで問題はありません。ええ、問題はないはずでした。

ところが先日、ネットワーク分断解消後にある Linux サーバーからスイッチの仮想IP(VIP)への通信ができなくなる現象が発生しました。原因を調べたところ、VIP を現在持っているスイッチの MAC アドレスではなく、バックアップスイッチ側の MAC アドレスが ARP キャッシュに載っていたためでした。

以下のような経緯で障害になったものと思われます。

  1. スプリットブレイン中、複数のマスターから VIP の ARP キャッシュを更新するためGratuitous ARP が投げられる
  2. スプリットブレイン解消後、keepalived は Gratuitous ARP を投げることなく収束する
  3. Linux サーバーの一部は、マスターでなくなったスイッチの MAC アドレスを ARP キャッシュに保持したままになる
  4. そのサーバーはずっと VIP と通信をし続けているため、ARP キャッシュエントリが破棄されない

4の挙動については、http://linux-ip.net/html/ether-arp.html に以下のように記述されていました。

Entries in the ARP cache are periodically and automatically verified UNLESS CONTINUALLY USED.

しかたないので、VIP とずっと通信をするサーバーについては定期的に ARP キャッシュを破棄するよう cron を仕込みました。同時刻に一斉に破棄しないよう、shuf でランダム化してあります。

*/5 * * * * root sleep $(shuf -i 1-60 -n 1); /sbin/ip neigh flush all

いろいろありますわー。


追記: @kazuho さんから、以下いただきました。