#モチベーション
OCHaCafe Premium#1:Oracle Cloudで考える高可用性アーキテクチャで、セカンダリIPをフェールオーバのデモを見て、やってみたくなった
結果
IPフェールオーバできた!
当初、複数VNICとセカンダリIPをごっちゃにしていたのと、セカンダリIPを作成するoci cliコマンドがなかなかみつからなかったので少々時間かかった。
試したこと
インスタンスを2つ作ってセカンダリIPを設定。oci cliを使って、セカンダリIPをフェールオーバする
1. 同じサブネットに属するComputeインスタンスを2つ作る
2.ociユーザのホームディレクトリにoci cliコマンドをインストール
3.動的グループの作成
instance#1とinstance#2が所属する動的グループを作成する
以下のルールを設定して試した
Any{instance.id='ocid1.instance.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxx',instance.id='ocid1.instance.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxx'}
4.ポリシーの作成
特定コンパートメント内でprivate-ipのmanageと、インスタンス・VCNへのuse権限を付与する
動的グループに対して、以下のポリシーを設定して試した
allow dynamic-group <動的グループ名> to manage private-ip in compartment <コンパートメント名>
allow dynamic-group <動的グループ名> to use virtual-network-family in compartment <コンパートメント名>
allow dynamic-group <動的グループ名> to use instance-family in compartment <コンパートメント名>
5.private-ipを設定するスクリプトを作成
両方のノードに、以下のスクリプトを作成して試した。
private-ipを作成/移動しただけでは、OSレベルでIPが設定されないため、別途ipコマンドで設定してあげる必要がある
#!/bin/bash
HOST1=instance1 # instance#1のホスト名
HOST2=instance2 # instnace#2のホスト名
VIP_ADDR=172.16.2.10 # セカンダリIP
VIP_NETMASK=24 # セカンダリIPのネットマスク
DEVNAME=ens3:0 # セカンダリIPのインタフェース名
case $(hostname -s) in
"${HOST1}")
# instance#1のVNIC OCID
VNIC_OCID=ocid1.vnic.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxx
;;
"${HOST2}")
# instance#2のVNIC OCID
VNIC_OCID=ocid1.vnic.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxx
;;
esac
oci --auth instance_principal network vnic assign-private-ip \
--vnic-id ${VNIC_OCID}\
--ip-address ${VIP_ADDR}\
--unassign-if-already-assigned
if [[ ${?} -ne 0 ]]; then
echo "oci cli command Error"
exit 1
fi
sudo ip addr add ${VIP_ADDR}/${VIP_NETMASK} dev ${DEVNAME} label ${DEVNAME}
if [[ ${?} -ne 0 ]]; then
echo "ip command Error"
exit 1
fi
exit 0
6.別のホストから付与したprivate ipあてにsshしてホスト名を取得する
※SSHのパススルー認証を設定済み
※hostキーが入れ替わって、ssh接続時にWARNINGがでるため、StrictHostKeyCheckingをnoにし、標準エラーをnullにすててる
$ VIP=172.16.2.10 # セカンダリIPを指定
$ while true
do
echo -n "$(date '+%Y/%m/%d %H:%M:%S') : "
ssh -o StrictHostKeyChecking=no -o UpdateHostKeys=yes ${VIP} hostname -s 2>/dev/null
sleep 1
done
7.作成したスクリプトを実行して、プライベートIPを移動させる。
2019/12/04 01:51:36 : instance1
2019/12/04 01:51:37 : instance1
2019/12/04 01:51:38 : instance1
2019/12/04 01:51:40 : instance1
★ ここで切り替わる
2019/12/04 01:51:41 : instance2
2019/12/04 01:51:43 : instance2
2019/12/04 01:51:44 : instance2
スクリプトを実行すると、private ipはF/Oするが、OSレベルでF/O元にIP設定は残っている。それでも問題なく通信できるのは、仮想ネットワークの制御側でPrivate IPとMACアドレスの対応を切り替えてくれてるからかな。。
→ arpキャッシュとtcpdumpを取ってると、arpキャッシュエントリは変わらず。echo requestの宛先MACとecho replyの送信元MACが異なっているパターンが見られるので、仮想ネットワーク制御側でMACフレームを書き換えているのかもしれない
tcpdump
09:00:39.473785 02:00:17:00:75:07 > 02:00:17:00:5e:18, ethertype IPv4 (0x0800), length 98: 172.16.1.2 > 172.16.1.20: ICMP echo request, id 29651, seq 1016, length 64
09:00:39.474351 02:00:17:00:49:b2 > 02:00:17:00:75:07, ethertype IPv4 (0x0800), length 98: 172.16.1.20 > 172.16.1.2: ICMP echo reply, id 29651, seq 1016, length 64
★ F/O
09:00:40.497816 02:00:17:00:75:07 > 02:00:17:00:5e:18, ethertype IPv4 (0x0800), length 98: 172.16.1.2 > 172.16.1.20: ICMP echo request, id 29651, seq 1017, length 64
→ echo requestの宛先MACは02:00:17:00:5e:18 (F/O元)
09:00:40.498566 02:00:17:00:49:b2 > 02:00:17:00:75:07, ethertype IPv4 (0x0800), length 98: 172.16.1.20 > 172.16.1.2: ICMP echo reply, id 29651, seq 1017, length 64
→ echo replyの送信元MACは02:00:17:00:49:b2 (F/O先)
09:00:41.521801 02:00:17:00:75:07 > 02:00:17:00:5e:18, ethertype IPv4 (0x0800), length 98: 172.16.1.2 > 172.16.1.20: ICMP echo request, id 29651, seq 1018, length 64
09:00:41.522357 02:00:17:00:49:b2 > 02:00:17:00:75:07, ethertype IPv4 (0x0800), length 98: 172.16.1.20 > 172.16.1.2: ICMP echo reply, id 29651, seq 1018, length 64