Linuxのbonding(802.3ad)で発生したトラフィックの偏りをなおした話

はじめに

とある環境の話。internalのLinuxサーバでbonding(ボンディング)を組んでいました。modeは4。802.3ad(LACP)準拠のリンクアグリケーションなモードです。

ちなみに、bondingとは・・・

ちなみに、"bonding"とは、ネットワークインターフェースを冗長化(または負荷分散)する方法で、複数のNICを束ねて1本に見せることができます。チーミング(teaming)と呼ばれたりもしますね。
で、Linuxではbondingにもいくつかモードがあって、複数のポリシーの中から選択することができます。

  • balance-rr 又は 0 - 耐障害性とロードバランシングのためラウンドロビンポリシーを設定します。利用可能な第 1 のインターフェースからそれぞれのボンディングされたスレーブインターフェースで送受信が順次行われます。
  • active-backup 又は 1 - 耐障害性のためアクティブなバックアップポリシーを設定します。利用可能な第 1 のボンディングされたスレーブインターフェースにより送受信が行われます。別のボンディングされたスレーブインターフェースは、アクティブなボンディングされたスレーブインターフェースが失敗した場合にのみ使用されます。
  • balance-xor 又は 2 - 耐障害性とロードバランシングのため XOR (排他的論理和) ポリシーを設定します。この方法を使用すると、インターフェースによって受信要求の MAC アドレスとスレーブ NIC の 1 つの MAC アドレスが一致します。このリンクが確立すると、利用可能な第 1 のインターフェースから送信が順次行われます。
  • broadcast 又は 3 - 耐障害性のためブロードキャストポリシーを設定します。全ての送信は、全てのスレーブインターフェースで行われます。
  • 802.3ad 又は 4 - IEEE 802.3ad 動的リンクアグリゲーションのポリシーを設定します。同一の速度とデュプレックス設定を共有するアグリゲーショングループを作成します。アクティブなアグリゲーターの全てのスレーブで送受信を行います。802.3ad に対応するスイッチが必要です。
  • balance-tlb 又は 5 - 耐障害性とロードバランシングのため送信ロードバランシング (TLB) ポリシーを設定します。発信トラフィックは、各スレーブインターフェースの現在の負荷に従って分散されます。受信トラフィックは、現在のスレーブにより受信されます。受信しているスレーブが失敗すると、別のスレーブが失敗したスレーブの MAC アドレスを引き継ぎます。
  • balance-alb 又は 6 - 耐障害性とロードバランシングのためアクティブロードバランシング (ALB) ポリシーを設定します。IPV4 トラフィック用の送受信ロードバランシングが含まれます。ARP ネゴシエーションにより、受信ロードバランシングが可能です。
25.7.2. チャンネルボンディングの使用 Red Hat Enterprise Linux 6 | Red Hat Customer Portal

はい、ここまでがおさらい。

閑話休題、とあるサーバで・・・

モード4のbondingの(送信時)負荷分散アルゴリズムは XOR スタイルとなるので、これまでも多少偏っているサーバはそれなりに見てきました。


駄菓子菓子!


今回は違ったのです。偏り方のレベルが・・・!!

まずはグラフを見てください

以下は、そのサーバのeth0とeth1のトラフィックのグラフです。

eth0のグラフ(before)


eth1のグラフ(before)

トラフィックの偏りがパないw

ここまで、くっきり偏ったのは初めて見たので、さすがに驚きました。もう笑っちゃうレベルw
片方が920Mbps、もう片方が40Mbpsとか・・・w
ということで、真面目に送信のハッシュポリシーを調べてみると、、、

  • 0 又は layer2 - デフォルト設定です。このパラメーターは、ハードウェア MAC アドレスの XOR を使用してハッシュを生成します。使用する公式は以下のとおりです:
(<source_MAC_address> XOR <destination_MAC>) MODULO <slave_count>
25.7.2. チャンネルボンディングの使用 Red Hat Enterprise Linux 6 | Red Hat Customer Portal

デフォルトはLayer 2となっているわけですね。
というわけで、主な送信元のMACアドレスを調べてみます。

$ tomahawk -t 10 -u username -c -f server.list '/sbin/ifconfig | grep "bond0 "'

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:50

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:8C

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:96

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:26

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:YY:AE

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:68

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:YY:E0

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:18

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:A0

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:ZZ:E0

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:ZZ:60

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:YY:XX:34

[email protected] % /sbin/ifconfig | grep "bond0 "
bond0     Link encap:Ethernet  HWaddr XX:XX:XX:YY:XX:30

・・・・・以下、省略・・・・・

送信先(とあるサーバ)のMACアドレスとの排他的論理和(XOR)が、ほっとんど"偽"という結果にww
というわけで、トラフィックがNICによって偏ってしまうのは当然の結果であったわけです。

802.3ad(LACP)モードでの送信ハッシュポリシー

調べていくと送信ハッシュポリシーは"layer2"、"layer3+4"、"layer2+3"の3種類から選択できることがわかります。

ということで、今回は"layer2+3"に送信ハッシュポリシーを変更してみました。

  • 2 又は layer2+3 - layer2 及び layer3 プロトコル情報の組み合わせを使用して、ハッシュを生成します。ハードウェア MAC アドレス及び IP アドレスの XOR を使用して、ハッシュを生成します。公式は以下のとおりです:
(((<source_IP> XOR <dest_IP>) AND 0xffff) XOR
  ( <source_MAC> XOR <destination_MAC> ))
    MODULO <slave_count>
25.7.2. チャンネルボンディングの使用 Red Hat Enterprise Linux 6 | Red Hat Customer Portal


設定は、"/etc/modprobe.conf"に以下のような感じで記載して、(念のため)リブートしました。

# cat /etc/modprobe.conf

・・・前半省略・・・

alias bond0 bonding
options bond0 mode=4 lacp_rate=1 miimon=200 xmit_hash_policy=layer2+3

すると、こうなりました!

以下が、上記設定後の各ネットワークインターフェースでのトラフィックのグラフです。
ちょっと見辛いですが、eth0とeth1のトラフィックが奇麗に分散できていることがわかります。

eth0のグラフ(after)


eth1のグラフ(after)

おわりに

bondingの設定パラメータは、たくさんの種類があるので、しっかり読んでおいた方がよいですね。反省。
ちなみに、(ここまでも紹介してきましたが)以下のRedHatさんのドキュメントが結構詳しいです。

24.7.2. チャンネルボンディングの使用
http://docs.redhat.com/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html


それでは! =͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞(๑•̀д•́

あわせて読みたい


Linuxネットワーク管理 第3版

Linuxネットワーク管理 第3版