RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

keepalivedを使って冗長化をやってみた

アイキャッチ画像

初めまして。ラクスでインフラを担当していますru369と申します。
今回は冗長化についてご参考になればいいなと思い、本記事にまとめさせていただきました。

▼まずは冗長化の意味から!

システムの一部に何らかの障害が発生した場合に備えて、
障害発生後でもシステム全体の機能を維持し続けられるように、
予備装置を平常時からバックアップとして配置し運用しておくこと

引用元:wikipedia

簡単に言うと【継続したサービス提供のために本稼働サーバとは別にもう1台備えておく=冗長化】ということですね。

今回はnginxが動いているサーバの冗長化を試みます。
冗長化にはkeepalivedを使ってみたいと思います。

keepalivedを使って冗長化

サーバの情報

テスト1号機【MASTER】 172.20.100.95
テスト2号機【BACKUP】 172.20.100.96
Virtual IPaddress(冗長化用) 172.20.100.98
OS Centos 7.9
※selinux、firewalldは無効化してます

諸々インストール

keepalived
yumパッケージでkeepalivedは提供されているのでサクッとインストール

# yum -y install keepalived

〇nginxインストール&起動、確認

nginxのyumリポジトリを追加
/etc/yum.repos.d/nginx.repoに以下の内容を記述

******************************
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
******************************

# yum install -y nginx
# systemctl start nginx

冗長化の確認等に利用するシェルスクリプト3つ

chk_nginx_status.sh

#!/usr/bin/bash
systemctl is-active nginx

chk_nginx_proc.sh

#!/usr/bin/bash

timeout 5 curl http://localhost:80
status=$?

if [ $status -eq 0 ]; then
  logger "nginx processes are alive."
  exit 0
elif [ $status -eq 130 ]; then
  logger "nginx process is hanging up."
  exit 1
else
  logger "Something is wrong."
  exit 1
fi

maintenance.sh

#!/bin/sh

[ -f "/etc/keepalived/maintenance" ] && exit 1

exit 0

keepalivedの設定ファイル

◇テスト1号機【MASTER】側
/etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
}

vrrp_script chk_nginx {
    script "/etc/keepalived/chk_nginx_status.sh"
    interval 2
    fall 2
    rise 2
}

vrrp_script chk_nginx_processes {
    script "/etc/keepalived/chk_nginx_proc.sh"
    interval 2
    fall 2
    rise 2
}

vrrp_script maintenance_mode {
    script "/etc/keepalived/maintenance.sh"
    interval 2
    weight 50
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    virtual_ipaddress {
        172.20.100.98
    }
    track_script {
      chk_nginx
      chk_nginx_processes
      maintenance_mode
    }
}

◇テスト2号機【BACKUP】側 ※MASTER側と異なるところのみ抜粋

    priority 100

keepalivedを起動と冗長化の状態確認

# systemctl start keepalived
【MASTER】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0

【BACKUP】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.96/16 brd 172.20.255.255 scope global noprefixroute eth0

サーバ間で共有するVirtual IPaddress 172.20.100.98 がMASTER側に付与されて冗長化されていそうな感じです。
動作テストで冗長化されているかを確認していきたいと思います。

▼動作テスト

以下のパターンで冗長化の動作テストしていきます。

  1. MASTER側のkeepalived/nginxを停止したらBACKUP側にVirtual IPが付与され冗長化を確認できるか
  2. MASTER側のnginxをハングアップさせたらBACKUP側にVirtual IPが付与され冗長化を確認できるか
  3. メンテナンス用のファイルを設置によってMASTER/BACKUPが入れ替わり冗長化を確認できるか

1.MASTER側のkeepalived/nginxを停止したらBACKUP側にVirtual IPが付与され冗長化を確認できるか

【MASTER】
# systemctl stop keepalived
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0

【BACKUP】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.96/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0

Virtual IPaddressがBACKUP側に移動して冗長化を確認できました。

  • nginx停止の場合は以下の通り
# systemctl stop nginx
# systemctl is-active nginx
inactive

★参考までに切り替わっている最中にping飛ばしてみました。

# ping 172.20.100.98
64 bytes from 172.20.100.98: icmp_seq=9 ttl=64 time=0.405 ms
64 bytes from 172.20.100.98: icmp_seq=10 ttl=64 time=0.412 ms
64 bytes from 172.20.100.98: icmp_seq=12 ttl=64 time=2.18 ms  ★ここで切り替わった
64 bytes from 172.20.100.98: icmp_seq=13 ttl=64 time=0.288 ms
64 bytes from 172.20.100.98: icmp_seq=14 ttl=64 time=0.314 ms

2.MASTER側のnginxをハングアップさせたらBACKUP側にVirtual IPが付与され冗長化を確認できるか

  • MASTER側のnginxにSIGSTOPを送信して、nginxを停止状態とする
【MASTER】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0

# ps -C nginx -o comm,command,pid,state
COMMAND         COMMAND                        PID S
nginx           nginx: master process /usr/ 114281 S
nginx           nginx: worker process       114282 S

# pkill -SIGSTOP nginx  ★ハングアップさせた
# ps -C nginx -o comm,command,pid,state
COMMAND         COMMAND                        PID S
nginx           nginx: master process /usr/ 114281 T
nginx           nginx: worker process       114282 T

# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0

【BACKUP】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.96/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0

こちらのパターンでもVirtual IPaddressがBACKUP側に移動して冗長化を確認できました。

3.メンテナンス用のファイルを設置によってMASTER/BACKUPが入れ替わり冗長化を確認できるか

/etc/keepalived/maintenanceというファイルがあれば、priority値が50下がり、MASTERとBACKUPが入れ替わる想定

〇メンテナンス用ファイル設置前後でのpriority値の変化

MASTER BACKUP
設置前のpriority値 1号機側:101 2号機側:100
設置後のpriority値 1号機側:51 2号機側:100

 ⇒設置後は2号機側(もとBACKUP側)のpriority値が高くなるのでMASTERとして昇格する。

【MASTER】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0
# touch /etc/keepalived/maintenance
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0

【BACKUP】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.96/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0

★このままBACKUP側にメンテナンス用のファイルを設置してみると元に戻る想定

元MASTER 元BACKUP
2号機側への設置前 priority値 1号機側:51 2号機側:100
2号機側への設置後 priority値 1号機側:51 2号機側:50
【BACKUP】
# touch /etc/keepalived/maintenance
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.96/16 brd 172.20.255.255 scope global noprefixroute eth0

【MASTER】
# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.20.100.95/16 brd 172.20.255.255 scope global noprefixroute eth0
    inet 172.20.100.98/32 scope global eth0

想定通りMASTER/BACKUPが入れ替わり冗長化を確認できました!
冗長化しているとメンテナンスするとき結構便利な印象です。
冗長化、一考の余地あり...。

▼まとめ

今回の冗長化は明示的にMASTER,BACKUPを設定してみましたが、confのstateをどちらもBACKUPにすることでフェイルバックを防ぐこともできます。
また、keepalivedでは冗長化の他にconfでnotification_emailを使ってアラート通知を飛ばしてみたり、notifyを利用したステータスチェックもできるみたいです。
色々と設定できそうなことがあるので運用状況にあったものを冗長化する際に検討する必要がありそうです。

この記事が少しでも皆様の幸せになることを願って。

※参考にしたページ
https://weblabo.oscasierra.net/nginx-centos7-install/
https://qiita.com/hana_shin/items/bda169d8d24f5954a992
https://mseeeen.msen.jp/build-cluster-with-keepalived-on-centos-7/


  • エンジニア中途採用サイト
    ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
    ご興味ありましたら是非ご確認をお願いします。
    20210916153018
    https://career-recruit.rakus.co.jp/career_engineer/

  • カジュアル面談お申込みフォーム
    どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
    以下フォームよりお申込みください。
    forms.gle

  • イベント情報
    会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.