CentOS 5.9でNICを2枚挿したときのネットワーク設定

10GbpsNIC環境でOSのネットワークスタックのパフォーマンスを測定しようとしたら意外と面倒だった.厳密には,面倒だったのはCentOS 6系での設定で結局あきらめた. 仕方がないからCentOS 5.9でやるとそれほどハマらずに設定できた.

2台のマシンがあり,オンボードNICと10GbpsNICが載っている.このとき,

  • 10GbpsNIC同士を直接10Gbps Eternetで接続する.
  • オンボードNICはゲートウェイを通してインターネットに接続できるようにする.

というのが課題.

これに対して以下の図のようなネットワーク構成にしたらちゃんと通信できた.

f:id:y_uuki:20130422021415p:plain

設定

大雑把な設定内容を以下のような感じ.

  • オンボードNIC周りと10GbpsNIC周りを異なるサブネットに置く.
  • インターネットに接続するために192.168.1.1をデフォルトゲートウェイとする.
  • 10.0.0.1を10.0.0.0/8サブネットをゲートウェイとする.
  • eth1に入ってきたパケットはeth1に出て行くようにルーティングする.

まず,eth0やeth1に対するIPアドレスなどの設定を/etc/sysconfig/network-scripts/ifcfg-eth*に書く.

以下,Host1のみだけどHost2においてもIPADDRとHWADDR以外は同様.

  • /sbin/sysconfig/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
BROADCAST=192.168.1.255
HWADDR=xx:xx:xx:xx:xx:xx
IPADDR=192.168.1.10
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes
  • /sbin/sysconfig/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
BROADCAST=10.255.255.255
HWADDR=yy:yy:yy:yy:yy:yy
IPADDR=10.0.0.100
NETMASK=255.0.0.0
NETWORK=10.0.0.0
ONBOOT=yes
GATEWAY=10.0.0.1

設定を有効にするためにnetworkを再起動.

# service network restart

しかし,ここでeth0経由でインターネットにつなげないという問題が発生した. routeコマンドでみるとデフォルトゲートウェイの設定がおかしかった(どうおかしかったかはメモってなくて忘れた)ので,/sbin/sysconfig/networkのGATEWAYDEVにデフォルトゲートウェイに対してパケットを送受信したいインタフェース名を書く.

GATEWAYDEV=eth0

networkを再起動すると,ipコマンドの出力は以下のようになり,eth0経由でインターネットに接続できた. これをHost1,Host2の両方で設定する.

host1% /sbin/ip -v
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.0.0     *               255.255.252.0   U     0      0        0 eth0
169.254.0.0     *               255.255.0.0     U     0      0        0 eth1
10.0.0.0        *               255.0.0.0       U     0      0        0 eth1
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0

次は,eth1側の方で,NICが複数あるとパケットを受信したときにそのパケットに対してどのインタフェースから送信するかをルーティングする必要がある.

今回の場合,eth1で受信したパケットはそのままeth1で返せば良い. 受信パケットに対するルーティングはiproute2で行う.

古来のrouteコマンドですと、宛先に応じてNICのデバイスやnext hop routerの指定を行いますが、Linuxではこのテーブルを複数持つことができ、さまざまな条件でどのテーブルを参照させるかを指定することができます。

「さまざまな条件」とは、例えば

  • 送信元IPアドレス
  • パケットが入ってきたデバイス名
  • fwmark といったものです。

同じサブネットへのNIC 2枚指し、またはソースルーティングのおはなし - (ひ)メモ

Host1を例にとり,まず10GbpsNIC通信用のテーブルexpを作成する.(新規に作成しなくても既存のmainテーブルにルールを追加すればよいだけな気がする) このテーブルはパケットの送信時に参照され,送信元IPアドレスが10.0.0.100であれば,eth1にパケットを送るという意味である.

  • /sbin/sysconfig/network-scripts/route-eth2
dev eth1 src 10.0.0.100 table exp

次に,上記テーブルを参照する条件をrule-eth2に書く. 参照条件として送信元IPアドレスが10.0.0.100であればexpテーブルを見るというように設定する.

  • /sbin/sysconfig/network-scripts/rule-eth2
from 10.0.0.100 table exp prio 200 

networkを再起動して設定を有効にするとpingは通るようになった.

host1% service network restart
host1% ping -I eth1 10.0.0.200

しかし,TCP/UDPのベンチマークツールであるiperfで通信すると,

host1% iperf -s -B 10.0.0.100
host2% iperf -c 10.0.0.100

No route to hostと怒られる.

tcpdumpでみてみると到達不能ICMPパケットが返ってきてるっぽい.

16:46:08.071054 IP 10.0.0.200.51674 > 10.0.0.100.ndmp: S 2955619377:2955619377(0) win 5840 <mss 1460,sackOK,timestamp 23138650 0,nop,wscale 7>
16:43:56.564510 IP 10.0.0.100 > 10.0.0.200: ICMP host 10.0.0.100 unreachable - admin prohibited, length 68

hidekiy blog: [linux] ping は通るのに No route to host と言われる

この辺はSELinuxとiptablesが邪魔をしている可能性があるので,あんまりよくないけどSELinuxとiptablesを切る.

SELinuxを切る.

# sestatus
# setenforce 0

SELinuxを無効化する | Smart -Web Magazine

iptablesを切る

# service iptables off

ここまでやって,10GbpsNIC間で問題なく通信できるようになった.

参考

途中要らない設定が入ってそう. ネットワーク難しい.