深夜2時のサーバーダウンと稼働率(Uptime)の課題
想像してみてください。1時間あたり数千ドルの売上があるECサイトを運営しているとします。深夜、突然サーバーのハードウェアが故障したり、Nginxがクラッシュしたりします。単一のサーバー(シングルノード)構成では、PCを開いて復旧作業を終えるまで、システムは「停止」したままです。そこで救世主となるのが、高可用性(High Availability: HA)クラスターです。
私自身、HA構成がなかったために苦い経験をしたことがあります。CentOS 8が突然のサポート終了(EOL)を迎えた際、わずか7日間で5台の本番サーバーをRocky Linuxへ移行しなければなりませんでした。ダウンタイムが1分増えるごとに損失が出るという極限のプレッシャーの中、事前にPacemakerとCorosyncを導入していたおかげで、ユーザーに気づかれることなくノード間でリソースを切り替えることができました。今回は、その経験から得た「落ちないシステム」の構築手順をまとめました。
クイックスタート:5分でHAクラスターを稼働させる
コマンドを入力する前に、CentOS、Rocky Linux、またはAlmaLinuxを実行しているサーバーを少なくとも2台用意してください。クラスター構築の前提となる固定IP設定を確認した上で、構成例は以下の通りです:
- ノード1: 192.168.1.10 (hostname: node1)
- ノード2: 192.168.1.11 (hostname: node2)
- 仮想IP (VIP): 192.168.1.100 (クラスター全体を代表するアドレス)
ステップ1:ソフトウェアのインストール
両方のノードに、yumを使用して主要なコンポーネントをインストールします:
# リポジトリと必要なパッケージのインストール
yum install -y pacemaker corosync pcs
# システム起動時にpcsdを自動開始するように設定
systemctl enable --now pcsd
ステップ2:haclusterユーザーのパスワード設定
インストール後、システムは自動的に hacluster ユーザーを作成します。ノード間で連携させるために、両方のノードで同じパスワードを設定する必要があります。
passwd hacluster
ステップ3:クラスターの初期化
ここでは、ノード1から以下のコマンドを実行するだけで完了します:
# ノード間の認証
pcs host auth node1 node2 -u hacluster
# 'my_cluster'という名前でクラスターを作成
pcs cluster setup my_cluster node1 node2
# 全ノードでクラスターを起動し、有効化
pcs cluster start --all
pcs cluster enable --all
ステップ4:仮想IP(VIP)の設定
VIPはシステムの「顔」です。ノード1がダウンした場合、このIPは5秒以内に自動的にノード2へ切り替わります。
# STONITHを無効化(検証・テスト環境のみ推奨)
pcs property set stonith-enabled=false
# 仮想IPリソースの作成
pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.1.100 cidr_netmask=24 op monitor interval=30s
pcs status コマンドで確認します。virtual_ip が Started になっていれば、半分成功です。
仕組みの解説:クラスターの「心臓」と「頭脳」
PacemakerとCorosyncを混同しがちですが、クラスターをサッカーチームに例えると分かりやすくなります:
Corosync:メッセージング層 (Messaging Layer)
Corosyncは「心拍(ハートビート)」の役割を担います。サーバー間で常に小さなパケットを送り合い、「私は生きています!」と確認し合います。ノードAがノードBからのメッセージを受信しなくなると、Corosyncは即座にノードBがオフラインになったというアラートを発信します。
Pacemaker:リソースマネージャー (Resource Manager)
Pacemakerは制御を行う「頭脳」の役割を担います。Corosyncからの情報に基づき、意思決定を行います。ノードBがダウンした場合、Pacemakerはサービスリスト(Web、DB、VIPなど)を確認し、それらをノードAで起動するように指示します。究極の目標は、常にサービスを「利用可能」な状態に保つことです。
悪夢の「スプリットブレイン」とSTONITHによる解決策
2つのノード間のネットワークが切断されたものの、両方のノードが稼働し続けている場合はどうなるでしょうか? 両方のノードが仮想IPを奪い合い、データを上書きし合うことになります。これが非常に危険な「スプリットブレイン」現象で、データベース全体を破壊する恐れがあります。
これを防ぐために STONITH (Shoot The Other Node In The Head) を使用します。競合が発生した際、正常なノードがハードウェア(iLO、IPMIなど)を介して、故障したノードを強制停止(フェンシング)させます。これにより、常に1つのノードだけが制御権を持つことが保証されます。
Webサーバー向けの高度な設定
仮想IPだけでは不十分です。Nginxのような実際のサービスと紐付ける必要があります。
1. Nginxのインストール
yum install -y nginx
systemctl enable nginx # 注意:手動で起動せず、Pacemakerに管理を任せる
2. Nginxリソースの作成
pcs resource create web_server ocf:heartbeat:nginx configfile=/etc/nginx/nginx.conf op monitor timeout=20s interval=10s
3. 制約条件(Constraints)の設定
デフォルトでは、Pacemakerはノード1でVIPを、ノード2でWebサーバーを実行してしまうことがあります。これではシステムが機能しません。これらを同じノードで動かす(Colocation)ように、かつ正しい順序(Order)で起動するように強制する必要があります。
# VIPとWebサーバーを同じノードで実行するように強制
pcs constraint colocation add web_server with virtual_ip INFINITY
# VIPを先に起動し、その後にWebサーバーを起動することを保証
pcs constraint order virtual_ip then web_server
現場の経験:ハマりやすいポイント
以前の大規模なシステム移行の経験から、システム管理者が注意すべき4つの重要なポイントを挙げます:
- ファイアウォールのポート開放: クラスター通信には 2224, 3121, 5403/tcp および 5404, 5405/udp のポートが必要です。サービスが動いているのに
pcs statusがOFFLINEになる場合は、まずfirewalldを確認してください。 - クォーラム(Quorum)の処理: 2ノード構成の場合、1台がダウンするともう一方が過半数票(クォーラム)を失い、自動的にサービスを停止してしまいます。
pcs property set no-quorum-policy=ignoreを設定して、残ったノードが正常に動作し続けるようにします。 - データの同期: Pacemakerは起動・停止を管理するだけで、コードや設定ファイルの同期は行いません。rsync を組み合わせるか、NFS/GlusterFSなどの共有ストレージを使用することをお勧めします。
- SELinuxへの注意: セキュリティ低下を避けるため、SELinuxを完全に無効にしないでください。
semanageを使用してPacemakerスクリプトに適切な権限を付与します。正しい設定方法については、私のブログのSELinuxガイドを参照してください。
PacemakerとCorosyncをマスターすることで、大規模システムの運用に自信が持てるようになります。トラブル発生時もクラスターが数秒で自動修復してくれるため、夜通し対応することなく、安心して眠りにつくことができるでしょう。

