Replikace databáze
Popis systému¶
Tento dokument popisuje konfiguraci replikace databáze PMC. Data v záložní databázi se replikují pomocí physical streaming replication. Konfigurace samotné replikace se nedělá manuálně. Zajištuje ji aplikace patroni. Celý systém je navržen tak, aby v případě nedostupnosti hlavní databáze automaticky došlo k přepnutí na záložní. Aplikace PMC se do databáze připojuje přes HAProxy, které kontroluje stav obou databází a přesměrovává připojení na databázi, která je v danou chvíli leader. Patroni pro svůj běh potřebuje key-value store (ETCD), ten běží ve třech instancích. Databáze bude dostupná při výpadku kteréhokoli z připojených serverů. V případě výpadku hlavního serveru je potřeba manuálně spustit záložní instanci PMC a na routeru přesměrovat připojení na záložní server. V základním stavu (kdy je hlavní databáze dostupná a na záložní se replikují data) se lze na záložní databázi připojit v read-only módu - toho by se dalo využít k vytváření záloh, reportingu atp.
V konfiguračních souborech a v popisu instalace se objevují návy a adresy tří serverů. Tyto adresy bude třeba změnit podle prostředí, kam se bude systém instalovat (stejně jako hesla atp...). Adresy v příkladech níže jsou následující:
- PMC01: 10.120.1.2
- PMC02: 10.120.1.3
- ETCD03: 10.120.0.10
- Virtuální adresa: 10.120.1.4
Popis jednotlivých částí¶
Haproxy - Pravidelně posílá dotazy na REST api Patroni (obě instance) a přesměrovává požadavky na ten server, který je aktuálně leader. Veškerá připojení do databáze budou vedena touto cestou.
Patroni - Zajišťuje běh databáze, stará se o to, aby byl vždy právě jeden leader a v případě výpadku provede failover. Vystavuje REST api, pomocí kterého se lze dozvědět jaká instance databáze je v danou chvíli leader.
ETCD - key-value store, který slouží k ukládání provozních dat Patroni. Aby celý systém fungoval je třeba mít tři instance. V jeden moment může být nedostupná maximálně jedna instance.
PMC - jelikož PMC nedovoluje běh ve více instancích, může být v jednu chvíli spuštěna pouze jedna instance. Pokud budeme druhou instanci udržovat a pravidelně aktualizovat, významně tím zkrátíme dobu, kdy je systém po výpadku hlavního serveru v nefunkčním stavu.
Keepalived - Virtuální ip adresa. Přednost má primární server. Při jeho výpadku je přesunuta na záložní. PMC bude nastaveno tak, aby komunikovalo právě s touto adresou. Keepalived samo o sobě není doporučeno používat na nedůvěryhodných sítích (mezi které patří privátní síť v Hetzneru). Proto bude pro komunikaci mezi servery použita VPN (wireguard).
schéma architektury systému¶
---
title: Architektura systému
---
block-beta
columns 3
srv1>"PMC01 10.120.1.2"]
block:a:2
columns 8
pmc_main("PMC MAIN")
space:5
db_main[("DB MAIN")]
space:3
haproxy1("HAProxy")
space:5
etcd1("ETCD")
space:3
patroni_main("Patroni")
space:2
keepalived1("Keepalived")
end
srv2>"ETCD03 10.120.0.10"]
block:b:1
columns 3
space:7
etcd3("ETCD"):2
space:4
end
space:1
srv3>"PMC02 10.120.1.3"]
block:c:2
columns 8
etcd2("ETCD")
space:3
patroni_backup("Patroni")
space:2
keepalived2("Keepalived")
space:2
haproxy2("HAProxy")
space:5
pmc_backup("PMC BKP")
space:5
db_backup[("DB Backup")]
end
patroni_main <--> db_main
patroni_main <--> etcd3
patroni_backup <--> db_backup
patroni_backup <--> etcd3
etcd1 <--> etcd2
etcd1 <--> etcd3
etcd2 <--> etcd1
etcd2 <--> etcd3
etcd3 <--> etcd1
etcd3 <--> etcd2
haproxy1 <--> patroni_main
haproxy1 <--> patroni_backup
haproxy1 <--> db_main
haproxy1 <--> db_backup
haproxy2 <--> patroni_main
haproxy2 <--> patroni_backup
haproxy2 <--> db_backup
haproxy2 <--> db_main
pmc_main <--> haproxy1
pmc_backup <--> haproxy2
db_backup --> db_main
keepalived1 <--> keepalived2
keepalived2 <--> keepalived1
style etcd1 fill:#0088FF, stroke:#333333;
style etcd2 fill:#0088FF, stroke:#333333;
style etcd3 fill:#0088FF, stroke:#333333;
style pmc_main fill:#55BB55, stroke:#333333;
style pmc_backup fill:#55BB5533,stroke:#333333;
style haproxy1 fill:#4444EE77, stroke:#333333;
style haproxy2 fill:#4444EE77, stroke:#333333;
style patroni_main fill:#8844EE, stroke:#333333;
style patroni_backup fill:#8844EE, stroke:#333333;
style db_main fill:#FF3333, stroke:#333333;
style db_backup fill:#FF3333, stroke:#333333;
style a fill:#88442235, stroke:#333333, stroke-width: 3px, stroke-dasharray: 10 10;
style b fill:#88442235, stroke:#333333, stroke-width: 3px, stroke-dasharray: 10 10;
style c fill:#88442235, stroke:#333333, stroke-width: 3px, stroke-dasharray: 10 10;
style srv1 fill:#88442235, stroke:#333333;
style srv2 fill:#88442235, stroke:#333333;
style srv3 fill:#88442235, stroke:#333333;
Instalace a konfigurace¶
Certifikáty¶
Veškerá komunikace mezi servery je šifrovaná. Níže seznam certifikátů, které jsou pro nastavení potřeba. Názvy souborů se objevují níže v textu.
| Soubory | Typ certifikátu | Popis |
|---|---|---|
| etcd.pem, etcd.key | Serverový certifikát | Certifikát pro ETCD. Všechny instance mají stejný. |
| patroni.pem, patroni.key | Serverový certifikát | Certifikát pro Patroni REST API, Využit také pro SSL připojení do databáze. |
| haproxy.pem | Klientský certifikát | Certifikát pro ověření HAProxy při dotazech na REST API Patroni. Soubor obsahuje certifikát i privátní klíč. |
| pmc2t-ca.cert.pem | Certifikát CA | Certifikát certifikační autority, která vydala všechny zmíněné certifikáty. Slouží k ověření vydavatele certifikátů. |
Připojení do databáze z aplikace PMC
V případě výpadku hlavní databáze se bude PMC připojovat do databáze přes síť. Proto je třeba v konfiguraci zapnout parametr ssl (implicitně je vypnutý). Doporučeno je také nastavit parametr sslmode minimálně na hodnotu verify-ca. Všechny možné parametry driveru je možné najít zde. Parametry související s ssl jsou blíže popsány zde. URL pro PMC může vypadat např. takto:
spring.datasource.jdbcUrl=jdbc:postgresql://10.120.1.4:5433/pmc?ssl=true&sslmode=verify-ca&sslrootcert=/opt/pmc/etl/pmc2t-ca.cert.pem
10.120.1.4:5433 je třeba vyměnit za ip a port připojení do HAProxy a /opt/pmc/etl/pmc2t-ca.cert.pem za cestu k certifikátu CA. To stejné platí také pro připojení datové pumpy.
Vytvoření certifikátů¶
Certifikáty se vytváří standardním způsobem. Příklad certifikátu pro Patroni
openssl req \
-new \
-subj "/C=CZ/ST=Czechia/O=Green Center/CN=Green Center PMC TEST PATRONI cert" \ # (1)!
-addext "subjectAltName=IP:127.0.0.1,IP:10.120.1.2,IP:10.120.1.3,IP:10.120.1.4" \
-newkey rsa:4096 \
-keyout ./newkey.pem \
-out ./newreq.pem
openssl ca \
-config ./pmc2t-ca.cnf \
-policy policy \
-out ./newcert.pem \
-extensions server_ext \
-infiles newreq.pem
mkdir patroni
cp ./newcert.pem ./patroni/patroni.pem
cp ./newreq.pem ./patroni/patroni.req.pem
openssl rsa -in newkey.pem -out ./patroni/patroni.key
-
CN
Uživatel v databázi se musí jmenovat podle CN certifikátu.
openssl req \
-new \
-subj "/C=CZ/ST=Czechia/O=Green Center/CN=Green Center PMC TEST haproxy client" \
-addext "subjectAltName=IP:127.0.0.1,IP:10.120.1.2,IP:10.120.1.3,IP:10.120.1.4" \
-newkey rsa:4096 \
-keyout ./newkey.pem \
-out ./newreq.pem
openssl ca \
-config ./pmc2t-ca.cnf \
-policy policy \
-out ./newcert.pem \
-extensions client_ext \
-infiles newreq.pem
mkdir haproxy
cp ./newcert.pem ./haproxy/haproxy.pem
cp ./newreq.pem ./haproxy/haproxy.req.pem
openssl rsa -in newkey.pem -out ./haproxy/haproxy.key
Instalace potřebných balíků¶
Konfigurace a spuštění etcd¶
Systemd service¶
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
EnvironmentFile=/etc/etcd/etcd.env
ExecStart=/usr/bin/etcd
Restart=always
RestartSec=10s
LimitNOFILE=40000
User=etcd
Group=etcd
[Install]
WantedBy=multi-user.target
Soubor .env¶
Jako konfigurační soubor nám poslouží .env file, na který se odkazujeme výše v systemd service souboru (EnvironmentFile).
ETCD_NAME="postgres-patroni-etcd-01"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_INITIAL_CLUSTER="postgres-patroni-etcd-01=https://10.120.1.2:2380,postgres-patroni-etcd-02=https://10.120.1.3:2380,postgres-patroni-etcd-03=https://10.120.0.10:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.120.1.2:2380"
ETCD_LISTEN_PEER_URLS="https://10.120.1.2:2380,https://127.0.0.1:2380"
ETCD_LISTEN_CLIENT_URLS="https://10.120.1.2:2379,https://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="https://10.120.1.2:2379"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_TRUSTED_CA_FILE="/etc/etcd/pmc2t-ca.cert.pem"
ETCD_CERT_FILE="/etc/etcd/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/etcd.key"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/pmc2t-ca.cert.pem"
ETCD_PEER_CERT_FILE="/etc/etcd/etcd.pem"
ETCD_PEER_KEY_FILE="/etc/etcd/etcd.key"
ETCDCTL_API=3
ETCD_NAME="postgres-patroni-etcd-02"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_INITIAL_CLUSTER="postgres-patroni-etcd-01=https://10.120.1.2:2380,postgres-patroni-etcd-02=https://10.120.1.3:2380,postgres-patroni-etcd-03=https://10.120.0.10:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.120.1.3:2380"
ETCD_LISTEN_PEER_URLS="https://10.120.1.3:2380,https://127.0.0.1:2380"
ETCD_LISTEN_CLIENT_URLS="https://10.120.1.3:2379,https://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="https://10.120.1.3:2379"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_TRUSTED_CA_FILE="/etc/etcd/pmc2t-ca.cert.pem"
ETCD_CERT_FILE="/etc/etcd/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/etcd.key"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/pmc2t-ca.cert.pem"
ETCD_PEER_CERT_FILE="/etc/etcd/etcd.pem"
ETCD_PEER_KEY_FILE="/etc/etcd/etcd.key"
ETCDCTL_API=3
ETCD_NAME="postgres-patroni-etcd-03"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_INITIAL_CLUSTER="postgres-patroni-etcd-01=https://10.120.1.2:2380,postgres-patroni-etcd-02=https://10.120.1.3:2380,postgres-patroni-etcd-03=https://10.120.0.10:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.120.0.10:2380"
ETCD_LISTEN_PEER_URLS="https://10.120.0.10:2380,https://127.0.0.1:2380"
ETCD_LISTEN_CLIENT_URLS="https://10.120.0.10:2379,https://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="https://10.120.0.10:2379"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_TRUSTED_CA_FILE="/etc/etcd/pmc2t-ca.cert.pem"
ETCD_CERT_FILE="/etc/etcd/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/etcd.key"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/pmc2t-ca.cert.pem"
ETCD_PEER_CERT_FILE="/etc/etcd/etcd.pem"
ETCD_PEER_KEY_FILE="/etc/etcd/etcd.key"
ETCDCTL_API=3
Spuštění¶
dokumentace k etcd
Informace k provozování etcd lze dohledat v oficiální dokumentaci. K vyřešení problémů s šifrováním mi také posloužil tento dokument.
Poznámka k serverům
Další kroky už provádíme výhradne na serverech PMC01 a PMC02. Server ETCD03 slouží pouze jako node v ETCD clusteru. Neběží na něm HAProxy, Postgres, Patroni, ani Keepalived.
Konfigurace a spuštění HAProxy¶
Je třeba využít funkce HAProxy, které nejsou dostupné ve verzi distribuované na Ubuntu 22.04, proto spustíme HAProxy v dockeru.
Docker-compose¶
Konfigurace haproxy¶
global
maxconn 100
log stdout local0 debug
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 boorvar_cluster
bind *:5433
option httpchk
# (1)!
http-check send hdr Authorization 'Basic aGFwcm94eTp2RG1GbnBiOWtjZ2pFZmJzeHh5YjVoN3ZkRGVzMmtvbnFFZmI5cTRqajNvbmN2RWQ='
http-check expect status 200 # (2)!
default-server inter 3s fall 2 rise 1 on-marked-down shutdown-sessions
# (3)!
server pgdb1_5432 10.120.1.2:5432 maxconn 100 check check-ssl port 8008 verify required ca-file /usr/local/etc/haproxy/pmc2t-ca.cert.pem crt /usr/local/etc/haproxy/haproxy.pem
server pgdb2_5432 10.120.1.3:5432 maxconn 100 check check-ssl port 8008 verify required ca-file /usr/local/etc/haproxy/pmc2t-ca.cert.pem crt /usr/local/etc/haproxy/haproxy.pem
- Authorization header vytvoříme následujícím způsobem:
echo -n "username:password" | base64 - Patroni se chová tak, že když je daná instance leader, tak vrátí status 200 (OK). V opačném případě vrátí 503 (Service Unavailable). Podle toho HAProxy pozná na který server má přesměrovávat připojení.
-
- server <name> <ip:port>
- Název serveru (pouze pro informaci) a připojení k postgresql databázi
- port <port>
- Port patroni REST API
- ca-file <filename>
- Certifikát CA, viz certifikáty
- crt <filename>
- Certifikát haproxy, viz certifikáty
Oba tyto certifikáty se uloží do stejného adresáře jako konfigurace HAProxy.
- server <name> <ip:port>
Spuštění kontejneru¶
Konfigurace a spuštění keepalived¶
Nastavení VPN¶
Vytvoření privátního a veřejného klíče¶
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
# Soubor privatekey obsahuje privátní klíč. Ten se do lokální konfigurace (viz níže) zadá jako PrivateKey.
# Soubor publickey obsahuje veřejný klíč. Ten se do vloží do konfigurace protější strany jako PublicKey.
# Po nastavení VPN je dobré tyto soubory smazat.
Vytvoření konfiguračního souboru pro wireguard¶
[Interface]
ListenPort = 51829
PrivateKey = <privatekey> # (1)!
Address = 10.30.0.1/24
PostUp = systemctl start keepalived
PostDown = systemctl stop keepalived
[Peer]
PublicKey = <publickey> # (2)!
AllowedIPs = 10.30.0.0/24
Endpoint = 10.120.1.3:51829
PersistentKeepalive = 25
- Nahradit obsahem souboru privatekey
- Nahradit obsahem souboru publickey protější strany
[Interface]
ListenPort = 51829
PrivateKey = <privatekey> # (1)!
Address = 10.30.0.2/24
PostUp = systemctl start keepalived
PostDown = systemctl stop keepalived
[Peer]
PublicKey = <publickey> # (2)!
AllowedIPs = 10.30.0.0/24
Endpoint = 10.120.1.2:51829
PersistentKeepalive = 25
- Nahradit obsahem souboru privatekey
- Nahradit obsahem souboru publickey protější strany
Konfigurace keepalived¶
V souboru je třeba na základě prostředí upravit několik věcí.
- auth_pass - Heslo pro přenos dat - maximálně 8 znaků. Toto je jeden z důvodů proč jako dodatečné zabezpečení přenášíme data přes VPN.
- interface - Zadat podle VPN interface. Pokud budete postupovat podle návodu výše, wg1 by mělo být v pořádku.
- virtual_ipaddress - V této sekci je třeba změnit samotnou adresu a také interface, na kterém bude adresa nastavena.
- unicast_peer, unicast_src_ip - Nastavit podle IP v rámci VPN.
Jako další krok musíme nastavit závislost keepalived na VPN
Spuštění¶
Konfigurace a spuštění patrioni¶
Konfigurace¶
dokumentace
Všechny konfigurační parametry jsou detailně popsány v dokumentaci.
Přednost parametrů¶
Existují tři způsoby jak upravit konfiguraci patroni. Níže je jejich výpis seřazený od nejnižší priority po nejvyšší (metody níže přepíší ty nahoře):
- Globální konfigurace
- Tato konfigurace je uložena v DCS (Distributed Configuration Store) a je společná pro celý cluster. První zápis do ní je vytvořen ze sekce bootstrap v konfiguračním souboru (viz níže).
- Další zápisy se provádí výhradně přes utilitu patronictl edit-config.
- Konfigurační soubor yml (níže).
- Proměnné prostředí
Příklad konfiguračního souboru¶
scope: postgresql-cluster
namespace: /service/
name: postgres-patroni-etcd-01 # (18)!
etcd3:
hosts: 10.120.1.2:2379,10.120.1.3:2379,10.120.0.10:2379 # (12)!
protocol: https # (13)!
cacert: /etc/patroni/pmc2t-ca.cert.pem # (14)!
cert: /etc/patroni/patroni.pem # (15)!
key: /etc/patroni/patroni.key # (16)!
log:
dir: /var/log/patroni
format: '%(asctime)s %(levelname)s: %(message)s'
level: DEBUG
max_queue_size: 1000
traceback_level: ERROR
type: plain
restapi:
listen: 0.0.0.0:8008 # (10)!
connect_address: 10.120.1.2:8008 # (11)!
authentication:
username: haproxy
password: vDmFnpb9kcgjEfbsxxyb5h7vdDes2konqEfb9q4jj3oncvEd
certfile: /etc/patroni/patroni.pem
keyfile: /etc/patroni/patroni.key
cafile: /etc/patroni/pmc2t-ca.cert.pem
verify_client: required
ctl: # (19)!
authentication:
username: haproxy
password: vDmFnpb9kcgjEfbsxxyb5h7vdDes2konqEfb9q4jj3oncvEd
certfile: /etc/patroni/patroni.pem
keyfile: /etc/patroni/patroni.key
cafile: /etc/patroni/pmc2t-ca.cert.pem
postgresql:
listen: 0.0.0.0:5432 # (5)!
connect_address: 10.120.1.2:5432 # (6)!
data_dir: /var/lib/postgresql/15/main # (4)!
bin_dir: /usr/lib/postgresql/15/bin # (3)!
authentication:
replication:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
rewind:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
superuser:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
pg_hba: # (1)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.2/32 cert # (8)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.3/32 cert # (9)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.4/32 cert # (20)!
- hostssl all "Green Center PMC TEST PATRONI cert" 127.0.0.1/32 cert # (7)!
- host all all 127.0.0.1/32 md5
- host all all 0.0.0.0/0 md5
- local all all trust
use_pg_rewind: true
parameters:
ssl: 'on'
ssl_cert_file: /etc/patroni/patroni.pem
ssl_key_file: /etc/patroni/patroni.key
ssl_ca_file: /etc/patroni/pmc2t-ca.cert.pem
archive_mode: always
archive_command: 'test ! -f /var/lib/postgresql/15/wal_archive/%f && cp %p /var/lib/postgresql/15/wal_archive/%f'
logging_collector: on
log_destination: 'stderr'
log_truncate_on_rotation: on
log_checkpoints: on
log_connections: on
log_disconnections: on
log_error_verbosity: default
log_lock_waits: on
log_temp_files: 0
log_autovacuum_min_duration: 0
log_min_duration_statement: 50
log_timezone: 'Europe/Prague'
log_filename: postgresql-%Y-%m-%d_%H.log
log_line_prefix: '%t [%p]: db=%d,user=%u,app=%a,client=%h '
unix_socket_permissions: 0700 # (21)!
bootstrap: # (17)!
initdb:
- encoding: UTF8
- data-checksums
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576 # Failover parameters
postgresql:
pg_hba: # (2)!
- hostssl replication "Green Center PMC TEST PATRONI cert" 10.120.1.2/32 cert
- hostssl replication "Green Center PMC TEST PATRONI cert" 10.120.1.3/32 cert
- hostssl replication "Green Center PMC TEST PATRONI cert" 10.120.1.4/32 cert
- hostssl replication "Green Center PMC TEST PATRONI cert" 127.0.0.1/32 cert
- host all all 127.0.0.1/32 md5
- host all all 0.0.0.0/0 md5
- local all all trust
use_slots: true
use_pg_rewind: true
parameters:
hot_standby: 'on'
max_connections: 1000
max_locks_per_transaction: 64
max_worker_processes: 8
max_prepared_transactions: 0
wal_level: replica
track_commit_timestamp: 'off'
max_wal_senders: 10
max_replication_slots: 10
wal_keep_segments: 8
wal_keep_size: 1024MB
wal_log_hints: 'on'
shared_buffers: 1024MB
ssl: 'on'
ssl_cert_file: /etc/patroni/patroni.pem
ssl_key_file: /etc/patroni/patroni.key
ssl_ca_file: /etc/patroni/pmc2t-ca.cert.pem
logging_collector: on
log_destination: 'stderr'
log_truncate_on_rotation: on
log_checkpoints: on
log_connections: on
log_disconnections: on
log_error_verbosity: default
log_lock_waits: on
log_temp_files: 0
log_autovacuum_min_duration: 0
log_min_duration_statement: 50
log_timezone: 'Europe/Prague'
log_filename: postgresql-%Y-%m-%d_%H.log
log_line_prefix: '%t [%p]: db=%d,user=%u,app=%a,client=%h '
unix_socket_permissions: 0700
authentication:
replication:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
rewind:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
superuser:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
tags:
nofailover: false
noloadbalance: false
clonefrom: true
- Pozor, pravidla pg_hba se čtou sekvenčně a použije se první, které odpovídá databázi, uživateli a způsobu připojení (hostssl vs host). Pokud je více takových pod sebou, použije se první. Např při nastavení:
hostssl all all 10.0.1.2/32 cert
hostssl all all 10.0.1.2/32 md5
nebude fungovat přihlášení heslem. - Pozor, pravidla pg_hba se čtou sekvenčně a použije se první, které odpovídá databázi, uživateli a způsobu připojení (hostssl vs host). Pokud je více takových pod sebou, použije se první. Např při nastavení:
hostssl all all 10.0.1.2/32 cert
hostssl all all 10.0.1.2/32 md5
nebude fungovat přihlášení heslem. - Cesta k adresáři se spustitelnými soubory postgresql.
- Adresář, ve kterém se budou nacházet data.
- IP a port na kterém bude databáze dostupná. Lze zadat více adres. V takovém případě se port musí nacházet za tou poslední. Např.:
listen: 127.0.0.1,10.0.1.2:5432
Pokud chceme povolit připojení na všech rozhraních, nastavíme:listen: 0.0.0.0:5432 - Adresa a port, na které bude databáze dostupná ostatním nodům.
-
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. -
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. -
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. - Adresa a port, na které bude REST api dostupné pro ostatní nody
- Adresa a port, na které bude poslouchat REST api - musí být dostupná z ostatních nodů a také ze všech instancí HAProxy
- Všechny nody ETCD clusteru
- Protokol pro připojení do ETCD clusteru
- Certifikát CA
- Klientský certifikát pro připojení do ETCD clusteru
- Klíč ke klientskému certifikátu pro připojení do ETCD clusteru
-
bootstrap
Tato sekce se čte pouze při vytváření clusteru. Jakmile je cluster vytvořen, je její obsah ingorován. Není tedy třeba ji aktualizovat při změně konfiguračních parametrů. Ke změně konfiguračních parametrů pro celý cluster je určen příkaz patronictl edit-config viz výše. - Název hosta. Musí být unikátní v celém clusteru.
- Parametry upravující chování aplikace patronictl
-
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. - Pouze uživatel postgres se může připojit k databázi přes unix socket - díky záznamu
local all all trustvpg_hbanebude pro připojení vyžadováno heslo. Toto je primárně kvůli zálohám.
scope: postgresql-cluster
namespace: /service/
name: postgres-patroni-etcd-02 # (18)!
etcd3:
hosts: 10.120.1.2:2379,10.120.1.3:2379,10.120.0.10:2379 # (12)!
protocol: https # (13)!
cacert: /etc/patroni/pmc2t-ca.cert.pem # (14)!
cert: /etc/patroni/patroni.pem # (15)!
key: /etc/patroni/patroni.key # (16)!
log:
dir: /var/log/patroni
format: '%(asctime)s %(levelname)s: %(message)s'
level: DEBUG
max_queue_size: 1000
traceback_level: ERROR
type: plain
restapi:
listen: 0.0.0.0:8008 # (10)!
connect_address: 10.120.1.3:8008 # (11)!
authentication:
username: haproxy
password: vDmFnpb9kcgjEfbsxxyb5h7vdDes2konqEfb9q4jj3oncvEd
certfile: /etc/patroni/patroni.pem
keyfile: /etc/patroni/patroni.key
cafile: /etc/patroni/pmc2t-ca.cert.pem
verify_client: required
ctl: # (19)!
authentication:
username: haproxy
password: vDmFnpb9kcgjEfbsxxyb5h7vdDes2konqEfb9q4jj3oncvEd
certfile: /etc/patroni/patroni.pem
keyfile: /etc/patroni/patroni.key
cafile: /etc/patroni/pmc2t-ca.cert.pem
postgresql:
listen: 0.0.0.0:5432 # (5)!
connect_address: 10.120.1.3:5432 # (6)!
data_dir: /var/lib/postgresql/15/main # (4)!
bin_dir: /usr/lib/postgresql/15/bin # (3)!
authentication:
replication:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
rewind:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
superuser:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
pg_hba: # (1)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.2/32 cert # (8)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.3/32 cert # (7)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.4/32 cert # (20)!
- hostssl all "Green Center PMC TEST PATRONI cert" 127.0.0.1/32 cert # (9)!
- hostssl all all 0.0.0.0/0 md5
- hostssl all all 0.0.0.0/0 cert
- host all all 127.0.0.1/32 md5
- host all all 0.0.0.0/0 md5
- local all all trust
use_pg_rewind: true
parameters:
ssl: 'on'
ssl_cert_file: /etc/patroni/patroni.pem
ssl_key_file: /etc/patroni/patroni.key
ssl_ca_file: /etc/patroni/pmc2t-ca.cert.pem
archive_mode: always
archive_command: 'test ! -f /var/lib/postgresql/15/wal_archive/%f && cp %p /var/lib/postgresql/15/wal_archive/%f'
logging_collector: on
log_destination: 'stderr'
log_truncate_on_rotation: on
log_checkpoints: on
log_connections: on
log_disconnections: on
log_error_verbosity: default
log_lock_waits: on
log_temp_files: 0
log_autovacuum_min_duration: 0
log_min_duration_statement: 50
log_timezone: 'Europe/Prague'
log_filename: postgresql-%Y-%m-%d_%H.log
log_line_prefix: '%t [%p]: db=%d,user=%u,app=%a,client=%h '
unix_socket_permissions: 0700 # (21)!
bootstrap: # (17)!
initdb:
- encoding: UTF8
- data-checksums
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576 # Failover parameters
postgresql:
pg_hba: # (2)!
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.2/32 cert
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.3/32 cert
- hostssl all "Green Center PMC TEST PATRONI cert" 10.120.1.4/32 cert
- hostssl all "Green Center PMC TEST PATRONI cert" 127.0.0.1/32 cert
- hostssl all all 0.0.0.0/0 md5
- hostssl all all 0.0.0.0/0 cert
- host all all 127.0.0.1/32 md5
- host all all 0.0.0.0/0 md5
- local all all trust
use_slots: true
use_pg_rewind: true
parameters:
max_connections: 1000
max_locks_per_transaction: 64
max_worker_processes: 8
max_prepared_transactions: 0
wal_level: replica
track_commit_timestamp: 'off'
max_wal_senders: 10
max_replication_slots: 10
wal_keep_segments: 8
wal_keep_size: 1024MB
wal_log_hints: 'on'
hot_standby: 'on'
shared_buffers: 1024MB
ssl: 'on'
ssl_cert_file: /etc/patroni/patroni.pem
ssl_key_file: /etc/patroni/patroni.key
ssl_ca_file: /etc/patroni/pmc2t-ca.cert.pem
logging_collector: on
log_destination: 'stderr'
log_truncate_on_rotation: on
log_checkpoints: on
log_connections: on
log_disconnections: on
log_error_verbosity: default
log_lock_waits: on
log_temp_files: 0
log_autovacuum_min_duration: 0
log_min_duration_statement: 50
log_timezone: 'Europe/Prague'
log_filename: postgresql-%Y-%m-%d_%H.log
log_line_prefix: '%t [%p]: db=%d,user=%u,app=%a,client=%h '
unix_socket_permissions: 0700
authentication:
replication:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
rewind:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
superuser:
username: Green Center PMC TEST PATRONI cert
sslmode: prefer
sslcert: /etc/patroni/patroni.pem
sslkey: /etc/patroni/patroni.key
sslrootcert: /etc/patroni/pmc2t-ca.cert.pem
tags:
nofailover: false
noloadbalance: false
clonefrom: false
- Pozor, pravidla pg_hba se čtou sekvenčně a použije se první, které odpovídá databázi, uživateli a způsobu připojení (hostssl vs host). Pokud je více takových pod sebou, použije se první. Např při nastavení:
hostssl all all 10.0.1.2/32 cert
hostssl all all 10.0.1.2/32 md5
nebude fungovat přihlášení heslem. - Pozor, pravidla pg_hba se čtou sekvenčně a použije se první, které odpovídá databázi, uživateli a způsobu připojení (hostssl vs host). Pokud je více takových pod sebou, použije se první. Např při nastavení:
hostssl all all 10.0.1.2/32 cert
hostssl all all 10.0.1.2/32 md5
nebude fungovat přihlášení heslem. - Cesta k adresáři se spustitelnými soubory postgresql.
- Adresář, ve kterém se budou nacházet data.
- IP a port na kterém bude databáze dostupná. Lze zadat více adres. V takovém případě se port musí nacházet za tou poslední. Např.:
listen: 127.0.0.1,10.0.1.2:5432
Pokud chceme povolit připojení na všech rozhraních, nastavíme:listen: 0.0.0.0:5432 - Adresa a port, na které bude databáze dostupná ostatním nodům.
-
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. -
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. -
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. - Adresa a port, na které bude REST api dostupné pro ostatní nody
- Adresa a port, na které bude poslouchat REST api - musí být dostupná z ostatních nodů a také ze všech instancí HAProxy
- Všechny nody ETCD clusteru
- Protokol pro připojení do ETCD clusteru
- Certifikát CA
- Klientský certifikát pro připojení do ETCD clusteru
- Klíč ke klientskému certifikátu pro připojení do ETCD clusteru
-
bootstrap
Tato sekce se čte pouze při vytváření clusteru. Jakmile je cluster vytvořen, je její obsah ingorován. Není tedy třeba ji aktualizovat při změně konfiguračních parametrů. Ke změně konfiguračních parametrů pro celý cluster je určen příkaz patronictl edit-config viz výše. - Název hosta. Musí být unikátní v celém clusteru.
- Parametry upravující chování aplikace patronictl
-
ověření certifikátem
Pokud je použito ověření do databáze pomocí certifikátu, musí být název uživatele shodný s CN (Common Name) klientského certifikátu. - Pouze uživatel postgres se může připojit k databázi přes unix socket - díky záznamu
local all all trustvpg_hbanebude pro připojení vyžadováno heslo. Toto je primárně kvůli zálohám.
Příprava na spuštění¶
Spuštění¶
# Jelikož bude postgres ovládat patroni, je nutné zastavit běžící instanci
sudo systemctl disable --now postgresql@15-main.service
# Spuštění patroni
sudo systemctl enable --now patroni
sudo patronictl -c /etc/patroni/config.yml list
# Vypíše stav clusteru. výstup by měl vypadat takto:
# + Cluster: postgresql-cluster (7514618054609667890) ----------+----+-----------+-----------------+
# | Member | Host | Role | State | TL | Lag in MB | Tags |
# +--------------------------+------------+---------+-----------+----+-----------+-----------------+
# | postgres-patroni-etcd-01 | 10.120.1.2 | Leader | running | 13 | | clonefrom: true |
# +--------------------------+------------+---------+-----------+----+-----------+-----------------+
Pokud výpis vypadá jako výše, spustíme patroni na záložním serveru
# Jelikož bude postgres ovládat patroni, je nutné zastavit běžící instanci
sudo systemctl disable --now postgresql@15-main.service
# Spuštění patroni
sudo systemctl enable --now patroni
sudo patronictl -c /etc/patroni/config.yml list
# Vypíše stav clusteru. výstup by měl vypadat takto:
# + Cluster: postgresql-cluster (7514618054609667890) -----------------+----+-----------+-----------------+
# | Member | Host | Role | State | TL | Lag in MB | Tags |
# +--------------------------+------------+---------+------------------+----+-----------+-----------------+
# | postgres-patroni-etcd-01 | 10.120.1.2 | Leader | running | 13 | | clonefrom: true |
# | postgres-patroni-etcd-02 | 10.120.1.3 | Replica | creating replica | | unknown | |
# +--------------------------+------------+---------+------------------+----+-----------+-----------------+
# Pokud je State jiný, než creating replica, spustit následující příkaz:
# sudo patronictl -c /etc/patroni/config.yml reinit postgresql-cluster postgres-patroni-etcd-02
# Přepnout na záložní server můžeme příkazem
# sudo patronictl -c /etc/patroni/config.yml switchover
Umístění logů
Po spuštění služby patroni se již databázové logy nebudou nacházet ve standardním umístění /var/log/postgresql, ale v adresáři /var/lib/postgresql/15/main/log.
Monitoring¶
Pro monitoring replikace vznikla šablona v Zabbixu. Její detailní popis je dostupný v repozitáři.