久しぶりに複数 NIC を使っての bonding について調べてみました。
bonding については、一次資料というか、ここを見ると詳細に書かれていますが、ディストリビューション毎には多少設定方法に違いというか方言があるように思います。
https://www.kernel.org/doc/Documentation/networking/bonding.txt
今回は Debian 8 Jessie においての設定を書いてみます。
bonding についての説明はここでは割愛します。また、サーバ用途等では可用性を重視して mode 1 の active-backup を使う事が多いので、この mode 固定で検証しました。
このモードは接続先のスイッチングハブにおいて特別な設定は必要なく、通常はどちらか片方の NIC で通信を行い、アクティブな NIC が不通になったときにもう片方の NIC に切り替わるという仕様です。
※mode 1 は、リンクアグリゲーション( LACP 等)のような帯域を増やす効果はありません。
bondig 用ドライバのインストール
aptitude install ifenslave
システム再起動後 dmesg を見ると、
[ 5.189114] bonding: Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
このように bondig 用のドライバが読込まれます。
NIC の監視方法は2種類あります。一つは NICのステータスを見る(UPしているか? Downしているか?)、もう一つは 指定した相手に対してARPパケットを送り、返事があるかどうかを調べる という方法です。
1.NIC のステータスを見る
/etc/network/interfaces を下記の様に編集します。
※下記例では、eth0 と eth1 を bonding するという設定です。
ポイントは…
1-1.allow-hotplug eth0 等は、書かない。
1-2.ipv6 関連の設定も書かない(自動で設定される!?)
1-3.modprobe.d や modules 等、ドライバ関連の記述も不要。
※/etc/network/if-pre-up.d/ifenslave を読むと、予め modprobe している事がわかります。
上記の設定が終わったら、システムを再起動します。
システムが立ち上がってきたら下記コマンドで bonding の状態を見る事ができます。
この設定では1秒(1,000msec)単位で NIC の状態をチェックしています。
ここで eth0 のLANケーブルを抜くと、自動的に eth1 へ接続が切り替わります。
/var/log/syslog には下記の様に記録されます。
ip a で表示される内容を見ると、bonding されている eth0 と eth1 の MAC アドレスが同じになっているのがわかります。
注)検証に使ったマシンには4個の Intel製 NIC が搭載されているので、上記の様に eth0 ~ eth3 まで表示されます。
また、ネットで検索してみると、例として…
bond-miimon 100 bond_downdelay 200 bond_updelay 200
このような設定が多いですが、年に一回あるかないかという障害に対応するために、100m杪(0.1秒)単位で監視する必要はないような気がします。今回設定した1秒単位の監視でも数パケットのロスで切り替わるので、問題無いと判断しています(個人的に)。
2.ARPパケットを使った監視
この設定は、上記 MII (Media Independent Interface) を使った監視とは同時に実行はできません。必ずどちらか一方となります。
注)両方の設定を行うと、MII監視が優先されるようです。
MII 監視と同様に、/etc/network/interface の設定内容を変更すれば良いと思ったのですが、残念ながらその方法では設定が出来ませんでした。
私が検証してうまく動いたのは、/etc/modprobe.d/ に設定ファイルを置く方法と、
/erc/rc.local で設定値を /proc へ書き込む方法です。
2-1./etc/modprobe.d/ に設定ファイルを置く方法(こちらをお勧め!)
/etc/modprobe.d/ に、bondig.conf というファイルを作成します。
# cat /etc/modprobe.d/bonding.conf alias bond0 bonding options bonding arp_interval=2000 arp_ip_target=192.168.0.1
2-2./erc/rc.local で設定値を /proc へ書き込む方法
# cat /etc/rc.local #!/bin/sh -e echo +192.168.0.1 > /sys/class/net/bond0/bonding/arp_ip_target echo 2000 > /sys/class/net/bond0/bonding/arp_interval exit 0
2-3./etc/network/interfaces には、下記の通り bond-mode と、slaves の情報だけを記述します。
2-1(もしくは2-2)と2-3の設定が終わったらシステムを再起動します。
立ち上がってきたらログインして、下記コマンドで bonding の状態を確認します。
このように、MII Polling Interval が 0(ゼロ=動作していない)で、ARP Poliing と ARP IP target が設定されていれば正しく動作しています。また、arp(Address Resolution Protocol)は L2 で動作するので、監視先は自分と同じセグメントに居る必要があります。arp パケットはセグメント境界を越える事はできません(ルータで破棄されます)。
3.動作確認
実際にスイッチングハブへLANケーブル2本で接続して、抜いたり入替えたり色々チェックしてみると、2つの確認方式の違いがわかってきます。正確に書くと、接続する先のスイッチングハブ or ルータ等のメーカによって、若干挙動が異なります。
特に MII を使った監視では、動作確認の為に、外部から送っている ping の応答が、長時間(10秒以上)止まる時があります。これは、スイッチングハブ(ブリッジ)の動作を考えると原因がなんとなくわかります。
ブリッジでは、どの MACアドレスを持つ機器が、どの物理ポートに接続されているかを管理しているフォワーディングテーブルがありますが、このフォワーディングテーブルの更新タイミングは、スイッチングハブやルータ等の設定によって一律ではありません。また、Gratuitous(グラチュータス)ARP を使って自分が接続されているポートを主張しようとしても、機器によっては Gratuitous ARP を禁止(無視)する場合があります。
https://ja.wikipedia.org/wiki/Gratuitous_ARP
原則として、スイッチングハブのポートへパケットが送られてくると、そのソース(送信元)Macアドレスをフォワーディングテーブルへ追加して学習します。これは物理ポートに接続に接続されている機器が、何もパケットを送らない(だんまり状態)と、フォワーディングテーブルの更新がされない…ということを意味します。
フォワーディングテーブルの管理については、色々な方法があるのですが、フラッティング(全ての物理ポートに同一パケットを送る)という動作が重要で、宛先のMACアドレスが現在保持しているフォワーディングテーブルに無い場合に、無条件にフラッティングしたり、宛先のMACアドレスはフォワーディングテーブルに存在するが、その物理ポートから何も応答がない場合にフラッティングしたり…とか、この辺の実装はメーカ毎に色々だったりします。
つまり、MII 監視の場合、単に NIC のリンク状態を見てアクティブポートを切替えるので、自 NIC から外部に何かパケットを送出することはしません。その為、接続されている機器(スイッチングハブやルータ)によっては、フォワーディングテーブルが更新されるまで通信が出来ないので、外部から見ると長時間接続が切れているように見える場合があります。
※特に ping で監視されている場合、外部から ICMP パケットが到着して初めて返事をするので…
※ただし、実際の運用ではなんらかのサービスが動いているので、自 NIC から何もパケットを送出しないという事は起きないので、このような長時間 ping に応答しないような状況にはならないとは思います。
それに比較すると ARP パケットを自 NIC から一定間隔で送出する方式は、どのような状況になってもその ARP パケットが送られた時点で、フォワーディングテーブルが更新されます。ですから、アクティブポートが切り替わるタイミングは MII 監視に比べてちょっと遅いですが、必ず一定時間経過後に通信が復旧します。
またスイッチングハブの故障等で、リンクアップしているのに実は通信は止まっているような状況だと、MII 監視ではポートは切り替わりません。特にスパニングツリーを使ったネットワークの冗長化を行っている場合等、接続先のスイッチが NIC 毎に異なる場合は、ARP 監視を使わないとダメかもしれません。
※上記例では、ARP パケットを送って監視する対象は1つですが、複数の監視先が設定ができるので、現場にあわせて設定する事をお勧めします。
安定した監視を望む場合には ARP 監視、素早い切替が必要な場合には MII 監視…と、個人的には思っています。
4.最後に Tips
4-1.設定するパラメータですが、ハイフォンでもアンダーバー(アンダースコア)でも、どちらでもOKです。設定をいろいろ触っていて気がつきました。
つまり、bond-mode と bond_mode は同じです。同様に arp_interval と arpーinterval も等価です。
4-2.MII 監視と ARP 監視は、同時に設定すると MII 監視が優先されます。ということは、/etc/modprobe.d/bonding.conf を作成しておき、/etc/network/interfaces に bond-miimon の設定を書けば、MII 監視が有効となり、その行をコメントアウトすると ARP 監視となります。テストする時は便利ですが、実運用に入るときは後々の混乱を防ぐ為に、どちらかの設定にしておいた方が良いと思います。
検証環境
Debian 8 Jessie kernel 3.16.0-7-686-pae
ifenslave 2.6
Intel(R) Celeron(R) CPU J1900 @ 1.99GHz (4 core 4 thread)
Intel Corporation 82583V Gigabit Network Connection ×4