はじめに
Web サービスや業務システムにおいて、「サーバー故障=サービス停止」はビジネスに直結する重大なリスクです。 ハードウェアや OS の障害はいつか必ず起こります。その際、人手を介さずに自動で予備のサーバーへ切り替え、サービスを継続させる仕組み――それが HA(High Availability:高可用性)クラスタ です。
本記事では、Linux 環境におけるクラスタ構築のデファクトスタンダードである Pacemaker と Corosync を組み合わせ、RHEL 9 / AlmaLinux 9 などの現代的な OS 環境で Web サーバーを冗長化する手順を解説します。
サーバーを止めない「HA クラスタ」とは?
HA クラスタとは、複数のサーバーを連携させ、あたかも「1つの強固なシステム」として振る舞わせる技術です。
一般的には 「稼働系(Active)」 と 「待機系(Standby)」 の2台で構成され、稼働系に障害が発生すると、Pacemaker がそれを検知し、瞬時に待機系へサービス(IP アドレスや Web サーバーなど)を引き継ぎます(フェイルオーバー)
- 最新の構成: Heartbeat ではなく、現在主流の Corosync を使ったクラスタの仕組み
- 現代的な手順: RHEL 9 / AlmaLinux 9 環境での
pcsコマンド を使った構築方法 - 実践的な設定: VIP(仮想 IP)、Apache、ファイルシステムを連動させるリソースグループの作成
- 動作検証: 実際にプロセスを強制終了させ、自動で切り替わる様子の確認
HA クラスタの仕組みと最新トレンド
HA クラスタは、単にサーバーを2台並べるだけでは機能しません。「相手が生きているかを確認する機能(通信)」と、「死んだとわかったらサービスを引き継ぐ機能(制御)」が連携して初めて成り立ちます。

なぜ Heartbeat ではなく Corosync なのか?(現代の標準構成)
かつては「Linux クラスタといえば Heartbeat」でしたが、現在(RHEL 7/CentOS 7 以降)は Pacemaker + Corosync の組み合わせがデファクトスタンダードです。
- Heartbeat(旧世代)
-
開発が停止しており、最新の OS ではパッケージ自体が提供されていないことが多いです。
- Corosync(新世代)
-
- 役割: ノード間の通信(メッセージング)と死活監視を担当します。
- 特徴: 高速で信頼性が高く、大規模なクラスタにも対応可能です。
つまり、「Corosync が土管(通信)を用意し、Pacemaker が頭脳(制御)として動く」 のが現代の構成です。

ちなみに、現在の Pacemaker は、Corosync の上で動作することを前提に設計されています。
重要な3つの要素: Resource、Constraint、Fencing
Pacemaker を設定する上で、必ず理解しておかなければならない3つの概念があります。
- クラスタが管理する「対象物」です。
- 例:VIP(仮想 IP アドレス)、httpd(Web サーバープロセス)、Filesystem(ディスクマウント)など。これらをひとまとめにして、障害時にセットで移動させます。
- リソースを「いつ、どこで、どう動かすか」のルールです。
- 場所制約(Location): どのノードで動かしたいか(例: 基本は active ノードで動かす)
- 順序制約 (Order): 起動する順番(例: VIP が付いてから → Apache を起動する)
- コロケーション制約 (Colocation): 一緒に動かすルール(例: VIP と Apache は必ず同じノードで起動する)
- 最も重要な「最後の安全装置」です。
- 通信が途絶えた際、相手が本当にダウンしているのか、単にケーブルが抜けただけなのか判断できないことがあります(スプリットブレイン)
- このとき、「相手の電源を強制的に切断(STONITH: Shoot The Other Node In The Head)」 して、データの破損(両方のノードが同時にディスクに書き込む事故)を物理的に防ぎます。
構築するシステム構成と前提条件
本記事では、以下の構成で Web サーバーの HA クラスタを構築します。 シンプルですが、実用的な Active/Standby 構成の基本形です。


構成: Web サーバー2台(Active/Standby) + 共有ストレージ
- ノード(サーバー)
-
RHEL 9 / AlmaLinux 9 などを2台用意します。
- node01 (Active): 通常時にサービスを提供する稼働系。
- node02 (Standby): node01 がダウンした時に代わりを務める待機系。
- 共有ストレージ
-
- 両方のノードから同時に読み書き可能なディスク領域です(iSCSI や Fibre Channel など)
- Web コンテンツ(HTMLファイルなど)をここに保存します。
- 提供するサービス(リソース)
-
- VIP(仮想 IP): クライアントがアクセスする IP アドレス (例: 192.168.1.100)
- Apache(httpd): Web サーバーソフト
- Filesystem: 共有ストレージを
/var/www/htmlなどにマウントする設定
前提設定: ホスト名解決、Firewalld、時刻同期の重要性
Pacemaker をインストールする前に、OS レベルで以下の準備を完了させておく必要があります。これらが不完全だと、クラスタは正常に動作しません。
クラスタを構成するノード同士が、互いのホスト名(node01, node02)で正しく通信できるようにします。DNS でも構いませんが、障害時の確実性を高めるため /etc/hosts に静的に記述することを推奨します。
# 全ノードの /etc/hosts に追記
192.168.1.101 node01
192.168.1.102 node02Corosync によるノード間通信と、Pacemaker の管理用通信を許可する必要があります。RHEL系では firewalld の「high-availability」サービスを許可するのが簡単です。
# 全ノードで実行
firewall-cmd --permanent --add-service=high-availability
firewall-cmd --reloadこれは非常に重要です。 ノード間で時刻がずれていると、ログの解析が困難になるだけでなく、クラスタが誤動作を起こして予期せぬフェイルオーバーが発生する原因になります。chrony などを使い、NTP サーバーと確実に同期させてください。
検証環境であれば、トラブルを避けるために一時的に Permissive または Disabled に設定するのも一つの手です。本番環境では適切にポリシーを設定して運用することを推奨します。
Pacemaker/Corosync のインストールとクラスタ作成
構成が決まったら、いよいよ構築作業に入ります。 RHEL 9 / AlmaLinux 9 系では、pcs コマンドを使うことで設定ファイルの直接編集を避け、対話的にセットアップが可能です。
インストールとサービスの起動
まずは両方のノード(node01, node02)で必要なパッケージをインストールし、サービスを起動します。
# 【両方のノードで実行】
# HAクラスタ関連のパッケージグループをインストール
dnf install -y pcs pacemaker corosync fence-agents-all
# pcsデーモンを起動・自動起動設定
systemctl enable --now pcsdクラスタ認証とセットアップ
ここからは片方のノード(node01)からの操作だけで、両方の設定を一括で行えます。これが pcs のすごく便利なところです。
まずは、クラスタを管理するための専用ユーザー hacluster(インストール時に自動作成されます)のパスワードを設定します。
# 【両方のノードで実行】
passwd hacluster
# (任意のパスワードを設定してください)次に、node01 から両ノードの認証を行います。
# 【node01 で実行】
# 両ノードを認証(先ほど設定した hacluster のパスワードを入力)
pcs host auth node01 node02 -u hacluster認証が成功したら、クラスタを作成・起動します。
# 【node01 で実行】
# クラスタ定義の作成(クラスタ名: mycluster)
pcs cluster setup mycluster node01 node02
# クラスタサービスの起動と自動起動設定(--all で全ノード一括操作)
pcs cluster start --all
pcs cluster enable --allクラスタの状態確認
正常に起動したか確認してみましょう。
# ステータス確認
pcs status出力結果で Cluster Summary の Online: に node01 と node02 の両方が表示されていれば、クラスタの土台は完成です。
リソースの登録とグループ化(pcsコマンド実践)
土台ができたら、いよいよ Pacemaker に「何を動かすのか」を教えていきます。 ここからは、すべての設定コマンドを node01(片方のノード) だけで実行すれば OK です。自動的に全ノードに同期されます。
STONITH(ストニスイ)設定について
まず最初に、安全装置である STONITH(フェンシング)の設定を行います。
- 本番環境での重要性
-
STONITH(Shoot The Other Node In The Head)は、応答しなくなったノードの電源を強制的に切断する機能です。これがないと、故障した(と見なされた)ノードがまだ動いていた場合、両方のノードが同時に共有ディスクに書き込みを行い、データが破損(スプリットブレイン) する大事故に繋がります。本番環境では、IPMI や物理スイッチと連携した STONITH 設定が必須です。
- 今回の設定(検証用)
-
今回は物理的な電源管理装置がない検証環境を想定しているため、例外的にこの機能を無効化(false) します。
# STONITH機能を無効化(検証環境のみ!) pcs property set stonith-enabled=false
各リソースの作成
Web サーバーを動かすために必要な3つの要素を、それぞれ Pacemaker に登録していきます。 なお、コマンド内の op monitor は「死活監視の間隔」を指定するおまじないです。
Web コンテンツ(HTML ファイルなど)が保存されている共有ディスクをマウントします。 ※ /dev/sdb は環境に合わせて変更してください。
# リソース名「HttpdFS」を作成
pcs resource create HttpdFS ocf:heartbeat:Filesystem \
device="/dev/sdb" \
directory="/var/www/html" \
fstype="xfs" \
op monitor interval=10sクライアントがアクセスするための「浮いている IP アドレス」です。 ※ 192.168.1.100 は環境に合わせて変更してください。
# リソース名「VirtualIP」を作成
pcs resource create VirtualIP ocf:heartbeat:IPaddr2 \
ip=192.168.1.100 \
cidr_netmask=24 \
op monitor interval=10sWeb サーバーソフト本体です。RHEL 9 系では Systemd 経由で制御するのが標準的です。 ※ 事前に dnf install httpd が完了している必要があります。
# リソース名「WebServer」を作成
pcs resource create WebServer systemd:httpd \
op monitor interval=10sこれらを「リソースグループ」にまとめて連動させる
今のままだと、3つのリソースがバラバラに起動してしまいます(例:ディスクをマウントする前に Apache が起動してエラーになる、など)。 これらを「同じノードで」「決まった順番で」起動させるために、リソースグループを作成します。
# グループ名「WebGroup」を作成し、3つのリソースを追加
# 追加順 = 起動順 になります(重要!)
pcs resource group add WebGroup HttpdFS VirtualIP WebServer


ポイント: グループに追加した順序(Filesystem → VIP → WebServer)で起動し、停止するときはその逆順(WebServer → VIP → Filesystem)で停止します。この制御を Pacemaker が全自動でやってくれるのです。
設定の確認
最後に、意図通りに登録されたか確認します。
pcs status出力結果で、Resource Group: WebGroup の下に3つのリソースが並び、全て Started node01 (または node02)になっていれば成功です。
動作検証: フェイルオーバー体験
最後に、作成したクラスタが期待通りに動くか、実際に障害を起こしてテストしてみましょう。
ステータス確認(pcs status)の見方
まずは正常時の状態を目に焼き付けておきます。
[root@node01 ~]# pcs status
...
Online: [ node01 node02 ]
Full list of resources:
Resource Group: WebGroup
HttpdFS (ocf::heartbeat:Filesystem): Started node01
VirtualIP (ocf::heartbeat:IPaddr2): Started node01
WebServer (systemd:httpd): Started node01- Online:
[ node01 node02 ]と表示され、両方のノードが正常に通信できているか。 - Started: 全てのリソースが 同じノード(今回は node01) で起動しているか。
手動スイッチオーバー(pcs resource move)
まずはコマンドを使って、安全にリソースを隣のノードへ引っ越しさせてみます。メンテナンス時によく使う手順です。
# WebGroup を node02 へ移動させる
pcs resource move WebGroup node02再度 pcs status を確認し、すべてが Started node02 になっていれば成功です。
move コマンドは、実は「今のノード(node01)では起動禁止!」という強い制約(Ban)を裏で作っています。 このままだと、将来 node02 が故障しても node01 に戻れなくなってしまいます。移動が終わったら必ず以下のコマンドで制約を解除してください。
疑似障害テスト(プロセス Kill / ノード停止)
では、いよいよ本番さながらの障害テストです。
現在稼働しているノード(Active)で、Apache のプロセスを無理やり Kill します。
# プロセスIDを確認して kill
kill -9 `pgrep httpd`期待する動作:
- Pacemaker が「おっ、Webサーバーが消えたぞ」と検知(Monitor)
- その場での再起動を試みる(Restart)
- それでもダメなら、諦めて隣のノードへ逃げる(Failover)



pcs status を連打して監視していると、一瞬 FAILED と表示された後、自動的に復旧する様子が見られるはずです。
もっと過激に、稼働系ノード(node01)を強制停止させます。
# node01 で実行(クラスタサービスを強制停止)
pcs cluster stop node01
# または、OSごと再起動してもOK
reboot期待する動作:
残った node02 が「相方が死んだ!」と判断し、すべてのリソース(VIP, Disk, Web)を引き継いで Started node02 になります。 クライアント(PC)から Web ブラウザで VIP にアクセスし続けてみてください。数秒〜数十秒の断絶の後、再びページが表示されれば成功です。
まとめ
本記事では、RHEL 9 / AlmaLinux 9 世代の標準技術である Pacemaker + Corosync を使い、Web サーバーの HA クラスタを構築しました。
- 脱 Heartbeat: 現代の Linux では Corosync が通信の土台を支えています。
- pcs コマンド: 複雑な設定ファイルを書かなくても、コマンドだけで安全に構築・運用が可能です。
- リソースグループ: VIP、ディスク、アプリをひとまとめにすることで、整合性を保ったまま切り替えられます。
以上、最後までお読みいただきありがとうございました。


