Patroni란?
Patroni는 Python 기반 PostgreSQL HA 솔루션으로, etcd/Consul/ZooKeeper 등 DCS(Distributed Configuration Store)를 사용해 Leader 선출과 자동 페일오버를 수행합니다.
구성 요소
| 컴포넌트 | 역할 |
|---|---|
| Patroni | PostgreSQL 프로세스 관리 + 페일오버 |
| etcd | Leader 선출용 분산 합의 저장소 |
| HAProxy | 애플리케이션 → Primary/Replica 라우팅 |
클러스터 구성
| 서버 | IP | 역할 |
|---|---|---|
| pg1 | 192.168.1.10 | PostgreSQL + Patroni + etcd |
| pg2 | 192.168.1.11 | PostgreSQL + Patroni + etcd |
| pg3 | 192.168.1.12 | PostgreSQL + Patroni + etcd |
| lb | 192.168.1.20 | HAProxy |
1. etcd 클러스터 설치 (3노드 모두)
sudo apt install -y etcd# /etc/default/etcd (pg1 기준)
ETCD_NAME="pg1"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.1.10:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.1.10:2379,http://127.0.0.1:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.10:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.10:2379"
ETCD_INITIAL_CLUSTER="pg1=http://192.168.1.10:2380,pg2=http://192.168.1.11:2380,pg3=http://192.168.1.12:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="pg-etcd-cluster"sudo systemctl enable --now etcd
# 상태 확인
etcdctl endpoint status --cluster -w table2. PostgreSQL 설치 (3노드 모두)
sudo apt install -y postgresql-17
sudo systemctl disable --now postgresql # Patroni가 대신 관리3. Patroni 설치 및 설정
sudo apt install -y python3-pip
pip3 install patroni[etcd] psycopg2-binary/etc/patroni/config.yml (pg1 기준)
scope: pg-cluster
namespace: /db/
name: pg1
restapi:
listen: 192.168.1.10:8008
connect_address: 192.168.1.10:8008
etcd:
hosts: 192.168.1.10:2379,192.168.1.11:2379,192.168.1.12:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576 # 1MB
postgresql:
use_pg_rewind: true
parameters:
wal_level: replica
max_wal_senders: 5
max_replication_slots: 5
hot_standby: on
initdb:
- encoding: UTF8
- data-checksums
pg_hba:
- host replication replicator 192.168.1.0/24 md5
- host all all 0.0.0.0/0 md5
users:
admin:
password: AdminPass!23
options: [createrole, createdb]
postgresql:
listen: 192.168.1.10:5432
connect_address: 192.168.1.10:5432
data_dir: /var/lib/postgresql/17/main
bin_dir: /usr/lib/postgresql/17/bin
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator
password: ReplPass!23
superuser:
username: postgres
password: PgPass!23
rewind:
username: rewind_user
password: RewindPass!23
tags:
nofailover: false
noloadbalance: false
clonefrom: falsepg2, pg3는 name, listen, connect_address의 IP만 각 서버에 맞게 변경합니다.
systemd 서비스
cat > /etc/systemd/system/patroni.service << 'EOF'
[Unit]
Description=Patroni PostgreSQL HA
After=network.target etcd.service
[Service]
User=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni/config.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now patroni4. 클러스터 상태 확인
patronictl -c /etc/patroni/config.yml list+ Cluster: pg-cluster ----+----+-----------+
| Member | Host | Role | State |
+--------+----------------+---------+---------+
| pg1 | 192.168.1.10 | Leader | running |
| pg2 | 192.168.1.11 | Replica | running |
| pg3 | 192.168.1.12 | Replica | running |
+--------+----------------+---------+---------+5. HAProxy 설정 (lb 서버)
sudo apt install -y haproxy# /etc/haproxy/haproxy.cfg
frontend pg_write
bind *:5432
default_backend pg_primary
backend pg_primary
option httpchk GET /master
http-check expect status 200
server pg1 192.168.1.10:5432 check port 8008
server pg2 192.168.1.11:5432 check port 8008
server pg3 192.168.1.12:5432 check port 8008
frontend pg_read
bind *:5433
default_backend pg_replicas
backend pg_replicas
balance roundrobin
option httpchk GET /replica
http-check expect status 200
server pg1 192.168.1.10:5432 check port 8008
server pg2 192.168.1.11:5432 check port 8008
server pg3 192.168.1.12:5432 check port 8008Patroni REST API의 /master, /replica 엔드포인트를 health check에 활용합니다.
6. 수동 전환 / 페일오버
# 계획된 전환 (데이터 무손실)
patronictl -c /etc/patroni/config.yml switchover pg-cluster
# 강제 페일오버 (비상 시)
patronictl -c /etc/patroni/config.yml failover pg-cluster정리
| 기능 | 담당 |
|---|---|
| Leader 선출 | etcd 분산 합의 |
| 자동 페일오버 | Patroni (TTL 30초 이내) |
| 쓰기 라우팅 | HAProxy → /master |
| 읽기 분산 | HAProxy → /replica (Round Robin) |
트러블슈팅 & 자주 묻는 질문
| 증상 | 원인 | 해결 |
|---|---|---|
| 페일오버가 안 됨 | etcd 쿼럼 상실(3노드 중 2개 다운) | etcd 노드 복구 → 과반수 확보 시 Patroni 자동 재개 |
| Split-brain 우려 | 네트워크 파티션 | Patroni는 DCS(etcd) 리더 임차로 방지 — etcd를 단일 신뢰 소스로 유지 |
patronictl list가 비어 있음 | config.yml의 namespace/scope 불일치 | 모든 노드의 namespace·scope 값이 동일한지 확인 |
| Leader 승격이 느림 | ttl/loop_wait 과대 설정 | ttl: 30, loop_wait: 10, retry_timeout: 10 권장 |
Q. postgresql patroni와 etcd는 각각 무슨 역할인가요? A. Patroni는 각 PostgreSQL 노드에 붙어 상태를 관리하고 페일오버를 실행하는 에이전트이고, etcd는 '누가 리더인가'를 분산 합의로 저장하는 신뢰 소스(DCS)입니다. etcd 과반수가 살아 있어야 리더 선출과 자동 페일오버가 동작합니다.
Q. Patroni만 있으면 되지 왜 etcd가 필요한가요? A. 단일 Patroni는 자기 노드만 압니다. 여러 노드가 '리더는 하나뿐'이라는 합의에 도달하려면 외부 분산 저장소가 필요하고, 그 역할을 etcd(또는 Consul·ZooKeeper)가 맡습니다. etcd 없이는 split-brain을 막을 수 없습니다.
이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.
질문 & 답변 (Q&A)
이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.