絖綛 N@i.jp  昨日:00019535
 今日:00008565
 総計:00082280
keywords
管理者専用
  Post   Add link   Control Panel 































新しいトピック
最新:10/01 12:07


新しいコメント
最新:07/28 16:47






管理人へMAIL

プライバシーポリシー

Raspberry Pi 3 (Raspbian Jessie) で bonding を試してみた

Raspberry Pi 3本体のEthenetと Gigabit Ethenet-USBアダプタを束ねて、通信性能を上げられないか試してみました。


参考URL <https://wiki.debian.org/Bonding>:Debian Wiki。Bondingに関する説明内容はDebian 6(squeeze), 7(Wheezy)がベースの様子。

 Raspberry Pi 3のファイルサーバーですが、Gigabit Ethernet-USBアダプタを使用することで 20MB/sec程のI/O性能が出るようになりました。でも、USB2.0の論理通信性能の半分以下ですから、この程度ではまだ性能的に物足りないですね。そこで、本体の 10/100base-T と Gigabit Ethernet を束ねることで性能を向上させることができないか試してみました。
 ネットワークデバイスを束ねる事をチーミング(Teaming)、またはLinuxではドライバ名からボンディング(Bonding)と言うそうです。
 複数のNICを束ねて1つの仮想ネットワークデバイスを構成しますので、1つのNICが故障したり通信経路が切断されても、他のNICによって通信が確保され(これを可用性と言う)、複数のネットワークデバイスに分散して通信することで通信帯域を広くしたり、負荷を分散させることができます。

 bondingの方法についてはネット検索すれば多くの事例が見つかるのですが、Raspbian Jessie(Debian 8)についてはまだ事例が少なく、内容が薄くて信頼性も低いものばかりでした(*1)。途中かなりハマったので、まだ少し味見した程度ですが、結論から言うと通信性能(スループット)を向上させることはできず、かえって性能低下してしまいました。ですから、負荷分散や可用性が目的であれば試す価値はあるかもしれませんが、通信性能(スループット)の向上が目的なら徒労に終わる可能性大ですので、そのつもりでお読みください。

 大まかな手順は以下のようになります。OSは Raspbian Jessie で、作業は root ユーザーで行います。

  1. ifenslaveのインストール
  2. "/etc/modules"の編集
  3. "/etc/network/interfaces"の編集
  4. "/etc/dhcpcd.conf"の編集
  5. 再起動

 しかし、この後にトラブルの発生と、その対処の内容が続きます。トラブルが起きないように整理した手順にはなっていませんので、ご自分で手順を整理して実施することをお勧めします。

 さて、NICを束ねる方法には以下の7種類があります。

mode名称負荷分散説明
0balance-rr送信時全スレーブを順番(ラウンドロビン)に使いパケットを送信。
リンクアグリケーション(EtherChannel)に対応しているスイッチが必要。
1active-backupなし1つのスレーブのみを active interfaceとしパケットを送信。
active interfaceに障害が発生した場合、他の backup slave を active interfaceに切り替え、冗長性を確保。
2balance-xor送信時送信元/先のMACアドレスを元に送信スレーブを決定しパケットを送信。
リンクアグリケーション(EtherChannel)に対応しているスイッチが必要。
3broadcast送信時全スレーブに同一パケットを送信。(通常は使用しない)
4802.3ad送受信IEEE 802.3ad(LACP)に準拠したリンクアグリゲーション。
802.3adに対応しているスイッチが必要。
5balance-tlb送信時各スレーブの負荷に応じて送信スレーブを決定しパケットを送信。受信は現在のスレーブで行う。
6balance-alb送受信balance-tlbの機能に加え、受信も負荷分散。

 どのモードを使用するかですが、今回の目的は通信性能向上ですから、モード 1, 3は除外します。ウチのは単なるスイッチングハブなので、スイッチに条件があるモード 0, 2, 4もダメなので、スイッチの条件が不要な balance-tlb(モード 5)か balance-alb(モード 6)で動くようにしたいのですが、今のところモード 5でしか成功していません。
 先ずは味見として、Raspberry Pi 3本体の eth0(10/100base-T)と eth1(Gigabit Ethernet-USBアダプタ)を balance-rr(モード0)で束ねてみます。ただし balance-rr で複数台のスイッチを使用している場合には、NIC切り替え時にパケットの順序の入れ替わりが起こるという、かなり致命的な問題があるという事なので、注意してください。(*2)

1. ifenslaveのインストール

 ifenslaveというボンディングモジュールをインストールします。

# apt-get update
# apt-get install ifenslave
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  ifenslave
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 8 個。
15.6 kB 中 0 B のアーカイブを取得する必要があります。
この操作後に追加で 27.6 kB のディスク容量が消費されます。
以前に未選択のパッケージ ifenslave を選択しています。
(データベースを読み込んでいます ... 現在 142280 個のファイルとディレクトリがインストールされています。)
.../archives/ifenslave_2.6_all.deb を展開する準備をしています ...
ifenslave (2.6) を展開しています...
man-db (2.7.0.2-5) のトリガを処理しています ...
ifenslave (2.6) を設定しています ...

2. "/etc/modules"の編集

 カーネルモジュールに bondingドライバーを追加します。

# echo "bonding" >> /etc/modules
# cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

bonding

3. "/etc/network/interfaces"の編集

 ネットワーク設定を任意のエディタ(vi等)で編集し、bond0 という仮想的なネットワークデバイスを作成します。

# cd /etc/network
# cp -p interfaces interfaces.bak    ※バックアップを作成しておきます
# vi interfaces

 編集結果は以下のようになります。

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

# The bonding interface
auto bond0
iface bond0 inet manual
    slaves eth0 eth1
    bond_mode 0
    bond_miimon 100
    bond_downdelay 200
    bond_updelay 200

#auto eth0
#allow-hotplug eth0
#iface eth0 inet manual

#auto eth1
#allow-hotplug eth1
#iface eth1 inet manual

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

#allow-hotplug wlan1
#iface wlan1 inet manual
#    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

 ポイントは以下の2点です。

  • eth0, eth1スタンザは全てコメントアウトする(*3)
  • ボンディングデバイス bond0 を追加し、その中でslaves eth0 eth1と記述する

また、Wi-Fi(wlan0)にもdhcpでIPアドレスが割り当てられるように設定しています。もし設定に間違いがあってEthernet経由でsshログインできなくなっても、Wi-Fi経由でログインできるようにするためです。(*4)

4. "/etc/dhcpcd.conf"の編集

 ネットワークデバイスに静的なIPアドレスを割り付ける(IPアドレスを固定する)には、Raspbian Jessieから"/etc/dhcpcd.conf"に記述するようになりましたので、bond0 にIPアドレスを割り付ける場合にも"/etc/dhcpcd.conf"に記述します。

# cd /etc
# cp -p dhcpcd.conf dhcpcd.conf.bak    ※こちらもバックアップを作成しておきます
# vi dhcpcd.conf
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.

# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel

〜略〜

#interface eth1
#   static ip_address=192.168.0.nnn/24
#   static routers=192.168.0.1
#   static domain_name_servers=192.168.0.1 8.8.8.8

interface bond0
    static ip_address=192.168.0.nnn/24
    static routers=192.168.0.1
    static domain_name_servers=192.168.0.1 8.8.8.8

 eth1に割り付けていたIPアドレスを bond0 の方に割り付けるように修正しました。

5. 再起動

 Raspberry Pi 3本体の10/100base-T Ethernetと、Gigabit Ethenetの両方にケーブル を繋いで rebootしてみます。すると・・・
 ダメでした orz。eth1 にだけケーブルを繋げている状態でなら通信(ssh)できますが、eth0 にもケーブルを繋げると途端に通信できなくなり、有線だけでなく wlan0(Wi-Fi)側も同じく通信できなくなります。
 ifconfig で見ると、bond0 にはIPアドレス192.168.0.nnnが割り付けられているのですが、eth1 にもルーターのDHCPサーバーから取得したと思われるIPアドレス192.168.0.7が割り付けられていました。

# ifconfig
bond0     Link encap:イーサネット  ハードウェアアドレス b8:27:eb:68:01:0a
          inetアドレス:192.168.0.nnn ブロードキャスト:192.168.0.255  マスク:255.255.255.0  ※これはOK
          inet6アドレス: fe80::3891:dce4:2e67:3ece/64 範囲:リンク
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  メトリック:1
          RXパケット:2223 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:2180 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:866606 (846.2 KiB)  TXバイト:619078 (604.5 KiB)

eth0      Link encap:イーサネット  ハードウェアアドレス b8:27:eb:68:01:0a  ※MACアドレスがbond0と同じなのは正しい
          UP BROADCAST SLAVE MULTICAST  MTU:1500  メトリック:1
          RXパケット:0 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:0 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:0 (0.0 B)  TXバイト:0 (0.0 B)

eth1      Link encap:イーサネット  ハードウェアアドレス b8:27:eb:68:01:0a  ※MACアドレスがbond0と同じなのは正しい
          inetアドレス:192.168.0.7 ブロードキャスト:192.168.0.255  マスク:255.255.255.0  ※これは何かおかしい
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  メトリック:1
          RXパケット:2223 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:2180 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:866606 (846.2 KiB)  TXバイト:619078 (604.5 KiB)

lo        Link encap:ローカルループバック
          inetアドレス:127.0.0.1 マスク:255.0.0.0
          inet6アドレス: ::1/128 範囲:ホスト
          UP LOOPBACK RUNNING  MTU:65536  メトリック:1
          RXパケット:643 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:643 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1
          RXバイト:223829 (218.5 KiB)  TXバイト:223829 (218.5 KiB)

wlan0     Link encap:イーサネット  ハードウェアアドレス b8:27:eb:3d:54:5f
          inetアドレス:192.168.0.8 ブロードキャスト:192.168.0.255  マスク:255.255.255.0
          inet6アドレス: fe80::85a3:217a:fde:5e04/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:135 エラー:0 損失:51 オーバラン:0 フレーム:0
          TXパケット:55 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:23853 (23.2 KiB)  TXバイト:7813 (7.6 KiB)

 eth1 へのIPアドレス割り付けは、

# ip addr flush dev eth1

とすると解除されます。しかし再起動すると復活してしまいます。でも、bond0 と eth0, eth1 のMACアドレスは同じだし、以下を見ても bonding はできている様子なのですが・・・(eth0 はケーブルを繋げてないので status が down になっています)

# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200

Slave Interface: eth0
MII Status: down
Speed: 10 Mbps
Duplex: half
Link Failure Count: 1
Permanent HW addr: b8:27:eb:68:01:0a
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 34:95:db:2b:e0:90
Slave queue ID: 0

6. トラブル対処

 このトラブルで数日はまっていました。色々ネット検索しても、同じようなトラブル事例が見つかりません。そもそも Raspbian Jessieでボンディングした事例自体が少なく、ましてトラブルに関する事例は全くと言って良いほど無いのです。
 どう考えても何かが勝手にルーターのDHCPサーバーからIPアドレスを取得して eth0, eth1 に割り当てているように思えます。IPアドレスを固定するのに"/etc/dhcpcd.conf"などという設定ファイルを使用していることから、辿り着いた仮説が「こんな事をするのは dhcpcd(dhcp client daemon)で、こいつが悪さをしているのではなかろうか?それなら"/etc/dhcpcd.conf"で eth0, eth1には何もするな!と設定すれば良いのではないか?」でした。では、その具体的な方法は?

denyinterfaces eth0 eth1
#interface eth0
#interface eth1
#    static ip_address=192.168.0.152/24
#    static routers=192.168.0.1
#    static domain_name_servers=192.168.0.1 8.8.8.8

interface bond0
    static ip_address=192.168.0.152/24
    static routers=192.168.0.1
    static domain_name_servers=192.168.0.1 8.8.8.8

 "/etc/dhcpcd.conf"内の interface eth0, eth1 スタンザを無くすようコメントアウトするだけでなく、"denyinterfaces eth0 eth1"を追加してみます。これで再起動してみたら、できました!

# ifconfig
bond0     Link encap:イーサネット  ハードウェアアドレス b8:27:eb:68:01:0a
          inetアドレス:192.168.0.nnn ブロードキャスト:192.168.0.255  マスク:255.255.255.0
          inet6アドレス: fe80::3891:dce4:2e67:3ece/64 範囲:リンク
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  メトリック:1
          RXパケット:4244 エラー:0 損失:1 オーバラン:0 フレーム:0
          TXパケット:7452 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:1312921 (1.2 MiB)  TXバイト:2751912 (2.6 MiB)

eth0      Link encap:イーサネット  ハードウェアアドレス b8:27:eb:68:01:0a  ※eth0にIPアドレスが割り当てられていない
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  メトリック:1
          RXパケット:2215 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:3731 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:703429 (686.9 KiB)  TXバイト:1386844 (1.3 MiB)

eth1      Link encap:イーサネット  ハードウェアアドレス b8:27:eb:68:01:0a  ※eth1にIPアドレスが割り当てられていない
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  メトリック:1
          RXパケット:2029 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:3721 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:609492 (595.2 KiB)  TXバイト:1365068 (1.3 MiB)

lo        Link encap:ローカルループバック
          inetアドレス:127.0.0.1 マスク:255.0.0.0
          inet6アドレス: ::1/128 範囲:ホスト
          UP LOOPBACK RUNNING  MTU:65536  メトリック:1
          RXパケット:1485 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:1485 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1
          RXバイト:562067 (548.8 KiB)  TXバイト:562067 (548.8 KiB)

wlan0     Link encap:イーサネット  ハードウェアアドレス b8:27:eb:3d:54:5f
          inetアドレス:192.168.0.8 ブロードキャスト:192.168.0.255  マスク:255.255.255.0
          inet6アドレス: fe80::85a3:217a:fde:5e04/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:533 エラー:0 損失:107 オーバラン:0 フレーム:0
          TXパケット:60 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:75896 (74.1 KiB)  TXバイト:11885 (11.6 KiB)

# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200

Slave Interface: eth0  ※eth0がスレーブになっている
MII Status: up
Speed: 100 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: b8:27:eb:68:01:0a
Slave queue ID: 0

Slave Interface: eth1  ※eth1がスレーブになっている
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 34:95:db:2b:e0:90
Slave queue ID: 0

# cat /sys/class/net/bond0/bonding/mode
balance-rr 0    ※balance-rr(モード 0)になっている

# ip route show table main
default via 192.168.0.1 dev bond0  metric 203
default via 192.168.0.1 dev wlan0  metric 304
192.168.0.0/24 dev bond0  proto kernel  scope link  src 192.168.0.152  metric 203
192.168.0.0/24 dev wlan0  proto kernel  scope link  src 192.168.0.8  metric 304

7. 性能測定

 せっかくですので、性能を測定してみます。

# iperf -c 192.168.0.xxx
------------------------------------------------------------
Client connecting to Titan, TCP port 5001
TCP window size: 70.0 KByte (default)
------------------------------------------------------------
[  3] local 192.168.0.nnn port 55592 connected with 192.168.0.xxx port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   224 MBytes   188 Mbits/sec

 かえって遅くなりました(^^;)。これじゃ意味な〜い!(負荷分散や可用性はできているのではないかと思いますが、通信スループットは低下してしまいました。まぁリンクアグリケーションに対応していないフツーのスイッチングハブ1台に繋いでいるのですから、当然の結果と言えますが。)一旦設定を元に戻して bond0 をお掃除(削除)します。Wi-Fi側からログインして、

# ifdown bond0
# echo "-bond0" > /sys/class/net/bonding_masters
# rmmod bonding
上記では一時的にボンディングデバイス(bond0)と、bondingドライバを削除しただけですから、再起動(reboot)すると元に戻ってしまいます。永続的にボンディングデバイス(bond0)を削除したい場合は、この後"/etc/modules"から bonding を削除(またはコメントアウト)してから再起動します。

8. モードを変えてみる

 balance-rr (モード 0)はリンクアグリケーション(EtherChannel)に対応しているスイッチが必要ですので、スイッチの条件がない balance-tlb (モード 5)に変えてみます。

 "/etc/network/interfaces"を編集し、設定を変更します。このモードの場合、スレーブデバイス(eth0, eth1)のスタンザを有効にしています。そうしないと bond0だけ作成されて eth0, eth1 が無い状態になり、有線(Ethernet)で通信できなくなってしまいましたので。
 "/etc/dhcpcd.conf"「4. "/etc/dhcpcd.conf"の編集」と同じです。

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

# The bonding interface
auto bond0
iface bond0 inet manual
    bond-slaves eth0 eth1
    bond-mode 5
    bond-miimon 100
    bond-downdelay 200
    bond-updelay 200

auto eth0
allow-hotplug eth0
iface eth0 inet manual

auto eth1
allow-hotplug eth1
iface eth1 inet manual

auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

 再起動後、ifconfigや"/sys/class/net/bond0/bonding/mode"等を見て設定変更が反映されていることを確認し、性能を測定してみます。

# iperf -c 192.168.0.xxx
------------------------------------------------------------
Client connecting to Titan, TCP port 5001
TCP window size: 43.8 KByte (default)
------------------------------------------------------------
[  3] local 192.168.0.nnn port 57950 connected with 192.168.0.xxx port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   238 MBytes   200 Mbits/sec

 balance-rr (モード 0) よりは良い性能ですが、Gigabit Ethernet-USBアダプタ 1本と同じか少し遅いという結果になりました。

 次に balance-alb (モード 6) にしてみた(bond-mode を 6に変えただけ)ところ、再起動したらネットワークが全滅になってしまいました(;_;)。起動用MicroSDカードをバックアップから書き戻して復旧させましたが、実験はここまでとしましょう。(これだけいじり倒して色々試せるってのもRaspberry Piの魅力の一つですよね。)

 と言うことで、今回の結論。サーバーとしての可用性や使い勝手を良くする(例えば、有線(eth0)と無線(wlan0)を束ねて同じIPアドレスにし、どちらの経路でも一つの単一のIPアドレスでアクセス可能にする)目的であれば NICをボンディングする意味はありましょうが、通信性能(スループット)の向上が目的なら意味は無いでしょう。(リンクアグリケーション対応の高価なスイッチを複数所有しているなら話は別かもしれませんが・・)


(*1):とは言うものの、自分も良く理解できてないので、この記事も「こうしたら何とかうまくいった」に過ぎないのではありますが・・・

(*2):一般的には、balance-rr (モード 0)は使用せず balance-xor (モード 2)の方を使用するそうです。またサーバー用途では可用性を重視するので、active-backup(モード 1)が一般的だそうです。

(*3):理由は良く分かってません。Debian Wikiの「Configuration - Example 1」に準じただけでして、スレーブデバイス(eth0, eth1)のスタンザを記述しなくても自動的に作成してくれるようです。

(*4):Wi-Fi(wlan0)を管理ネットワーク的に使用して、ボンディングがうまくできなかった場合には、Wi-Fiからログインして復旧させようとの目論みだったのですが、アホでした。Wi-Fiもボンディングデバイスと同じサブネット(セグメント)のIPアドレスが割り当てられるのですから、きちんとルーティング設定しないとダメですね。最悪、Wi-Fi(wlan0)から入ってボンディングデバイスから出るというルーティングになり、出力のボンディングデバイス設定がダメダメだとネットワーク全滅ってことになるでしょうな。また後日に、きちんとルーティング設定してから再チャレンジしてみようか。


< 過去の記事 [ 8月の 全てのカテゴリ リスト ] 新しい記事 >

2016 calendar
8月
123456
78910111213
14151617181920
21222324252627
28293031


掲示板
最新:08/15 17:19


GsBlog was developed by GUSTAV, Copyright(C) 2003, Web Application Factory All Rights Reserved.