Pgpool-II の準備

各 Swarm ノード上で実行している Kompira エンジンや Kompira アプリケーションサーバのコンテナからアクセス可能なデータベースとして、 PostgreSQL/Pgpool-II クラスタを構築する手順について説明します。

Pgpool-II を用いたデータベースクラスタには最低で 3台 のホストが必要となります。

ここでは、Docker Swarm クラスタのホスト上にデータベースクラスタを同居した形で構築していますが、Docker Swarm クラスタとは別にデータベースクラスタを構築しても構いません。

PostgreSQL/Pgpool-II のセットアップ

ここでは、ke2-docker パッケージに附属するセットアップ用のスクリプトを用いて構築する手順を示します。このスクリプトは RHEL 9系 (CentOS Stream 9、Rocky Linux 9、AlmaLinux 9など互換 OS を含む) のサーバを対象としています。その他の OS 上にセットアップする場合は、スクリプトの内容を参考にして構築してください。

なお、本セットアップスクリプトでは、PostgreSQL/Pgpool-II の各ユーザとパスワードをデフォルトで以下のように設定します。

ユーザ名パスワード備考
kompirakompiraKompiraアクセス用のユーザ
pgpoolpgpoolPgpool-IIでの以下用途の専用ユーザ
レプリケーション遅延チェック(sr_check_user)
ヘルスチェック(health_check_user)
postgrespostgresオンラインリカバリの実行ユーザ
replreplPostgreSQLのレプリケーション専用ユーザ

重要: 上記のユーザ名・パスワードは setup_pgpool.sh のデフォルト値(検証・初期構築向けの弱いパスワード)です。本番運用では必ず独自の強いパスワードに変更してください。

強いパスワードを設定する方法は 2 通りあります。構築後の同期作業が不要でミスが起きにくいため、初期構築時に指定する方法を推奨します。

  • 推奨: 初期構築時に指定する — setup_pgpool.sh の実行時に環境変数 PG_KOMPIRA_PASS / PG_POOL_PASS / PG_PASS / PG_REPL_PASS で各ユーザのパスワードを指定すると、その値で初期化されます(次の (2) を参照)。
  • 構築後に変更する — すでにデフォルト値で構築してしまった場合は、資格情報管理 §4.3 の手順で変更します。この場合、PostgreSQL 側だけでなく Pgpool-II の pool_passwd全ノードで同期する必要があります。

(1) 各ホストへのスクリプトファイル転送

ke2-docker パッケージの ke2/cluster/swarm ディレクトリに含まれる以下のスクリプトファイルを、クラスタを構成する各ホストに転送してください。

  • setup_pgpool.sh
  • setup_pgssh.sh

(2) PostgreSQL/Pgpool-II のインストール

各ホストで setup_pgpool.sh スクリプトを実行します。このスクリプトでは、PostgreSQL 16、および、Pgpool-II のインストールと初期設定を行います。setup_pgpool.sh 起動時には以下の環境変数を指定する必要があります。

  • CLUSTER_VIP: Pgpool-II で使用する仮想IPアドレス
  • CLUSTER_HOSTS: クラスタを構成するホスト名(空白区切り)。各ホストの hostname コマンドの出力と一致させてください(FQDN で運用している場合は FQDN を指定します)。

CLUSTER_HOSTS の最初のホストを「プライマリサーバ」として、残りのホストを「セカンダリサーバ」としてセットアップします。また CLUSTER_HOSTS の順番に Pgpool-II 上でのノード ID を 0, 1, 2,... と割り当てます。したがって、各ホスト上で setup_pgpool.sh を実行する際に、CLUSTER_HOSTS のホスト順序は同一にする必要があることに注意してください。

さらに、本番運用では以下の環境変数で各ユーザの初期パスワードを指定してください(省略すると前掲のデフォルトの弱いパスワードになります)。

  • PG_KOMPIRA_PASS: kompira ユーザのパスワード
  • PG_POOL_PASS: pgpool ユーザのパスワード
  • PG_PASS: postgres ユーザのパスワード
  • PG_REPL_PASS: repl ユーザのパスワード

注意: これらのパスワードは全ホストで同一の値を指定してください。 プライマリサーバが指定値でユーザを作成し、各ホストは自身に指定された値で Pgpool-II の認証情報 (pool_passwd) を生成するため、ホスト間で値が異なると認証に失敗します。

以下に実行例を示します(デフォルトの弱いパスワードのままセットアップする例)。

[全ホスト]$ CLUSTER_VIP=10.20.0.100 CLUSTER_HOSTS='ke2-server1 ke2-server2 ke2-server3' ./setup_pgpool.sh

本番運用向けに、初期パスワードを指定してセットアップする例を以下に示します(<...> は実際の強いパスワードに置き換え、全ホストで同じ値を指定してください)。

[全ホスト]$ CLUSTER_VIP=10.20.0.100 CLUSTER_HOSTS='ke2-server1 ke2-server2 ke2-server3' \
    PG_KOMPIRA_PASS='<KOMPIRA_PASSWORD>' PG_POOL_PASS='<PGPOOL_PASSWORD>' \
    PG_PASS='<POSTGRES_PASSWORD>' PG_REPL_PASS='<REPL_PASSWORD>' \
    ./setup_pgpool.sh

一般ユーザで実行する場合、起動後に sudo のパスワードの入力を求められます。

(3) Pgpool-II 用の SSH 接続設定

各ホストで setup_pgssh.sh スクリプトを実行します。このスクリプトでは Pgpool-II の自動フェイルオーバおよびオンラインリカバリ機能を利用するため、各ノード間で postgres ユーザが公開鍵認証で SSH 接続できるように設定します。 先ほどの手順と同様に CLUSTER_HOSTS 環境変数を指定して setup_pgssh.sh スクリプトを実行してください。

[全ホスト]$ CLUSTER_HOSTS='ke2-server1 ke2-server2 ke2-server3' ./setup_pgssh.sh

setup_pgssh.sh は postgres ユーザの SSH 鍵ファイルを作成し、公開鍵ファイルを CLUSTER_HOSTS で指定された各ホストの ~postgres/.ssh/authorized_keys に追加することで、パスワード無しで SSH 接続できるようにします。 一般ユーザで実行する場合、起動後に sudo のパスワードを入力、および、実行ユーザがクラスタを構成する各リモートホストにログインするためのパスワードとリモートホストでの sudo パスワードの入力を求められます。

パスワード入力を間違えるなどで公開鍵の転送に失敗していると、Pgpool-II が正常に機能しなくなるので注意してください。

前提: setup_pgssh.sh を実行するユーザは、CLUSTER_HOSTS に指定した全ホストへ SSH ログインでき、かつ各ホストで sudo できる必要があります。 上記の対話パスワード入力は、実行ユーザが各ホストへログインできることが前提です。SSH ログインできないホストがあると公開鍵を配布できず、Pgpool-II が正常に機能しません。事前に全ホスト間で実行ユーザの SSH ログインが可能なことを確認しておいてください。

Pgpool-II の起動とオンラインリカバリ

ここでは、Pgpool-II を起動して PostgreSQL のクラスタ構成を行ないます。

(1) Pgpool-II の起動

プライマリサーバ(ここでは ke2-server1 を想定)から順番に、各ホスト上で以下のコマンドを実行して Pgpool-II を起動してください。

[全ホスト]$ sudo systemctl start pgpool

注意: Pgpool-II の起動直後は、watchdog による仮想IP (VIP) の割り当てに数秒程度かかることがあります。 起動直後に VIP 経由の接続(次の手順の psql -h $CLUSTER_VIP など)を行うと "No route to host" 等で失敗する場合があります。その場合は数秒待ってから再度実行してください。

(2) プライマリサーバの状態確認

プライマリサーバでは setup_pgpool.sh の実行によって、既に PostgreSQL サーバが起動しています。 いずれかのホスト上で以下のコマンドを実行して、プライマリサーバで PostgreSQL がプライマリモードで動作していることを確認してください。

[任意のホスト]$ psql -h $CLUSTER_VIP -p 9999 -U pgpool postgres -c "show pool_nodes"

$CLUSTER_VIP の部分は Pgpool-II で使用する仮想IPアドレスに置き換えるか、シェル変数 CLUSTER_VIP としてそのアドレスを設定しておいてください。下記の例では、プライマリサーバである ke2-server1 で PostgreSQL がプライマリモードで起動しており(pg_status が "up"、pg_role が "primary")、ke2-server2 と ke2-server3 では PostgreSQL がまだ起動していないこと(pg_status が "down")が分かります。

[ke2-server1]$ psql -h 10.20.0.100 -p 9999 -U pgpool postgres -c "show pool_nodes"
ユーザー pgpool のパスワード: 
 node_id |   hostname  | port | status | pg_status | lb_weight |  role   | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+-------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | ke2-server1 | 5432 | up     | up        | 0.333333  | primary | primary | 0          | true              | 0                 |                   |                        | 2024-06-11 18:18:20
 1       | ke2-server2 | 5432 | down   | down      | 0.333333  | standby | unknown | 0          | false             | 0                 |                   |                        | 2024-06-11 18:16:06
 2       | ke2-server3 | 5432 | down   | down      | 0.333333  | standby | unknown | 0          | false             | 0                 |                   |                        | 2024-06-11 18:16:06
(3 行)

(3) スタンバイサーバのオンラインリカバリ

Pgpool-II のオンラインリカバリ機能を利用し、ke2-server2 と ke2-server3 をスタンバイサーバとして起動させて、Pgpool-II 管理下に追加します。

オンラインリカバリさせるには、以下のように pcp_recovery_node コマンドを実行してください。

[任意のホスト]$ pcp_recovery_node -h $CLUSTER_VIP -p 9898 -U pgpool -n <NODE_ID> -W

<NODE_ID> の部分はオンラインリカバリさせるノード ID に置き換えてください。上で確認したとおり ke2-server1 がノードID 0 でプライマリサーバとして動作していますので、ここではノード ID に 1 および 2 を指定して ke2-server2 と ke2-server3 をオンラインリカバリさせています。

[ke2-server1]$ pcp_recovery_node -h 10.20.0.100 -p 9898 -U pgpool -n 1 -W
Password:
pcp_recovery_node -- Command Successful

[ke2-server1]$ pcp_recovery_node -h 10.20.0.100 -p 9898 -U pgpool -n 2 -W
Password:
pcp_recovery_node -- Command Successful

(4) スタンバイサーバの状態確認

オンラインリカバリによって PostgreSQL のスタンバイサーバが起動していることを、再び以下のコマンドで確認してください。

[任意のホスト]$ psql -h $CLUSTER_VIP -p 9999 -U pgpool postgres -c "show pool_nodes"

以下の例では、ke2-server2 と ke2-server3 で PostgreSQL がスタンバイサーバとして起動していること(pg_status が "up"、pg_role が "standby")が分かります。

[ke2-server1]$ psql -h 10.20.0.100 -p 9999 -U pgpool postgres -c "show pool_nodes"
ユーザー pgpool のパスワード: 
 node_id |   hostname  | port | status | pg_status | lb_weight |  role   | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+-------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | ke2-server1 | 5432 | up     | up        | 0.333333  | primary | primary | 0          | false             | 0                 |                   |                        | 2024-06-11 18:18:20
 1       | ke2-server2 | 5432 | up     | up        | 0.333333  | standby | standby | 0          | true              | 0                 | streaming         | async                  | 2024-06-11 18:22:54
 2       | ke2-server3 | 5432 | up     | up        | 0.333333  | standby | standby | 0          | false             | 0                 | streaming         | async                  | 2024-06-11 18:22:54
(3 行)