1. やりたいこと
Tokyo1 Zone: 10.0.0.0/24
Tokyo2 Zone: 10.1.0.0/24
Tokyo3 Zone: 10.2.0.0/24
という構成であるとする。ここで、
- Server-A(10.0.0.7)
- Server-B(10.1.0.7)
というサーバーにアクセスする際にIPアドレスレベルでfailoverができるように、普段はVIP(192.168.10.10)でアクセスし、もしSever-Aに障害が発生しても別ZoneのServer-BにこのVIPのままアクセスさせたい。
なお、この192.168.10.10はVPCでprefixレベルで定義していないIPアドレスである。
なお、VPC外部からの切り替えについては、こちらを参照してください。
2 設定方法
2-1. Custom Route(Egress)の設定
ドキュメントは、
https://cloud.ibm.com/docs/vpc?topic=vpc-about-custom-routes&locale=en
https://cloud.ibm.com/docs/vpc?topic=vpc-create-vpc-route&locale=en
を参照。
- 初期状態ではEgressタイプのデフォルトのルートテーブルが存在している。このテーブルを編集することにする。
-
192.168.10.10/32
宛のパケットが10.0.0.7
に転送されるように構成する。
- 上記の例では、この経路をtokyo1にしか適用していないため、同様にtokyo2, tokyo3に対しても実施する。最終結果は以下の通り。
(参考)
https://cloud.ibm.com/docs/vpc?topic=vpc-about-custom-routes#limitations-custom-routes
For egress custom routes, when you add a destination route, you must select a zone. However, the next hop doesn't have to be in the same zone. For ingress custom routes, the next hop must be in the same zone.
この状態で、このVPC内の任意のサーバーから192.168.10.10宛のパケットは、
アクセス元サーバー -> Implicit Router -> Server-A(10.0.0.7)
となる。
[root@syasuda-tok1-vpc1 ~]# ping -c 3 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
--- 192.168.10.10 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms
[root@server-a ~]# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
17:29:51.382761 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 14185, seq 1, length 64
17:29:52.382690 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 14185, seq 2, length 64
17:29:53.382696 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 14185, seq 3, length 64
2-2. Server-A/Server-Bに192.168.10.10を付与
今回はipコマンドで暫定的にIPアドレスを付与した。
[root@server-a ~]# ip a list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:04:02:70:58 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.7/24 brd 10.0.0.255 scope global dynamic eth0
valid_lft 291sec preferred_lft 291sec
inet6 fe80::4ff:fe02:7058/64 scope link
valid_lft forever preferred_lft forever
[root@server-a ~]# ip a add 192.168.10.10 dev eth0
[root@server-a ~]# ip a list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:04:02:70:58 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.7/24 brd 10.0.0.255 scope global dynamic eth0
valid_lft 262sec preferred_lft 262sec
inet 192.168.10.10/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::4ff:fe02:7058/64 scope link
valid_lft forever preferred_lft forever
[root@server-b ~]# ip a list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:04:02:71:37 brd ff:ff:ff:ff:ff:ff
inet 10.1.0.7/24 brd 10.1.0.255 scope global dynamic eth0
valid_lft 270sec preferred_lft 270sec
inet6 fe80::4ff:fe02:7137/64 scope link
valid_lft forever preferred_lft forever
[root@server-b ~]# ip a add 192.168.10.10 dev eth0
[root@server-b ~]# ip a list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:04:02:71:37 brd ff:ff:ff:ff:ff:ff
inet 10.1.0.7/24 brd 10.1.0.255 scope global dynamic eth0
valid_lft 251sec preferred_lft 251sec
inet 192.168.10.10/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::4ff:fe02:7137/64 scope link
valid_lft forever preferred_lft forever
2-3. IP spoofingの有効化
Server-AやServer-Bからの戻りのパケットは本来自身が所有していない192.168.10.10がsourceとなるパケットになるため、IP Spoofingを有効化する。
IP Spoofingの有効化方法については、こちらも参照。
2-4. Security Group/Network ACLで通信を許可する。
(省略)
3. テスト
##3-1. Server-A正常時のアクセス
デフォルトの状態では、このVPC内の任意のサーバーから192.168.10.10宛のパケットは、
アクセス元サーバー -> Implicit Router -> Server-A(10.0.0.7)
となる。
#送信元
[root@client ~]# ping -c 3 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=5.23 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.281 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.404 ms
--- 192.168.10.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.281/1.974/5.237/2.307 ms
#Server-A
[root@server-a ~]# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
17:39:53.722252 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 14890, seq 1, length 64
17:39:53.722341 IP 192.168.10.10 > 10.0.0.12: ICMP echo reply, id 14890, seq 1, length 64
17:39:54.723566 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 14890, seq 2, length 64
17:39:54.723593 IP 192.168.10.10 > 10.0.0.12: ICMP echo reply, id 14890, seq 2, length 64
17:39:55.723697 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 14890, seq 3, length 64
17:39:55.723730 IP 192.168.10.10 > 10.0.0.12: ICMP echo reply, id 14890, seq 3, length 64
#Server-B
[root@server-b ~]# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
3-2. Server-A障害時のアクセス(Server-Bへの切り替えテスト)
Server-A障害によって経路をAPIなどを使って以下のように変更することを想定。
自動スクリプトのサンプルはIBM Cloud: VPC Custom Routesの切り替えスクリプト・サンプルを参照。
これにより、このVPC内の任意のサーバーから192.168.10.10宛のパケットは、
アクセス元サーバー -> Implicit Router -> Server-A(10.1.0.7)
となる。
#送信元
[root@client ~]# ping -c 3 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=57 time=1.82 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=57 time=1.64 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=57 time=1.67 ms
--- 192.168.10.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.640/1.713/1.823/0.079 ms
#Server-A
[root@server-a ~]# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
#Server-B
[root@server-b ~]# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
17:47:08.063999 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 15512, seq 1, length 64
17:47:08.064091 IP 192.168.10.10 > 10.0.0.12: ICMP echo reply, id 15512, seq 1, length 64
17:47:09.065852 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 15512, seq 2, length 64
17:47:09.065877 IP 192.168.10.10 > 10.0.0.12: ICMP echo reply, id 15512, seq 2, length 64
17:47:10.067421 IP 10.0.0.12 > 192.168.10.10: ICMP echo request, id 15512, seq 3, length 64
17:47:10.067455 IP 192.168.10.10 > 10.0.0.12: ICMP echo reply, id 15512, seq 3, length 64