keepalivedを使って、プライマリDNSサーバー停止時のタイムアウト待ちを軽減する
【やりたい事】
DNS解決時に、プライマリーDNS/セカンダリーDNSの順番で名前解決を行う。
プライマリーDNSのbindが落ちると、プライマリーDNSで解決が出来ない(=タイムアウト待ち)後にセカンダリーDNSで解決
つまり、タイムアウト待ちでブラウジングレスポンス低下。
ちなみに、プロセス停止状態でもOS停止状態でも、53/UDPなのでタイムアウトが発生。
つまりは、プライマリーDNSのIPでDNS解決させないといけないので、クラスター構成にしてみる。
pacemakerのインストール/設定に比べ、keepalivedのほうが単純明快で分かりやすいと思う。
pacemakerは3つのコンポーネントの組み合わせなので、取っつきにくい印象
一方、keepalivedは単独で動作し、設定ファイルも1つ。
単純な動作で良ければ、keepalivedのほうが簡単かもしれない
構築
HW
プライマリ: RaspberryPI 3B (RaspberryPi OS-Lite 5.15.61-v7+ armv7l dns-ka01) 192.168.100.1
セカンダリ: Intel PC/AT互換機 (Debian11 5.10.0-21-686-pae 5.10.162-1 i686 dns-ka02) 192.168.100.2
構築手順
(1) keepalivedインストール
[dns-ka01] # apt-get install keepalived
[dns-ka02] # apt-get install keepalived
(2) keepalived の設定
DNSで使用する仮想IPアドレスを、192.168.100.11, 192.168.100.12 とする
相互のの死活監視は、2つ設定
- プロトコル VRRP にて確認 (keepalivedの機能)
- オリジナルスクリプトにてサービス起動状態を確認
(1) 相互監視用のオリジナルスクリプトを作成
keepalivedには、スクリプトを実行して、スクリプトのEXITコードで死活状態をkeepalivedに渡す機能がある。
よって、オリジナルスクリプトを作成して、
サービス正常 ⇒ Exit 0
サービス異常 ⇒ Exit 1
となるスクリプトを作成する
/etc/keepalived/check-dnslookup.sh
#!/bin/bash timeout 5 /usr/bin/host -t a localhost 127.0.0.1 status=$? if [ $status -eq 0 ]; then exit 0 elif [ $status -eq 1 ]; then exit 1 else echo "$0 Something is wrong." exit 1 fi
(2) オリジナルスクリプト実行ユーザーの作成
オリジナルスクリプトを実行するように設定する場合、実行ユーザーを事前に作成しておく。
※ 専用ユーザーを作成せずとも、動作はするが、ログに以下のようなワーニングメッセージを吐く。
Keepalived_vrrp[xxxx]: WARNING - default user 'keepalived_script' for script execution does not exist - please create. Keepalived_vrrp[xxxx]: SECURITY VIOLATION - scripts are being executed but script_security not enabled.
[dns-ka01] # useradd keepalived_script
[dns-ka02] # useradd keepalived_script
(3) keepalived.confの設定
= dns-ka01 (192.168.100.1) =
global_defs { vrrp_garp_master_refresh 60 enable_script_security script_user keepalived_script } vrrp_script chk_bind_process { script "/etc/keepalived/check-dnslookup.sh" interval 5 fall 2 rise 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass PASS } unicast_peer { 192.168.100.2 } track_script { chk_bind_process } virtual_ipaddress { 192.168.100.11 } } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass PASS } unicast_peer { 192.168.100.2 } track_script { chk_bind_process } virtual_ipaddress { 192.168.100.12 } }
= dns-ka02 (192.168.100.2) =
global_defs { vrrp_garp_master_refresh 60 enable_script_security script_user keepalived_script } vrrp_script chk_bind_process { script "/etc/keepalived/check-dnslookup.sh" interval 5 fall 2 rise 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass PASS } unicast_peer { 192.168.100.1 } track_script { chk_bind_process } virtual_ipaddress { 192.168.100.11 } } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 priority 150 advert_int 1 authentication { auth_type PASS auth_pass PASS } unicast_peer { 192.168.100.1 } track_script { chk_bind_process } virtual_ipaddress { 192.168.100.12 } }
2台分の設定ファイル。まったく同じに見えますが、以下の項目が異なります。
・ priority の行。 数字に着目 (数字が大きいほうが優先)
・ unicast_peerの部分のIPアドレス (相手のIPアドレスを指定)
動作
1. どちらかのサーバーのOSが停止やbindプロセスが停止すると、VIPが片寄せされます。
[稼働中] dns-ka01: PriIP 192.168.100.1 SecIP: 192.168.100.11 dns-ka02: PriIP 192.168.100.2 SecIP: 192.168.100.12 [dns-ka01のOS停止] dns-ka01: OS停止中 dns-ka02: PriIP 192.168.100.2 SecIP: 192.168.100.12, 192.168.100.11
2. 復旧すると、フェールバックされます。
クライアント設定
各クライアントの/etc/resolv.confを以下の通りに設定します。
nameserver 192.168.100.11 nameserver 192.168.100.12
フェイルオーバー テスト
- dns-ka01のLAN線を抜く
- namedをstopする
仮想IPアドレスは、期待通り片寄されます。
動作原理は未確認だが、ログから察するに、
(検証機 dns-ka02のログ) *** LAN線を抜いた *** kernel: [ 683.176250] pcnet32 0000:02:01.0 ens33: link down Keepalived_vrrp[1159]: Netlink reports ens33 down Keepalived_vrrp[1159]: (VI_1) Entering FAULT STATE Keepalived_vrrp[1159]: (VI_2) Entering FAULT STATE Keepalived_vrrp[1159]: (VI_2) sent 0 priority *** LAN線を挿した *** Keepalived_vrrp[1159]: Netlink reports ens33 up kernel: [ 719.176070] pcnet32 0000:02:01.0 ens33: link up Keepalived_vrrp[1159]: (VI_1) Entering BACKUP STATE Keepalived_vrrp[1159]: (VI_2) Entering BACKUP STATE Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) Entering MASTER STATE *** namedを停止 *** Keepalived_vrrp[1159]: Track script chk_bind_process is already running, expect idle - skipping run Keepalived_vrrp[1159]: VRRP_Script(chk_bind_process) timed_out Keepalived_vrrp[1159]: (VI_1) Entering FAULT STATE Keepalived_vrrp[1159]: (VI_2) Entering FAULT STATE Keepalived_vrrp[1159]: (VI_2) sent 0 priority *** namedを起動 *** Keepalived_vrrp[1159]: VRRP_Script(chk_bind_process) succeeded Keepalived_vrrp[1159]: (VI_1) Entering BACKUP STATE Keepalived_vrrp[1159]: (VI_2) Entering BACKUP STATE Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) received lower priority (100) advert from 192.168.100.1 - discarding Keepalived_vrrp[1159]: (VI_2) Entering MASTER STATE
注意点
管理プログラムがいないので、起動/停止する際は順番にに注意が必要かもしれない。
→ メンテナンスの為、仮想IPを落さないという動作が出来ない。
→ MASTERから落とすと、当然のごとくBACKUP側がMASTERになる。
MASTER側のkeepalived再起動の際は、仮想IPがBACKUP側に移り、すぐに戻ってくる事象が発生する事に注意。
man keepalived.confを見ると様々な設定項目がある。
複雑な動作をさせたい場合は、manを見て欲しい。
(googleると基本動作部分は多くHitするけど・・)