EVPN オールアクティブ上の Linux アクティブ-バックアップ bond:何が壊れるか
オールアクティブな EVPN セグメントはどちらのリーフにもユニキャストを送るが、Linux のアクティブ-バックアップ bond は単一のポートでしか待ち受けない。検証の前に両モデルを揃えよう。
サーバーにアクティブ-バックアップ bond を置き、ファブリックにオールアクティブな Ethernet セグメントを置くと、戻りのトラフィックの半分がエラーカウンターを一つも動かさずに消えることがある。どちらの設定も単独では間違っていない。問題は両者の受け渡しにあり、一方は単一のポートを選び、もう一方は接続されたすべてのリーフが届けられると仮定している。各方向で一つのフレームを追えば、食い違いは明らかになる。
アクティブ-バックアップは受信フレームに何をするか
ボンディングモード 1 は送信パスに一つのスレーブだけを置き、現在のスレーブが故障したときだけ切り替える。この部分はよく知られている。ここで重要なのは受信側だ。カーネルはアクティブなスレーブに届いたフレームだけをスタックに渡し、他のスレーブに現れたフレームは破棄する。この all_slaves_active 設定はまさにその規則を緩めるために存在し、既定では無効になっている。 ip -d link show bond0 モードの隣に現在値を表示する。
/proc/net/bonding/bond0 アクティブなスレーブを名指しし、各スレーブのリンク状態を報告する。どのポートが現在トラフィックを運んでいるかについて、正直な情報源はこのファイルだけだ。
このモードのホストは、一度に一つの受信パスしか使えず、ファブリックを知らないままローカルに選ばれる。そのホスト宛てのフレームがもう一方のケーブルに届くと、スイッチのポートは受信として数え、ホストのスタックは決して見ず、ホスト自身のドロップカウンター以外のすべてのカウンターは完全に健全に見える。
オールアクティブなマルチホーミングは遠隔のネクストホップに何をするか
EVPN マルチホーミングは、ESI で識別される一つの Ethernet セグメントを共有するリーフの集合を記述し、そのセグメントをファブリックの残りに広告する。オールアクティブモデルでは、遠隔のピアはセグメントのアドレスに対して複数のネクストホップをインストールする。サーバー向けのユニキャストはどちらのリーフにも到着でき、ファブリックはフローごとに自由に選べる。これが設計の狙いそのものであり、サーバーの bond が満たすべき前提でもある。
フラッディングされるトラフィックは別の規則に従う。リーフはセグメントごとに指定フォワーダーを選出するため、ブロードキャスト、未知のユニキャスト、マルチキャストは通常そのいずれかを通って入る。したがってユニキャストとフラッディングは別々の判断を行い、ホストの bond 状態に現れるのはその一方だけだ。
二つの選出が食い違う場所
カーネルはリンク状態と独自のポリシーからアクティブなスレーブを選ぶ。ファブリックは EVPN ルートからネクストホップを選び、リーフ間の選出から指定フォワーダーを選ぶ。どちらのプロセスも相手に問い合わせない。異なるリーフを選ぶと、障害は方向に依存する。サーバーが送るものは正常に出て行き、応答だけが消える。
サポートされる回避策は二つあり、互換ではない。ファブリックが一つの論理接続として扱える bond をホストに与える、つまり実際にはリーフとネゴシエートした LACP bond を使い、両方のリンクを本当に同時にアクティブにする。あるいはファブリック側からのシングルアクティブ配送も受け入れ、セグメントを bond と同じ一ポートずつのモデルに従わせる。うまくいかないのは、一つのポートでしか待ち受けない bond の前にオールアクティブなセグメントを置く構成であり、非アクティブなスレーブで受信を意図的に有効にして二重配送を受け入れるのでなければ成立しない。
バックアップケーブルが健全に見え続ける理由
トラフィックを運ばないケーブルもリンクアップを報告し、bond の待機スレーブは準備できているように見えるよう設計されている。運用者はそれを冗長性と読み、疑問を持つのをやめる。
代わりに、戻りのフレームがどの物理ポートを使ったかを問う。ホストでは bond 単位ではなくスレーブ単位で受信パケットを数える。bond のカウンターは非対称性を隠すからだ。リーフでは、 サーバーの MAC に対するブリッジの転送エントリ と、EVPN ルートが運ぶネクストホップ集合を見る。エントリがホストのリンクを待機側にしているリーフを指しているなら、設計はホストが無視するポートへ配送している。これはハードウェア障害ではなく設定の不一致であり、リンク状態の監視をいくら行っても表面化しない。
リンク状態ではなく、両方向の配送を試す
障害ごとに一行、方向ごとに一列のマトリクスを作り、インターフェース状態ではなく配送されたトラフィックを埋める。最初の行は通常運用であり、食い違いはまさにそこに隠れる。症状はアプリケーションの問題に見えるからだ。
次に、アクティブなホストリンクを外し、リーフを一つ外し、そのリーフのアップリンクを外し、それぞれを順に元へ戻す。各手順の後に、アクティブなスレーブ、EVPN セグメントの状態、遠隔の転送エントリ、両方向で観測したスループットを記録する。ホストリンクが上がったままファブリックへの経路を失うリーフが興味深いケースだ。接続は広告されたままで、静かに行き止まりになり得る。アプリケーションが依存するフラッディングトラフィックと、新しいユニキャストフローの両方で試す。両者は異なる転送判断を使うからだ。
マトリクスが意図した経路での双方向配送を示したときにだけ、設計を受け入れる。リンクアップした二本のケーブルはその結果ではない。