高可用性アーキテクチャの概要
高可用性(High Availability)システムは、複数のサーバーで同一サービスを稼働させ、一台に障害が発生した場合でも自動的に別のサーバーが処理を引き継ぐ仕組みです。これにより、サービスの停止時間を最小限に抑え、継続的な運用を実現します。ここでは、VRRP プロトコルを用いたフェイルオーバーを実現する Keepalived と、ロードバランシングおよびヘルスチェックを行う HAProxy の構成について解説します。
Keepalived によるフェイルオーバー構成
Keepalived は、VRRP(Virtual Router Redundancy Protocol)を利用して仮想 IP アドレスを管理し、マスターノードの障害時にバックアップノードへ IP を移譲します。これにより、クライアントからは単一の IP アドレスとしてサービスが見え、裏側のサーバー切り替えを意識させることなく稼働し続けます。
主要な動作原理
- heartbeat メカニズム: マスターノードは定期的にマルチキャストで生存信号を送信します。バックアップノードはこの信号を受信できなくなった場合、マスターが障害発生たと判断し、権限を奪取します。
- 優先度ベースの選出: 複数のノード間でマスターを選出する際、優先度(priority)の高いノードが選定されます。
- モード: デフォルトの抢占モードでは、優先度の高いノードが復旧すると即座にマスターに戻ります。非抢占モードでは、現在のマスターが完全にダウンするまで切り替えが発生しません。
設定ファイルの構成例 (keepalived.conf)
以下の設定では、仮想 IP に 10.0.0.200 を使用し、インターフェース eth0 をバインドします。マスターノードの優先度を 120、バックアップノードを 100 として設定します。
! Keepalived Configuration
global_defs {
router_id ha_node_alpha
}
vrrp_script check_web_service {
script "/usr/local/bin/check_service.sh"
interval 2
weight -20
}
vrrp_instance VIP_WEB {
state MASTER
interface eth0
virtual_router_id 51
priority 120
advert_int 1
authentication {
auth_type PASS
auth_pass secure_password_2024
}
virtual_ipaddress {
10.0.0.200
}
track_script {
check_web_service
}
notify_master "/usr/local/bin/notify_master.sh"
notify_backup "/usr/local/bin/notify_backup.sh"
}
サービス監視スクリプトの作成
Keepalived 自体はプロセスの監視を行わないため、Web サーバーなどの死活監視スクリプトを用意し、障害時に優先度を下げるか、Keepalived を停止させる必要があります。
#!/bin/bash
# check_service.sh
TARGET_SERVICE="nginx"
if ! pgrep -x "$TARGET_SERVICE" > /dev/null; then
echo "$(date): $TARGET_SERVICE is down. Stopping keepalived."
systemctl stop keepalived
exit 1
fi
exit 0
このスクリプトに実行権限を付与し、設定ファイルの vrrp_script セクションで呼び出すようにします。
脳分裂(Split-Brain)現象への対策
ネットワークの分断などにより、双方のノードが相手を検知できず、同時にマスター権限を取得してしまう現象を脳分裂と呼びます。これを防ぐためには、ファイアウォールで VRRP プロトコル(プロトコル番号 112)の通信を許可し、マルチキャスト通信が阻害されないように設定する必要があります。
firewall-cmd --permanent --add-protocol=vrrp
firewall-cmd --reload
HAProxy によるロードバランシング
HAProxy は、TCP レイヤー(L4)および HTTP レイヤー(L7)で動作する高性能なロードバランサーです。複数のバックエンドサーバーへトラフィックを分散し、ヘルスチェック機能により障害のあるサーバーを自動的にプールから除外します。
主な特徴とアルゴリズム
- ラウンドロビン (roundrobin): 接続を順にサーバーへ割り振ります。短接続に適しています。
- leastconn: 現在の接続数が最も少ないサーバーを選択します。長接続に適しています。
- source: クライアントの IP アドレスに基づいてハッシュ計算を行い、特定のサーバーに固定します。
設定ファイルの構成例 (haproxy.cfg)
グローバル設定でプロセス数と最大接続数を定義し、フロントエンドで受信したリクエストをバックエンドサーバー群へ転送します。統計情報ページも有効化しています。
global
log 127.0.0.1 local0 notice
user haproxy
group haproxy
daemon
nbproc 4
maxconn 2048
pidfile /var/run/haproxy.pid
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
retries 3
timeout connect 5000
timeout client 30000
timeout server 30000
listen stats
bind 0.0.0.0:8404
mode http
stats enable
stats uri /haproxy?stats
stats refresh 10s
stats auth admin:secure_admin_pass
frontend http_front
bind 0.0.0.0:80
mode http
option forwardfor
default_backend web_servers
backend web_servers
mode http
balance roundrobin
option httpchk GET /health
server web01 192.168.10.11:80 check inter 2000 rise 2 fall 3
server web02 192.168.10.12:80 check inter 2000 rise 2 fall 3
server web03 192.168.10.13:80 check inter 2000 rise 2 fall 3 backup
上記の設定では、/health エンドポイントへの HTTP GET リクエストによりバックエンドの死活を確認し、失敗が連続するとトラフィックの送信を停止します。また、backup パラメータが付与されたサーバーは、通常のサーバーが全てダウンした場合にのみ使用されます。