Create: 2014/10/10
LastUpdate: 2014/10/11
LVS を Keepalived の VRRP方式で冗長化してみます。
Keepalived を VRRP方式で冗長化する方法については以下のサイトが参考になります。
- 「Linux Virtual Server」と「Keepalived」で作る冗長化ロードバランサ
- CentOS 6.5 で LVS (IPVS) を keepalived で冗長化してみる
- keepalivedを利用する際に気をつけておくこと
- keepalivedの運用ノウハウお見せします ~ 設定ファイルを同期する
シナリオ
ここでは、次の機能をもったLVSサーバを構築して冗長化してみます。
- web01、web02 にヘルスチェックを行いHTTPを負荷分散する。(IPVS+Keepalivedで実装)
- web01、web02 へDNATして、192.168.1.0/24 側から SSH できるようにする。(iptablesで実装)
- web01、web02 が、192.168.1.0/24側 にアクセスできるようにIPマスカレードする。(iptablesで実装)
赤字で示したIPアドレスは仮想IPです。web01、web02 の利用者は仮想IPを使用します。
障害時は、仮想IPをLVS02 付け替えて、LVS02を使用します。
web01、web02の利用者が、この仮想IPを使用していれば、LVS01 ダウンの影響をなるべくうけずに、LVS02経由でweb01、web02 を利用できるようにします。
障害の検知と仮想IPの付け替えは、Keepalived が自動的に行います。
IPVS+Keepalived の設定
今回は、keepalived.conf を以下のようにし、LVS01 と LVS02 は同じ設定にします。
赤字部分が、VRRPで冗長化する設定です。
virtual_server では、ヘルスチェックと負荷分散の設定をしています。LVS(NAT)でweb01、web02にヘルスチェックして負荷分散する手順については、「 [CentOS6][IPVS+Keepalived] 異なるサブネットでWEBサーバの負荷分散(NAT)」 を参考にしてください。
! Configuration File for keepalived global_defs { !notification_email { ! acassen@firewall.loc ! failover@firewall.loc ! sysadmin@firewall.loc !} !notification_email_from Alexandre.Cassen@firewall.loc !smtp_server 192.168.200.1 !smtp_connect_timeout 30 router_id LVS } vrrp_instance VI_EXT { state BACKUP interface eth0 virtual_router_id 51 priority 101 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.90/24 dev eth0 192.168.1.93/24 dev eth0 192.168.1.94/24 dev eth0 } } vrrp_instance VI_INT { state BACKUP interface eth1 virtual_router_id 52 priority 101 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.90/24 dev eth1 } } vrrp_sync_group VG { group { VI_EXT VI_INT } } virtual_server 192.168.1.90 80 { delay_loop 6 lb_algo rr lb_kind NAT !nat_mask 255.255.255.0 !persistence_timeout 50 protocol TCP real_server 10.0.0.93 80 { weight 10 inhibit_on_failure HTTP_GET { url { path / status_code 200 } connect_timeout 3 !nb_get_retry 3 !delay_before_retry 3 } } real_server 10.0.0.94 80 { weight 10 inhibit_on_failure HTTP_GET { url { path / status_code 200 } connect_timeout 3 !nb_get_retry 3 !delay_before_retry 3 } } }vrrp_instance の VI_EXT では、 eth0 のVRRPと仮想IPアドレスを設定しています。
vrrp_instance の VI_INT では、と eth1 のVRRPと仮想IPアドレスを設定しています。
vrrp_sync_group で VI_EXT と VI_INT をまとめて、eth0 もしくは eth1 のどちらかが切れた場合でも、両方のインスタンスが同時に切り替わるようにしています。
つまりLVS01 の eth0 または eth1 がダウンしたら、LVS02 に切り替わります。
state BACKUP と nopreempt を指定すると、すでにマスターが稼働していた場合、自分のプライオリティ設定が相手よりも高くてもマスターへ昇格しないようになります。
つまり、LVS01 と LVS02 は、先に起動したほうがマスターになります。また、LVS01がダウンして LVS02がマスターに昇格後、LVS01 を正常にアップしても LVS01 はマスターに昇格しません。
IPマスカレードとDNAT の設定
IPマスカレードとDNATの設定は LVS01 と LVS02 に設定し、設定内容は同じにします。
iptables の設定手順は、「 [TIPS][CentOS 6] iptables で IPマスカレード と DNAT を設定する」 を参照してください。
10.0.0.0/24 側から見て出口となる eth0 に IPマスカレードを設定します。
192.168.1.93 宛ての通信は、10.0.0.93 (web01) に転送するように DNAT します。
192.168.1.94 宛ての通信は、10.0.0.94 (web02) に転送するように DNAT します。
LVS01 と LVS02 で iptables の設定を確認すると以下のとおり。
# service iptables status テーブル: nat Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 DNAT all -- 0.0.0.0/0 192.168.1.93 to:10.0.0.93 2 DNAT all -- 0.0.0.0/0 192.168.1.94 to:10.0.0.94 Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 1 MASQUERADE all -- 10.0.0.0/24 0.0.0.0/0 Chain OUTPUT (policy ACCEPT) num target prot opt source destination
web01 と web02 のデフォルトゲートウェイの設定
web01 と web02 はデフォルトゲートウェイを LVSサーバの仮想IP( 10.0.0.90 )にします。
仮想IPを指定することで、LVS01からLVS02に切り替わっても、設定変更なしで通信できるようにします。
# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 10.0.0.90 0.0.0.0 UG 0 0 0 eth0
Keepalived 冗長化の動作確認
LVS01 をマスタにしたいので、LVS01 の keepalived を起動し、次に、LVS02 の keepalived を起動します。
# service keepalived startLVS01 で IPVS の状態を確認します。Weightが 0 でなければヘルスチェックOKで、負荷分散が可能な状態です。
# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.90:80 rr -> 10.0.0.93:80 Masq 10 0 0 -> 10.0.0.94:80 Masq 10 0 0LVS01 の仮想IPアドレスを確認します。
Keppalived で設定する仮想IPアドレスは、ifconfig コマンドでは確認できないので ip コマンドを使用します。
LVS01 がマスタであれば、仮想IPアドレスを見ることができます。
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:f3:b1:c6:82:41 brd ff:ff:ff:ff:ff:ff inet 192.168.1.91/24 brd 192.168.1.255 scope global eth0 inet 192.168.1.90/24 scope global secondary eth0 inet 192.168.1.93/24 scope global secondary eth0 inet 192.168.1.94/24 scope global secondary eth0 inet6 2001:c90:8023:a9d1:f8f3:b1ff:fec6:8241/64 scope global dynamic valid_lft 2591993sec preferred_lft 604793sec inet6 fe80::f8f3:b1ff:fec6:8241/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether b2:40:a2:1e:65:83 brd ff:ff:ff:ff:ff:ff inet 10.0.0.91/24 brd 10.0.0.255 scope global eth1 inet 10.0.0.90/24 scope global secondary eth1 inet6 fe80::b040:a2ff:fe1e:6583/64 scope link valid_lft forever preferred_lft foreverKeepalived のログが /var/log/messages に出力されるので、STATE を確認してみます。
LVS01で以下のようにコマンドを実行して、最終行が MASTER であれば、LVS01 がマスタです。
# egrep "Keepalived.* STATE" /var/log/messages | tail Oct 11 09:54:06 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering BACKUP STATE Oct 11 09:54:06 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering BACKUP STATE Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Transition to MASTER STATE Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Group(VG) Syncing instances to MASTER state Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Transition to MASTER STATE Oct 11 09:54:10 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering MASTER STATE Oct 11 09:54:13 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering MASTER STATELVS02 も確認してみます。
以下の例では、IPVSは問題ありません。LVS02のヘルスチェックもOKです。
仮想IPアドレスは表示されず、ログの STATE からもLVS02 がバックアップであることが確認できます。
# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.90:80 rr -> 10.0.0.93:80 Masq 10 0 0 -> 10.0.0.94:80 Masq 10 0 0 # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 72:87:6b:c0:29:1f brd ff:ff:ff:ff:ff:ff inet 192.168.1.92/24 brd 192.168.1.255 scope global eth0 inet6 2001:c90:8023:a9d1:7087:6bff:fec0:291f/64 scope global dynamic valid_lft 2591828sec preferred_lft 604628sec inet6 fe80::7087:6bff:fec0:291f/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 2a:93:94:eb:17:ae brd ff:ff:ff:ff:ff:ff inet 10.0.0.92/24 brd 10.0.0.255 scope global eth1 inet6 fe80::2893:94ff:feeb:17ae/64 scope link valid_lft forever preferred_lft forever # egrep "Keepalived.* STATE" /var/log/messages | tail Oct 11 09:54:46 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering BACKUP STATE Oct 11 09:54:46 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering BACKUP STATE
LVS01 のeth1 をダウンして、LVS02 に切り替えてみます。
以下のようにして LVS01 の eth1 をダウンします。
# ifdown eth1LVS01 の状態を確認してみると、eth1 DOWN して、仮想IPも削除されています。
Keepalived の STATE は "FAULT" と表示されます。
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:f3:b1:c6:82:41 brd ff:ff:ff:ff:ff:ff inet 192.168.1.91/24 brd 192.168.1.255 scope global eth0 inet6 2001:c90:8023:a9d1:f8f3:b1ff:fec6:8241/64 scope global dynamic valid_lft 2591856sec preferred_lft 604656sec inet6 fe80::f8f3:b1ff:fec6:8241/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000 link/ether b2:40:a2:1e:65:83 brd ff:ff:ff:ff:ff:ff # egrep "Keepalived.* STATE" /var/log/messages | tail Oct 11 09:54:06 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering BACKUP STATE Oct 11 09:54:06 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering BACKUP STATE Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Transition to MASTER STATE Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Transition to MASTER STATE Oct 11 09:54:10 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering MASTER STATE Oct 11 09:54:13 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering MASTER STATE Oct 11 18:21:20 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering FAULT STATE Oct 11 18:21:21 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering FAULT STATELVS02 の状態を見ると、仮想IPが追加されて、Keepalived の STATE は "MASTER" になっています。
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 72:87:6b:c0:29:1f brd ff:ff:ff:ff:ff:ff inet 192.168.1.92/24 brd 192.168.1.255 scope global eth0 inet 192.168.1.90/24 scope global secondary eth0 inet 192.168.1.93/24 scope global secondary eth0 inet 192.168.1.94/24 scope global secondary eth0 inet6 2001:c90:8023:a9d1:7087:6bff:fec0:291f/64 scope global dynamic valid_lft 2591863sec preferred_lft 604663sec inet6 fe80::7087:6bff:fec0:291f/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 2a:93:94:eb:17:ae brd ff:ff:ff:ff:ff:ff inet 10.0.0.92/24 brd 10.0.0.255 scope global eth1 inet 10.0.0.90/24 scope global secondary eth1 inet6 fe80::2893:94ff:feeb:17ae/64 scope link valid_lft forever preferred_lft forever # egrep "Keepalived.* STATE" /var/log/messages | tail Oct 11 09:54:46 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering BACKUP STATE Oct 11 09:54:46 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering BACKUP STATE Oct 11 18:21:24 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Transition to MASTER STATE Oct 11 18:21:24 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Transition to MASTER STATE Oct 11 18:21:25 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering MASTER STATE Oct 11 18:21:26 exlb02 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering MASTER STATE
LVS01 の eth1 を UP してみます。
# ifup eth1LVS01 の状態は以下のとおり。eth1 は正常に戻りましたが、Keepalived の STATE は "BACKUP" です。
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:f3:b1:c6:82:41 brd ff:ff:ff:ff:ff:ff inet 192.168.1.91/24 brd 192.168.1.255 scope global eth0 inet6 2001:c90:8023:a9d1:f8f3:b1ff:fec6:8241/64 scope global dynamic valid_lft 2591893sec preferred_lft 604693sec inet6 fe80::f8f3:b1ff:fec6:8241/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether b2:40:a2:1e:65:83 brd ff:ff:ff:ff:ff:ff inet 10.0.0.91/24 brd 10.0.0.255 scope global eth1 inet6 fe80::b040:a2ff:fe1e:6583/64 scope link valid_lft forever preferred_lft forever # egrep "Keepalived.* STATE" /var/log/messages | tail Oct 11 09:54:06 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering BACKUP STATE Oct 11 09:54:06 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering BACKUP STATE Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Transition to MASTER STATE Oct 11 09:54:09 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Transition to MASTER STATE Oct 11 09:54:10 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering MASTER STATE Oct 11 09:54:13 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering MASTER STATE Oct 11 18:21:20 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering FAULT STATE Oct 11 18:21:21 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering FAULT STATE Oct 11 18:32:19 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_EXT) Entering BACKUP STATE Oct 11 18:32:19 exlb01 Keepalived_vrrp[975]: VRRP_Instance(VI_INT) Entering BACKUP STATE