SEIL/x86 FujiとkeepalivedでVRRP
Posted on 2021/02/05(Fri) 19:45 in technical
SEIL/x86 FujiとkeepalivedでVRRP
先日書いた 味見日報 - MAP-E は仕様変更があった場合に急に繋がらなくなる可能性もありそうなので、既存ルーターであるSEIL/x86 FujiとVRRPを組んで、MAP-Eゲートウェイが使用できない場合にPPPoE回線側にフォールバックするようにします。
味見日報 - MAP-E (2)
とも言う。
環境
SEIL/x86 Fuji
# show system version
SEIL/x86 Fuji Ver. 7.02 (Release)
MAP-Eゲートウェイ
$ uname -a
Linux ipoe-gw 5.4.0-65-generic #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ dpkg -l keepalived | grep keepalived
ii keepalived 1:2.0.19-2 amd64 Failover and monitoring daemon for LVS clusters
IPアドレスは以下のようにします。
- 192.168.1.1: 既存ルーターのVIP
- 192.168.1.2: 既存ルーター#1の実IP(SEIL側。PPPoEへのフォールバック用)
- 192.168.1.4: MAP-EゲートウェイのVIP
- 192.168.1.5: MAP-Eゲートウェイの実IP(MAP-Eゲートウェイ側)
設定
VRRPは以下の設定を行います。
- Priority
- MAP-Eゲートウェイ: 245
- 既存ルーター(SEIL): 240
- Preempt: On
- MAP-Eが使えるときは常にMAP-Eを優先します
- vrid: 4
- VIPの末尾から採用
SEIL/x86 Fuji vrrp configuration
1行だけ。
vrrp lan1 add vrid 4 address 192.168.1.4/24 priority 240
Note
SEIL/x86 Fujiはauthenticationをサポートしていない(RFC3768まで)ので、認証コードもありません。RFC5798があれば...
keepalived configuration
keepalivedでは、VRRPの設定以外に以下の設定も盛り込みます。
- MAP-Eトンネル経由の通信で、想定したグローバルIPv4アドレスを使っているかチェックする
Install keepalived
まずはkeepalivedを入れます。
$ sudo apt install -y keepalived
Create MAP-E tunnel check script
MAP-Eのトンネルが機能しているかチェックするスクリプトを書きます。
#!/bin/bash
[[ "$(curl -s https://api.ipify.org)" == "192.0.2.1" ]]
Note
192.0.2.1
は文書用アドレスなので、実際は自身の環境におけるMAP-EのグローバルIPv4アドレスを入れます。https://api.ipify.org
は重くて応答が遅い場合があるのでhttps://inet-ip.info/ip
やhttps://checkip.amazonaws.com
など、自分の環境から安定して応答が得られそうなサービスを使います。僕は最近https://inet-ip.info/ip
に変えました。
実行権限を与えておきます。成功時にexit code 0を返すようになっていればOKです。
この場合、アドレスが一致しないと1が返ります。
$ sudo chmod +x /etc/keepalived/check_mape.sh
$ sudo /etc/keepalived/check_mape.sh
$ echo $?
0
Create keepalived.conf
/etc/keepalived/keepalived.conf を書きます。先ほど書いたスクリプトを vrrp_script
の script
に指定します。
vrrp_script check_mape {
script "/etc/keepalived/check_mape.sh"
interval 10 # Run script every i seconds
fall 3 # If script returns non-zero f times in succession, enter FAULT state
rise 2 # If script returns zero r times in succession, exit FAULT state
timeout 5 # Wait up to t seconds for script before assuming non-zero exit code
}
vrrp_instance mape {
state MASTER
interface eth0
garp_master_delay 5
virtual_router_id 4
priority 245
preempt
advert_int 1
virtual_ipaddress {
192.168.1.4
}
track_script {
check_mape
}
}
Note
interval
/ fall
/ rise
/ timeout
の値は適当ですので、環境に合わせて設定してください。
Start keepalived
後は起動して完了です。
$ sudo systemctl enable keepalived
$ sudo systemctl start keepalived
状態確認
SEIL/x86 Fuji vrrp status
# show status vrrp
interface: lan1
vrid: 4
priority: 240
state: backup
address #0: 192.168.1.4/24
interval: 1 sec
preempt: on
keepalived status
keepalivedのログから最終ステートがMASTERなのを確認します。
$ journalctl -u keepalived | grep Entering | tail -1
Feb 05 04:55:23 ipoe-gw Keepalived_vrrp[22253]: (mape) Entering MASTER STATE
keepalivedは/32のアドレスを付与するので、指定したアドレスを持っていればOKです。
$ ip -4 address show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 192.168.1.5/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.1.4/32 scope global eth0
valid_lft forever preferred_lft forever
その他
いつ切り替わったか気になる時は Qiita - keepalivedの通知をSlackへ流す 設定を追加しておくと良いと思います。
内部NWでメールを飛ばす場合は特に気にならないのですが、Slack通知を使う場合はMAP-Eの接続が途絶えた場合に通知経路をどうするか考える必要がありそうです。
雑な考えだと hooks.slack.com
は1つのAレコードしか持っていない気がするので、FAULTした場合は以下のようにSlack向けの経路を一時的に設定することで通知の欠損を回避できると思います。
if [[ "$STATE" == "FAULT" ]]; then
SLACK_IP=$(dig +short hooks.slack.com A)
ip route add ${SLACK_IP}/32 via 192.168.1.1
curl ...
ip route del ${SLACK_IP}/32 via 192.168.1.1
fi
トンネル疎通確認用の経路だけ常にトンネルに向けておいて、keepalivedのnotify契機でデフォルトルートを設定する方が妥当でしょうか。
この辺りは考えだすと止まらないので一旦棚上げにしてしまいます。
終わり
RFC準拠だからSEILともVRRPするのは問題ないと思っていたので、フォールバックの仕組みとしては問題なく動きそう。
障害発生時やMAP-Eの仕様変更があった時に上手く気付けると良いなぁ。