Linux の bonding のモードまとめ

いまさら bonding について学びました。

わたしがこれまでに関わったプロジェクトでは 2 本で active-backup が多かったです。active-backup ならスイッチに特別な要件が必要ないし、冗長化だけが目的なのならわたしのようなスイッチとかわからんマンには簡単なのが良いです。たまに負荷分散したいときに balance-rr を使うこともあったようです。

## モードごとの特徴

- balance-rr (0)
    - 送信の負荷分散：ラウンドロビンで分散
    - 受信の負荷分散：スイッチに依存
    - スイッチの制約：スイッチで EtherChannel を構成する必要がある
- balance-xor (2)
    - 送信の負荷分散：MAC アドレスに基づいたハッシュで分散
        - ルータ越しだと常に同じアダプタ
        - ハッシュのポリシーは変更できる
    - 受信の負荷分散：スイッチに依存
    - スイッチの制約：スイッチで EtherChannel を構成する必要がある
- 802.3ad (4)
    - 送信の負荷分散：MAC アドレスに基づいたハッシュで分散
        - ルータ越しだと常に同じアダプタ
        - ハッシュのポリシーは変更できる
    - 受信の負荷分散：スイッチに依存
    - スイッチの制約：スイッチで 802.3ad を構成する必要がある
- balance-tlb (5)
    - 送信の負荷分散：負荷に応じてアダプタを選択
    - 受信の負荷分散：アクティブなアダプタのみ
        - アクティブなアダプタが故障すると別のアダプタが MAC アドレスを引き継ぐ
    - スイッチの制約：なし
- balance-alb (6)
    - 送信の負荷分散：負荷に応じてアダプタを選択
    - 受信の負荷分散：負荷に応じてアダプタを選択
        - 通信相手の ARP テーブルを書き換えることでアダプタを選択（ARP ネゴシエーション）
        - ルータ越しだと常に同じアダプタ
    - スイッチの制約：なし

「スイッチに依存」というのは、スイッチ側の EtherChannel での負荷分散の設定に依存するという意味です。

## 補足

- active-backup (1)
    - 負荷分散しないので除外しています
- broadcast (3)
    - 用途がよくわからないので除外しています
    - ミラーポートみたいな使い方？
- balance-tlb と balance-alb はすべてのアダプタの MAC アドレスが異なる値になる
    - balance-tlb
        - 故障時にアクティブアダプタの MAC アドレスを他のアダプタが引き継ぐ
    - balance-alb
        - ARP ネゴシエーションで通信相手の ARP テーブルを書き換える
    - その他のモードだと MAC アドレスはすべてのアダプタで同じ

## ハッシュポリシー

balance-xor や 802.3ad では bonding のパラメータ `xmit_hash_policy` でハッシュのポリシーを指定できる。ポリシーは次の３つある。

- layer2
    - MAC アドレスに基づくハッシュ
- layer2+3
    - IP プロトコルのパケット
        - MAC アドレスと IP アドレスに基づくハッシュ
    - IP プロトコル以外のトラフィック
        - layer2 と同じ
- layer3+4
    - フラグメントされていない TCP/UDP パケット
        - IP アドレスと TCP/UDP ポート番号に基づくハッシュ
    - フラグメントされている TCP/UDP またはその他の IP パケット
        - IP アドレス に基づくハッシュ
    - IP プロトコル以外のトラフィック
        - layer2 と同じ

具体的なところは [RHEL のドキュメント][rhel-bonding] が詳しかった。

[layer3+4 を使用することを積極的に考慮すると良い][ibm-knowledge] らしい、が、IP パケットがフラグメントされた場合に TCP や UDP でパケットが複数のアダプタにまたがってストライピングされることがあるため、それが原因でなにかしらの問題があるときは layer2+3 にすると良いらしい。

[RHEL のドキュメント][rhel-bonding] だと、layer3+4 は、

> このポリシーで使用されるアルゴリズムは、802.3ad に対応していません。

とあるので、802.3ad なら layer2+3 にする必要がありそう。

layer2 はルータ越しだと偏ってしまうので同一セグメントの通信しか存在しない状況でなければ使えなさそう（バックエンドのネットワークとか）。

[Linux カーネルのドキュメント][linux-bonding] によると encap2+3 とか encap3+4 とかもあるらしい。カプセル化されたパケットをどうするかの違いがあるらしい。

## さいごに

概ね balance-rr か、あるいはスイッチで EtherChannel できないときの active-backup でよいと思うのだけれども、その他のモードを使いたい状況ってどういうものだろうか？

NIC を負荷分散しなければならないほどのシステムで EtherChannel できないスイッチを使うような状況は考えにくいように思うし。

負荷分散したいけど EtherChannel だと煩雑でめんどくさいので 802.3ad とか balance-tlb とか balance-alb とか、だろうか。

balance-xor などで、宛先によってI/Fを固定させたいこともあるのだろうか。

## 参考

- [4.5. チャンネルボンディングの使用 - Red Hat Enterprise Linux 7][rhel-bonding]
- [IBM Knowledge Center][ibm-knowledge]
- [Linux Ethernet Bonding Driver HOWTO][linux-bonding]
- [Linuxのbonding(802.3ad)で発生したトラフィックの偏りをなおした話 - 元RX-7乗りの適当な日々](http://d.hatena.ne.jp/rx7/20120412/p1)
- [[CentOS] ボンディングを構成する - かえでのWebログ](http://kaede.blog.abk.nu/rh-bonding)

[ibm-knowledge]: http://www-01.ibm.com/support/knowledgecenter/ST5Q4U/com.ibm.storwize.v7000.unified.143.doc/mng_t_pub_netw_bondingmodes2_4.html?lang=ja

[rhel-bonding]: https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html

[linux-bonding]: https://www.kernel.org/doc/Documentation/networking/bonding.txt