keepalivedでサイトを冗長化するまとめ。

サーバを2台用意して、ホットスタンバイ構成で異なるNICにVIPを付け替える方法。

冗長化

keepalivedでサイトを冗長化する際の記録。

今回は互いにVRRPで監視するNICと、VIPを付け替えるNICが異なる場合の方法。

グローバルIPが1つしかない場合や、社内で開発サーバ用のIPを1つしか貰えなかった時に役立ちます。(管理者がケチな時・・・)

作業概要

冗長化概要
冗長化の概要図

イメージ的にはこんな感じ。

keepalivedでの互いの生存確認はNIC1の「172.16.0.0/24」の帯域で。

VIPを付け替えるのはNIC2になります。(僕の自宅ネットワークが192.168.20.0/24で構築されている)

要するに雲の部分が自宅ネットワークなのでうまくいけば僕のPCから「http://192.168.20.190」でサイトにアクセスできる。

グローバルIPの場合は192.168.20.190をグローバルにする。

NIC1の「172.16.0.0/24」はなんでもいいです、Server1とServer2が同じ帯域にあれば。

ネットワーク設定

virtualboxで2台サーバを立てて検証した。

NICは2つにして2台ともNIC1は「enp0s3」、NIC2は「enp0s8」になっている。

NIC1の設定

#vi ifcfg-enp0s3
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="enp0s3"
UUID="7a89f293-6129-41b9-bf79-97ecd720c671"
DEVICE="enp0s3"
ONBOOT="yes"
IPADDR=172.16.0.11
NETMASK=255.255.255.0

Server1のIPADDRは「172.16.0.11」、Server2のIPADDRは「172.16.0.12」にする。

NIC2の設定

#vi ifcfg-enp0s8
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="no"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="enp0s8"
UUID="988b2437-2ac1-36ff-a5e9-2bb95fcf4de9"
DEVICE="enp0s8"
ONBOOT="no"

NIC2はVIPを付与するだけなので、自動起動しないようにしている。「ONBOOT=”no”」

IPの確認

設定が終わったらサーバを再起動してIPを確認する。

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:13:bb:98 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.11/24 brd 172.16.0.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:50:b5:26 brd ff:ff:ff:ff:ff:ff

上記はServer1のIPを表示している、enp0s3に「172.16.0.11/24」がenp0s8にはIPが付与されていない。

keepalivedの設定

インストール

# yum -y install keepalived

ついでにtcpdumpもインストールしておく。(VRRP確認用)

# yum -y install tcpdump

設定

keepalivedの設定ファイル/etc/keepalived/keepalived.confを設定する。

vrrp_instanceのところを下記に修正

#vi /etc/keepalived/keepalived.conf
~
vrrp_instance VI_1 {
    state MASTER
    interface enp0s3
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.20.190/24 dev enp0s8
    }
~

vrrpを使っての死活監視はenp0s3でするけど、VIPをつけるのはenp0s8って感じの設定。

基本的にはServer1とServer2は同じ設定でいい。

個人的な趣味でServer1が起動しているときは常にServer1をマスターにしたいから

Server1は「priority:150」、Server2は「priority:100」にしている。

サイトの設定

サイトの冗長化が目的なので、一応サイトを準備する。

apacheをインストールしてhtmlファイルを用意する。

Server1につながっているときはMASTERが表示される。

Server2につながっているときはBACKが表示される。

Server1のindex.html

/var/www/html/index.html

<h1>MASTER</h1>

Server2のindex.html

<h1>BACK</h1>

firewalldの設定

keepalivedはvrrpを使用して監視するのでfirewalldでvrrpを許可しないといけない。

検証段階で面倒なのでfirewalldを止める。

# systemctl stop firewalld

SELinuxが邪魔な時もある、今回は特に邪魔しなかったけどうまくいかない時は止めてみるのもありかと。

※両方ともセキュリティに大切な機能です、本番稼働させるときはちゃんと設定しましょう。

keepalivedの起動

さぁ、ここまできたらいよいよ起動させるときです。

起動前にServer1とServer2にVIPが付与されていないことをもう一度確認しましょう。

Server1

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:13:bb:98 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.11/24 brd 172.16.0.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:50:b5:26 brd ff:ff:ff:ff:ff:ff

Server2

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:13:bb:98 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.12/24 brd 172.16.0.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:50:b5:26 brd ff:ff:ff:ff:ff:ff

keepalived起動

Server1(マスター)から起動しましょう。

# systemctl start keepalived
# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: active (running)

Active: active (running)になっていれば起動しています。

vipの確認

vipがServer1のenp0s8についているか確認します。

# ip a
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:50:b5:26 brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.190/24 scope global enp0s8
       valid_lft forever preferred_lft forever

vipがServer2のenp0s8に「ついていない」ことも確認します。

# ip a
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:50:b5:26 brd ff:ff:ff:ff:ff:ff

もしServer1とServer2両方ともVIPが付与されていたらVRRPによる通信がうまくいっていない可能性があります。

firewalldやSELinuxの確認や、ネットワークでマルチキャストが許可されているか確認してください。

サイトへアクセス確認

ブラウザでVIP「http://192.168.20.190/index.html」にアクセスします。

マスタ側確認
Master画面

Server1にVIPが付与されているので「Master」と表示されるはずです。

切り替えテスト

現在Server1についているVIPがServer2に切り替わるかをテストします。

Server1のkeepalived停止

Server1のkeepalivedを停止します。

# systemctl stop keepalived

Server2のvip確認

Server2にvipが付与されているか確認します。

# ip a
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:50:b5:26 brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.190/24 scope global enp0s8
       valid_lft forever preferred_lft forever

サイトへアクセス確認

ブラウザでVIP「http://192.168.20.190/index.html」にアクセスします。

BACK側確認
BACK画面

Server2にVIPが付与されているので「BACK」と表示されるはずです。

これで切り替わったことが確認できます。

まとめ

keepalivedでサイトの冗長化すれば障害などが起きた時に自動で切り替わってくれます。

夜中に叩き起こされて呼び出されることもなくなるかも。

安心して寝ることができます。

まぁ、今回の設定ではkeepalivedが停止したときやサーバがダウンしたときしか切り替わりませんが。

サービスレベルでの切り替えとなると、拡張してhttp監視とかも必要になるでしょう。

備忘録

VRRPを確認

ネットワークを流れるvrrpを確認する。

# tcpdump vrrp -nn -c3
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
17:15:48.197528 IP 172.16.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 150, authtype none, intvl 1s, length 20
17:15:49.198192 IP 172.16.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 150, authtype none, intvl 1s, length 20
17:15:50.217098 IP 172.16.0.11 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 150, authtype none, intvl 1s, length 20
3 packets captured
4 packets received by filter
0 packets dropped by kernel

VRRPを流すIPを指定したいとき。

NICに複数IPを保持していていVRRPを流すIPを指定したいときは下記を追加

# vi /etc/keepalived/keepalived.conf
~
vrrp_instance VI_1 {
    state MASTER
    interface enp0s3
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    mcast_src_ip 172.16.0.12 # ←これを追加するとVRRPのIPを指定できる
    virtual_ipaddress {
        192.168.20.190/24 dev enp0s8
    }
~

マルチキャストが使えない時

ユニキャストが指定できるらしい。※未検証

# vi /etc/keepalived/keepalived.conf
    unicast_src_ip 172.16.0.11
    unicast_peer {
        172.16.0.12
	172.16.0.13
    }