これまた誰かの役に立てばということで。
keepalived (VRRP)はその仕組み上、ネットワーク分断時にマスターが二つ以上できます。俗にいう、スプリットブレインというやつです。
ネットワーク分断が解消したのち、マスターは一つに収束します。ネットワークスイッチの類であれば大概の場合これで問題はありません。ええ、問題はないはずでした。
ところが先日、ネットワーク分断解消後にある Linux サーバーからスイッチの仮想IP(VIP)への通信ができなくなる現象が発生しました。原因を調べたところ、VIP を現在持っているスイッチの MAC アドレスではなく、バックアップスイッチ側の MAC アドレスが ARP キャッシュに載っていたためでした。
以下のような経緯で障害になったものと思われます。
- スプリットブレイン中、複数のマスターから VIP の ARP キャッシュを更新するためGratuitous ARP が投げられる
- スプリットブレイン解消後、keepalived は Gratuitous ARP を投げることなく収束する
- Linux サーバーの一部は、マスターでなくなったスイッチの MAC アドレスを ARP キャッシュに保持したままになる
- そのサーバーはずっと 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 さんから、以下いただきました。
garp_master_refresh設定する方が良い? / “スプリットブレインが起きたら ARP フラッシュが必要になった - はざまブログ” http://t.co/8aOjJaYurH
— Kazuho Oku (@kazuho) 2015, 3月 20