これまでENIを複数アタッチした場合のルーティングがよくわからず、複数のIPが必要な場合は、
ENIにSecondary IPを付与してCentOS(6)で利用」の記事にあるようにENIを複数アタッチするのではなく、
同じENIのSecondary IPなどを利用するようにしていました。

しかし、理解が浅い状態のままでは良くないと思っていたところに@j3tm0t0さんが、下記の素晴らしいブログ記事を
書いてくれました。

もう一度ENIについて考えてみた(Linux編)

このブログ記事を読むことで、複数ENIのルーティングの問題、それを解決するためのPolicy Based Routingが
わかると思います。

上記のブログ記事では、各ENIが別々のサブネットに接続されていましたが、今回、1つのサブネットに2つのENI、
そして各ENIに2つのIP(EIPも)を付与し、下記のように4つすべてのEIPに対して、通信できるようにしてみます。

実際のENIやIPの設定は下記のようになります。
(セキュリティグループの設定も忘れないようにします)

CentOS6上のネットワーク設定は下記の通りです。

# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=on

# cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
DEVICE=eth0:0
ONBOOT=yes
BOOTPROTO=static
NETADDR=10.0.0.0
NETMASK=255.255.255.0
IPADDR=10.0.0.22

# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=dhcp
ONBOOT=on
DEFROUTE=no

# cat /etc/sysconfig/network-scripts/ifcfg-eth1:0
DEVICE=eth1:0
ONBOOT=yes
BOOTPROTO=static
NETADDR=10.0.0.0
NETMASK=255.255.255.0
IPADDR=10.0.0.24

この状態で、上記4つのEIPへPingしてみると下記のような結果になりました。

$ ping 54.aaa.aaa.aaa
PING 54.aaa.aaa.aaa (54.aaa.aaa.aaa): 56 data bytes
64 bytes from 54.249.41.77: icmp_seq=0 ttl=53 time=22.453 ms

$ ping 54.bbb.bbb.bbb
PING 54.bbb.bbb.bbb (54.bbb.bbb.bbb): 56 data bytes
64 bytes from 54.249.41.71: icmp_seq=0 ttl=52 time=5.440 ms

$ ping 54.ccc.ccc.ccc
PING 54.ccc.ccc.ccc (54.ccc.ccc.ccc): 56 data bytes
Request timeout for icmp_seq 0

$ ping 54.ddd.ddd.ddd
PING 54.ddd.ddd.ddd (54.ddd.ddd.ddd): 56 data bytes
Request timeout for icmp_seq 0

eth1の設定にDEFROUTE=noを入れているため、デフォルトルートがeth0のままで、eth1への通信が返れず、
eth1に付けた2つのEIPへのPingも返っていない状態です。
(尚、ルーティングは下記のようになっています)

# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0

ここでPolicy Based Routingです。
現状のルールは、以下になります。

# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default

下記のように設定します。

# ip rule add from 10.0.0.21 table 1021 prio 1021
# ip route add table 1021 default via 10.0.0.1 dev eth0

# ip rule add from 10.0.0.22 table 1022 prio 1022
# ip route add table 1022 default via 10.0.0.1 dev eth0

# ip rule add from 10.0.0.23 table 1023 prio 1023
# ip route add table 1023 default via 10.0.0.1 dev eth1

# ip rule add from 10.0.0.24 table 1024 prio 1024
# ip route add table 1024 default via 10.0.0.1 dev eth1

上記は、例えば10.0.0.24からの通信はeth1を使ってデフォルトルートが10.0.0.1に行くようにしています、
それが、他の10.0.0.21,10.0.0.22,10.0.0.23に対しても同様に行っています。

そうすると、ルールは下記のようになります。

# ip rule show
0: from all lookup local
1021: from 10.0.0.21 lookup 1021
1022: from 10.0.0.22 lookup 1022
1023: from 10.0.0.23 lookup 1023
1024: from 10.0.0.24 lookup 1024
32766: from all lookup main
32767: from all lookup default

この状態で実際に最初と同じようにPingしてみると、下記のように、今度はすべてのEIPに対して通信することが
できました。

$ ping 54.aaa.aaa.aaa
PING 54.aaa.aaa.aaa (54.aaa.aaa.aaa): 56 data bytes
64 bytes from 54.aaa.aaa.aaa: icmp_seq=0 ttl=53 time=5.869 ms

$ ping 54.bbb.bbb.bbb
PING 54.bbb.bbb.bbb (54.bbb.bbb.bbb): 56 data bytes
64 bytes from 54.bbb.bbb.bbb: icmp_seq=0 ttl=52 time=5.997 ms

$ ping 54.ccc.ccc.ccc
PING 54.ccc.ccc.ccc (54.ccc.ccc.ccc): 56 data bytes
64 bytes from 54.249.45.44: icmp_seq=0 ttl=53 time=5.857 ms

$ ping 54.ddd.ddd.ddd
PING 54.ddd.ddd.ddd (54.ddd.ddd.ddd): 56 data bytes
64 bytes from 54.ddd.ddd.ddd: icmp_seq=0 ttl=52 time=5.799 ms

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら