‘Quick start on RHEL 8’

このクイックスタートを使用して、RHEL 8でEDB Postgres Advanced ServerまたはEDB Postgres Extended Serverバージョン15を使用して高可用性のデモクラスターを作成します。 etcdホストはetcd1 、etcd2 、およびetcd3 と呼ばれます。ストリーミングレプリケーションの2つのデータベースノードはpg-patroni1 とpg-patroni2 です。

Demo diagram

Demo diagram


Etcd

etcdをインストールして設定するには、 'Installing and configuring etcd' を参照してください。

EDB Postgres AdvancedまたはExtended Server

pg-patroni1 とpg-patroni2 の両方のホストで、好みのフレーバーのPostgresをインストールします。 EDBリポジトリを使用してこれらの製品をインストールする方法の詳細については、

EDB Postgres Advanced Server または EDB Postgres Extended Server を参照してください。

選択したPostgresフレーバーによって環境変数が決まります。

EDB Postgres Advanced Serverの場合、次の設定を使用します。

export PGPORT=5444
export PGUSER=enterprisedb
export PGGROUP=enterprisedb
export PGDATA="/var/lib/edb/as15/data"
export PGBIN="/usr/edb/as15/bin"
export PGSOCKET="/var/run/edb/as15"

EDB Postgres Extended Serverの場合、次の設定を使用します。

export PGPORT=5432
export PGUSER=postgres
export PGGROUP=postgres
export PGDATA="/var/lib/edb-pge/15/data"
export PGBIN="/usr/edb/pge15/bin"
export PGSOCKET="/var/run/edb-pge"

Patroniは最初のPostgresクラスターをブートストラップ(作成)し、サービスの開始を担当するため、このサービスでsystemctl が無効になっていることを確認します。

$ sudo systemctl disable edb-as-15.service
```または

```bash
$ sudo systemctl disable edb-pge-15.service

Postgresサービスへの接続を受け入れるように、各データベースノードでファイアウォールを構成します。

$ sudo firewall-cmd --quiet --zone=public --add-port=$PGPORT/tcp --permanent
$ sudo firewall-cmd --quiet --reload

ウォッチドッグ

Patroniは、ウォッチドッグデバイスと対話するコンポーネントです。 pg-patroni1 とpg-patroni2 の両方のホストでソフトウェアウォッチドッグの権限を設定します。

$ cat <<EOF | sudo tee /etc/udev/rules.d/99-watchdog.rules
KERNEL=="watchdog", OWNER="$PGUSER", GROUP="$PGGROUP"
EOF
$ sudo sh -c echo "softdog" >> /etc/modules-load.d/softdog.conf
$ sudo modprobe softdog
$ sudo chown $PGUSER:$PGGROUP /dev/watchdog

パトローニ

pg-patroni1 とpg-patroni2 の両方のホストで、etcdのPatroniとその依存関係をインストールします。

'Installing Patroni' を参照してください。

/etc/patroni.yml でPatroni構成を定義します。

$ CLUSTER_NAME="demo-cluster-1"
$ MY_NAME=$(hostname --short)
$ MY_IP=$(hostname -I | awk  {print $1})
$ cat <<EOF | sudo tee /etc/patroni.yml
scope: $CLUSTER_NAME
namespace: /db/
name: $MY_NAME

restapi:
  listen: "0.0.0.0:8008"
  connect_address: "$MY_IP:8008"
  authentication:
    username: patroni
    password: mySupeSecretPassword

etcd3:
    hosts:
    - etcd1:2379
    - etcd2:2379
    - etcd3:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      parameters:
        archive_mode: "on"
        archive_command: "/bin/true"

  initdb:
  - encoding: UTF8
  - data-checksums
  - auth-local: peer
  - auth-host: scram-sha-256

  pg_hba:
  - host replication replicator 0.0.0.0/0 scram-sha-256
  - host all all 0.0.0.0/0 scram-sha-256

  # Some additional users which needs to be created after initializing new cluster
  users:
    admin:
      password: admin%
      options:
        - createrole
        - createdb

postgresql:
  listen: "0.0.0.0:$PGPORT"
  connect_address: "$MY_IP:$PGPORT"
  data_dir: $PGDATA
  bin_dir: $PGBIN
  pgpass: /tmp/pgpass0
  authentication:
    replication:
      username: replicator
      password: confidential
    superuser:
      username: $PGUSER
      password: my-super-password
    rewind:
      username: rewind_user
      password: rewind_password
  parameters:
    unix_socket_directories: "$PGSOCKET,/tmp"

watchdog:
  mode: required
  device: /dev/watchdog
  safety_margin: 5

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false
EOF

注釈

この例の`postgresql: authentication:` セクションでは、初期化(initdb)中にスーパーユーザーが作成され、後でPatroniがデータベースに接続するために使用します。レプリケーションユーザーは、スタンバイサーバーがストリーミングレプリケーションを介してレプリケーションソースにアクセスするために作成および使用されます。最後に、巻き戻しユーザーが作成され、必要に応じて pg_rewind で使用されます。次に、パスワードポリシーに合わせて構成例のパスワードを変更することをお勧めします。

$MY_IP および$MY_NAME はローカルホストに固有です。それ以外の場合、 patroni.yml 構成はすべてのPatroniノードで同じです。

Patroniは、bin_dir の場所でpostgres バイナリを見つけますが、 EDB Postgres Advanced Serverバイナリはedb-postgres と呼ばれます。 Patroniがそのバイナリを見つけられるようにするシンボリックリンクを作成します。

$ sudo ln -s /usr/edb/as15/bin/edb-postgres /usr/edb/as15/bin/postgres

Patroniのインストールソースによっては、 systemd file が既に作成されている場合があります。正確なシステムユーザー、グループ、および構成パスを使用して独自のファイルを定義します。

$ cat <<EOF | sudo tee /etc/systemd/system/patroni.service
[Unit]
Description=Runners to orchestrate a high-availability Postgres
After=syslog.target network.target

[Service]
Type=simple
User=$PGUSER
Group=$PGGROUP
EnvironmentFile=-/etc/patroni_env.conf
ExecStart=patroni /etc/patroni.yml
ExecReload=/bin/kill -s HUP \$MAINPID
KillMode=process
TimeoutSec=30
Restart=no

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl daemon-reload
$ sudo systemctl enable patroni
$ sudo systemctl start patroni

最初にpg-patroni1 でPatroniサービスを開始して、Postgresクラスターのリーダーにします。次に、pg-patroni2 を起動します。

クラスターのメンバーをリストするには、 patronictl コマンドを使用します。

$ patronictl -c /etc/patroni.yml list
+ Cluster: demo-cluster-1 (7104275668989116902) ----+----+-----------+
| Member      | Host            | Role    | State   | TL | Lag in MB |
+-------------+-----------------+---------+---------+----+-----------+
| pg-patroni1 | 192.168.121.61  | Leader  | running |  1 |           |
| pg-patroni2 | 192.168.121.135 | Replica | running |  1 |         0 |
+-------------+-----------------+---------+---------+----+-----------+

Patroni REST APIはポート8008 で利用できます。必要に応じてファイアウォールを構成します。

$ sudo firewall-cmd --quiet --zone=public --add-port=8008/tcp --permanent
$ sudo firewall-cmd --quiet --reload

HAProxy

PGDG yum extras リポジトリにはhaproxyパッケージが含まれています。

システムで yum.postgresql.org を設定して使用するには、 PostgreSQL Linux downloads website を参照してください。

この例では、 pg-patroni1 とpg-patroni2 の両方のホストにHAProxyをインストールします。

$ sudo dnf --enablerepo=pgdg-rhel8-extras install -y haproxy
$ sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bck
$ cat <<EOF | sudo tee /etc/haproxy/haproxy.cfg
global
    maxconn 100

defaults
    log    global
    mode    tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen read-write
    bind *:5000
    option httpchk OPTIONS /read-write
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server pg-patroni1 pg-patroni1:$PGPORT maxconn 100 check port 8008
    server pg-patroni2 pg-patroni2:$PGPORT maxconn 100 check port 8008

listen read-only
    balance roundrobin
    bind *:5001
    option httpchk OPTIONS /replica
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server pg-patroni1 pg-patroni1:$PGPORT maxconn 100 check port 8008
    server pg-patroni2 pg-patroni2:$PGPORT maxconn 100 check port 8008
EOF

$ sudo setsebool -P haproxy_connect_any=1
$ sudo systemctl enable haproxy
$ sudo systemctl start haproxy

ポート5000 を使用する読み取り-書き込みと、ポート5001 を使用する読み取り専用の2つのセクションがあります。すべてのPostgresホストは、すべてプライマリまたはスタンバイの潜在的な候補であるため、両方のセクションに含まれています。 HAproxyが各ホストに現在持っているロールを知るには、Patroni REST APIを照会します。

$ curl -s http://pg-patroni1:8008
{
   "state":"running",
   "postmaster_start_time":"2023-03-21 11:23:54.709344+00:00",
   "role":"master",
   "server_version":150002,
   "xlog":{
      "location":67112696
   },
   "timeline":1,
   "replication":[
      {
        "usename":"replicator",
        "application_name": "pg-patroni2",
        "client_addr": "192.168.121.135",
        "state":"streaming",
        "sync_state":"async",
        "sync_priority":0
      }
   ],
   "dcs_last_seen":1679401036,
   "database_system_identifier":"7104275668989116902",
   "patroni":{
      "version":"3.0.1",
      "scope":"demo-cluster-1"
   }
}

注釈

/replica エンドポイントを使用することにより、Patroniはスタンバイサーバーのみにリダイレクトします。 /read-only を使用して、プライマリも含めます。

HAProxyがリッスンするポートにアクセスする必要がある場合は、ファイアウォールを構成します。

$ sudo firewall-cmd --quiet --zone=public --add-port=7000/tcp --permanent
$ sudo firewall-cmd --quiet --zone=public --add-port=5000/tcp --permanent
$ sudo firewall-cmd --quiet --zone=public --add-port=5001/tcp --permanent
$ sudo firewall-cmd --quiet --reload

ポート 5000 とポート 5001 を使用して、読み書き接続または読み取り専用接続を選択できるようになりました。

$ psql -U admin -d postgres -h pg-patroni1 -p 5000 -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
- ------------------
 f
(1 row)

$ psql -U admin -d postgres -h pg-patroni1 -p 5001 -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
- ------------------
 t
(1 row)