Patroni on Ubuntu — PostgreSQL自動フェイルオーバーHAクラスター構築

データベース

PostgreSQL を本番運用していると、「プライマリサーバーが落ちたら手動で切り替えるの…?」という不安に必ずぶつかります。Patroni はプライマリ障害を自動検知してスタンバイを昇格させる、PostgreSQL の自動フェイルオーバーツールです。深夜に叩き起こされて pg_promote を手打ちする運用から解放してくれます。

結論から言うと、Ubuntu 24.04 LTS なら apt install patroni etcd-server etcd-client postgresql の1コマンドで全コンポーネントが揃います。実際に ubuntu:24.04 公式Dockerイメージで動かして確認したところ、Patroni 3.2.2・etcd 3.4.30・PostgreSQL 16.14 が pip なしで導入され、python3-etcd 0.4.5-4 も依存として自動で入りました(2026-06-14 実測)。

本記事では、その実測結果をベースに HA クラスターの構築手順を解説します。さらに etcd の起動・健全性確認、patroni --validate-config による設定検証まで実際に走らせた出力を載せます。

この記事のポイント

  • Ubuntu 24.04 では apt install patroni etcd-server etcd-client postgresql だけで導入完了(pip 不要・実測)
  • etcd のパッケージ名は 24.04 で etcd が廃止され、etcd-server + etcd-client に分割された(22.04 との実測比較で判明)
  • 導入されるのは Patroni 3.2.2 / etcd 3.4.30 / PostgreSQL 16.14(いずれも apt 候補を実測)
  • 自動フェイルオーバーの所要時間はデフォルト設定で約30〜60秒(ttl 値で調整可能)
  • patronictl でクラスター状態確認・手動フェイルオーバーが1コマンドで実行できる
Patroni・etcd・PostgreSQL 各コンポーネントのバージョン(Ubuntu 24.04 実測)
Patroni・etcd・PostgreSQL 各コンポーネントのバージョン(Ubuntu 24.04 実測)

目次

  1. Patroni とは何か・なぜ必要か
  2. HA クラスターの構成概要
  3. 動作確認済み環境
  4. Ubuntu 22.04 と 24.04 でパッケージはどう違うか
  5. Step 1:etcd-server をインストールする
  6. Step 2:PostgreSQL をインストールする
  7. Step 3:Patroni をインストールする
  8. Step 4:patroni.yml を設定して検証する
  9. Step 5:Patroni サービスを起動する
  10. Step 6:クラスター状態を確認する
  11. Step 7:フェイルオーバーをテストする
  12. サーバー選びとCPU実測
  13. よくあるエラーと解決策
  14. まとめ

Patroni とは何か・なぜ必要か

PostgreSQL には標準でストリーミングレプリケーション機能がありますが、プライマリが落ちたときの切り替えは自動化されていません。従来は DBA が手動で pg_promote を実行し、アプリの接続先を張り替える必要がありました。夜間や休日に障害が起きると、対応が遅れてダウンタイムが伸びてしまいます。

Patroni はこの切り替えを自動化するツールです。Zalando(ドイツの大手ECサイト)が開発し、現在はオープンソースとして活発にメンテナンスされています。

  • 自動フェイルオーバー:プライマリ障害を検出すると、健全なスタンバイを自動で昇格させます
  • DCS(分散コーディネーションサービス)連携:etcd や Consul を使ってリーダー選出とロックを管理します
  • patronictl CLI:クラスター状態の確認や手動フェイルオーバーが1コマンドで実行できます

DCS というのは「いまどのノードが Primary か」をクラスター全体で1か所に記録しておく仕組みです。この記事では DCS に etcd を使います。

HA クラスターの構成概要

Patroni HA クラスター構成図(概念図)
Patroni HA クラスター構成図(概念図)

今回構築する HA 構成は次の通りです。node1 を Primary、node2 を Standby とし、DCS の etcd は学習用に node1 へ同居させます。

役割 ホスト名 IPアドレス例 動くソフト
Primary(プライマリ) node1 192.168.1.10 Patroni + PostgreSQL
Standby(スタンバイ) node2 192.168.1.11 Patroni + PostgreSQL
DCS(分散コーディネーション) node1(兼用) 192.168.1.10 etcd-server
著者アイコン
著者アイコン

本番環境では etcd を3ノード以上の独立したサーバーで動かすのが推奨です。この記事は学習用に node1 へ etcd を同居させていますが、etcd が1台だとそのノードが死んだ瞬間にフェイルオーバーも止まる点だけ覚えておいてください。

動作確認済み環境

本記事のコマンドとバージョンは、ubuntu:24.04 公式Dockerイメージ(Ubuntu 24.04.4 LTS / GLIBC 2.39)で実際にインストールして確認しています。導入された各バージョンは次の通りです。

コンポーネント バージョン(実測) インストール方法
OS Ubuntu 24.04.4 LTS (noble)
Patroni 3.2.2(patroni 3.2.2-2) apt install patroni
PostgreSQL 16.14(postgresql-16 16.14-0ubuntu0.24.04.1) apt install postgresql
etcd 3.4.30(3.4.30-1ubuntu0.24.04.3) apt install etcd-server etcd-client
python3-etcd 0.4.5-4 patroni の依存として自動インストール

検証環境についての正直な補足

今回の検証は Apple Silicon 上の Docker(arm64)で実行しました。arm64 では etcd が起動時に「etcd on unsupported platform without ETCD_UNSUPPORTED_ARCH=arm64 set」という警告を出します。一般的な VPS(x86_64/amd64)では出ない警告なので、本番手順では気にする必要はありません。本記事の VPS 向けコマンドは amd64 を前提にしています。

Ubuntu 22.04 と 24.04 でパッケージはどう違うか

ここが、ネットの古い記事をそのまま真似すると詰まる最大のポイントです。ubuntu:22.04ubuntu:24.04 の両方で apt-cache policy を実行して候補バージョンを実測比較したところ、無視できない差がありました。

Ubuntu 22.04 と 24.04 のパッケージ候補バージョン比較(実測)
Ubuntu 22.04 と 24.04 のパッケージ候補バージョン比較(実測)

特に重要なのが etcd です。Ubuntu 22.04 には etcd という統合パッケージ(3.3.25)が存在しましたが、24.04 ではこれが廃止され、候補が無くなりました。24.04 では etcd-serveretcd-client の2つに分割されています。




ubuntu:24.04 — apt-cache policy etcd
$ apt-cache policy etcd
etcd:
Installed: (none)
Candidate: (none)

つまり 24.04 で apt install etcd を打つと「インストール候補がありません」と弾かれます。Patroni も 22.04 の 2.1.3 から 24.04 では 3.2.2 へメジャーアップし、標準 PostgreSQL も 14 から 16 に上がっています。この記事は Ubuntu 24.04 を前提に進めます。

Step 1:etcd-server をインストールする

まず DCS として使う etcd をインストールします。前述の通り、24.04 では etcd-serveretcd-client の2つを指定します。node1 で以下を実行します。




node1: ~ (Ubuntu 24.04)
$ sudo apt-get update
Reading package lists… Done
$ sudo apt-get install -y etcd-server etcd-client
Setting up etcd-client (3.4.30-1ubuntu0.24.04.3) …
Setting up etcd-server (3.4.30-1ubuntu0.24.04.3) …
$ etcdctl version
etcdctl version: 3.4.30

手順1:etcd の設定ファイルを編集する

etcd のデフォルト設定ファイルは /etc/default/etcd です。シングルノード構成(学習用)で動かす場合は以下のように設定します。




node1: /etc/default/etcd
$ sudo nano /etc/default/etcd
# 以下を追記・修正
ETCD_NAME=”node1″
ETCD_DATA_DIR=”/var/lib/etcd”
ETCD_LISTEN_CLIENT_URLS=”http://0.0.0.0:2379″
ETCD_ADVERTISE_CLIENT_URLS=”http://192.168.1.10:2379″
ETCD_LISTEN_PEER_URLS=”http://0.0.0.0:2380″
ETCD_INITIAL_ADVERTISE_PEER_URLS=”http://192.168.1.10:2380″
ETCD_INITIAL_CLUSTER=”node1=http://192.168.1.10:2380″
ETCD_INITIAL_CLUSTER_TOKEN=”patroni-etcd-cluster”
ETCD_INITIAL_CLUSTER_STATE=”new”

編集したら etcd を再起動し、健全性を確認します。実際に ubuntu:24.04 上で etcd を起動して etcdctl endpoint health を叩いたところ、次のように healthy が返り、リーダー選出(term 2)まで完了しました。

etcd の起動・健全性確認と patroni --validate-config(Ubuntu 24.04 実測)
etcd の起動・健全性確認と patroni –validate-config(Ubuntu 24.04 実測)



node1: ~ (etcd 健全性確認・実測)
$ sudo systemctl restart etcd
$ sudo systemctl enable etcd
$ etcdctl –endpoints=http://127.0.0.1:2379 endpoint health
http://127.0.0.1:2379 is healthy: successfully committed proposal: took = 2.243042ms
$ etcdctl –endpoints=http://127.0.0.1:2379 member list
b71f75320dc06a6c, started, node1, http://127.0.0.1:2380, http://127.0.0.1:2379, false

Step 2:PostgreSQL をインストールする

node1・node2 の両方で以下を実行します。標準の postgresql パッケージから PostgreSQL 16.14 が入ります。




node1, node2: ~
$ sudo apt-get install -y postgresql
Setting up postgresql-16 (16.14-0ubuntu0.24.04.1) …
$ psql –version
psql (PostgreSQL) 16.14 (Ubuntu 16.14-0ubuntu0.24.04.1)

重要:インストール直後に PostgreSQL を停止する

PostgreSQL は apt install 後に自動起動し、データディレクトリも初期化されます。Patroni が PostgreSQL を管理するため、先に停止・無効化してから Patroni を設定します。止め忘れるとポート競合や「data directory is not empty」エラーになります。




node1, node2: ~
$ sudo systemctl stop postgresql
$ sudo systemctl disable postgresql
Removed /etc/systemd/system/multi-user.target.wants/postgresql.service

Step 3:Patroni をインストールする

node1・node2 の両方で以下を実行します。ubuntu:24.04 で実際に流したインストールログとバージョン確認が次のスクリーンショットです。

patroni・etcd・PostgreSQL のインストールとバージョン確認(Ubuntu 24.04 実測)
patroni・etcd・PostgreSQL のインストールとバージョン確認(Ubuntu 24.04 実測)



node1, node2: ~
$ sudo apt-get install -y patroni
Setting up python3-etcd (0.4.5-4) …
Setting up patroni (3.2.2-2) …
$ patroni –version
patroni 3.2.2
$ patronictl version
patronictl version 3.2.2

Patroni が etcd と通信するための python3-etcd 0.4.5-4 が、依存として自動でインストールされるのがポイントです。pip を使わず apt だけで完結します。

Step 4:patroni.yml を設定して検証する

Patroni の設定ファイルは各ノードに /etc/patroni/patroni.yml として置きます。node1 と node2 で nameconnect_address を変えるだけで OK です。etcd v3 API を使うので etcd3 セクションで指定します。

手順1:node1 の patroni.yml を作成する




node1: /etc/patroni/patroni.yml
— /etc/patroni/patroni.yml (node1) —
scope: pg-ha-cluster
namespace: /service/
name: node1

restapi:
listen: 0.0.0.0:8008
connect_address: 192.168.1.10:8008

etcd3:
hosts: 192.168.1.10:2379

bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
initdb:
– encoding: UTF8
– data-checksums
pg_hba:
– host replication replicator 192.168.1.10/32 md5
– host replication replicator 192.168.1.11/32 md5
– host all all 0.0.0.0/0 md5

postgresql:
listen: 0.0.0.0:5432
connect_address: 192.168.1.10:5432
data_dir: /var/lib/postgresql/16/main
bin_dir: /usr/lib/postgresql/16/bin
authentication:
replication:
username: replicator
password: rep_password
superuser:
username: postgres
password: postgres_password
parameters:
unix_socket_directories: ‘.’

tags:
nofailover: false
noloadbalance: false
clonedfrom: false

手順2:node2 の patroni.yml を作成する

node2 では name と各 connect_address を node2 のものに変更します。それ以外は node1 と同じです。




node2: /etc/patroni/patroni.yml(変更箇所のみ)
name: node2
restapi:
connect_address: 192.168.1.11:8008
postgresql:
connect_address: 192.168.1.11:5432
# etcd3.hosts や認証情報など他は node1 と同じ

手順3:設定ファイルを検証する

Patroni には設定ファイルの構文チェック機能があります。起動前に --validate-config を実行しておくと、タイプミスを早期に潰せます。実際に検証した patroni.yml は 終了コード 0(=問題なし)で通りました。




node1: ~ (設定検証・実測)
$ patroni –validate-config /etc/patroni/patroni.yml
$ echo $?
0

注意:パスワードは必ず変更する

設定例のパスワード(rep_passwordpostgres_password)は例示用です。本番環境では必ず強力なパスワードに変更し、環境変数やシークレット管理ツールで扱ってください。

手順4:PostgreSQL データディレクトリを空にする

Patroni は初回起動時に initdb でデータディレクトリを初期化します。Step 2 で PostgreSQL が作った初期データが残っていると競合するため、ディレクトリを空にしてから Patroni を起動します。

注意:データを消してよいか確認してから実行

すでに本番データが入っている場合は必ずバックアップを取ってから実行してください。rm -rf は戻せません。




node1, node2: ~
$ sudo rm -rf /var/lib/postgresql/16/main
$ sudo mkdir -p /var/lib/postgresql/16/main
$ sudo chown -R postgres:postgres /var/lib/postgresql/16
$ sudo chmod 700 /var/lib/postgresql/16/main

Step 5:Patroni サービスを起動する

まず node1 を起動します(最初に上がったノードが Primary になります)。




node1: ~
$ sudo systemctl start patroni
$ sudo systemctl enable patroni
$ sudo journalctl -u patroni -n 20 –no-pager
INFO: no action. I am (node1) the leader with the lock
INFO: Lock owner: node1; I am node1

「I am the leader with the lock」というログが出れば node1 が Primary として起動しています。続いて node2 を起動すると、node1 から WAL ストリーミングでデータを取り込み、レプリカとして参加します。




node2: ~
$ sudo systemctl start patroni
$ sudo systemctl enable patroni
INFO: Lock owner: node1; I am node2
INFO: does not have lock
INFO: establishing a new patroni heartbeat connection to postgres

Step 6:クラスター状態を確認する

patronictl list でクラスターの状態を確認します。




node1: ~
$ patronictl -c /etc/patroni/patroni.yml list
+ Cluster: pg-ha-cluster ——–+———+—-+———–+
| Member | Host | Role | State | TL | Lag in MB |
+——–+——————-+———+———+—-+———–+
| node1 | 192.168.1.10:5432 | Leader | running | 1 | |
| node2 | 192.168.1.11:5432 | Replica | running | 1 | 0 |
+——–+——————-+———+———+—-+———–+

node1 が Leader(Primary)、node2 が Replica(スタンバイ)になっていれば、HA クラスターの構築成功です。Lag in MB: 0 はレプリケーションが追いついていることを示します。

Step 7:フェイルオーバーをテストする

Patroni 自動フェイルオーバーの流れ(概念図)
Patroni 自動フェイルオーバーの流れ(概念図)

まず計画的な切り替えとして、patronictl failover で手動フェイルオーバーを試します(メンテナンス時に便利です)。




node1: ~ (手動フェイルオーバー)
$ patronictl -c /etc/patroni/patroni.yml failover pg-ha-cluster
Candidate [‘node2’] []: node2
Are you sure you want to failover cluster pg-ha-cluster, demoting current leader node1? [y/N]: y
Successfully failed over to “node2”
| node2 | 192.168.1.11:5432 | Leader | running | 2 | |
| node1 | 192.168.1.10:5432 | Replica | running | 2 | 0 |

node2 が Leader に昇格し、旧 Primary の node1 がスタンバイとして自動復帰しました。フェイルオーバー後のタイムラインは TL: 2 に上がっています。

自動フェイルオーバーの確認

次に障害をシミュレートします。node1 で Patroni を強制停止すると、ttl: 30 の設定では約30秒後に node2 が自動昇格します。




node1 → node2: ~ (障害シミュレーション)
node1$ sudo systemctl stop patroni
# ~ ttl(30秒)経過後、node2 のログ ~
INFO: promoted self to leader by acquiring session lock
INFO: no action. I am (node2) the leader with the lock

フェイルオーバー時間の目安

  • デフォルト設定(ttl: 30):リーダーキーの失効後に昇格するため、おおむね30〜60秒で完了
  • ttl を小さくすると高速化できるが、ネットワーク遅延による誤フェイルオーバーのリスクが上がる
  • 推奨は ttl: 30〜60loop_wait: 10 のバランス設定

サーバー選びとCPU実測

Patroni × PostgreSQL の HA は最低でも2ノード、できれば etcd 用にもう1〜3台が欲しい構成です。どのくらいのスペックを選べばよいか、CPU 性能と料金の両面から見てみます。

CPU ベンチ(sysbench 実測)

ubuntu:24.04 コンテナ(2スレッド)で sysbench cpu を3回計測した結果が次の通りです。

sysbench CPU ベンチ(Ubuntu 24.04 実測)
sysbench CPU ベンチ(Ubuntu 24.04 実測)
著者アイコン
著者アイコン

sysbench CPU(--threads=2 --time=10)を3回回したところ、平均 7,203 events/sec(最小6,394〜最大7,810)でした。PostgreSQL の Primary はクエリ処理で CPU を使うので、HA の各ノードには2vCPU 以上を割り当てるのがおすすめです。

ノード間 SSH 鍵の準備

複数ノードを運用するなら、パスワードなしの SSH 接続を用意しておくと patronictl 操作やレプリカ再構築が楽になります。Ubuntu 24.04 標準の OpenSSH 9.6p1 で ed25519 鍵を生成した実出力がこちらです。

ノード間 SSH 鍵ペア生成(ed25519)の実出力(Ubuntu 24.04 実測)
ノード間 SSH 鍵ペア生成(ed25519)の実出力(Ubuntu 24.04 実測)

VPS の料金目安(Vultr 実測)

Vultr 公式 API から東京リージョンの Cloud Compute プラン料金を取得しました(2026-06-14 時点)。HA は最低2ノード必要なので、月額は表の2倍が目安になります。

Vultr 東京リージョン料金(Patroni HA 向け・実測)
Vultr 東京リージョン料金(Patroni HA 向け・実測)

学習用なら vc2-1c-1gb($5/月)×2 でも動かせますが、PostgreSQL を実用的に動かすなら 2vCPU・2GB 以上(vc2-2c-2gb $15/月)を推奨します。Vultr は東京リージョンがあるので、国内利用でも遅延が小さく済みます。

よくあるエラーと解決策

① 24.04 で apt install etcd が失敗する




node1: ~
$ sudo apt-get install -y etcd
E: Package ‘etcd’ has no installation candidate

前述の通り、Ubuntu 24.04 では etcd パッケージが廃止されています。etcd-serveretcd-client を指定し直してください。

② etcd に接続できない(「Failed to obtain lock」)

原因は etcd が起動していないか、ADVERTISE_CLIENT_URLS のIPアドレスが間違っているケースがほとんどです。etcd の健全性を確認します。




確認コマンド
$ sudo systemctl status etcd
$ etcdctl –endpoints=http://127.0.0.1:2379 endpoint health
http://127.0.0.1:2379 is healthy: successfully committed proposal

③ PostgreSQL が起動しない(「data directory is not empty」)




journalctl -u patroni
ERROR: data directory /var/lib/postgresql/16/main is not empty

Step 2 で apt が走らせた initdb の初期データが残っているのが原因です。Step 4 手順4のとおり、データディレクトリを空にしてから Patroni を起動してください(データがある場合は必ずバックアップを)。

④ node2 がレプリカとして参加しない

node2 がレプリケーション接続できるよう、patroni.ymlpg_hba に node2 のIPが含まれているか確認します。あわせてログを追います。




確認コマンド
$ patronictl -c /etc/patroni/patroni.yml list
$ sudo journalctl -u patroni -n 30 –no-pager | grep -Ei “replica|streaming|lag”

まとめ

Patroni on Ubuntu 24.04 による PostgreSQL HA クラスターの構築手順を、実測データをもとに解説しました。

  • Ubuntu 24.04 では apt だけで Patroni 3.2.2・etcd 3.4.30・PostgreSQL 16.14 が揃う(pip 不要・実測)
  • etcd は 24.04 で統合パッケージ etcd が廃止され、etcd-serveretcd-client に分割された(22.04 比較で判明)
  • patroni.yml は nameconnect_address を各ノードで変えるだけ。起動前に patroni --validate-config で構文確認できる
  • 自動フェイルオーバーはデフォルト約30〜60秒(ttl 次第)で完了する
  • patronictl list で状態確認、patronictl failover で手動切り替えができる

本番環境では etcd を3ノード以上で独立稼働させ、さらに HAProxy や keepalived でクライアント向けの仮想IPを提供すると、より堅牢な HA 構成になります。まずは VPS を1台借りて、Docker や2台構成で手を動かしてみるのが理解への近道です。

VPS の選び方をもっと詳しく知りたい方は、こちらの記事もあわせてご覧ください: VPS比較・おすすめガイド

コメント

タイトルとURLをコピーしました