Keepalivedを使ってサーバーを冗長化

ラズパイでサーバーを構築していると、いつダウンするか分かりません。そんな時でも、サーバーを冗長化することで稼働し続けるシステムにできないかと考え、「Keepalived」を使った冗長化システムを構築したので紹介します。

今までのシステム構成は以下です。

この構成だと、稼働中のMasterがダウンすると転送先が途絶えてしまうので、手動でスレーブ側に切り替えるまでサービスが停止してしまいます。障害はある日突然おきてしまうので、すぐに切り替えることができない場合も想定されます。まずいです・・・・

そこで、それらの問題を解決できる、Keepalivedを使った冗長化システムを考えてみました。ポイントは、ルータの転送先アドレスは固定にしたいので、VIP(仮想IP)用います。冗長化したサーバー間のやり取りは、Keepalivedを使えば、VRRP(Virtual Router Redundancy Protocol)を実現できるので、障害発生時に自動でSlave側に切り替えてくれるはずです。

では、実際にシステムを組んでみて検証してみます。

まずは、Keepalivedをインストールします。

$sudo apt-get install keepalived

今回のシステムでは、VIP(仮想IP)を使うので、システムのデバイスに割り当てられていないIPアドレスをバインドしてやる必要があります。

$su
#echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind

上記コマンドで一時的に割り付けられますが、再起動すると設定がきえてしまうので、再起動後も反映されるためには以下の値を/etc/sysctl.confに追記して設定を反映します。

↓/etc/sysctl.confに以下を追記
net.ipv4.ip_nonlocal_bind = 1

$sudo sysctl -p

今回のシステムに合わせて、keepalivedの設定を作成します。「/etc/keepalived/keepalived.conf」という新しいファイルを作成して編集します。

VRRPの構成と仕組み

Master側の設定ファイルです。

設定で注意するポイントは以下です。

  • virtual_router_idとauth_passは、MasterとSlaveで同じ値に設定
  • priorityの設定は、master側を高い値に設定
  • masterとslave側のIPアドレスとvirtual ipaddressを同じサブネットで設定

master側の設定ファイル「keepalived.conf」の記載例です。

global_defs {
    vrrp_garp_master_refresh 60
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
# ユニキャスト設定の補足を参照
#    unicast_peer {
#        192.168.30.11
#        192.168.30.12
#    }
    virtual_ipaddress {
        192.168.30.20
    }
}

slave側の設定ファイル「keepalived.conf」の記載例です。priority の設定値をmaster側より低い値に設定しています。

global_defs {
    vrrp_garp_master_refresh 60
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
# ユニキャスト設定の補足を参照
#    unicast_peer {
#        192.168.30.11
#        192.168.30.12
#    }
    virtual_ipaddress {
        192.168.30.20
    }
}

以上で、設定は完了です。設定を反映させるためにkeepalivedを再起動します。

$ sudo service keepalived restart

keepalivedが正しく動作しているかを検証します。

まずは、master側の状態を確認します。master側もslave側も稼働している場合は、priorityの設定値が高いmaster側にVIPが割り付けられます。(期待通りです)

$ ip a
1: lo: 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
・・・(省略)
inet 192.168.30.11/24 brd 192.168.30.255 scope global noprefixroute eth0 ★ここは設定したmaster側のIPアドレス
valid_lft forever preferred_lft forever
inet 192.168.30.20/32 scope global eth0 ★ここがVIPのアドレス
・・・(省略)
valid_lft forever preferred_lft forever
3: wlan0: mtu 1500 qdisc noop state DOWN group default qlen 1000
・・・(省略)

続いて、slave側の状態を確認します。master側もslave側も稼働している場合は、priorityの設定値が低いslave側にはVIPが割り付けられません。VIPの割り付けがないですね。(期待通りです)

$ ip a
1: lo: 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
・・・(省略)
inet 192.168.30.12/24 brd 192.168.30.255 scope global noprefixroute eth0 ★ここは設定したslave側のIPアドレス
★ここにVIPの割り付けがないことを確認
・・・(省略)
valid_lft forever preferred_lft forever
3: wlan0: mtu 1500 qdisc noop state DOWN group default qlen 1000
・・・(省略)

では、master側のEhternetケーブルを抜いてみます。物理的にケーブルを抜いてみました。

slave側の状態を再度確認します。master側がダウンしているので、VRRPで障害を検出して、slave側にVIPが割りつけられます。(期待通りです)

$ ip a
1: lo: 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
・・・(省略)
inet 192.168.30.12/24 brd 192.168.30.255 scope global noprefixroute eth0 ★ここは設定したslave側のIPアドレス
valid_lft forever preferred_lft forever
inet 192.168.30.20/32 scope global eth0 ★ここがVIPのアドレス
・・・(省略)
valid_lft forever preferred_lft forever
3: wlan0: mtu 1500 qdisc noop state DOWN group default qlen 1000
・・・(省略)

最後に、master側のEhternetケーブルを挿し戻します。

slave側の状態を確認します。master側が復活したので、priorityの設定値が低いslave側にはVIPが割り付けられません。(期待通りです)

$ ip a
1: lo: 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
・・・(省略)
inet 192.168.30.12/24 brd 192.168.30.255 scope global noprefixroute eth0 ★ここは設定したslave側のIPアドレス
★ここにVIPの割り付けがないことを確認
・・・(省略)
valid_lft forever preferred_lft forever
3: wlan0: mtu 1500 qdisc noop state DOWN group default qlen 1000
・・・(省略)

master側の状態を確認します。master側が復活すると、priorityの設定値が高いmaster側にVIPが割り付けられます。(全て期待通りです)

$ ip a
1: lo: 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
・・・(省略)
inet 192.168.30.11/24 brd 192.168.30.255 scope global noprefixroute eth0 ★ここは設定したmaster側のIPアドレス
valid_lft forever preferred_lft forever
inet 192.168.30.20/32 scope global eth0 ★ここがVIPのアドレス
・・・(省略)
valid_lft forever preferred_lft forever
3: wlan0: mtu 1500 qdisc noop state DOWN group default qlen 1000
・・・(省略)

全て期待通りに動作していることが確認できました。これでmaster側がダウンした場合でも、slave側に切り替わってサービスを継続できます。ラズパイでサーバーを稼働している場合は、冗長化をおこなうことが重要だと思います。MicroSDが壊れた場合でも、安心して交換作業ができますね。同時に壊れたらどうするかということも頭によぎりましたが、考えないことにしました・・・・(3重化?)

【ユニキャスト設定の補足】

暫く稼働していて気づいたのですが、MASTER側のログに1秒間隔でWarningメッセージが出力されていました。(BACKUP側には出力されず)1秒間隔っていうので…マスタ側からスレーブ側に送っている「VRRP Advertisement」の送信間隔と一致していると思い設定を見直しました。マルチキャストでやり取りできる場合は、設定ファイル(keepalived.conf)の以下のブブはいらないはずです。

    unicast_peer {
        192.168.30.11
        192.168.30.12
    }

しかも、マスタ側からスレーブ側の送信するので、以下のように記載しないと1秒周期で鬼のようなWarningメッセージがログに出力されます….

MASTER側の設定ファイル

  unicast_src_ip 192.168.30.11
    unicast_peer {
        192.168.30.12
    }

BACKUP側の設定ファイル

  unicast_src_ip 192.168.30.12
    unicast_peer {
        192.168.30.11
    }

とりあえず、マルチキャスト設定(コメント扱い)と、上記のユニキャスト設定にして試してみましたが、どちらの場合もWarningメッセージは出力されないようになりました。

マルチキャストが通らない場合は、ユニキャスト設定が必要になると思いますので、環境に合わせて設定されると良いと思います。

【ユニキャストとマルチキャストについて】
ユニキャストとは、単一のアドレスを指定して、1対1で行われるデータ通信のことです。
マルチキャストとは、特定のアドレスを指定して、1対複数で行われるデータ通信のことです。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA