2016年5月14日土曜日

Linuxのネットワークチーミング(Bonding)の設定

物理サーバを構築する際は、NICをチーミングし冗長構成を取ることが鉄板となっている。今までWindowsであればチーミングの設定を実施したことはあったが、Linuxでは実施したことがなかった。

LinuxにおいてはOS標準でBondingと呼ばれるチーミング機能が備わっているので、勉強のために設定してみた。

事前確認

まずは、何もしていない状態でNICのステータスを確認する。eth0とeth1が存在し、eth0だけにIPアドレスが設定されている状況となっている。この状態から、eth0とeth1のBonding設定を行う。

# ifconfig -a
---------------------------
eth0      Link encap:Ethernet  HWaddr 00:0C:29:A9:38:65
          inet addr:192.168.11.111  Bcast:192.168.11.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:496551 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12338 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:33709638 (32.1 MiB)  TX bytes:3731810 (3.5 MiB)

eth1      Link encap:Ethernet  HWaddr 00:0C:29:A9:38:6F
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
---------------------------

Bonding設定

以下の手順で設定する。

①カーネルパラメータの設定

Bondingを有効化するためのカーネルパラメータの設定ファイルを新規作成する。

/etc/modprobe.d/bonding.conf
---------------------------
alias bond0 bonding
---------------------------

②bond0のインターフェースの設定

チーミングした場合、実際のNICにはIPアドレスは設定せず、bond0のデバイスに設定することになる。チーミングに関する各種設定についても、このファイルの「BONDING_OPTS」という項目にてスペース区切りで記載する。

チーミングのオプションは以下を参照すること。

・25.7.2. チャンネルボンディングの使用
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html

今回は以下の設定を行った。

---------------------------
 mode=1                    ←切り替わりモードの設定(1はactive-backup)
 miimon=100               ←NICの監視感覚(単位:ms)
 primary=eth0             ←Bondingデバイス起動時の優先NIC
 primary_reselect=0      ←優先NIC復旧時に自動で戻るようにするか(0は自動で優先NICに戻る)
---------------------------

/etc/sysconfig/network-scripts/ifcfg-bond0
---------------------------
DEVICE=bond0
IPADDR=192.168.11.111
NETMASK=255.255.255.0
GATEWAY=192.168.11.31
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS="mode=1 miimon=100 primary=eth0 primary_reselect=0"
---------------------------

③bond0に複数IPアドレスを設定

Bondingであっても、1つのデバイスに複数IPの設定が可能なので、2つめのIPアドレス設定のデバイスファイルを作成する。こちらには、チーミングのオプション設定は不要。

/etc/sysconfig/network-scripts/ifcfg-bond0:1
---------------------------
DEVICE=bond0:1
IPADDR=192.168.11.112
NETMASK=255.255.255.0
ONBOOT=yes
BOOTPROTO=none
---------------------------

④eth0の設定

eth0は現状使用中のNICなので、バックアップを取得してから作り直すと良い。なお、Linuxのnetworkサービスは、本ディレクトリ内のファイルでifcfg-*で始まるものを読み込む仕様の模様。バックアップファイルを同じディレクトリに作る場合は、不要な設定ファイルの読み込みが発生しないよう、ファイル名には注意する。具体的には、バックアップの保存ディレクトリを別にするか、.bakを付ければ読み込まない仕様なのでそのように対処しても良い。

<良いバックアップファイル名>
 20160514_ifcfg-eth0
 ifcfg-eth0_20160514.bak

<悪いバックアップファイル名>
 ifcfg-eth0_20160514

設定は以下のとおり。IPアドレスやゲートウェイの設定を削除し、MASTER、SLAVEといった値を設定する。

/etc/sysconfig/network-scripts/ifcfg-eth0
---------------------------
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
MASTER=bond0
SLAVE=yes
NM_CONTROLLED=no
BOOTPROTO=none
HWADDR=00:0C:29:A9:38:65
---------------------------

⑤eth1の設定

eth1もeth0と同様に設定する。eth0のifcfg-eth0の設定をコピーしてDEVICEとHWADDRを変更するだけで作れる。

/etc/sysconfig/network-scripts/ifcfg-eth1
---------------------------
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
MASTER=bond0
SLAVE=yes
NM_CONTROLLED=no
BOOTPROTO=none
HWADDR=00:0C:29:A9:38:6F
---------------------------

Bonding有効化

networkサービスをリスタートし、設定ファイルの読み込みを行う。なお、ifcfg-eth0を変更してしまっているので、初回だけエラーが出力される。
※「Determining if ip address ~」のメッセージについては後述

# service network restart
---------------------------
インターフェース eth0 を終了中:  /etc/sysconfig/network-scripts/ifdown-eth: line 121: /sys/class/net/bond0/bonding/slaves: そのようなファイルやディレクトリはあ りません
                                                           [  OK  ]
ループバックインターフェースを終了中                       [  OK  ]
ループバックインターフェイスを呼び込み中                   [  OK  ]
インターフェース bond0 を活性化中:  Determining if ip address 192.168.11.111 is already in use for device bond0...
Determining if ip address 192.168.11.112 is already in use for device bond0...
                                                           [  OK  ]
---------------------------

2回目のリスタートは問題なし。

# service network restart
---------------------------
インターフェース bond0 を終了中:  [  OK  ]
ループバックインターフェースを終了中  [  OK  ]
ループバックインターフェイスを呼び込み中 [  OK  ]
インターフェース bond0 を活性化中:  Determining if ip address 192.168.11.111 is already in use for device bond0...
Determining if ip address 192.168.11.112 is already in use for device bond0...
[  OK  ]
---------------------------

最終的に以下の通りインターフェースが設定された。bond0、bond0:1にIPアドレスが設定されており、eth0とeth1はSLAVEとして起動していることがわかる。

# ifconfig -a
---------------------------
bond0     Link encap:Ethernet  HWaddr 00:0C:29:A9:38:65
          inet addr:192.168.11.111  Bcast:192.168.11.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:2574 errors:0 dropped:0 overruns:0 frame:0
          TX packets:648 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:401668 (392.2 KiB)  TX bytes:182251 (177.9 KiB)

bond0:1   Link encap:Ethernet  HWaddr 00:0C:29:A9:38:65
          inet addr:192.168.11.112  Bcast:192.168.11.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1

eth0      Link encap:Ethernet  HWaddr 00:0C:29:A9:38:65
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:44 errors:0 dropped:0 overruns:0 frame:0
          TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3720 (3.6 KiB)  TX bytes:3832 (3.7 KiB)

eth1      Link encap:Ethernet  HWaddr 00:0C:29:A9:38:65
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:54 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4320 (4.2 KiB)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
---------------------------

Bondingの詳細なステータスは以下ファイルを確認すればわかる。

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

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: eth0 (primary_reselect always)
Currently Active Slave: eth0   ←★eth0がActive
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:a9:38:65
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:a9:38:6f
Slave queue ID: 0
---------------------------

切り替えテスト

eth0を切断してみると以下のとおりになる。1秒毎にpingを打っていたが欠けは無し。

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

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: eth0 (primary_reselect always)
Currently Active Slave: eth1   ←★eth1に切り替わる
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: down   ←★downになる
Speed: Unknown
Duplex: Unknown
Link Failure Count: 1   ←★+1される
Permanent HW addr: 00:0c:29:a9:38:65
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:a9:38:6f
Slave queue ID: 0
---------------------------

eth0を接続し直すと、「primary_reselect always」の設定が入っているので自動で切り戻る。こちらもping欠けは無し。

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

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: eth0 (primary_reselect always)
Currently Active Slave: eth0   ←★eth0に切り替わる
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 1
Permanent HW addr: 00:0c:29:a9:38:65
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:a9:38:6f
Slave queue ID: 0
---------------------------

「Determining if ip address ~」のメッセージについて

Bondingの話とは直接関係ない話となるが、networkサービスリスタート時に出力される「Determining if ip address ~」のメッセージについて説明しておく。これはエラーメッセージではなく、割り当てようとしているIPアドレスが他機器で利用されていないかチェックする機能による出力メッセージとなる。

例えばあえて重複するIPアドレスを設定してみると、以下のとおり「Error, some other host already uses address ~」と表示され、対象のインターフェースは活性化されない。

# service network restart
---------------------------
インターフェース bond0 を終了中:                           [  OK  ]
ループバックインターフェースを終了中                       [  OK  ]
ループバックインターフェイスを呼び込み中                   [  OK  ]
インターフェース bond0 を活性化中:  Determining if ip address 192.168.11.111 is already in use for device bond0...
Determining if ip address 192.168.11.110 is already in use for device bond0...
Error, some other host already uses address 192.168.11.110.
                                                           [  OK  ]
---------------------------

この機能を止めたい場合は前段で設定したifcfg-*のファイルに「ARPCHECK=no」のオプションを追加すればよいらしい。ただし、有効にしておくことの影響はないと思うので、万が一IPアドレスが重複してしまうような場合を想定して有効のままにすることをお勧めする。