Patroni kurulumuyla ilgili oldukça fazla kaynak bulunmakta fakat kurulum ve yönetimini beraber barındıran kaynağa denk gelmedim. Bu yazıda hem Patroni kurulumu hem de kurulum sonrası yönetimiyle alakalı detaylara ulaşabilirsiniz.
PostgreSQL cluster'larının yönetimi için kullanılan Patroni ile ilgili temel bilgilerin yer aldığı Autofailover üzerine hazırladığım yazı serisine aşağıdaki linklerden erişebilirsiniz.
PostgreSQL ve Autofailover
PostgreSQL'de Autofailover ve Patroni 1 (Giriş)
PostgreSQL'de Autofailover ve Patroni 2 (Kurulum, Konfigürasyon ve Yönetim)
PostgreSQL'de Autofailover ve Patroni 3 (Mevcut PostgreSQL Cluster'inin Patroni'ye Geçirilmesi)
Patroni, PostgreSQL veritabanlarının kurulumundan ve konfigürasyonundan sorumludur. Yani Patroni'yi kurduğumuz sunucular aynı zamanda Patroni ile kurulmuş PostgreSQL'leri barındıracak. Üç node'lu PostgreSQL ve üç node'lu ETCD cluster'larını oluşturacağım.
Kuruluma önce üç node'lu ETCD cluster yapısını kurarak başlayacağım. Tüm sunucularda aşağıdaki paketler kurulur.
yum install -y gcc python-devel epel-release
ETCD Kurulumu
ETCD, GO dili ile yazılmış, CoreOS tarafından geliştirilen, dağıtık sistemlerin konfigürasyonları için kullanılan distributed High Available key-value store’u olarak tanımlanır.
Üç ETCD sunucusunun her birinde aşağıdaki paket kurulur.
yum install etcd -y
Paketin kurulmasıyla /etc/etcd/etcd.conf dosyası oluşur içinde ETCD cluster yapısının kurulması için MEMBER ve CLUSTERING altındaki parametrelerin bazıları düzenlenir. ETCD_INITIAL_CLUSTER_STATE değişkeninin değeri “new” olmasına dikkat edelim.
Primary etcd - /etc/etcd/etcd.conf
[root@guncek01 ~]# cat /etc/etcd/etcd.conf
#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://ETCD_IP1:2380,http://127.0.0.1:7001"
ETCD_LISTEN_CLIENT_URLS="http://ETCD_IP1:2379,http://127.0.0.1:2379"
ETCD_NAME="cluster1"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://ETCD_IP1:2379"
ETCD_INITIAL_CLUSTER="cluster1=http://ETCD_IP1:2380,cluster2=http://ETCD_IP2:2380,cluster3=http://ETCD_IP3:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD paketinin kurulumu ve etcd.conf dosyasındaki düzenleme tüm ETCD node’larında yapılmalı. Etcd.conf dosyası içinde yapılacak düzenlemeler node’ların IP’siyle beraber yeniden düzenlenmeli.
Etcd.conf içinde yapılan değişikliğin yansıması için node’lar üzerindeki etcd servisleri sırayla başlatılır ve sunucunun başlamasıyla etcd servisinin de başlaması için servis enable edilir.
systemctl start etcd
systemctl enable etcd
Her node üzerinde aynı düzenlemeler yapıldıktan sonda ETCD Health-Check yapılır.
[root@guncek01 ~]# etcdctl cluster-health
member 147c3c754f89f96f is healthy: got healthy result from http://ETCD_IP1:2379
member 58b8f74d65899ae4 is healthy: got healthy result from http://ETCD_IP2:2379
member ea2bd704a356529e is healthy: got healthy result from http://ETCD_IP3:2379
cluster is healthy
Oluşturduğumuz bu ETCD cluster'i altındaki tüm member'ları ayrıca listeleyebilirsiniz. "member list" komutunu herhangi bir ETCD node'u üzerinde çalıştırabilirsiniz.
[root@guncek01 pgsql]# etcdctl member list
147c3c754f89f96f: name=cluster3 peerURLs=http://ETCD_IP3:2380 clientURLs=http://ETCD_IP3:2379 isLeader=false
58b8f74d65899ae4: name=cluster2 peerURLs=http://ETCD_IP2:2380 clientURLs=http://ETCD_IP2:2379 isLeader=true
d5233d20be500cbc: name=cluster1 peerURLs=http://ETCD_IP1:2380 clientURLs=http://ETCD_IP1:2379 isLeader=false
ETCD Cluster'a yeni node eklemek
Ayakta olan ETCD cluster'larının birinde eklemek istediğimiz yeni node'un IP'sini kullanarak yeni node ekleyebiliriz.
etcdctl member add cluster1 http://NEW_ETCD_NODE_IP:2380
ETCD Cluster'dan node çıkarmak
ETCD clsuter'i üzerinden bir node'u çıkarmak için member id’yi kullanarak o node’u cluster’dan çıkarırız.
etcdctl member remove 41cc095a288b712a
Patroni Kurulumu
Kuruluma başlamadan önce tüm Postgres node'ları arasında root kullanıcısı için karşılıklı olarak parolasız ssh yapılması için gerekli düzenleme yapılması gerekir. Bu düzenlemeyi yaptıysanız, Patroni kurulumuna devam edebilirsiniz.
Patroni kurulumu öncesinde Postgres rpm paketlerini kurmak gerekir. Patroni ile Postgres node'ları bootstrap(başlatılması) yapılsa da en nihayetinde replikasyonun kurulması gibi işlemleri Postgres'in tool'larını kullanarak yapacak. Dolayısıyla Postgres kurulumu için gereken tüm paketleri kurmak gerekecek.
yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum install postgresql11 postgresql11-server -y
Tüm Postgres node'ları üzerinde RPM'leri kurduktan sonra aynı node'lar üzerinde Patroni kurulumu yapacağız.
cd /usr/src/
wget https://github.com/cybertec-postgresql/patroni-packaging/releases/download/1.6.0-1/patroni-1.6.0-1.rhel7.x86_64.rpm
yum install patroni
Patroni’nin bootstrap sırasında oluşturacağı veritabanına ait cluster dizini olmalı. Patroni için yeni cluster dizini oluşturulur.
mkdir /var/lib/pgsql/patroni -p
chown postgres:postgres /var/lib/pgsql/patroni
chmod 700 /var/lib/pgsql/patroni
Patroni’nin log dizini tüm sunucular üzerinde oluşturulur. Patroni servisinin başlamasıyla log dosyası, bizim oluşturduğumuz dizin altında oluşturulacaktır.
mkdir /var/log/patroni
chown postgres:postgres /var/log/patroni
chmod 755 /var/log/patroni
Patroni paketinin kurulmasıyla /usr/src/app/patroni/etc dizini altında postgresql.yml.sample dosyası oluşturulmuştur. Bu dosyanın yedeğini alarak yeni postgresql.yml konfigürayon dosyası üzerinden çalışmaya devam edilir. Bu dosya tüm PostgreSQL sunucuları üzerinde oluşturulmalıdır.
cp /usr/src/app/patroni/etc/postgresql.yml.sample /usr/src/app/patroni/etc/postgresql.yml
IP adresi, name, restapi, etcd, listen, connected address alanları her veritabanı sunucusu için unique alanlar olduğundan bu alanları sunucu bazlı doldurmak gerekir.
Primary patroni - /usr/src/app/patroni/etc/postgresql.yml
[root@guncek02 ~]# cat /usr/src/app/patroni/etc/postgresql.yml
scope: batman2
namespace: /db/
name: postgresql0
log:
dir: /var/log/patroni
restapi:
listen: 127.0.0.1:8008
connect_address: 127.0.0.1:8008
# certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem
# keyfile: /etc/ssl/private/ssl-cert-snakeoil.key
# authentication:
# username: username
# password: password
etcd:
host: ETCD_IP1:2379
protocol: http
bootstrap:
# this section will be written into Etcd:///config after initializing new cluster
# and all other cluster members will use it as a `global configuration`
dcs:
ttl: 30
loop_wait: 30
retry_timeout: 30
maximum_lag_on_failover: 1048576
# master_start_timeout: 300
# synchronous_mode: false
postgresql:
use_pg_rewind: true
use_slots: true
parameters:
log_line_prefix: " time:%m pid=%p host=%h db=%d app=%a "
wal_level: hot_standby
hot_standby: "on"
wal_keep_segments: 8
max_wal_senders: 5
max_replication_slots: 5
wal_log_hints: "on"
archive_mode: "off"
archive_timeout: 1800s
# archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f
# recovery_conf:
# restore_command: cp ../wal_archive/%f %p
# some desired options for 'initdb'
initdb: # Note: It needs to be a list (some options need values, others are switches)
- encoding: UTF8
- data-checksums
pg_hba: # Add following lines to pg_hba.conf after running 'initdb'
- host all all DB_IP1/32 md5
- host all all DB_IP2/32 md5
- host all all DB_IP3/32 md5
- host replication replicator DB_IP1/32 md5
- host replication replicator DB_IP2/32 md5
- host replication replicator DB_IP3/32 md5
- host all all 0.0.0.0/0 md5
# - hostssl all all 0.0.0.0/0 md5
# Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter)
# post_init: /usr/local/bin/setup_cluster.sh
# Some additional users users which needs to be created after initializing new cluster
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: DB_IP1:5432
connect_address: DB_IP1:5432
data_dir: /var/lib/pgsql/patroni
bin_dir: /usr/pgsql-11/bin
# pgpass: /tmp/pgpass0
authentication:
replication:
username: replicator
password: 'replicator'
superuser:
username: postgres
password: 'postgres'
#watchdog:
# mode: automatic # Allowed values: off, automatic, required
# device: /dev/watchdog
# safety_margin: 5
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
Önce primary olmak üzere Patroni servisleri node’lar üzerinde sırasıyla çalıştırılır. Sırayla çalıştırılmasının sebebi primary sunucunun ayağa kalkmasından sonra diğer Postgres node’larının replika olarak ayağa kaldırılmasıdır. Bunu da pg_basebackup ile yapacaktır. Patroni servisini önce primary sunucuda sonra standby sunucuda başlattım.
systemctl start patroni
systemctl enable patroni
Primary patroni log -
2019-12-25 16:22:39,406 INFO: Lock owner: postgresql0; I am postgresql0
2019-12-25 16:22:39,411 INFO: no action. i am the leader with the lock
Standby patroni log -
2019-12-25 16:21:39,411 INFO: Lock owner: postgresql0; I am postgresql1
2019-12-25 16:21:39,411 INFO: does not have lock
2019-12-25 16:21:39,415 INFO: no action. i am a secondary and i am following a leader
Patroni cluster listesine bakalım.
[root@guncek02 ~]# patronictl -d etcd://localhost:2379 -c /usr/src/app/patroni/etc/postgresql.yml list
+---------+-------------+---------------+--------+---------+----+-----------+
| Cluster | Member | Host | Role | State | TL | Lag in MB |
+---------+-------------+---------------+--------+---------+----+-----------+
| batman2 | postgresql0 | DB_IP1 | Leader | running | 1 | 0 |
| batman2 | postgresql1 | DB_IP2 | | running | 1 | 0 |
+---------+-------------+---------------+--------+---------+----+-----------+
Patroni cluster içine tüm Postgres node'larını ekledik. Primary Postgres servisini kapatalım ve testlere başlayalım.
service patroni stop
Standby sunuculardan birin primary olarak devam eder.[root@guncek03 ~]# patronictl -d etcd://localhost:2379 -c /usr/src/app/patroni/etc/postgresql.yml list
+----------+-------------+---------------+--------+---------+----+-----------+
| Cluster | Member | Host | Role | State | TL | Lag in MB |
+----------+-------------+---------------+--------+---------+----+-----------+
| batman_3 | postgresql0 | DB_IP1 | | running | 11 | 0 |
| batman_3 | postgresql1 | DB_IP2 | Leader | running | 11 | 0 |
| batman_3 | postgresql2 | DB_IP3 | | stopped | | unknown |
+----------+-------------+---------------+--------+---------+----+-----------+
Yeni primary(eski standby) sunucunun log dosyasında artık yeni primary olduğuna dair log yazılır.2019-12-25 16:28:27,396 INFO: Lock owner: postgresql1; I am postgresql1
2019-12-25 16:28:27,402 WARNING: Watchdog not supported because leader TTL 30 is less than 2x loop_wait 30
2019-12-25 16:28:27,407 INFO: no action. i am the leader with the lock
Eski primary sunucuyu yeniden başlatalım. Bir süre sonra eski primary artık standby sunuculardan biri olarak cluster’a katılacak.
[root@guncek02 ~]# service patroni start
Redirecting to /bin/systemctl start patroni.service
[root@guncek02 ~]# patronictl -c /usr/src/app/patroni/etc/postgresql.yml list
+----------+-------------+---------------+--------+---------+----+-----------+
| Cluster | Member | Host | Role | State | TL | Lag in MB |
+----------+-------------+---------------+--------+---------+----+-----------+
| batman_3 | postgresql0 | DB_IP1 | | running | 11 | 0 |
| batman_3 | postgresql1 | DB_IP2 | Leader | running | 11 | 0 |
| batman_3 | postgresql2 | DB_IP3 | | running | 11 | 0 |
+----------+-------------+---------------+--------+---------+----+-----------+
Patroni Cluster’indan Node Silmek
/usr/src/app/patroni/bin/patronictl -d etcd://localhost:2379 -c /usr/src/app/patroni/etc/postgresql.yml remove batman_3
PostgreSQL konfgürasyon parametrelerinin güncellenmesi
Patroni ile PostgreSQL'i entegre ettikten sonra PostgreSQL konfigürasyon parametrelerini ALTER SYSTEM komutunu kullanarak veya postgresql.conf içinde düzenleme yaparak değiştirilmemelidir. Replikalardan birinde patronictl komutu edit-config seçeneği ile çalıştırılır. Örneğin wal_keep_segments değerinin değiştirilmek istersek, patronictl komutunu çalıştırdıktan sonra değişikliği kaydedelim. Yapılan değişiklik DCS sayesinde tüm sunucular üzerinde aynı değişiklikler uygulanacak.
[root@guncek02 ~]# patronictl -c /usr/src/app/patroni/etc/postgresql.yml edit-config
---
+++
@@ -8,7 +8,7 @@
log_line_prefix: ' time:%m pid=%p host=%h db=%d app=%a '
max_replication_slots: 5
max_wal_senders: 5
- wal_keep_segments: 10
+ wal_keep_segments: 8
wal_level: hot_standby
wal_log_hints: 'on'
use_pg_rewind: true
Apply these changes? [y/N]: y
Configuration changed
Patroni log dosyasında yapılan değişiklik aşağıdaki gibi yansıyacaktır.
grep -i changed /var/log/patroni/patroni.log
2019-12-30 10:02:58,878 INFO: Changed wal_keep_segments from 10 to 8
2019-12-30 10:02:58,879 INFO: PostgreSQL configuration items changed, reloading configuration.
2019-12-30 10:03:28,865 INFO: Lock owner: postgresql1; I am postgresql1
Mevcut bir Postgres veritabanının Patroni'ye taşınmasını anlatan serinin son yazısına buradan ulaşabilirsiniz.
Comments
Post a Comment