ng_bridge+CARPは危ない(かもしれない)

注意: ng_bridgeを使った場合の話です。ngctlする人向けです。ifconfigでbridgeする人には関係ない(はず)の内容です。

CARPを設定したら60秒おきに切れたり繋ったりする。
対策としては、CARPをGRE/VXLANなどに通すか、ng_bridgeのループ判定を無効化する。

なんで「かも」かというと、これを書いた前日に散々発生したくせに、調査を始めたら全然起きなくなったから。
でも起きると60秒間通信不能になるので、危険ではあるはず。

なにが問題か

ng_bridgeは簡易ループ判定を持っている。
この判定はパケット受信時に「記憶しているMACアドレスとポートの対が異なる」現象がminStableAge(デフォルト1秒)より短い間隔で発生すると、ループありと判定するもの。
参考: ng_bridgeの判定部分

carp(ucarp)は、送信元MACアドレスを 00:00:5E:00:00:<vhid> にして送るため、ng_bridgeからすると同じMACアドレスからのパケットがいろんなポートから出入りすることになって、上記ループ判定に引っかかることがある。

解決策その1

ng_bridgeにバレなければいいので、encapsuleすればいい。GREとかVXLANとか。
GREだとpeer-to-peerしかできないので、3台以上でcarpしたい場合には向かないが、multicast(=ethernetからすればbroadcast)を減らせるというメリットがある。

解決策その2

encapsuleすると障害の原因が増えかねない。ループは自己責任で、というならこちら。
setconfigでloopTimeout=0にする。set後にgetconfigするとloopTimeoutがいなくなるが、効いている模様。

# ngctl msg br0: getconfig
Rec'd response "getconfig" (2) from "[5]:":                                                                                          │     performing TSO on the inner frames in hardware: cxgbe(4).
Args:   { debugLevel=1 loopTimeout=60 maxStaleness=900 minStableAge=1 }
# ngctl msg br0: setconfig '{ debugLevel=1 loopTimeout=0 maxStaleness=900 minStableAge=1 }'
# ngctl msg br0: getconfig
Rec'd response "getconfig" (2) from "[5]:":
Args:   { debugLevel=1 maxStaleness=900 minStableAge=1 }

ところで……

CARPはMASTERがadvertise中にBACKUPはadvertiseしないため、この事象はあまり発生しないように思える。
しかし、CARPが動作するような状況、つまり中間にある機器(switch, netif)の一時障害が発生すると、両者がMASTERになり、この一時障害の解消時に問題を引き起こす可能性がある。

ちなみに、CARPのパスワードを間違えると相互にadvertiseする状態になるので、すぐにこの現象を引き起こすことになる。

Comments are closed.