CorosyncとPacemakerでフェイルオーバー構成を作る方法

## 記事の内容は？

この記事では、CorosyncとPacemakerを用いてフェイルオーバー構成を作る具体的な手順を紹介します。

## 読者の想定は？

- フェイルオーバー構成を作りたい人
- Linuxに関する基礎知識のある人
- ネットワークに関する基礎知識のある人

## システム構成は？

### Webサーバー

- **Apache**を用いたWebサーバーが2台存在します

### クラスタリング

- **Corosync**と**Pacemaker**により、互いに死活監視を行います

### アクティブ・スタンバイ構成

- 常に1つのサーバーが**アクティブ**で、もう1つのサーバーが**スタンバイ**です
- アクティブ側のみ**仮想IPアドレス**を割り振ります
- アクティブ側のみ**Apache**を起動させます

### ユーザーアクセス

- ユーザーは**仮想IPアドレス**でWebサーバーにアクセスします

### フェイルオーバー

- アクティブ側に障害が発生した場合、スタンバイ側に**フェイルオーバー**します

### システム構成図

SERVER01がアクティブ、SERVER02がスタンバイの状態を表しています。

![システム構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3753173/e49bf952-7eaa-eb70-9a4d-448fbbdafaa0.png)

## 前提とする環境は？

- Lubuntu 22.04.4
- Apache 2.4.52
- Corosync 3.1.6
- Pacemaker 2.1.2
- PCS 0.10.11

## 構築手順は？

### 1. パッケージのインストール

必要なパッケージをインストールします。
両方のサーバーで実施します。

```bash
$ apt install apache2 corosync pacemaker pcs resource-agents
```

### 2. サービスの起動設定

クラスタリング関連サービスの自動起動を有効化します。
両方のサーバーで実施します。

```bash
$ systemctl enable pacemaker
$ systemctl enable corosync
$ systemctl enable pcsd
```

### 3. クラスタ構成の定義

クラスタ構成の定義ファイルを作成します。
両方のサーバーで実施します。

```bash:/etc/corosync/corosync.conf
totem {
    version: 2
    secauth: off
    cluster_name: hacluster
    crypto_cipher: none
    crypto_hash: none
    rrp_mode: active

    interface {
        ringnumber: 0
        bindnetaddr: 192.168.10.0
        mcastport: 5405
        ttl: 1
    }
    transport: udpu
}

nodelist {
    node {
        name: SERVER01
        ring0_addr: 192.168.10.155
        nodeid: 1
    }
    node {
        name: SERVER02
        ring0_addr: 192.168.10.156
        nodeid: 2
    }
}

quorum {
    provider: corosync_votequorum
    expected_votes: 2
}

logging {
    to_logfile: yes
    to_syslog: yes
    logfile: /var/log/cluster/corosync.log
}
```

Corosyncを再起動して設定内容を反映させます。

```bash
$ systemctl restart corosync
```

### 4. クラスタの認証処理

クラスタ管理用ユーザーのパスワードを設定します。
両方のサーバーで実施します。

```bash
$ passwd hacluster
```

クラスタ管理用ユーザーを認証します。
片方のサーバーで実施します。

```bash
# haclusterユーザーのパスワードをpasswordとした場合
$ pcs cluster auth -u hacluster -p password
```

以下の実行結果のように、両方のサーバーで認証ができれば成功です。

```bash:実行結果
SERVER01: Not authorized
SERVER02: Not authorized
Nodes to authorize: SERVER01, SERVER02
SERVER02: Authorized
SERVER01: Authorized
```

### 5. クラスタの起動

クラスタを起動します。
片方のサーバーで実施します。

```bash
$ pcs cluster start --all
```

### 6. クラスタの設定変更

クラスタの設定を変更します。
片方のサーバーで実施します。

```bash
$ pcs property set stonith-enabled=false
$ pcs property set no-quorum-policy=ignore
```

### 7. リソースの設定

リソースの設定をします。
片方のサーバーで実施します。

仮想IPアドレスのリソースを作成します。
オプション(ip, cidr_netmask, nic)の値は自身の環境に合わせてください。

```bash
# 仮想IPアドレスのリソース作成
$ pcs resource create vip ocf:heartbeat:IPaddr2 \
>     ip=192.168.10.150 cidr_netmask=24 nic=enp0s8 \
>     op monitor interval=30s
```

Apacheのリソースを作成します。

```bash
# Apacheのリソース作成
$ pcs resource create web ocf:heartbeat:apache \
>     configfile=/etc/httpd/conf/httpd.conf statusurl="http://127.0.0.1/server-status" \
>     op monitor interval=30s
```

リソースをグループに追加します。

```bash
$ pcs resource group add failover vip web
```

最後に、リソースに3回異常があったらフェイルオーバーするよう設定変更します。

```bash
$ pcs resource defaults update migration-threshold=3
```

### 8. クラスタの状態監視

クラスタの状態を監視します。

```bash
$ crm_mon -fA
```

ここまでの手順が成功している場合、以下のような実行結果になります。

![クラスタ監視1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3753173/752cfb1a-dd54-61db-265e-cf9b70322bc6.png)

SERVER01に仮想IPアドレスが割り振られ、Apacheが起動していることが確認できます。
以降の動作確認は、クラスタの状態監視をしながら実施すると動きが分かりやすいです。

### 9. フェイルオーバーの確認

仮想IPアドレスでApacheにアクセスできることを確認します。
その際、SERVER01にアクセスログが出力されることも確認します。

![Apacheアクセス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3753173/aecc29dc-7f68-c77a-1bf5-e521d6eae278.png)

SERVER01で動作しているApacheのプロセスを `kill` コマンドで削除します。
これを3回繰り返すとフェイルオーバーします。

![クラスタ監視2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3753173/5f70199f-f19d-bcdd-ca07-e5d1fe231361.png)

リソースがSERVER02に切り替わっていることが確認できます。
また、再度仮想IPアドレスでApacheにアクセスすると、SERVER02にアクセスログが出力されることも確認できます。

### 10. 復旧

現在、クラスタはSERVER01に異常があると認識しています。
そのため、次にSERVER02に異常が発生した際、SERVER01へフェイルオーバーすることができません。

SERVER01に異常がないことを確認できた場合はリソースのクリーンアップを行います。

```bash
$ pcs resource cleanup
```

これにより、クラスタはSERVER01の異常が取り除かれたことを認識し、次にSERVER02で異常があった際はSERVER01へフェイルオーバーします。

## エラーが発生した場合は？

エラーが発生した際はログを見るようにしましょう。
ログファイルのパスも環境に応じて変わりますが、多くの場合は `/var/log` の配下にあります。

この記事の環境下でのログファイルのパスは以下のとおりです。

- Apacheのアクセスログ: /var/log/apache2/access.log
- Apacheのエラーログ: /var/log/apache2/error.log
- Corosyncのログ: /var/log/corosync/corosync.log
- Pacemakerのログ: /var/log/pacemaker/pacemaker.log
- PCSのログ: /var/log/pcsd/pcsd.log

ログを見てもわからない場合はChatGPTなどの生成AIを利用してください。
細かい設定変更の意味や意図についても生成AIに尋ねると良いと思います。