[KE16] AWS での冗長構成の構築ガイドライン
# 1. はじめに
AWS 上で Kompira enterprise（以下Kompira）の冗長構成の構築を計画するときに検討すべき点や、構築する際の手順について説明します。

## 1.1. 変更履歴
| 日付 | 版数 | 担当 | 備考 |
| --- | --- | --- | --- |
| 2021/10/05 | 1.0 | FP根岸 | 初版 |
| 2021/10/07 | 1.1 | FP髙橋 | 「3.3.8. pacemaker の自動起動設定の選択」節のタイトルを 「3.3.8. pacemaker の自動起動設定の解除」に変更 |
| 2021/10/27 | 1.2 | FP髙橋 | 「3.3.6.1. ターゲットグループの作成」の「Advanced health check settings」の設定パラメータを修正、スクリーンショット画像の差し替え<BR>「3.3.7. Stonith の設定」での説明文を変更 |
| 2021/10/29 | 1.3 | FP髙橋 | Kompira v1.6.3 でインストールスクリプトが修正されたため、対処不要となった「3.3.3.4. pacemaker の導入確認とインストールスクリプトの修正」および関連する記述を削除 |
| 2022/11/14  | 1.4 | FP髙橋 | Amazon Linux2 対応について追記<BR>サブネット間のルーティング設定について追記<BR>「2.6.1.1. 推奨値」に KE v1.6.7 で Corosync のトークン値がデフォルトで 30000 になったことを追記<BR>「3.3.3.1. 追加インターフェイスの確認」に設定手順を追記<BR>「3.3.3.2. 静的ルートの設定」に設定手順を追記 |
| 2023/02/10 | 1.5 | FP髙橋 | インスタンスの種類について、T系インスタンスの利用を避けるように変更<BR>「2. 事前検討」の推奨構成を変更<BR>「3.2.4. 本記事におけるインスタンスの AMI」に注意書きを追記 |
| 2023/07/27 | 1.6 | FP髙橋 |「2.6.2.3. PROXY 環境下における STONITH の利用」「3.1.4. PROXY サーバの準備」「3.3.7.1. Pacemaker への PROXY の設定」を追加  |


## 1.2. 対象環境
- Kompira enterprise: v1.6.2 以上
- OS:
    - Red Hat Enterprise Linux (RHEL): 8.4 以上（推奨）または 7.9 以上（代替）
    - CentOS: Strem 8 以上（代替）または 7.6 以上（代替）
    - Amazon Linux 2（代替）（Kompira enterprise v1.6.7 以上でサポート）

上記OSは、本記事執筆時においてAWS上に存在し、動作確認を行ったAMIのOSバージョンを基準としています。

本記事では、以下のAMIを利用して動作確認を行っています。

| AMI (AMI名) | AMI ID |
| --- | --- |
| CentOS 8 (x86_64) - with Updates HVM<br>(CentOS-8-ec2-8.2.2004-20200923-1.x86_64-471d022d-974f-4f9c-8e39-b00d9b583833-ami-03b6a1d995f5a5146.4) | ami-01d5ac8f5f8804300 |
| CentOS 7 (x86_64) - with Updates HVM<br>(CentOS-7-20200923-2003.x86_64-d9a3032a-921c-4c6d-b150-bde168105e42-ami-0c5a39cd417835870.4) | ami-02cae3195fa1622a8 |
| Red Hat Enterprise Linux 8.4 with High Availability<br>(RHEL_HA-8.4.0_HVM-20210504-x86_64-2-Hourly2-GP2) | ami-0b2e47f3b2e23d235 |
| Red Hat Enterprise Linux 7 with High Availability<br>(RHEL_HA-7.9_HVM-20210315-x86_64-2-Hourly2-GP2) | ami-0dd38e30236fe14ea |

また、RHELについては、HA add-on が付属した AMIを利用する事を前提としています。
既存HAサブスクリプションをAWSに持ち込むことも可能ですが、本記事の対象外です。

## 1.3. 注意事項
- 2021/09 時点でのAWSの仕様を前提としています。

## 1.4. 制限事項
AWS 環境で冗長構成を構築するうえで、現時点では以下の制限事項が有ります。

- リージョンをまたいだ冗長構成には対応していません。
- VPCをまたいだ冗長構成には対応していません。
- VIP方式のアクセス振り分けには対応していません。

## 1.5. サポートポリシー
以下に該当する場合は、冗長構成としてのすべてもしくは一部の機能がサポート対象外となります。

- 2 台のインスタンスのOSの種類とバージョンが同一で無い場合
- 2 台のインスタンスの種類や構成が同一で無い場合
- 異なるVPCに配置した インスタンス 間で冗長構成を構築した場合
- インスタンス間通信にパブリックIPアドレスを用いて冗長構成を構築した場合（インスタンスにパブリック IP アドレスを割り当てること自体は問題ありません）
- AWS ロードバランサを利用しない場合（外部からのアクセス振り分けがサポート対象外となります）

## 1.6. 関連資料
- RHEL8 
    - [高可用性クラスターの設定および管理](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html-single/configuring_and_managing_high_availability_clusters/index)
    - [AWS での RED HAT HIGH AVAILABILITY クラスターの設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/deploying_red_hat_enterprise_linux_8_on_public_cloud_platforms/configuring-a-red-hat-high-availability-cluster-on-aws_deploying-a-virtual-machine-on-aws)
- RHEL7
    - [HIGH AVAILABILITY アドオンの概要](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html-single/high_availability_add-on_overview/index)

# 2. 事前検討
AWS 環境において冗長構成を構築する上で、事前に検討しておくべき事項を示します。

| 項目 | 選択肢・設定項目など | 推奨構成 |
| --- | --- | --- |
| OS の種類 | 1. CentOS 8.x 系 または 7.x 系<br>2. RHEL 8.x 系 または 7.x 系	| CentOS 8.x系 または RHEL 8.x 系 |
| インスタンスの種類や構成 | メモリ8GB以上 | m4.large 以上<BR><span style="color:#d86e00;">※T系インスタンスの利用は避けてください</span> |
| | なるべく高速なストレージ | SSD |
| インスタンスの配置 | リージョンの選択（東京／大阪など） | 任意 |
| | VPCとサブネットの構成 | 同一VPC内の別々のサブネットにインスタンスを配置する |
| | 可用性ゾーンを分離する/しない | 可用性ゾーンを「分離する」 |
| ネットワークの設定 | セキュリティグループ | インスタンス間の通信は「すべて透過」 |
| | ネットワークインターフェイスを追加する／しない | 任意 |
| | パブリック IP アドレスの割り当て | パブリック IP を「割り当てる」 |
| フロントエンドの設定 | AWSのLBを利用する / 独自にLBを用意する、など | AWSのLBを「利用する」 |
| ミドルウェアの設定 | Corosync の設定 | タイムアウト値を「延長する」 |
| | STONITH を設定する／しない | STONITHを「設定する」 |

## 2.1. OSの種類
どの OS を利用するかを検討してください。**ただし、冗長構成を構築する 2 台の インスタンス のOSは同一のものにしておいてください。**

<span style="color: #d86e00">※ 2台のインスタンスのOSの種類とバージョンが同一で無い場合は、サポート対象外となります。</span>

OSは以下の選択肢の組み合わせから選ぶことが出来ます。

- CentOSまたはRHEL
    - RHEL は Red Hat 社によるサポートがありますが、CentOSに比べてコストがかかります。
- 8.x 系または7.x 系
    - RHEL の場合は8.x系の利用を推奨します（冗長構成関連を含むいくつかのミドルウェアのバージョンが新しい・OS のサポート期間が長いため）。
    - CentOS の場合は、8のサポートが2021年末で終了するため、7の方が良い可能性があります。（2024年末までのサポート）

RHEL を選択される場合、冗長構成を組むサーバに Red Hat 社が提供する HA add-on が必要になります。AWS においては HA add-on が付属した AMI がいくつか用意されていますので、**HA add-on 付きの AMI を利用することを推奨します**。HA サブスクリプションを別途購入して、AWS に持ち込むことも可能かと思われますが、本記事の対象外です。

- HA 付きの RHEL 仮想マシンの価格
    - [Red Hat Enterprise Linux 8.4 with High Availability](https://aws.amazon.com/marketplace/pp/prodview-lk3liabqn4x2i?ref=cns_srchrow)
    - [Red Hat Enterprise Linux 7 with High Availability](https://aws.amazon.com/marketplace/pp/prodview-y67nt7vkcqufo?sr=0-1&ref_=beagle&applicationId=AWSMPContessa)

<span style="color: #d86e00">注意：RHEL を用いて冗長構成を構築するときに、後述する STONITH を設定していない（または有効にしていない）場合、Red Hat 社のサポート対象外になることに注意してください。</span>

- [RHEL High Availability クラスターのサポートポリシー - フェンシング/STONITH の一般的な要件](https://access.redhat.com/ja/articles/5942751)

OSの種類自体は、オンプレやローカルの仮想環境上に構築する場合と特別な要件の差異はありません。その為、OSの種類の選定は、Kompira のサポート対象OSに紐づいた検討で問題有りません。

## 2.2. インスタンス の種類や構成
どのインスタンスの種類（サイズ）を利用するか、またどういった構成をとるかについて検討してください。**ただし、冗長構成を構築する2 台のインスタンスの種類や構成は同一にしてください。**

<span style="color: #d86e00">※ 2 台のインスタンスの種類や構成が同一で無い場合は、サポート対象外となります。</span>

まず インスタンスの種類では、Kompira のハードウェア要件のうちメモリについて**「メモリ：8GB以上」**となっていることに、ご注意ください。

AWS上のインスタンスの種類としては「m4.large」が最小になります。ただし、インスタンスを作成するAMIによっては、利用できるインスタンスの種類が限定されている場合もあります。動作させるジョブフローの特性（メモリ使用量が多くなりそう、CPU負荷が高そう、など）に合わせて、利用するインスタンスの種類について検討してください。

次に インスタンスの構成として、「ディスク」についてはその**ストレージの種類としてできれば高速なもの（HDD よりは SSD）を選択することを推奨します**。Kompira はすべてのオブジェクト情報をデータベースに記録して動作するため、I/O 性能によってシステム全体の動作速度に影響を与えることがあります。

また、データベースのサイズが大きくなる見込みの場合は、追加ディスクを割り当ててそこに Postgresql のデータベースクラスターを配置する、あるいは作成済みのデータベースクラスターを移動させる、といったことを検討してください（追加ディスクの設定やデータベースクラスターの配置については本記事の対象外です）。

どのインスタンスを利用すれば・どういった構成をとれば性能面で十分であるかは一概に示すことは出来ませんので、**実運用を開始する前に実際のジョブフローでの性能評価**などを行なって、必要であればより高性能なインスタンスの種類に変更する・より高速なストレージを選択する、といったことを検討してください（OS やミドルウェアのチューニングについては本記事の対象外です）。

インスタンス の種類や構成によってコストが大きく変わりますので、非機能要件とコストのバランスを検討してください。

## 2.3. インスタンス の配置
Kompira の冗長構成はサーバ2台で構築します。それぞれのインスタンスをどのように配置するかを検討してください。具体的には、リージョンの選択、可用性ゾーンを分離するか否か、サブネットの構成などが課題となります。

※ なお、現時点では、<span style="color: #d86e00">異なるリージョンをまたいだ冗長構成には対応しておりません</span>。

### 2.3.1. リージョンの選択
まず、ご利用になるリージョンを選択してください。多くの場合は国内案件になる思いますので、東京または大阪リージョンを選択されると思います。

弊社ではインスタンスごとに可用性ゾーンをわけて冗長構成を構築することを推奨していますが、東京/大阪リージョンのどちらでも可能な構成となるので、より案件に適したリージョンを使用してください。

### 2.3.2. VPCとサブネットの検討
一般的にクラウド環境では インスタンスを配置するネットワークを指定できるようになっています。AWS であれば、大きな CIDR ブロックを割り当てた VPC 内にサブネットを作成し、インスタンスのインターフェイスにサブネットの紐づけを行います。

インスタンスを「異なるVPCの異なるサブネット」に分離して相互に通信できるようにすることも可能ですが、本記事の対象外となり、サポートも対象外となります。

**ネットワークの分離については、「同一VPCの異なるサブネット」にて行う事を推奨します**。
※ AWS上で可用性ゾーンを分離するためには、2台のインスタンスが異なるサブネットである必要があります。

インスタンスを作成したときに、ネットワークインターフェイスに紐づいたサブネットから、ローカルIPアドレスが割り当てられます（自動または手動）。インスタンス間の通信は基本的にはこのローカルIPアドレスを用いて互いに通信しますので、これがIPリーチャブルであることが必須になります。

インスタンスを異なるサブネットに配置して、インスタンス間通信用にネットワークインターフェイスを追加する場合は、OS 上で静的なルート設定を追加する必要がありますのでご注意ください。

Kompira の冗長構成において、この インスタンス間通信に利用するローカルIPアドレスは利用期間中には（インスタンス再起動などにおいても）変化しないことを想定しています。一般的には再起動などではアドレスの割り当てが変化することはないとおもいますが、利用期間中にインスタンスを停止させることが考えられる場合は、静的にアドレス割り当てることもご検討ください。

なお、ネットワークインターフェイスに割り当てたパブリックIPアドレスを用いた冗長構成も可能かもしれませんが、本記事の対象外であり、また、サポート対象外となります。

### 2.3.3. マルチAZの検討
AWS では、サブネットに対して可用性ゾーン（以下AZ)」を指定することができます。AZ はサブネットに対する指定となり、異なる AZ は同リージョン内の異なるデータセンタに配置されるため、データセンタ障害に対して高い可用性を期待することができます。
　
システム全体としての可用性向上のため、**AWS で冗長構成を構築する場合は、2つのインスタンスを異なる AZ に配置（以下マルチAZ）することを推奨します**。

ただし、マルチ AZ を利用する構成では、AZ 間の通信に若干のコストがかかるため、可用性とコストのバランスを検討してください。

- [同一の AWS リージョンでのデータ転送](https://aws.amazon.com/jp/ec2/pricing/on-demand/#Data_Transfer_within_the_same_AWS_Region)

なお、可用性をそこまで重視しない場合は、同一サブネット内に2つのインスタンスを作り、マルチAZを利用しない構成も可能であり、サポート対象となります。

本記事では、マルチAZを利用した構築手順について示します。

## 2.4. ネットワークの設定
### 2.4.1. セキュリティグループの設定
クラウド環境では仮想ネットワークや インスタンスごとのセキュリティ対策のひとつとして、特定の通信を遮断したり・透過させたりする、いわばファイアーウォールの設定ができるものがあります。Kompira の冗長構成では、**インスタンス間の通信はすべてのプロトコル・すべてのポートを通過するように設定することを推奨します**。

AWS では「セキュリティグループ」が該当します。相手のインスタンス、あるいはサブネットや VPC からの通信をすべて許可するよう設定することを検討してください。

なお、特定ポートのみを通信許可させたいといった場面もあると思いますが、その具体的な設定方法については本記事の対象外です。

### 2.4.2. ネットワークインターフェイスの追加
インスタンス間通信用のネットワークインターフェイスを追加するかを検討してください。

AWS 環境で冗長構成を構築するうえで、**インスタンス間通信用のネットワークインターフェイスを追加するかどうかは任意となります**。ただし、追加する場合は以下に注意してください。

- 2 台の インスタンス 両方にネットワークインターフェイスを追加してください。
- 追加するネットワークインターフェイスは、メインインターフェイスと同一の AZ に属するインターフェイスしか追加できません。
- マルチ AZ 環境においてインスタンス間通信用のネットワークインターフェイスを設定する場合、インスタンス間通信の為の静的ルートの設定が必要になります。
- 冗長構成のセットアップ時には、**インスタンス間通信用に追加したネットワークインターフェイスに割り当てられたローカルIPアドレスを利用してください**。

以下は、補足的な説明となります。

一般的には冗長構成ではサーバ間の通信が安定的に行われることが重要であるため、専用のネットワークインターフェイスを（できれば複数）用意してサーバ間を直結するような構成が推奨されています。これは、サーバ間以外の通信トラフィックによる影響をなるべく受けないようにすること、またネットワークインターフェイスに故障が生じても通信が継続できるようにすること、などが意図されています。

ただし、仮想化環境においては 、ネットワークインターフェイスは仮想化されていて、単独で故障する可能性は物理環境にくらべて低いと考えられます。一方で、インスタンス間の通信自体についても仮想化されていることから、仮想的なネットワーク構成を独立させていたとしても、外部の影響を受けうることは十分に考えられます。そうした影響により、冗長構成が過敏に障害であると誤検知してしまうのを軽減するために「Corosyncの設定」も参照してください。

本記事では、インスタンス 間通信用のネットワークインターフェイスを追加する場合の構築手順を示します。

### 2.4.3. パブリック IP アドレスの割り当て
各インスタンスにパブリック IPアドレスを割り当てるかを検討してください。

構築時や運用時にAWS の外部から直接インスタンス にアクセスする場合は、パブリックIPアドレスを割り当ててください。構築時のみに インスタンス への外部アクセスが必要であるような場合は、構築作業が完了したのちにパブリックIPアドレスを開放（または削除）することも可能ですが、その手順などについては本記事の対象外です。

AWSにおいて、インスタンスのネットワークインターフェイスが1つの場合、パブリックIPをインスタンス作成時に割り当てることができますが、**ネットワークインターフェイスが2つ以上の場合、インスタンス作成時にはパブリックIPを割り当てることができない為、Elastic IPを作成し、インスタンスに割り当ててください**。

本記事では、各 インスタンスのメインネットワークインターフェイスに、Elastic IP でパブリック IP アドレスを割り当てる場合の手順を示します。

## 2.5. フロントエンドの設定
Kompiraの冗長構成はアクティブ・スタンバイ方式であり、ある時点では2台のサーバのうちいずれかがアクティブ状態となり、もう一方がスタンバイ状態となります。アクティブ状態のサーバは実際にジョブフローを動作させたり、外部からブラウザでアクセスできるようになります。2台のサーバは異なるIPアドレスを持っているため、外部からアクセスするときにアクティブなサーバを判断してそのIPアドレスを指定してアクセスすることは可能ですが、これは実用性に欠けるため、何らかの方法でアクセスを振り分ける必要があります。アクセスを振り分ける代表的な方式を以下に示します。

- VIP によるアクセス振り分け
- ロードバランサによるアクセス振り分け

### 2.5.1. VIPによるアクセス振り分け
Kompira冗長構成の標準のセットアップでは、事前に用意したIPアドレス (VIP) をアクティブ状態のサーバに対して追加で付与する、という方式（VIP 方式）を用います。外部からは常にVIPを指定してアクセスすることで、その時にアクティブなサーバに対してアクセスできることになります。

しかし、クラウド環境では IP アドレスも管理対象のリソースであり、プラットフォームや構成によっては VIP を簡単には利用できないことがあります。

現時点では AWS で冗長構成を構築するときに、<span style="color: #d86e00">VIP 方式のアクセス振り分けには対応していません</span>。

### 2.5.2. ロードバランサによるアクセス振り分け
VIP 方式以外のアクセス振り分け方法としては、ロードバランサを利用することが一般的です。AWS 環境においては **AWS が提供するロードバランサを利用することを推奨します**。

インスタンスが外部からアクセス可能（IP リーチャブルかつ HTTP(s) ポート透過）な構成であれば、AWS 外部に独自にロードバランサを設置することも可能かもしれません。<span style="color: #d86e00">しかし、AWS ロードバランサを利用しない場合は、外部からのアクセス振り分けについては、サポート対象外となります（ジョブフローなどの内部で動作する機能についてはサポート対象となります）。</span>

本記事では、AWS の Application Load Balancerを利用した構築手順について示します。

## 2.6. ミドルウェアの設定
### 2.6.1. Corosyncの設定
ハートビート通信の設定パラメータの調整を検討してください。

冗長構成では複数のノードが協調して動作する必要があるため、各ノードが正常に連携できる状態であるかを常に相互監視しています。これには例えば、他ノードが応答しない（ノード停止・ネットワーク断線など）といった状況判断を含んでいます。こうした監視を実現するため、冗長構成を管理するミドルウェアの一つである Corosync が各ノードで動作しつつ、ネットワークを通して互いの情報を交換しています。これを一般的にハートビート通信と言いますが、この通信の安定性が重要であることは言うまでもありません。

しかし、物理的なネットワークで直結するような場合に比べて、クラウド環境での通信は安定性に欠けることがあると言われています（配置によってはネットワークの遅延が大きくなったり、プラットフォームのメンテナンスの影響を受けたりする、など）。

ハートビート通信が不安定であると、たとえば実際には正常に動作している他ノードがダウンしたなどと誤検知をすることがあります。こうした誤検知をもとに、不要なフェイルオーバが開始されたり、両系がアクティブとなるスプリットブレインと呼ばれる現象が生じたりと、冗長構成全体に悪影響を与えてしまい、最悪システムが利用できない状態になってしまうことも考えられます。

誤検知をなるべく軽減するためには、Corosync のハートビート通信に関連するパラメータを調整することが有効です。基本な対策としては、故障判断に関わる**タイムアウト値を大きくする方向で調整して「故障判断を遅らせる」ことで、一時的な通信の遅延や断絶に対して過敏に反応しないようにします**。当然、本当に故障したときにもその検知が遅くなることを意味しますが、「誤検知の抑制」と「故障判断の早さ」はトレードオフになりますので、用途や要件に合わせてそのバランスを検討してください。

Corosync は様々なパラメータを調整できるようになっていますが、このなかで、先にあげたノード故障の判断に関連する重要なパラメータを以下に示します。

| パラメータ | デフォルト値 | 設定例 | 備考 |
| --- | --- | --- | --- |
| totem.token | 1000 | 30000 | トークンを受信しなかった後にトークンの損失が宣言されるまでの時間（ミリ秒） |
| totem.consensus | 1200 | 36000 | メンバーシップ構成の新しいラウンドを開始する前にコンセンサスが達成されるまで待機する時間（ミリ秒） |
| totem.join | 50 | 1000 | メンバーシッププロトコルの join メッセージを待つ時間（ミリ秒） |

他にも多数のパラメータがありますので、詳細については `corosync.conf (5)` のマニュアルを参照してください。

これらのパラメータを調整することで、ノード故障の判断を遅らせて誤検知を軽減させることができます。具体的な設定値については、個別に検討していただきたいですが、以下に推奨値を示しておきます。

#### 2.6.1.1. 推奨値
本記事ではトークン値を大きくすることで、ノードの故障判断を遅らせるように設定します。

| パラメータ | 推奨値 |
| --- | --- |
| totem.token | 30000 |

※ v1.6.7 からトークン値はデフォルトで 30000 を設定するようになりました。【v1.4追記】

### 2.6.2. STONITHの設定
障害ノードを再起動させるためのSTONITHを利用するかを検討してください。

クラスターリングを管理するPacemakerは、障害ノードを強制的に停止または再起動させるSTONITH (Shoot The Other Node In The Head) という仕組み（フェンシングとも言います）を持っています。これは例えば、故障して応答しないノードの電源を強制的に落としたり、ネットワーク障害によって複数のノードがマスターになってしまうのを防ぐために１つのマスター以外を強制的に再起動させる、といったために利用します。

フェンシングについての更なる情報は Red Hat のドキュメントを参照してください。

- RHEL8
    - [フェンシングの概念](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_and_managing_high_availability_clusters/con_high-availability-add-on-concepts-overview-of-high-availability#_fencing)
    - [フェンシングの設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_and_managing_high_availability_clusters/proc_configuring-fencing-creating-high-availability-cluster)
    - [RED HAT HIGH AVAILABILITY クラスターでのフェンシングの設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_and_managing_high_availability_clusters/assembly_configuring-fencing-configuring-and-managing-high-availability-clusters)
- RHEL7
    - [フェンシングの概要](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/high_availability_add-on_overview/s1-fencing-haao)
    - [フェンス機能: STONITH の設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/high_availability_add-on_reference/ch-fencing-haar)

STONITH の仕組みや設定は複雑です。STONITH を設定しないと冗長構成として動作しないわけではありませんが、いくつかの障害ケースにおいては STONITH でしか救えないと言われています。また、STONITH が有効に設定されていることが Red Hat のサポート要件であることにはご注意ください。

#### 2.6.2.1. STONITHによる相打ち対策
STONITH は他ノードを強制的に停止または再起動させる、という強力な機能を持つために、ある場面では悩ましい課題が生じます。ネットワーク障害などによって複数のノードがマスターとなってしまう、いわゆるスプリットブレイン状態になったときに、**それぞれのノードが相手のノードが故障したと判断して相撃ちしてしまう可能性がある**ということです。この相撃ちが発生してしまうと、2台のサーバが同時に強制停止して完全にすべてのサービスが停止する、という問題が起こりえます。

この相撃ち問題を解消する方法はいくつか考えられていますが、本記事では以下の方式を紹介します。

- 本来は「故障したノードを再起動する」という一つの設定でもよいが、各ノードを再起動させる STONITH を分けて 2 つ設定する。
- それぞれの STONITH 設定で、相手ノードを再起動させるまでの遅延時間に数秒以上の差をつける。

STONITH 設定を分離して遅延時間に差をつけることで、同時に相手ノードの故障を検知した場合でも相撃ちしにくい状況にします（相撃ちを完全に防ぐことは出来ません）。

なお、この遅延時間は固定の設定となり、同時に故障を検知した場合は遅延時間の小さいノードが先に再起動することになり、遅延時間の大きいノードは生き残ることになります（再起動されたノードからの STONITH は発動しないため）。いわば STONITH の遅延時間を大きく設定されたノードが（生き残る）優先度が高くなるとも言えます。

理想的には障害検出時点でマスター状態のノードが生き残る可能性が高くなるように制御できるとよいのですが、現時点ではそのような設定方法は見出されていません。

#### 2.6.2.2. スタートアップ時のフェンシング無効化
デフォルトの STONITH の設定では、以下のような運用上の注意点があります。

- **いずれかのサーバで最初にクラスターを開始したときに、別のサーバの状態が確認できない場合に念のためにフェンシングします（再起動させてしまいます）。**

たとえば、次のようなことが起きることになります。

- プライマリとセカンダリいずれも、サーバとしては起動しているがクラスターは停止している（pacemaker が起動していない）というときに、プライマリでクラスターを開始（`pcs cluster start`）すると、セカンダリサーバを再起動させます。
- セカンダリサーバが停止（シャットダウン）している状態で、プライマリでクラスターを開始すると、セカンダリサーバを起動させます。

デフォルトでは、このように１台目のクラスター起動時に別のサーバを強制的に再起動させてしまうことに注意してください。この**「スタートアップ時のフェンシング機能」については無効にしておくことを推奨します**。設定値 `startup-fencing` を `false` とすることで無効にできます。

#### 2.6.2.3. PROXY 環境下における STONITH の利用
AWS 環境で STONITH を利用する場合、各 VM から AWS の管理 API を呼び出せるようになっている必要があります。VM からインターネットアクセスが許可されている場合は問題ありませんが、外部アクセスを制限するようなネットワーク構成に VM を配置する場合は、AWS の管理 API を呼び出せるように HTTPS を中継するプロキシサーバを用意する必要があります。

# 3. 構築
## 3.1. 構築前の検討
先に示した事前検討すべき項目以外に、構築作業に必要な事項を確認しておきます。

### 3.1.1. ノード名の決定
インスタンスに付けるノード名を決めておいてください。

インスタンスに付けるノード名は任意ですが、冗長構成では 2 台を「プライマリ」と「セカンダリ」と呼称して説明しますので、区別できるようにしておいてください。プライマリ＝１号機・セカンダリ＝２号機、といったイメージで問題ありませんが、「アクティブ」と「スタンバイ」はある時点での状態によって入れ替わりますのでご注意ください（セカンダリがアクティブになることも冗長構成としては適正です）。

本記事では以下のように名称を付けます。

| 項目 | 本記事での値 |
| --- | --- |
| プライマリ機の名称 | `ke01` |
| セカンダリ機の名称 | `ke02` |

### 3.1.2. その他名称やパラメータの決定
ノード名以外にも、ロードバランサの名称や VPC、サブネットやルートテーブルの名前等、構成に合わせ、様々なオブジェクトの名前やパラメータの決定をする必要があります。
　
### 3.1.3. IAMユーザの権限準備
AWS 用の STONITH デバイスである `fence-agents-aws` を利用する場合、インスタンスから `awscli` を利用した EC2 インスタンスの起動/停止が行えるよう IAM ユーザを用意し、アクセスキー等を準備してください。

必要となる権限は後述します。

### 3.1.4. PROXY サーバの準備
STONITH を利用する場合、かつ、VM から外部に直接 HTTPS アクセスできない場合は、別途 VM からの HTTPS アクセスを中継できるプロキシサーバを用意してください。

## 3.2. 留意事項
### 3.2.1. 権限について
実際に構築作業を行うときは、各環境において作業に必要な権限を持っている必要があります。

- クラウド環境の設定や操作をする場合は、必要な権限を持つアカウントで実施してください。
- VM のコンソール上で設定や操作をする場合は root 権限で実施してください。

### 3.2.2. 手順について
本記事の手順では、VPCやサブネットの作成から実施します。
いくつかのオブジェクトは既存の物を利用しても問題ありませんが、その場合には手順のスキップや、手順内で指定するオブジェクト名を読み替える等の対応を適時行ってください。

また、本記事において、特に記載のないパラメータについてはデフォルト値で設定しています。
実際の構築時は、案件の要件やポリシーに従い各種パラメータを調整してください。

なお、本記事では、執筆時の都合上国内リージョンの構築を行っていませんが、実際の構築の際は、国内リージョン等、要件や環境に沿ったリージョンを選択してください。
※ 表記的な違いはありますが、手順上の違いはありません。

### 3.2.3. 本記事における構成図
本記事における構築手順は、以下構成の構築を行うものとして記載します。

![image.png](https://image.docbase.io/uploads/73a2eec7-a696-430d-b63e-16428ce2fb81.png =WxH)


- 追加インターフェイスの設定は任意となりますが、本記事では追加する場合の手順を記載します。
- 追加インターフェイスの設定を行わない場合に実施が不要となる手順等については、手順内で補足を行います。

### 3.2.4. 本記事におけるインスタンスの AMI
本記事では、以下のAMIを利用しインスタンスを作成します。

| AMI(AMI名) | インスタンスタイプ |
| --- | --- |
| Red Hat Enterprise Linux 8.4 with High Availability<br>(RHEL_HA-8.4.0_HVM-20210504-x86_64-2-Hourly2-GP2) | m4.large |

インスタンスタイプについて、Kompira enterprise の推奨要件を満たす最小は「m4.large」となります。

本記事における構成図や利用 AMI については、構築手順を示す為の一例となりますので、実際に構築する際は、事前検討を通じ、要件に見合った構成や AMI、インスタンスタイプを選択してください。

※ T系インスタンスでは冗長構成の安定性に問題が生じる場合がありますので、ご利用を避けるようにしてください。【v1.5追記】

### 3.2.5. 本記事における構成パラメータ例
| 大項目 | 中項目 | 本記事での構成 |
| --- | --- | --- |
| OS | 種類 | RHEL |
| | バージョン | 8.4 |
| インスタンスの配置 | リージョン名 | オハイオ |
| | 可用性ゾーンの分離 | する（aとbに配置） |
| | サブネット | 異なるサブネットにインスタンスを配置する |
| インスタンスの種類や構成 | AMI | Red Hat Enterprise Linux 8.4<br>with High Availability |
| | 種類 | m4.large |
| | ストレージ | SSD |
| | サイズ | 30GB |
| ネットワークの設定 | セキュリティグループ | 2つ作成する<br>- メインインターフェイス/LB用<br>（外部/LBからの接続の許可）<br>- 追加インターフェイス用<br>（インスタンス間通信の許可） |
| | インスタンス間通信用<br>ネットワークインターフェイス | 追加する |
| | パブリックIPの割り当て | 行う（Elastic IPの関連付け） |
| | ルートテーブル | 2つ作成する<br>- メインインターフェイスのサブネット用<br>（インターネットへの経路有り）<br>- 追加インターフェイスのサブネット用<br>（インターネットへの経路無し） |
|  | プロキシサーバ | 利用しない |
| フロントエンドの設定 | アクセス振り分け手法 | Application Load Balancer を利用する |
| ミドルウェアの設定 | Corosync の設定 | totem.token=30000 |
| | STONITH の設定 | STONITH を設定する |
| ノード名 | プライマリ機の名称 | `ke01` |
| | セカンダリ機の名称 | `ke02` |
| ローカル IP アドレス | プライマリ機の IP アドレス | 172.131.1.101/24<br>172.131.101.101/24
| | セカンダリ機の IP アドレス | 172.131.2.102/24<br>172.131.102.102/24 |

## 3.3. 構築手順
### 3.3.1. ネットワークのセットアップ
#### 3.3.1.1. VPCの作成
インスタンスを配置するためのVPCを作成してください。
 
![image.png](https://image.docbase.io/uploads/fd72801c-4357-4edb-af23-57c7402c4a88.png =WxH)

本記事では、以下のパラメータでVPCを作成しました。

| 名前タグ – オプション | IPv4 CIDR ブロック |
| --- | --- |
| ke-vpc | 172.131.0.0/16 |

#### 3.3.1.2. サブネットの作成
2台のインスタンスを配置するサブネットを作成してください。インスタンスへの追加インターフェイスを付与する場合には4つ、付与しない場合は2つ必要となります。

既存のサブネットを使用しても問題ありませんが、**2台のインスタンスが配置されるサブネットは、可用性の観点より別々のAZとすることを推奨します**。また、追加インターフェイスとメインインターフェイスは同じAZにする必要があります。
 
![image.png](https://image.docbase.io/uploads/939ec447-39a0-46d7-815b-a988e12b074f.png =WxH)

※上記画像は1つ目のサブネット作成時のものです。

本記事では、以下のパラメータでサブネットを4つ作成しました。

| サブネット名 | アベイラビリティゾーン | IPv4 CIDRブロック | 用途 |
| --- | --- | --- | --- |
| ke-subnet01 | us-east-2a | 172.131.1.0/24 | プライマリ機のサービス通信用 |
| ke-subnet02 | us-east-2b | 172.131.2.0/24 | セカンダリ機のサービス通信用 |
| ha-subnet01 | us-east-2a | 172.131.101.0/24 | プライマリ機のインスタンス間通信用 |
| ha-subnet02 | us-east-2b | 172.131.102.0/24 | セカンダリ機のインスタンス間通信用 |

#### 3.3.1.3. インターネットゲートウェイの作成
インターネット通信を行うため、インターネットゲートウェイの作成を行ってください。

![image.png](https://image.docbase.io/uploads/68a92e3a-787f-4501-8223-4f9a7892fc55.png =WxH)

本記事では、名前を「ke-igw」と設定しました。
作成後、VPCにアタッチしてください。
 
![image.png](https://image.docbase.io/uploads/5086c3a2-a20e-43e8-9a48-833d51d2ca2f.png =WxH)

#### 3.3.1.4. ルートテーブルの作成（1つ目）
1つ目のルートテーブル（メインインターフェイスのサブネット用）を作成してください。
 
![image.png](https://image.docbase.io/uploads/5e40e83f-b87e-4aa5-ba35-6e6a0d301fa8.png =WxH)

以下のパラメータでルートテーブルを作成しました。

| 名前 – オプション | VPC |
| --- | --- |
| ke-rt | ke-vpc |

作成したルートテーブルに、送信先「0.0.0.0/0」のルートを追加してください。
先ほど作成したインターネットゲートウェイをターゲットとします。
 
![image.png](https://image.docbase.io/uploads/582a093a-e7c3-4de1-8abc-4163528f1b45.png =WxH)

その後、2台のインスタンスのメインインターフェイスに指定するサブネットとなる「ke-subnet01」
「ke-subnet02」を関連付けしてください。
 
![image.png](https://image.docbase.io/uploads/c337b446-a4bc-451e-b10c-1957d65988c7.png =WxH)

#### 3.3.1.5. ルートテーブルの作成（2つ目）
2つ目のルートテーブル（メインインターフェイスのサブネット用）を作成します。
この作業は、追加インターフェイスの設定を行わない場合必要有りません。
 
![image.png](https://image.docbase.io/uploads/7e76430e-c671-44ac-8540-0ed7c028514d.png =WxH)

以下のパラメータでルートテーブルを作成しました。

| 名前 – オプション | VPC |
| --- | --- |
| ha-rt | ke-vpc |

作成後、2台のインスタンスの追加インターフェイスに指定するサブネットとなる「ha-subnet01」
「ha-subnet02」を関連付けしてください。

![image.png](https://image.docbase.io/uploads/f0f303b4-22eb-4161-9141-29bb15436991.png =WxH)

ルートテーブルは、デフォルトで自身のVPC内のCIDRブロックに対するルートを持っている為、
このルートテーブルに新しくルートを追加する必要はありません。

#### 3.3.1.6. Elastic IPの作成
外部からインスタンスに直接アクセスを行うための Elastic IP を作成してください。

なおこの手順は、追加インターフェイスの設定を行わない場合、任意の作業となります。追加インターフェイスの作成を行わない場合、インスタンス作成時に、Elastic IPアドレスとは異なる方式でパブリックIPを付与することが可能なためです。

![image.png](https://image.docbase.io/uploads/56e078da-ab61-412c-a17c-26cd6db544cf.png =WxH)

 
※上記画像は1つ目の Elastic IP 作成時のものです。

ここでは、Elastic IPを2つ作成し、それぞれのNameタグに「ke-eip01」「ke-eip02」と設定しました。
インスタンスへの関連付けは、後述の手順にて実施します。

#### 3.3.1.7. セキュリティグループの作成（1つ目）
外部からのアクセスを許可するためのセキュリティグループを設定してください。
これは、インスタンスのメインのインターフェイスや、ロードバランサに指定するためのものとなります。

- **注意事項**
    - **実際の案件では、細かくセキュリティグループを指定する必要が出てくる可能性があります。**
        - ロードバランサに設定するセキュリティグループと、インスタンスに設定するセキュリティグループを分けたうえ、さらに細かい設定を投入する、等。
    - **本記事は、あくまで作成の一例であり、最低限のものとして読み進めてください。**

![image.png](https://image.docbase.io/uploads/710649d4-f42f-4ce1-98a2-eede51715d6a.png =WxH)

本記事では、「ke-sg01」の名前でセキュリティグループを作成し、以下のインバウンドルールを設定しました。

| タイプ | ソース | 用途 |
| --- | --- | --- |
| すべてのトラフィック | カスタム：172.131.1.0/24 | ロードバランサからの通信許可 |
| すべてのトラフィック | カスタム：172.131.2.0/24 | ロードバランサからの通信許可 |
| SSH | カスタム：xxx.xxx.xxx.xxx/32 | 作業元からのSSH接続許可 |
| HTTPS | カスタム：xxx.xxx.xxx.xxx/32 | 作業元からのHTTPS接続許可 |

**繰り返しになりますが、セキュリティグループのインバウンド/アウトバウンドのルールについては、要件によりもっと細かい設定を行う必要があるかもしれません。**

#### 3.3.1.8. セキュリティグループの作成（2つ目）
インスタンス間通信を行う為のセキュリティグループを設定してください。
この作業は、追加インターフェイスの設定を行わない場合必要有りません。

![image.png](https://image.docbase.io/uploads/ea34b79f-d180-47dc-8cc3-9d7627d3ae2c.png =WxH)
 
本記事では「ha-sg01」の名前でセキュリティグループを作成し、以下のインバウンドルールを設定しました。

| タイプ | ソース | 用途 |
| --- | --- | --- |
| すべてのトラフィック | カスタム：172.131.101.0/24 | インスタンス間通信用 |
| すべてのトラフィック | カスタム：172.131.102.0/24 | インスタンス間通信用 |

このセキュリティグループは、2台のインスタンスのインスタンス間通信を行う為の物となるため、
外部からのアクセスは想定していません。

また、インスタンス間通信については、全てのトラフィックを許可することを推奨します。

### 3.3.2. インスタンスのセットアップ
#### 3.3.2.1. ネットワークインターフェイスの作成
インスタンス間通信に使用する追加インターフェイスを作成してください。
この作業は、追加インターフェイスの設定を行わない場合必要有りません。

![image.png](https://image.docbase.io/uploads/9a1065d9-afc0-4ced-851d-82a4ea6fbee2.png =WxH)

※上記画像は1つ目のネットワークインターフェイス作成時のものです。

本記事では、2台のインスタンス双方に追加インターフェイスを設定するため以下2つのネットワークインターフェイスを作成しました。

| サブネット | プライベートIPアドレス | セキュリティグループ | Nameタグ |
| --- | --- | --- | --- |
| ha-subnet01 | カスタム：172.131.101.101 | ha-sg01 | ha-if01 |
| ha-subnet02 | カスタム：172.131.102.102 | ha-sg01 | ha-if02 |
※サブネット及びセキュリティグループは、IDではなく名前を記載しています。

プライベートIPアドレスは自動割り当てでも問題は有りませんが、冗長構成構築時の管理のし易さや統一性を考え、本記事では固定としています。

#### 3.3.2.2. インスタンスの作成
同じ構成のインスタンスを2台作成してください。
ここでは、追加インターフェイスの設定を行うかどうかで、若干設定が変化します。

##### ステップ1: Amazon マシンイメージ(AMI) の選択
まずは事前に検討したAMIを選択してください。

![image.png](https://image.docbase.io/uploads/c4d87c06-ccbe-4846-ab7c-40ab000db130.png =WxH)
 

本記事では「Red Hat Enterprise Linux 8.4 with High Availability」を選択しました。

##### ステップ2: インスタンスタイプの選択
続いて、事前に検討したインスタンスタイプを選択してください。

![image.png](https://image.docbase.io/uploads/77649b20-0231-4fad-aeae-a3e7db024e58.png =WxH)

本記事では「m4.large」を選択しました。

##### ステップ3: インスタンスの詳細の設定
インスタンスの詳細の設定では、以下項目を設定してください。

- ネットワークには「ke-vpc」を指定してください
- サブネットは以下を指定してください。
    - プライマリ機は「ke-subnet01」
    - セカンダリ機は「ke-subnet02」
- ネットワークインターフェイスのデバイス eth0 のプライマリIPに以下を指定してください。
    - プライマリ機は「172.131.1.101」
    - セカンダリ機は「172.131.2.102」
- ネットワークインターフェイスにeth1を追加したうえ、ネットワークインターフェイスに以下を指定してください。
    - プライマリ機は「ha-if01」
    - セカンダリ機は「ha-if02」
 
![image.png](https://image.docbase.io/uploads/0ca2acdf-a6e8-4bd5-a52f-f191f3624808.png =WxH)

※上記画像はプライマリ機作成時のものです。

追加インターフェイスを設定しない場合は、ネットワークインターフェイスeth1の追加は不要です。
また、その場合は「自動割り当てパブリックIP」を「有効」にしてパブリックIPを与えることが可能です。

##### ステップ4: ストレージの追加
ストレージは任意のサイズを指定してください。
     
![image.png](https://image.docbase.io/uploads/401cfc79-c3c1-4c38-90ee-64d987fe7628.png =WxH)

本記事では「30GB」を指定しました。

##### ステップ5: タグの追加
タグの追加では、Nameキーに、プライマリ機は「ke01」、セカンダリ機は「ke02」を指定してください。
 
![image.png](https://image.docbase.io/uploads/8978237b-927d-46fd-bb2b-11c98872a6f7.png =WxH)

※上記画像はプライマリ機作成時のものです。

##### ステップ6: セキュリティグループの設定
セキュリティグループは、ke-sg01を指定してください。
 
![image.png](https://image.docbase.io/uploads/afc73f01-98f2-428b-82db-395b1e8d8b27.png =WxH)

#### 3.3.2.3. Elastic IPの関連付け
前項までに作成した2つのElastic IPを、2台のインスタンスのメインインターフェイスに関連付けてください。
この手順は、追加インターフェイスの設定を行わず、インスタンス作成時に自動割り当てパブリックIPを有効にしている場合は不要です。

![image.png](https://image.docbase.io/uploads/f5fe7b78-0713-4e50-b932-5bb40daa2a3f.png =WxH)
 
※上記画像はプライマリ機のインターフェイスへの関連付け時のものです。

### 3.3.3. OSセットアップ
Kompiraのセットアップの前に、OS側でいくつかの事前作業を行います。
構成や、使用するAMI次第では不要な作業となる可能性があります。

#### 3.3.3.1. 追加インターフェイスの確認
追加インターフェイスを設定している場合、Kompira のセットアップ前に、OS 側で追加インターフェイスが認識され、IP が設定されていることを（例えば `ip address` コマンドを用いて）確認してください。

AMI によっては追加インターフェイスの設定がされていない場合があります。<span style="color: #d86e00">（※ 本書執筆時に動作確認した AMI では「CentOS 7」および「RHEL 7」が該当します。CentOS 7 は NetworkManager も未導入）</span>

```
$ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
    inet 172.XX.XX.XX/20 brd 172.XX.XX.255 scope global dynamic eth0
       valid_lft 3468sec preferred_lft 3468sec
    inet6 fe80::XXXX:XXXX:XXXX:XXXX/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST> mtu 9001 qdisc mq state DOWN group default qlen 1000
    link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
```

上の例では、追加した `eth1` インターフェースに IP アドレスが設定されていません。こうした場合は、OS ごとの設定手順に従って、追加インターフェースの設定を行なってください。ここでは、RHEL7/CentOS7 系での設定方法の一例を以下に示します（`eth1` という名称の部分は実際の状況に合わせてください）。

1. `/etc/sysconfig/network-scripts/ifcfg-eth1` という設定ファイルを作成して、以下の内容を保存してください。

    ```
    BOOTPROTO=dhcp
    DEVICE=eth1
    METRIC=200
    ONBOOT=yes
    TYPE=Ethernet
    USERCTL=no
    ```

2. eth1 デバイスを ifup してください。

    ```
    $ sudo ifup eth1
    ```

3. IP アドレスが設定されていることを確認してください。

    ```
    $ ip address
        :
    3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
        link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
        inet 172.XX.XX.XX/20 brd 172.31.47.255 scope global dynamic eth1
    ```

#### 3.3.3.2. 静的ルートの設定
マルチAZ環境で、なおかつ追加インターフェイスを設定している場合、インスタンス間通信を追加インターフェイスで行うよう静的ルートの設定を行ってください。なお、この設定は両方のインスタンスでそれぞれ行う必要があります。

##### 3.3.3.2.1. nmcli コマンドによる静的ルートの設定
NetworkManager が導入されている（RHEL8/RHEL7/CentOS Stream 8 系など）環境であれば、nmcli コマンドで静的ルートを設定することができます。

```
$ sudo nmcli conn mod "System eth1" +ipv4.routes "172.YY.YY.0/20 172.XX.XX.1"
```

このとき、`"System eth1"` の部分は NetworkManager が認識している追加インターフェースの名称を、`172.YY.YY.0/20` の部分（宛先）は対向インスタンスの追加インターフェースのサブネットの CIDR を、`172.XX.XX.1` の部分（ゲートウェイ）は自インスタンスの追加インターフェースのサブネットの `.1` アドレスを、指定してください。それぞれのインスタンスの設定でサブネットのアドレスが入れ替わることに注意してください。

静的ルートを設定したら、追加インターフェースを down および up しなおしてください。

```
$ sudo nmcli conn down "System eth1" 
$ sudo nmcli conn up "System eth1" 
```

両方のインスタンスで設定できれば、追加インターフェースの IP アドレスで相互に ping コマンドなどで導通確認してください。

ただし、AMIによっては、追加インターフェイスに対する静的ルートがnmcliコマンドで設定反映出来ない場合があります（<span style="color: #d86e00">※ 本書執筆時に動作確認したAMIでは「RHEL 8.4」が該当します</span>）。そうした場合の対策の一例を以下に示します。
    
-  `/etc/rc.local` に実行権限を付与したうえ、`/etc/rc.local` 内に `route add ` コマンドによる静的ルート追加を追記する方法などを用いて静的ルートを追加してください。
    - その際 ` route add` の前に若干（3秒等）の sleep を入れることで、静的ルート追加の動作が安定します。

##### 3.3.3.2.2. route-interface 設定ファイル による静的ルートの設定
NetworkManager が導入されていない（CentOS7 系など）環境であれば、route-interface 設定ファイルを作成して静的ルートを設定することができます。

`/etc/sysconfig/network-scripts/route-eth1` という設定ファイルを作成して、以下の内容を保存してください。

```
ADDRESS0=172.YY.YY.0
NETMASK0=255.255.240.0
GATEWAY0=172.XX.XX.1
```

このとき、設定ファイル名の `eth1` の部分は追加インターフェースの名称を、`172.YY.YY.0` および `255.255.240.0` の部分（宛先）は対向インスタンスの追加インターフェースのサブネットを、`172.XX.XX.1` の部分（ゲートウェイ）は自インスタンスの追加インターフェースのサブネットの `.1` アドレスを、指定してください。それぞれのインスタンスの設定でサブネットのアドレスが入れ替わることに注意してください。

静的ルートを設定したら、追加インターフェースを down および up しなおしてください。

```
$ sudo ifdown eth1
$ sudo ifup eth1
```

両方のインスタンスで設定できれば、追加インターフェースの IP アドレスで相互に ping コマンドなどで導通確認してください。

#### 3.3.3.3. 言語とタイムゾーンの設定
AMIによっては、デフォルトで言語やタイムゾーンが日本に設定されていない場合があります。
その場合、必要に応じて言語設定やタイムゾーンの設定を行ってください。

Kompiraセットアップ時に言語を指定することでも可能ですが、その場合は言語パックが導入されている必要があります。

本記事で使用したAMI「RHEL 8.4」では言語パックが標準でインストールされていない為、以下コマンドにて言語パックのインストール、言語の設定、タイムゾーンの指定を事前に行っています。

##### 言語の設定
```
# dnf install glibc-langpack-ja
# localectl set-locale LANG=ja_JP.utf8
```

##### タイムゾーンの設定
```
# timedatectl set-timezone Asia/Tokyo
```

#### 3.3.3.4. その他
一般ユーザの作成や、ホスト名の設定等、OSの一般的なセットアップ作業を必要に応じて実施してください。

### 3.3.4. Kompira セットアップ
#### 3.3.4.1. Kompira のインストール
通常の手順に従って、各インスタンスにKompiraをインストールしてください。

- Kompiraのダウンロード
- Kompiraのインストール

この段階で、各インスタンスにインストールした Kompira にアクセスできるか確認しておいてください。

#### 3.3.4.2. ライセンスの導入（準備出来る場合）
ライセンスを準備できる状況であれば、この段階で各インスタンスのKompira にライセンスを導入しておくことをお勧めします。

- ライセンスの発行手続き
- ライセンスの導入

### 3.3.5. 冗長構成のセットアップ
Kompira をインストールしたプライマリ機およびセカンダリ機それぞれにおいて、ダウンロードした Kompira パッケージに含まれる `setup_cluster.sh` を実行することで冗長構成のセットアップを行なうことができます。

#### 3.3.5.1. セットアップオプションの確認
冗長構成をセットアップするために `setup_cluster.sh` を実行するとき、事前に検討した構成パラメータを適用させるために環境変数やコマンドオプションを用いて指定しますので、その内容を確認します。

- プライマリ機およびセカンダリ機に付ける内部的な名称を指定するために、環境変数で `PRIMARY_NAME=<プライマリ機ホスト名>` および `SECONDARY_NAME=<セカンダリ機ホスト名>` のように渡します。ちなみに、この指定を省略した場合は `ha-kompira1` および `ha-kompira2` という名称がデフォルトで適用されます。
- インスタンス間通信に利用する IP アドレスを指定するため、`--heartbeat-primary=<プライマリ機ローカルIPアドレス>` および `--heartbeat-secondary=<セカンダリ機ローカルIPアドレス>` とオプションを指定します。インスタンス 間通信用ネットワークインターフェイスを追加している場合はそのローカルIPアドレスを、追加していない場合はメインのネットワークインターフェイスのローカルIPアドレスを指定することに注意してください。また、このように IP アドレスを直接指定する事を示すために `--manual-heartbeat` というオプションも合わせて指定します。
- VIP によるアクセス振り分けを行なわないため、`--without-vip` というオプションを指定します。
- Corosync の通信パラメータを調整するため、`--token=30000` というオプションを指定します。

これらのオプションなどに加えて、プライマリ機でのセットアップ時には `--primary` オプションを、セカンダリ機でのセットアップ時には `--secondary` オプションを指定して `setup_cluster.sh` を実行するようにしてください。

なお、**プライマリ機のセットアップが成功して、冗長構成としてのすべてのリソースが片系で正常に動作を開始するのを確認してから、セカンダリ機のセットアップを開始するようにしてください。**

#### 3.3.5.2. プライマリ機で setup_cluster.sh 実行
先に検討した構成パラメータをもとに、プライマリ機では以下のように setup_cluster.sh を実行します。

```
# PRIMARY_NAME=ke01 SECONDARY_NAME=ke02 \
./setup_cluster.sh --primary \
--manual-heartbeat --heartbeat-primary=172.131.101.101 --heartbeat-secondary=172.131.102.102 \
--without-vip --token=30000
```
※	この段階でプライマリ機のKompiraにアクセスできることを確認してください。

#### 3.3.5.3. セカンダリ機で setup_cluster.sh 実行
先に検討した構成パラメータをもとに、セカンダリ機では以下のように setup_cluster.sh を実行します。

```
# PRIMARY_NAME=ke01 SECONDARY_NAME=ke02 \
./setup_cluster.sh --secondary \
--manual-heartbeat --heartbeat-primary=172.131.101.101 --heartbeat-secondary=172.131.102.102 \
--without-vip --token=30000
```

※	この段階で冗長構成の正常性を確認してください。またフェイルオーバや障害系の復旧が出来ることを確認しておくことを推奨します。正常性確認等の基本的な手順については「4. 冗長構成の管理」を参考にしてください。

### 3.3.6. ロードバランサの設定
#### 3.3.6.1. ターゲットグループの作成
ロードバランサの作成前に、「EC2  > ターゲットグループ」でロードバランサのターゲットグループを作成してください。

まずは Specify group details の設定を行います。

- Basic configurationでは以下を指定してください。
    - 「Choose a target type」は Instances を指定してください。
    - 「Target group name」は任意です。本記事では「ke-tg」としました。
    - 「Protocol」は「HTTPS」を指定してください。Port は自動的に 443 に変化します。
    - 「VPC」は「ke-vpc」を指定してください。
- Health checksでは以下を指定してください。
    - 「Health check protocol」は HTTPS を指定してください。
    - 「Health check path」には、ステータスコード 200 が返却されるパスを指定してください。
        - 本記事では「/.login」としました。
    - 「Advanced health check settings」の項目は、デフォルトでは間隔が長いので値の調整を行ってください。
        - 本記事では「Healthy threshold」を 2、「Timeout」を 3、「Interval」を 5 に変更しました。

![image.png](https://image.docbase.io/uploads/b73a7897-0cd2-4145-baa2-b322afe77d5f.png =WxH)


続けて、Register targets の設定を行います。

- 画面上部の「Available instances」よりプライマリ機とセカンダリ機のインスタンスを選択し、「Include as pending below」をクリックして画面下部の「Targets」に所属させてください。

![image.png](https://image.docbase.io/uploads/33c34be1-726c-49ee-9129-3c97ebcdec15.png =WxH)

#### 3.3.6.2. ロードバランサの作成
AWS の管理コンソールよりロードバランサを作成してください。なお、ロードバランサの種類は「Application Load Balancer」を選択します。

- Basic configurationでは以下を指定してください。
    - 「Load balancer name」は任意です。
        - 本記事では、事前に記載した構成図の通り「ke-lb」としました。
- Network mappingでは以下を指定してください。
    - 「VPC」は「ke-vpc」を指定してください。
    - 「Mappings」は、2台のインスタンスが利用するサブネットが所属するAZをすべてチェックしたうえ、「subnet」には「ke-subnet01」および「ke-subnet02」を指定してください。
- Security Groups は「ke-sg01」を指定してください。
- Listeners and routing では以下を指定してください。
    - Listenerはでデフォルト1つのみで問題有りません。
    - 「Protocol」は「HTTPS」を選択してください。Port は自動的に 443 に変更されます。
    - 「Default action」は、上で作成したターゲットグループ「ke-tg」を指定してください。
- Secure listener settings は任意の値を設定してください。

![image.png](https://image.docbase.io/uploads/4eda78e9-1fbe-46bc-b30a-cdc2639ad449.png =WxH)

#### 3.3.6.3. ロードバランサ経由でのKompiraアクセス確認
この段階で外部アクセスをアクティブ状態のサーバに振り分けるようになっているはずなので、ブラウザからロードバランサ経由で Kompira に確認できることを確認してください。

AWS の管理コンソールにて、作成したロードバランサを選択することで、ロードバランサに設定された DNS の A レコードを確認することができます。

![image.png](https://image.docbase.io/uploads/aa2163ba-2d69-4333-88d7-348cf2838f11.png =WxH)

ブラウザでこのアドレスを入力してアクセスできることを確認します。なお、本記事でのロードバランサの設定では https アクセスになることに注意してください。

![image.png](https://image.docbase.io/uploads/1b036675-22c3-43a6-8efb-8684f72b1ea2.png =WxH)

#### 3.3.6.4. ロードバランサのアイドルタイムアウト値の調整
ロードバランサのアイドルタイムアウト時間はデフォルト 60s になっています。通常は問題有りませんが、ジョブフローのインポート等、長時間アクセスを行うような場合では、この値を調整する必要があるかもしれません。
　
必要に応じて、ロードバランサのアイドルタイムの調整を行ってください。アイドルタイムアウトの値は、ロードバランサの一覧より対象のロードバランサを選択したうえ、画面下部に表示される「説明」タブの下部にある「属性の編集」より行うことができます。

![image.png](https://image.docbase.io/uploads/e9107998-78f6-45f7-8f88-0f37b03e51c3.png =WxH)

### 3.3.7. STONITH の設定
STONITH の設定を行わない場合は、本項の手順は不要となります。

#### 3.3.7.1. Pacemaker への PROXY の設定
STONITH を利用する場合、かつ、VM から外部に直接 HTTPS アクセスできない場合は、事前に用意したプロキシサーバに関する情報を Pacemaker に設定する必要があります。

Pacemaker の設定ファイル `/etc/sysconfig/pacemaker` の末尾に以下の行を追加してください。このとき `<proxy>:<proxy_port>` の部分は用意したプロキシサーバのアドレスに合わせてください。

```
http_proxy=http://<proxy>:<proxy_port>
https_proxy=http://<proxy>:<proxy_port>
no_proxy="localhost,169.254.169.254"
```

この設定を適用するには Pacemaker を再起動する必要があります。以降の設定に進む前に、一度両系をスタンバイ系・アクティブ系の順に停止して、再度アクティブ系・スタンバイ系の順に開始してください。

#### 3.3.7.2. 自身のインスタンスIDの確認
プライマリ機、セカンダリ機双方で以下コマンドを実行し、自身のインスタンスIDを控えてください。

```
# echo $(curl -s http://169.254.169.254/latest/meta-data/instance-id)
```

本記事では、それぞれ以下の通りのインスタンスIDが取得できました。

| 項目 | 本記事での値 |
| --- | --- |
| プライマリ機のインスタンスID | `i-090ae9b9f686a4aaf` |
| セカンダリ機のインスタンスID | `i-0e4b80f1f2247c867` |

#### 3.3.7.3. アクセスキー、シークレットキーの確認
STONITH の設定にて fence デバイスを作成する際、インスタンスの状態取得/起動/停止の権限を持つ IAM ユーザのアクセスキーとシークレットキーが必要になるので、事前に準備を行い、控えておいてください。

STONITH 用にユーザを新規に作成する場合には、ユーザの作成画面で「アクセスキー・プログラムによるアクセス」にチェックをつけてください。

![image.png](https://image.docbase.io/uploads/e29017d6-dd88-4ddd-bfb9-5abd8af37971.png =WxH)

また、ポリシーとして `AmazonEC2FullAccess` を割り当てても問題有りませんが、新しくポリシーを作成する場合には、少なくとも以下の権限を含めてください。

- `ec2:DescribeInstances`
- `ec2:TerminateInstances`
- `ec2:StartInstances`
- `ec2:StopInstances`

#### 3.3.7.4. リージョンIDの確認
fence デバイスの作成には、インスタンスの存在するリージョン ID が必要になるので、事前に控えておいてください。

#### 3.3.7.5. STONITH デバイスの作成
事前に確認しておいた情報を用いて、STONITH デバイスを作成します。

まず、2 台のインスタンスに AWS 対応のフェンスデバイスである `fence-agents-aws` と、内部的に利用されるフェンスデバイスが内部的に使用する `awscli` をインストールしてください。

```
# dnf install -y fence-agents-aws awscli
```

次に、フェンスデバイスを作成します。これは pacemaker が起動しているいずれのインスタンスでも実行できますが、アクティブ状態のノードで作業することを推奨しておきます。

本記事では相撃ち対策のために、STONITH を 2 つ作成してそれぞれに異なる遅延時間を指定する、という設定方法をとります。ここではプライマリ機を優先して生き残らせるために、プライマリ機を再起動させる STONITH の遅延時間を大きく、セカンダリ機を再起動させる STONITH の遅延時間を小さくすることとします。

| フェンスデバイス | 再起動対象ノード | STONITH実行ノード | 遅延時間（秒） |
| --- | --- | --- | --- |
| res_stonith1 | ke01 | ke02 | 5 |
| res_stonith2 | ke02 | ke01 | 1 |

`pcs stonith create` コマンドで以下のように 2 つフェンスデバイスを作成します。ここで、前項までに控えた各パラメータが必要になります。また、たくさんあるパラメータのうち `pcmk_host_list` と `delay` が異なっていることに注意してください。

```
#pcs stonith create res_stonith1 fence_aws \
 access_key=AKxxxxxxxxxxxxxxxx7Z \
 secret_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
 region=us-east-2 \
 pcmk_host_map="ke01:i-090ae9b9f686a4aaf delay=5" \
 power_timeout=240 pcmk_reboot_timeout=480 pcmk_reboot_retries=4

#pcs stonith create res_stonith2 fence_aws \
access_key=AKxxxxxxxxxxxxxxxx7Z \
 secret_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
 region=us-east-2 \
 pcmk_host_map="ke02:i-0e4b80f1f2247c867 delay=1"\
 power_timeout=240 pcmk_reboot_timeout=480 pcmk_reboot_retries=4
```

次に、それぞれの STONITH が自身を再起動するノードでは起動しないように、リソースの場所制約を設定します。これにより、`res_stonith1` は `ke02` で起動し、`res_stonith2` は `ke01` で起動するようになります。

```
# pcs constraint location res_stonith1 avoids ke01
# pcs constraint location res_stonith2 avoids ke02
```

スタートアップ時のフェンシングを無効化するために、プロパティ `startup-fencing` を `false` にセットします。

```
# pcs property set startup-fencing=false
```

最後に STONITH を有効化するために、プロパティ `stonith-enabled` を `true` にセットします。

```
# pcs property set stonith-enabled=true
```

### 3.3.8. pacemaker の自動起動設定の解除
マスター状態で動作していたノードが電源オフあるいは STONITH で強制再起動させられたような場合も、スレーブ動作していたノードがフェイルオーバしてマスター動作を引き継ぎます。しかし、元々マスターで動作していたノード（とくに故障などはしていなかったと仮定）を起動後そのまま冗長構成に参加させると Postgresql がマスター同士のために、レプリケーション接続でエラーが発生してフェイルオーバした現在のマスターノードがダウンしてしまう場合があります。

再起動ノードのクラスター復帰は慎重に作業するべき作業になるので、pacemaker サービスおよび corosync サービスの自動起動設定を解除しておくことを推奨します。

```
# systemctl disable pacemaker
# systemctl disable corosync
```

ただし、1 台目のサーバを起動したときもクラスターが自動起動しなくなりますので、以下のコマンドで起動させてください。

```
# pcs cluster start
```

<span style="color: #d86e00">※ なお、STONITH が有効で、かつ、スタートアップ時のフェンシングを無効にしていない場合は、１台目のサーバを起動したときに、別のサーバを強制的に再起動させてしまうことにも注意してください。</span>

## 3.4. その他の設定手順
### 3.4.1. Pacemaker アラートの設定
冗長構成を構築していても、サーバやサービスに不具合が生じることがあります。冗長構成を管理する Pacemaker というミドルウェアは、各サーバ自体やサーバ上で動作しているサービスの動作を監視しており、その結果から状況に応じてフェイルオーバを開始するなどの制御を担っています。

冗長構成を運用するうえでは、Pacemaker が監視しているリソース（サーバ自体やサービス）の状態が変化したことの記録を取ったり、変化したことを通知してほしい、という場合があります。

Pacemaker にはアラートという機能があり、こうした状態変化のログへの記録やメールでの通知が出来ますので、その設定方法について紹介しておきます。

#### 3.4.1.1. ログの設定
Pacemaker アラートをログファイルに記録したい場合、Pacemaker に付属する `alert_file.sh.sample` というサンプルスクリプトを利用することが出来ます。

まず、各サーバ上で以下の手順を実行して、`alert_file.sh` スクリプトの有効化とログファイルの準備をしてください。なお記録するログファイル名は指定できますが、ここでは `/var/log/pacemaker_alert.log` としています。

```
# install -m 0755 /usr/share/pacemaker/alerts/alert_file.sh.sample /var/lib/pacemaker/alert_file.sh
# install -m 0600 -o hacluster -g haclient /dev/null /var/log/pacemaker_alert.log
```

次に、アクティブ状態のサーバ上で以下の手順を実行して、Pacemaker アラートの設定を行なってください。

```
# pcs alert create id=alert_file description="Log events to a file." path=/var/lib/pacemaker/alert_file.sh \
    meta timestamp-format="%Y-%m-%d %H:%M:%S.%06N"
# pcs alert recipient add alert_file id=alert_logfile value=/var/log/pacemaker_alert.log
```

セカンダリの停止、及び再起動（冗長構成の参加）を行い、スタンバイ状態に回復したときに、pacemaker_alert.log に記録された内容を以下に例示します。

```
2021-09-24 15:41:26.503787: Resource operation 'notify' for 'res_rabbitmq' on 'ke01': ok
2021-09-24 15:41:26.624162: Resource operation 'notify' for 'res_pgsql' on 'ke01': ok
2021-09-24 15:41:27.163644: Resource operation 'notify' for 'res_pgsql' on 'ke01': ok
2021-09-24 15:41:32.510714: Resource operation 'notify' for 'res_rabbitmq' on 'ke01': ok
2021-09-24 15:42:35.880877: Resource operation 'notify' for 'res_rabbitmq' on 'ke01': ok
2021-09-24 15:42:36.043042: Resource operation 'notify' for 'res_pgsql' on 'ke01': ok
2021-09-24 15:42:37.464065: Resource operation 'notify' for 'res_pgsql' on 'ke01': ok
2021-09-24 15:42:48.924662: Resource operation 'notify' for 'res_rabbitmq' on 'ke01': ok
```

#### 3.4.1.2. メール通知の設定
Pacemaker アラートをメールで通知したい場合、Pacemaker に付属する `alert_smtp.sh.sample` というサンプルスクリプトを利用することが出来ます。

まず、各サーバ上で以下の手順を実行して、`alert_smtp.sh` スクリプトの有効化を行ってください。

```
# install -m 0755 /usr/share/pacemaker/alerts/alert_smtp.sh.sample /var/lib/pacemaker/alert_smtp.sh
```

次に、アクティブ状態のサーバ上で以下の手順を実行して、Pacemaker アラートの設定を行なってください。このとき、アラートメールの送信元と送信先を指定することが出来ますので、ご利用の環境に合わせて設定してください。

```
# pcs alert create id=smtp_alert path=/var/lib/pacemaker/alert_smtp.sh \
    options email_sender=pacemaker@example.co.jp
# pcs alert recipient add smtp_alert value=staff@example.co.jp
```

ただし、`alert_smtp.sh` では `sendmail` コマンドを用いてメールの送信を行ないますので、各サーバのメール配送に関する設定が適切になされていないと正しくメールが送信されない、または届かないことがありますのでご注意ください。とくにクラウド環境では迷惑メール対策として `OP25B` と呼ばれる仕組みで、外部へのメール送信がブロックされていることがあります。

- [Amazon EC2 インスタンスまたは AWS Lambda 関数のポート 25 に対する制限を解除するにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-port-25-throttle/)

アラートメールを外部に送信したい場合は必要に応じて個別に対策を行なってください。その方法などにつきましては、本記事の対象外となります。

# 4. 冗長構成の管理
## 4.1. crm_mon コマンドによる正常性確認
root 権限で crm_mon コマンドを実行することで、冗長構成の状態を確認できます。
そのままコマンドを実行した場合、若干表示される情報が足りない為、-Af をつけて実行します。

```
# crm_mon -Af
```

上記コマンドを実行すると、topコマンド等と同様、常時画面にステータスが更新されて表示されるため、
「ctrl+c」を押してプロンプトに戻るか、コマンド実行時に追加で「-1」オプションをつけてください。

### 4.1.1. 通常運転時（両系）の正常性確認
```
[root@ke01 pacemaker]# crm_mon -Af1
Cluster Summary:
  * Stack: corosync
  * Current DC: ke01 (version 2.0.5-9.el8_4.1-ba59be7122) - partition with quorum
  * Last updated: Thu Sep 16 18:00:11 2021
  * Last change:  Thu Sep 16 17:39:18 2021 by hacluster via crmd on ke01
  * 2 nodes configured
  * 11 resource instances configured

Node List:
  * Online: [ ke01 ke02 ]

Active Resources:
  * Resource Group: webserver:
    * res_memcached     (systemd:memcached):     Started ke01
    * res_httpd (ocf::heartbeat:apache):         Started ke01
    * res_kompirad      (systemd:kompirad):      Started ke01
    * res_kompira_jobmngrd      (systemd:kompira_jobmngrd):      Started ke01
    * res_lsyncd        (systemd:lsyncd):        Started ke01
  * Clone Set: res_pgsql-clone [res_pgsql] (promotable):
    * Masters: [ ke01 ]
    * Slaves: [ ke02 ]
  * Clone Set: res_rabbitmq-clone [res_rabbitmq]:
    * Started: [ ke01 ke02 ]
  * res_stonith1        (stonith:fence_aws):     Started ke02
  * res_stonith2        (stonith:fence_aws):     Started ke01

Node Attributes:
  * Node: ke01:
    * master-res_pgsql                  : 1001
    * rmq-node-attr-last-known-res_rabbitmq     : rabbit@ke01
    * rmq-node-attr-res_rabbitmq        : rabbit@ke01
  * Node: ke02:
    * master-res_pgsql                  : 1000
    * rmq-node-attr-last-known-res_rabbitmq     : rabbit@ke02
    * rmq-node-attr-res_rabbitmq        : rabbit@ke02

Migration Summary:
```

- チェックポイント
    - `Online:` に 2 台表示されている。
    - リソースグループ `webserver` の全てのリソースが `Started` になっている。
    - クローンセット `res_pgsql-clone` で、`Masters:` と `Slaves:` に 1 台ずつ表示されている。
    - クローンセット `res_rabbitmq-clone` で、`Started:` に 2 台表示されている。
    - `Node Attributes:` の `master-res_pgsql` で、Slave 側が 1000 になっている。
    
### 4.1.2.	縮退運転時（片系）の正常性確認
```
[root@ke01 pacemaker]# crm_mon -Af1
Cluster Summary:
  * Stack: corosync
  * Current DC: ke01 (version 2.0.5-9.el8_4.1-ba59be7122) - partition with quorum
  * Last updated: Thu Sep 16 18:23:56 2021
  * Last change:  Thu Sep 16 18:20:56 2021 by root via crm_attribute on ke01
  * 2 nodes configured
  * 11 resource instances configured

Node List:
  * Online: [ ke01 ]
  * OFFLINE: [ ke02 ]

Active Resources:
  * Resource Group: webserver:
    * res_memcached     (systemd:memcached):     Started ke01
    * res_httpd (ocf::heartbeat:apache):         Started ke01
    * res_kompirad      (systemd:kompirad):      Started ke01
    * res_kompira_jobmngrd      (systemd:kompira_jobmngrd):      Started ke01
    * res_lsyncd        (systemd:lsyncd):        Started ke01
  * Clone Set: res_pgsql-clone [res_pgsql] (promotable):
    * Masters: [ ke01 ]
  * Clone Set: res_rabbitmq-clone [res_rabbitmq]:
    * Started: [ ke01 ]
  * res_stonith2        (stonith:fence_aws):     Started ke01

Node Attributes:
  * Node: ke01:
    * master-res_pgsql                  : 1001
    * rmq-node-attr-last-known-res_rabbitmq     : rabbit@ke01
    * rmq-node-attr-res_rabbitmq        : rabbit@ke01

Migration Summary:
```

- チェックポイント
    - Online: に少なくとも 1 台表示されている。
    - リソースグループ `webserver` の全てのリソースが `Started` になっている。
    - クローンセット `res_pgsql-clone` で、`Masters:` に 1 台表示されている。
    - クローンセット `res_rabbitmq-clone` で、`Started:` に 1 台表示されている。
    - `res_pgsql-clone` の `Masters:` と `res_rabbitmq-clone` の `Started:` が同じになっている。

## 4.2. 手動フェイルオーバ
両系で正常に冗長構成が動作している状態において、手動でフェイルオーバさせたい場面もあるかと思います。手動でフェイルオーバさせる方法はいくつかあります。

- アクティブ状態にあるサーバをシャットダウンする
- アクティブ状態にあるサーバ上のクラスターを停止させる

ここでは、アクティブ状態にあるサーバ上のクラスターを停止させる方法を紹介します。以下のコマンドをアクティブ状態のサーバで実行してください。

```
# pcs cluster stop
```

アクティブ状態のサーバが停止して、しばらくするとフェイルオーバが開始するはずです。フェイルオーバに成功すると、これまでスタンバイ状態であったサーバがアクティブ状態に昇格して、サービスを継続します。ただし、この時点では、もともとアクティブ状態であったサーバは動作を止めているため、冗長構成としては片系での縮退運転をしている状態になりますので注意してください。

## 4.3. 障害系の復旧
片系での縮退運転になっている状態で、動作を止めていた系のサーバを冗長構成に復旧させるためには `sync_master.sh` というコマンドを実行する必要があります。このコマンドはアクティブ状態で動作中のサーバとデータベースなどの同期を行なって、適切にスタンバイ状態として動作を開始することで、両系での通常運転に復旧することを試みます。

以下はクラスターが停止しているセカンダリ機で sync_master.sh を実行したときの様子です。

```
[root@ke02 ~]# /opt/kompira/bin/sync_master.sh
[2021-09-16 18:36:34] ****: ****************************************************************
[2021-09-16 18:36:34] ****: Kompira-1.6.2.post7:
[2021-09-16 18:36:34] ****: Start: Sync with the Master
[2021-09-16 18:36:34] ****:
[2021-09-16 18:36:34] INFO:     SYSTEM                   = RHEL
[2021-09-16 18:36:34] INFO:     SYSTEM_NAME              = rhel8
[2021-09-16 18:36:34] INFO:     SYSTEM_RELEASE           = Red Hat Enterprise Linux release 8.4 (Ootpa)
[2021-09-16 18:36:34] INFO:     SYSTEM_RELEASEVER        = 8.4
[2021-09-16 18:36:34] INFO:     PLATFORM_PYTHON          = /usr/libexec/platform-python
[2021-09-16 18:36:34] INFO:     PYTHON                   = /usr/bin/python3.6
[2021-09-16 18:36:34] INFO:     SYSTEMD                  = true
[2021-09-16 18:36:34] INFO:     TMPDIR                   = /tmp
[2021-09-16 18:36:34] ****: ----------------------------------------------------------------
[2021-09-16 18:36:34] ****: Check cluster status.
[2021-09-16 18:36:34] ****:
[2021-09-16 18:36:35] INFO: Pacemaker is stop.
[2021-09-16 18:36:35] ****: ----------------------------------------------------------------
[2021-09-16 18:36:35] ****: Start pacemaker service.
[2021-09-16 18:36:35] ****:
[2021-09-16 18:36:35] INFO: Start service: pacemaker
[2021-09-16 18:36:35] VERBOSE: run: systemctl start pacemaker
[2021-09-16 18:36:35] INFO: Waiting Current DC...................
[2021-09-16 18:36:58] INFO: Pacemaker has stablized.
[2021-09-16 18:36:58] INFO: HA_LOCALNAME=ke02
[2021-09-16 18:36:58] INFO: HA_OTHERNAME=ke01
[2021-09-16 18:37:00] WARN: PostgreSQL is stop (rc=2)
[2021-09-16 18:37:00] INFO: Pacemaker is running (SLAVE)
[2021-09-16 18:37:00] INFO: Waiting for the resources to stabilize.
    PostgreSQL   | RabbitMQ
    -1000,  1001 |                  #NA,          rabbit@ke01
    -1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |                  #NA,          rabbit@ke01
     1000,  1001 |          rabbit@ke02,          rabbit@ke01
[2021-09-16 18:37:13] INFO: Resources stabilized.
[2021-09-16 18:37:13] INFO: PostgreSQL is running as a hot standby.
[2021-09-16 18:37:13] INFO: PostgreSQL on this node is running as a Slave.
[2021-09-16 18:37:13] INFO: Enter the pacemaker in maintenance mode.
[2021-09-16 18:37:13] VERBOSE: run: pcs property set maintenance-mode=true
[2021-09-16 18:37:13] VERBOSE: run: crm_failcount -r res_vip -D
crm_resource: Resource 'res_vip' not found
Error performing operation: No such device or address
[2021-09-16 18:37:13] VERBOSE: status=105
[2021-09-16 18:37:13] VERBOSE: run: crm_failcount -r res_httpd -D
Cleaned up res_memcached on ke02
Cleaned up res_httpd on ke02
Cleaned up res_kompirad on ke02
Cleaned up res_kompira_jobmngrd on ke02
Cleaned up res_lsyncd on ke02
[2021-09-16 18:37:14] VERBOSE: run: crm_failcount -r res_kompirad -D
Cleaned up res_memcached on ke02
Cleaned up res_httpd on ke02
Cleaned up res_kompirad on ke02
Cleaned up res_kompira_jobmngrd on ke02
Cleaned up res_lsyncd on ke02
[2021-09-16 18:37:14] VERBOSE: run: crm_failcount -r res_kompira_jobmngrd -D
Cleaned up res_memcached on ke02
Cleaned up res_httpd on ke02
Cleaned up res_kompirad on ke02
Cleaned up res_kompira_jobmngrd on ke02
Cleaned up res_lsyncd on ke02
[2021-09-16 18:37:14] VERBOSE: run: crm_failcount -r res_lsyncd -D
Cleaned up res_memcached on ke02
Cleaned up res_httpd on ke02
Cleaned up res_kompirad on ke02
Cleaned up res_kompira_jobmngrd on ke02
Cleaned up res_lsyncd on ke02
[2021-09-16 18:37:14] VERBOSE: run: crm_failcount -r res_memcached -D
Cleaned up res_memcached on ke02
Cleaned up res_httpd on ke02
Cleaned up res_kompirad on ke02
Cleaned up res_kompira_jobmngrd on ke02
Cleaned up res_lsyncd on ke02
[2021-09-16 18:37:14] VERBOSE: run: crm_failcount -r res_rabbitmq -D
Cleaned up res_rabbitmq:0 on ke02
Cleaned up res_rabbitmq:1 on ke02
[2021-09-16 18:37:14] INFO: Exit the pacemaker from maintenance mode.
[2021-09-16 18:37:14] VERBOSE: run: pcs property set maintenance-mode=false
[2021-09-16 18:37:15] INFO: PostgreSQL is running as a hot standby.
[2021-09-16 18:37:15] INFO: Pacemaker is running (SLAVE)
[2021-09-16 18:37:15] INFO: Waiting for the resources to stabilize.
    PostgreSQL   | RabbitMQ
     1000,  1001 |          rabbit@ke02,          rabbit@ke01
[2021-09-16 18:37:15] INFO: Resources stabilized.
[2021-09-16 18:37:15] INFO: Display failcount for each resources.
scope=status  name=fail-count-res_vip value=0
scope=status  name=fail-count-res_httpd value=0
scope=status  name=fail-count-res_kompirad value=0
scope=status  name=fail-count-res_kompira_jobmngrd value=0
scope=status  name=fail-count-res_lsyncd value=0
scope=status  name=fail-count-res_memcached value=0
scope=status  name=fail-count-res_pgsql value=0
scope=status  name=fail-count-res_rabbitmq value=0
[2021-09-16 18:37:15] INFO: Display constraint setings of resources.
Location Constraints:
  Resource: res_stonith1
    Disabled on:
      Node: ke01 (score:-INFINITY)
  Resource: res_stonith2
    Disabled on:
      Node: ke02 (score:-INFINITY)
Ordering Constraints:
  promote res_pgsql-clone then start webserver (kind:Mandatory)
  Resource Sets:
    set res_rabbitmq-clone role=Started set webserver
Colocation Constraints:
  webserver with res_pgsql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master)
  res_pgsql-clone with res_rabbitmq-clone (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started)
Ticket Constraints:
[2021-09-16 18:37:16] INFO: Display state of resources.
  * Resource Group: webserver:
    * res_memcached     (systemd:memcached):     Started ke01
    * res_httpd (ocf::heartbeat:apache):         Started ke01
    * res_kompirad      (systemd:kompirad):      Started ke01
    * res_kompira_jobmngrd      (systemd:kompira_jobmngrd):      Started ke01
    * res_lsyncd        (systemd:lsyncd):        Started ke01
  * Clone Set: res_pgsql-clone [res_pgsql] (promotable):
    * Masters: [ ke01 ]
    * Slaves: [ ke02 ]
  * Clone Set: res_rabbitmq-clone [res_rabbitmq]:
    * Started: [ ke01 ke02 ]
[2021-09-16 18:37:16] ****:
[2021-09-16 18:37:16] ****: Finish: Sync with the Master (status=0)
[2021-09-16 18:37:16] ****: ****************************************************************
```

最終的に `status=0` で正常終了しており、冗長構成が正常に復旧したことがわかります。

### 4.3.1. マスターノードが電源オフあるいは強制再起動した場合の sync_master による復旧時の注意
マスター状態で動作していたノードが、シャットダウン操作を伴わない電源オフ、あるいは STONITH で強制再起動させられるような場合、Postgresql のディスク上の状態はマスター動作していたときのままとなっています。再起動後にフェイルオーバが成功しているクラスターに参加させると、Postgresql がマスター同士であるためレプリケーション接続でエラーが発生してフェイルオーバした現在のマスターノードがダウンしてしまう場合があります。

こうした事態が想定されるときは、再起動したノードで sync_master.sh を実行する前に、手動でデータベースを現在のマスターからコピーしておくことを推奨します。

```
# rm -rf /var/lib/pgsql/12/data.old
# mv -f /var/lib/pgsql/12/data /var/lib/pgsql/12/data.old
(cd /; sudo -u postgres pg_basebackup -h ha-kompira-other -U repl -D /var/lib/pgsql/12/data -X stream -P)
```
