Pacemaker Booth を用いたディザスタリカバリ

Booth は、Pacemaker で物理ネットワークが異なるサイト間のクラスタ管理を行うアドオン機能で、サイトにチケットを付与することで、リソースが稼働するサイトを制御します。Booth を使うことで災害対策として遠隔地サイトにまたがるクラスタを実現できます。

本記事では、Booth の概要、インストール・設定方法、基本的な使い方について紹介します。

Booth とは

Pacemaker は WAN 経由で複数のサイトのクラスタ状態を管理できないため、サイトの障害やサイト間のネットワークに問題が発生した場合には、別のサイトが稼働中であるかどうかは Pacemaker が判断できません。各サイトの状態の確認およびサイト間の切り替えは人間の判断で行うか、クラスタチケット管理 (CTR) 機能を用いて自動的に行います。

CTR 機能を使うと、マルチサイトクラスタにおいて、チケットが付与されたサイトが稼働系になり、そのチケットに依存するリソースを起動する権限が与えられます。
チケットが取り消された場合は、サイトが待機系に切り替わり、そのチケットに依存するリソースが停止状態になります。

Pacemaker で CTR を実現するには、アドオン機能である Booth を導入する必要があります。

Booth を利用することで、地理的に離れた複数のサイトを跨いでチケット管理を行うことができ、チケットを付与/取り消しすることで、サイト間での稼働系/待機系の切り替えや自動フェイルオーバ、リソースの起動/停止を制御することが可能になります。

Booth によるチケット管理の仕組み

Booth を用いたマルチサイトクラスタ環境では、通常のサイト (稼働系サイト/待機系サイト) に加えて、アービトレータ (調停役) と呼ばれるもう1つのサイト (1つのノード) を追加する必要があります。

ネットワーク障害等によりサイト間の通信が途絶えた場合には、別のサイトの障害なのか、サイト間のネットワークの障害なのかを区別する方法はないため、スプリットブレインに陥る可能性があります。これはクラスタ環境での固有の問題となります。そのため、フェイルオーバなどの決定について多数決による合意形成のために3つのサイトが必要です。3つ目のサイト (アービトレータ) を導入することで、合意形成によってサイト間のフェイルオーバーを制御することができ、スプリットブレインに陥ることを防ぎます。

以下はマルチサイトクラスタの基本的な構成となります。

両方のサイトおよびアービトレータで boothd デーモンが起動しており、お互い通信し、情報交換します。稼働系のサイトに障害が発生した場合、Booth の合意形成によって待機系のサイトにチケットを付与し、待機系のサイトを自動的に稼働系に昇格させます。

Booth を利用することで、チケット管理の自動化ができ、複数の拠点にまたがるマルチサイトクラスタでの自動フェイルオーバが可能になり、ダウンタイムを最小限に抑えることができます。

クラスタ構成

本記事では、2つのクラスタサイト (2ノード構成) および1つのアービトレータを含むマルチサイトクラスタを構築します。

クラスタ構成は以下になります。

仮想IP ホスト名 IPアドレス
サイトA 192.168.101.100 clusterA-1 192.168.101.101
clusterA-2 192.168.101.102
サイトB 192.168.102.100 clusterB-1 192.168.102.101
clusterB-2 192.168.102.102
サイトC 192.168.100.100 arbitrator

仮想IPは Booth 間通信で利用されるIPアドレスとなります。

前提条件

  • 今回は検証目的で RHEL クローン OS の Rocky Linux 環境を用いて検証を行います。Rocky Linux では Red Hat High Availability Add-On 相当のパッケージが HighAvailability リポジトリに含まれているため、今回はそちらのリポジトリを利用してインストールします。バージョン情報は以下になります。
OS Rocky Linux 8.6
Pacemaker 2.1.2
Corosync 3.1.5
PCS 0.10.12
Booth 1.0
  • アービトレータを含むすべてのノードの /etc/hosts にノード情報が登録されています。
(両サイトのすべてのノードおよびアービトレータで実行)
# vi /etc/hosts
(以下を追加)
192.168.101.101 clusterA-1
192.168.101.102 clusterA-2
192.168.102.101 clusterB-1
192.168.102.102 clusterB-2
192.168.100.100 arbitrator

Pacemaker のインストールおよびクラスタの初期設定

ここでは、Pacemaker のインストールおよびクラスタの初期設定の手順を記載します。

1. Pacemaker をインストールします。

両サイトのすべてのノードで Rocky Linux の HighAvailability リポジトリを有効にして Pacemaker をインストールします。

(両サイトのすべてのノードで実行)
# yum install -y --enablerepo=ha pacemaker pcs fence-agents-all

RHEL 環境を利用している場合は、Red Hat 社によって提供される Red Hat High Availability Add-On のパッケージを利用してインストールしてください。詳細についてはこちらを参照してください。

2. firewalld デーモンが起動している場合は、クラスタで必要なポートを有効化するように以下のコマンドを実行します。

(両サイトのすべてのノードおよびアービトレータで実行)
# firewall-cmd --permanent --add-service=high-availability
# firewall-cmd --reload

3. 両サイトのすべてのノードで hacluster ユーザのパスワードを設定します。

(両サイトのすべてのノードで実行)
# passwd hacluster
Changing password for user hacluster.
New password: (haclusterユーザのパスワードを入力)
Retype new password: (haclusterユーザのパスワードを入力)
passwd: all authentication tokens updated successfully.

4. 両サイトのすべてのノードで以下のコマンドを実行し、pcsd の自動起動を有効化します。

(両サイトのすべてのノードで実行)
# systemctl start pcsd.service
# systemctl enable pcsd.service

5. 両サイトでクラスタを構成するノードに対して、hacluster ユーザの認証を行います。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs host auth clusterA-1 clusterA-2 -u hacluster
Password: (haclusterユーザのパスワードを入力)
clusterA-1: Authorized
clusterA-2: Authorized
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs host auth clusterB-1 clusterB-2 -u hacluster
Password: (haclusterユーザのパスワードを入力)
clusterB-1: Authorized
clusterB-2: Authorized

6. 両サイトでクラスタを作成します。それぞれの名前を clusterA、clusterB とします。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs cluster setup clusterA clusterA-1 clusterA-2
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs cluster setup clusterB clusterB-1 clusterB-2

7. 両サイトでクラスタを起動します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs cluster start --all
[root@clusterA-1 ~]# pcs status
Cluster name: clusterA
...
Node List:
* Online: [ clusterA-1 clusterA-2 ]
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs cluster start --all
[root@clusterB-1 ~]# pcs status
Cluster name: clusterB
...
Node List:
* Online: [ clusterB-1 clusterB-2 ]

8. クラスタを安全に運用するために、フェンシングの設定が必要になりますが、今回は Booth によるマルチサイトクラスタを説明することを目的としているため、以下のコマンドを実行し、フェンシングを無効にします。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs property set stonith-enabled=false
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs property set stonith-enabled=false

9. 両サイトで検証用のリソースグループを作成します。今回は、Apache および IPaddr2 を含むリソースグループを作成します。作成手順はこちらを参照してください。

リソースが作成されていることを確認します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs status
Cluster name: clusterA
...
Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Started clusterA-1
    * VIP       (ocf::heartbeat:IPaddr2):        Started clusterA-1
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs status
Cluster name: clusterB
...
Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Started clusterB-1
    * VIP       (ocf::heartbeat:IPaddr2):        Started clusterB-1

以上で、Pacemaker クラスタの初期設定は完了です。

Booth のインストールおよび設定

ここでは、Booth のインストールおよび設定手順を記載します。

1. Booth をインストールします。

両サイトのすべてのノードに booth-core および booth-site パッケージをインストールします。

(両サイトのすべてのノードで実行)
# yum install -y --enablerepo=ha booth-site booth-core

アービトレータノードに pcs、booth-core、および booth-arbitrator パッケージをインストールします。

(アービトレータノードで実行)
[root@arbitrator ~]# yum install -y --enablerepo=ha pcs booth-core booth-arbitrator

2. Booth の設定を行います。

Booth の設定やチケットは、まず片方のサイトで 作成した後、すべてのクラスタノードおよびアービトレータで設定の同期を行うという流れになります。
今回は、まずサイトAのノード1で設定を行います。

サイトAのノード1で以下のコマンドを実行し、Booth の設定を行います。
sites に各サイトの仮想IP、arbitrators にアービトレータノードのIPアドレスを指定します。

(サイトAのノード1で実行)
[root@clusterA-1 ~]# pcs booth setup sites 192.168.101.100 192.168.102.100 arbitrators 192.168.100.100

3. チケットを作成します。

サイトAのノード1でチケットを作成します。

(サイトAのノード1で実行)
[root@clusterA-1 ~]# pcs booth ticket add apacheticket expire=120 acquire-after=60 timeout=5

それぞれのオプションの意味は以下の通りです。

  • timeout: Booth 間パケット送信のタイムアウト時間。
  • expire: 通信が失敗した後のチケットの有効期限。有効期限を過ぎるとチケットが取り消される (revoke)。
  • acquire-after: チケットが取り消された後、他のサイトに付与されるまでの時間。

Booth の設定は /etc/booth/booth.conf ファイルに書き込まれます。
現在の設定を確認するには pcs booth config を実行します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth config
authfile = /etc/booth/booth.key
site = 192.168.101.100
site = 192.168.102.100
arbitrator = 192.168.100.100
ticket = "apacheticket"
  acquire-after = 60
  expire = 120
  timeout = 5

その他の設定オプションについてはこちらを参照してください。

4. 現在のクラスタのすべてのノードに対して Booth 設定の同期を行います。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth sync
Sending booth configuration to cluster nodes...
clusterA-1: Booth config saved
clusterA-2: Booth config saved

5. アービトレータノードで Booth 設定を同期します。

(アービトレータノードで実行)
[root@arbitrator ~]# pcs host auth clusterA-1 -u hacluster
Password: (haclusterユーザのパスワードを入力)
clusterA-1: Authorized
(アービトレータノードで実行)
[root@arbitrator ~]# pcs booth pull clusterA-1
Fetching booth config from node 'clusterA-1'...
Booth config saved

6. サイトBで Booth 設定を同期します。

(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs host auth clusterA-1 -u hacluster
Password: (haclusterユーザのパスワードを入力)
clusterA-1: Authorized
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs booth pull clusterA-1

[root@clusterB-1 ~]# pcs booth sync

7. アービトレータノードで Booth を起動します。

サイトAおよびサイトBでは、Booth は Pacemaker のリソースとして管理され、Pacemakerによって起動するため、各クラスタノードで Booth を手動で起動しないでください。

(アービトレータノードで実行)
[root@arbitrator ~]# pcs booth start
[root@arbitrator ~]# pcs booth enable

8. 両サイトで Booth リソースを作成します。IPアドレスにそれぞれのクラスタの仮想IPを指定します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth create ip 192.168.101.100
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs booth create ip 192.168.102.100

上記コマンドを実行すると、booth-ip および booth-service を含むリソースグループ booth-booth-group が作成されます。

9. 両サイトで作成した検証用のリソースグループ apachegroup にチケット制約を追加します。

チケット制約とは、チケットがクラスタサイトに付与された場合にのみ、リソースの起動を許可する制約となります。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs constraint ticket add apacheticket apachegroup
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs constraint ticket add apacheticket apachegroup

上記チケット制約を追加すると、apachegroup のリソースが Stopped になり、チケットが付与されるまで起動しません。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs status
Cluster name: clusterA
...
Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Stopped
    * VIP       (ocf::heartbeat:IPaddr2):        Stopped
  * Resource Group: booth-booth-group:
    * booth-booth-ip    (ocf::heartbeat:IPaddr2):        Started clusterA-2
    * booth-booth-service       (ocf::pacemaker:booth-site):     Started clusterA-2
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs status
Cluster name: clusterB
...
Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Stopped
    * VIP       (ocf::heartbeat:IPaddr2):        Stopped
  * Resource Group: booth-booth-group:
    * booth-booth-ip    (ocf::heartbeat:IPaddr2):        Started clusterB-2
    * booth-booth-service       (ocf::pacemaker:booth-site):     Started clusterB-2

現在設定されているチケット制約確認するには、pcs constraint ticket を実行します。

10. 片方のサイトにチケットを付与します。

ここでは、サイトAを稼働系にするために、サイトAのいずれかのノードで以下のコマンドを実行し、チケットを付与します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth ticket grant apacheticket

サイトAのクラスタにチケットを付与すると、サイトAのクラスタのリソースが起動します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs status
Cluster name: clusterA
...
Node List:
  * Online: [ clusterA-1 clusterA-2 ]

Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Started clusterA-1
    * VIP       (ocf::heartbeat:IPaddr2):        Started clusterA-1
  * Resource Group: booth-booth-group:
    * booth-booth-ip    (ocf::heartbeat:IPaddr2):        Started clusterA-2
    * booth-booth-service       (ocf::pacemaker:booth-site):     Started clusterA-2

サイトBでは、チケットが付与されていないため、リソースが Stopped のままの状態となります。

(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs status
Cluster name: clusterB
...
Node List:
  * Online: [ clusterB-1 clusterB-2 ]

Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Stopped
    * VIP       (ocf::heartbeat:IPaddr2):        Stopped
  * Resource Group: booth-booth-group:
    * booth-booth-ip    (ocf::heartbeat:IPaddr2):        Started clusterB-2
    * booth-booth-service       (ocf::pacemaker:booth-site):     Started clusterB-2

以上で、Booth の設定は完了です。

Booth の基本的な使い方

Booth クラスタの状態の確認

現在の稼働系サイト、チケットや Booth 間の接続詳細情報などを確認するには、pcs booth status を実行します。

(いずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth status
TICKETS:
ticket: apacheticket, leader: 192.168.101.100, expires: 2022-08-17 13:07:03

PEERS:
site         192.168.102.100, last recv: 2022-08-17 13:05:03
        Sent pkts:13 error:0 resends:0
        Recv pkts:12 error:0 authfail:0 invalid:0

arbitrator   192.168.100.100, last recv: 2022-08-17 13:05:03
        Sent pkts:13 error:0 resends:0
        Recv pkts:12 error:0 authfail:0 invalid:0

フェイルオーバ

稼働系サイトに障害が発生した場合の自動フェイルオーバを検証します。

稼働系サイトAのクラスタを停止します。

(サイトAのいずれかのノードで実行)
[root@clusterA-1 ~]# pcs cluster stop --all

しばらくすると、サイトBにチケットが付与され、リソースが起動することを確認します。

(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs booth status
TICKETS:
ticket: apacheticket, leader: 192.168.102.100, expires: 2022-08-17 13:21:10

PEERS:
site         192.168.101.100, last recv: 2022-08-17 13:12:04
        Sent pkts:86 error:0 resends:49
        Recv pkts:26 error:0 authfail:0 invalid:0

arbitrator   192.168.100.100, last recv: 2022-08-17 13:19:09
        Sent pkts:13 error:0 resends:0
        Recv pkts:12 error:0 authfail:0 invalid:0
(サイトBのいずれかのノードで実行)
[root@clusterB-1 ~]# pcs status
Cluster name: clusterB
...
Node List:
  * Online: [ clusterB-1 clusterB-2 ]

Full List of Resources:
  * Resource Group: apachegroup:
    * WebSite   (ocf::heartbeat:apache):         Started clusterB-1
    * VIP       (ocf::heartbeat:IPaddr2):        Started clusterB-1
  * Resource Group: booth-booth-group:
    * booth-booth-ip    (ocf::heartbeat:IPaddr2):        Started clusterB-2
    * booth-booth-service       (ocf::pacemaker:booth-site):     Started clusterB-2

サイトBに以下のようなログが出力され、チケットがサイトBに付与されていることが分かります。

Aug 17 13:15:03 clusterB-2 booth: [4088]: warning: apacheticket (Fllw/0/0): lost at 192.168.101.100
Aug 17 13:15:04 clusterB-2 booth: [4088]: info: apacheticket (Fllw/1/0): starting new election (term=1)
Aug 17 13:15:09 clusterB-2 booth: [4088]: info: apacheticket (Cndi/1/0): elections finished
Aug 17 13:15:09 clusterB-2 booth: [4088]: info: apacheticket (Lead/1/119997): granted successfully here

手動でフェイルオーバさせたい場合には、稼働系でチケットの取り消し (revoke) した後、待機系に付与 (grant) するという流れになります。

例えば、サイトAが稼働系の場合は、まず、サイトAからチケットを取り消します。
サイトの仮想IPを明示的に指定して pcs booth ticket revoke/grant を実行する場合は、どちらのノードでも実行可能です。

(いずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth ticket revoke apacheticket 192.168.101.100

次に、待機系サイトBにチケットを付与します。

(いずれかのノードで実行)
[root@clusterA-1 ~]# pcs booth ticket grant apacheticket 192.168.102.100

サイトBにチケットを付与すると、サイトBが稼働系になり、リソースが起動します。

マルチサイトクラスタにおける DRBD の使用

マルチサイトクラスタで DRBD を使用する場合には、DRBD のデータを WAN を介して待機系サイトにレプリケーションする仕組みが必要になります。

DRBD Proxy を使うことで、WAN 環境のような遠距離レプリケーションを効率的に行えます。DRBD Proxy は LINBIT 社が提供している有償オプション製品であり、詳細についてはこちらを参照してください。

おわりに

今回は、Pacemaker のアドオン機能 Booth を用いてマルチサイトクラスタの構築・設定方法や基本的な使い方について紹介しました。

Booth を使うことで、地理的に離れた複数の拠点にまたがる高可用性クラスタを構築できます。システムの高可用性や災害対策を検討している方に、本記事の内容がお役に立てれば幸いです。