PATRONİ
Patroni Nedir?
Patroni, yüksek erişilebilir PostgreSQL kümelerinin dağıtımını ve bakımını özelleştirmek ve otomatikleştirmek için kullanılan bir küme yöneticisi aracıdır. Python’da yazılmıştır ve yüksek erişilebilirlik için dağıtılmış bir yapılandırma deposu olarak etcd, Consul ve ZooKeeper’ı kullanır. Ek olarak Patroni, veritabanı çoğaltma, yedekleme ve geri yükleme yapılandırmalarını yönetebilir.
Kurulumu yaptığım mimarinin özetle çalışma şekli;
- Uygulamalar, veritabanına erişmek için HAProxy'ye bağlanır.
- HAProxy, yapılandırılmış kurallara ve sunucuların sağlık durumuna göre bağlantı isteklerini birincil PostgreSQL sunucusuna yönlendirir.
- Birincil sunucuya yapılan değişiklikler (yazma işlemleri) streaming replication yoluyla yedek sunucuya eş zamanlı olarak aktarılır.
- Patroni, her iki PostgreSQL sunucusunda da çalışır ve kümenin durumunu etcd üzerinden izler.
- Birincil sunucu arızalanırsa:
- Patroni, etcd'deki birincil sunucu bilgisinin kaybolduğunu veya sağlıksız olduğunu tespit eder.
- Yedek sunucular arasında yeni bir birincil sunucu seçimi (leader election) yapılır (etcd'nin yardımıyla).
- Seçilen yeni birincil sunucu, etcd'de güncellenir. Bizim sadece 1 yedek makinemiz olduğu için bu işlem yapılmayacak.
- HAProxy, durum kontrolü sayesinde eski birincil sunucunun sağlıksız olduğunu fark eder ve yeni birincil sunucuya trafik yönlendirmeye başlar.
- Uygulamalar, HAProxy üzerinden kesintisiz bir şekilde veritabanına erişmeye devam edebilir.
Ubuntu İşletim Sisteminin Kurulması ve MobaXterm Üzerinden SSH Bağlantısının Kurulması
Bu videoda, kurulum için ihtiyacımız olan ubuntu işletim sisteminin kurulumunu yaptık ve 4 makinayı aynı anda kullanmamız gerektiği için tek bir ekranda bütün makineleri görüntülemek işimizi kolaylaştıracaktı bu yüzden mobaxterm üzerinden ssh bağlantısı yaptık. Sonrasında da uzak bağlantıda ubuntu işletim sistemi kurulu makinemize postgresql kurulumu yaptık. Aşağıdaki kodları sırayla çalıştırararak postgresql kurulumunu tamamlayabilirsiniz.
# Import the repository signing key:
sudo apt install curl ca-certificates
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
# Create the repository configuration file:
. /etc/os-release
sudo sh -c "echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $VERSION_CODENAME-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
# Update the package lists:
sudo apt update
# Install the latest version of PostgreSQL:
# If you want a specific version, use 'postgresql-17' or similar instead of 'postgresql'
sudo apt -y install postgresql
Patroni Kurulumu
PostgreSQL, açık kaynaklı ve popüler veritabanıdır. Ancak, yüksek erişilebilirlik için herhangi bir özelliğe sahip değildir. Burada en çok kullanılan çözüm Patronidir. Patroni, yüksek erişilebilir PostgreSQL kümelerinin dağıtımını ve bakımını özelleştirmek ve otomatikleştirmek için kullanılan bir küme yöneticisi aracıdır. Python’da yazılmıştır ve yüksek erişilebilirlik için dağıtılmış bir yapılandırma deposu olarak etcd, Consul ve ZooKeeper’ı kullanır. Ek olarak Patroni, veritabanı çoğaltma, yedekleme ve geri yükleme yapılandırmalarını yönetebilir. Ben bu yazımda 4 node’dan oluşan bir cluster kurulum yapacağım ama sizler isterseniz postgresql node’larını kendinize göre arttırabilirsiniz.
Gerekli Kaynaklar:
- 4 tane Ubuntu 20.04 Server
- Serverların birbirine ssh üzerinden tam erişimi. (SSH key trust)
Sunucular
| Server | Yüklenecek Uygulamalar | IP |
|---|---|---|
| psql01 | Postgresql, Patroni | 192.168.52.179 |
| psql01 | Postgresql, Patroni | 192.168.52.180 |
| etcd | etcd | 192.168.52.169 |
| ha | HAProxy | 192.168.52.181 |
ETCD Kurulumu
ETCD, PostgreSQL kümesinin durumunu tutar. Herhangi bir PostgreSQL düğümünün durumunda herhangi bir değişiklik olduğunda, Patroni ETCD key/value deposundaki durum değişikliğini günceller. ETCD, bu bilgiyi ana düğümü seçmek için kullanır ve kümeyi çalışır durumda tutar.
sudo apt install etcd
etcd kurulumu tamamlandıktan sonra conf dosyasını oluşturalım
sudo nano /etc/default/etcd
ETCD_LISTEN_PEER_URLS="http://192.168.52.169:2380"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://192.168.52.169:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.52.169:2380"
ETCD_INITIAL_CLUSTER="default=http://192.168.52.169:2380,"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.52.169:2379"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
nano ile conf dosyasını düzenleyerek kendi ETCD makine IPnize göre burayı ayarlayın. Conf edit bittikten sonra etcd servisini yeniden başlatın.
systemctl restart etcd
systemctl status etcd
HAProxy Kurulumu
HAProxy Master/Slave düğümlerinde ki değişiklikleri takip eder ve client bir bağlantı talep ettiğinde uygun ana düğüme yönlendirir.
sudo apt install haproxy
HAProxy kurulumu yapıldıktan sonra postgresql ve patroni tarafına geçeceğiz. Patroni, postgresql kurulduktan sonra ise en son olarak HAProxy config yapacağız.
Patroni ve Postgresql Kurulumu
Postgresql kurulumu için yukarıda linkini bıraktığım yazıdan yardım alabilirisniz. Patroni kurulumu için gerekli komutlar:
apt install python3-pip python3-dev libpq-dev -y
pip3 install --upgrade pip
pip install patroni
pip install python-etcd
pip install psycopg2
İhtiyaç duyduğumuz bütün altyapı kurulumunu bitirmiş olduk. Buradan sonra artık clusterımızı yaratıp ayarlarını yapacağız.
Patroni Konfigürasyon
Patroni’nin config dosyası clusterın bütün detaylarını içeren bir yml dosyasıdır. Patroni clusterını yönetirken postgresql kullanıcılarına ihtiyaç duyar ilk olarak bu kullanıcıları iki postgresql node unda da belirlemeniz gerekiyor. Hem default kullanıcı olan postgres kullanıcısının şifresini berliliyeceğiz hem de replicator diye yeni bir kullanıcı create edip onu da patroni configinde kullanacağız. Sırasıyla aşağıdaki komutları çalıştırın.
sudo -u postgres psql
ALTER USER postgres PASSWORD 'sifre123';
CREATE USER replicator WITH ENCRYPTED PASSWORD 'sifre321';
Patroni’nin bazı postgresql dosyalarına erişmesi için bir link oluşturmak gerekiyor. Bu komutu iki postgre node’una da uygulayın.
ln -s /usr/lib/postgresql/17/bin/* /usr/sbin/
Son olarak Patroni’nin data için kullanacağı klasörleri belirleyip gerekli izinleri vermemiz gerekiyor.
mkdir -p /data/patroni
chown -R postgres:postgres /data/
chmod -R 700 /data/
Kullanıcıları ve klasörleri oluşturup gerekli izinleri verdikten sonra patroni.yml dosyamızı yazmaya başlayabiliriz.
PSQL01 Node’una bağlanıp işlemlere başlayalım.
sudo nano /etc/patroni.yml
scope: prodcluster # Cluster ismi
namespace: /db/
name: prodpsql01 # Node ismi
restapi:
listen: 192.168.52.179:8008 # Node IP'si
connect_address: 192.168.52.179:8008 # Node IP'si
etcd:
host: 192.168.52.169:2379 # etcd server IP'si
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
initdb:
- encoding: UTF8
- data-checksums
pg_hba:
- host replication replicator 127.0.0.1/32 md5
- host replication replicator 192.168.52.179/0 md5 # psql01 IP'si
- host replication replicator 192.168.52.180/0 md5 # psql02 IP'si
- host all all 0.0.0.0/0 md5
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 192.168.52.179:5432 # psql01 IP'si
connect_address: 192.168.52.179:5432 # psql01 IP'si
data_dir: /data/patroni # Patroninin kullanacağı data klasörü
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator # Replicator kullanıcısı oluştururken benden farklı yazdıysanız değiştirin.
password: sifre321
superuser:
username: postgres # Postgres şifresini benden farklı yaptıysanız değiştirin
password: sifre123
parameters:
unix_socket_directories: '.'
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
Kullanıcıları ve klasörleri oluşturup gerekli izinleri verdikten sonra patroni.yml dosyamızı yazmaya başlayabiliriz.
PSQL02 Node’una bağlanıp işlemlere başlayalım.
sudo nano /etc/patroni.yml
scope: prodcluster # Cluster ismi
namespace: /db/
name: prodpsql02 # Node ismi
restapi:
listen: 192.168.52.180:8008 # Node IP'si
connect_address: 192.168.52.180:8008 # Node IP'si
etcd:
host: 192.168.52.169:2379 # etcd server IP'si
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
initdb:
- encoding: UTF8
- data-checksums
pg_hba:
- host replication replicator 127.0.0.1/32 md5
- host replication replicator 192.168.52.179/0 md5 # psql01 IP'si
- host replication replicator 192.168.52.180/0 md5 # psql02 IP'si
- host all all 0.0.0.0/0 md5
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 10.90.214.183:5432
connect_address: 10.90.214.183:5432
data_dir: /data/patroni # Patroninin kullanacağı data klasörü
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator # Replicator kullanıcısı oluştururken benden farklı yazdıysanız değiştirin.
password: sifre321
superuser:
username: postgres # Postgres şifresini benden farklı yaptıysanız değiştirin
password: sifre123
parameters:
unix_socket_directories: '.'
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
Patroni için gerekli yml dosyasını yazdıktan sonra Patroni’yi bir linux servisi haline getirmek için servis dosyası oluşturmamız gerekiyor. Bunu her iki postgresql node’unda da uygulayın.
PSQL02 Node’una bağlanıp işlemlere başlayalım.
sudo nano /etc/systemd/system/patroni.service
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target
[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni.yml
KillMode=process
TimeoutSec=30
Restart=no
[Install]
WantedBy=multi-user.target
Bütün ayarları yaptık artık cluster’ı başlatabiliriz.
systemctl daemon-reload
systemctl enable patroni
systemctl enable postgresql
systemctl start patroni
systemctl start postgresql
Postgresql clusterımız hazır. Şimdi HAProxy config’ide bitirip Clusterımız için database endpointimizi alacağız.
HAProxy Konfigürasyon
HAProxy node’unda gerekli config dosyasını düzenleyeceğiz. Ben configimde database endpoint için 5000 portunu kullandım siz değiştirebilirsiniz.
sudo nano /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 postgres
bind *:5000
option httpchk
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server PSQL01 192.168.52.179:5432 maxconn 100 check port 8008
server PSQL02 192.168.52.180:5432 maxconn 100 check port 8008
Configi bu şekilde kaydedip çıkın ve HAProxy Servisini restart edin.
systemctl restart haproxy
HAProxy config tamamlandıktan sonra http://192.168.52.181:7000 url’inden haproxy status sayfasını ziyaret edelim ve clusterı görüntüleyelim.
Kurulumu tamamladık artık herşeyi hazır ve çalışır durumda. Birde Patronictl kullanarak clusterımızı inceliyelim.
patronictl -c /etc/patroni.yml list
Kurulum Sonrası İnceleme
Bu videoda, kurulumunu yaptığımız ve tanıttığımız cihazlar beklenilen şekilde çalışıyor mu, pasif hale getirildiklerinde patroninin çalışması nasıl etkileniyor gibi incelemeler ve testler yaptık.
Automatic Failover
Primary sunucumuzun çökmesi durumunda otomatik olarak standby sunucumuzun primary sunucuya döndüğünü başarıyla test ettik. Ana makinamızda patroniyi restart edip anlık olarak iletişimi kestik ve anında liderlik, standby sunucuya geçti. Patroni restart etme komutuna ve lider-standby durumlarını kontrol etmek için aşağıdaki komutları çalıştırın.
sudo systemctl restart patroni
patronictl -c /etc/patroni.yml listManuel Failover
Çökme yaşamadan kendi isteğimizle liderliği devretmemiz de mümkün. Lider olmasını istediğiniz sunucumuzda aşağıdaki komutu çalıştırmanız yeterli.
patronictl -c /etc/patroni.yml failoverPrimary Node - Read/Write Testi
Okuma ve yazma işlemi yapabilir. Çökmesi durumunda standby node, primary node olur automatic failover sayesinde. Bir tablo oluşturup okuma yazma işlemleri yapabildiğini test ettik. Aşağıdaki komutlar ile tabloyu oluşturabilirsiniz.
CREATE TABLE logs (
id SERIAL PRIMARY KEY,
message TEXT,
created_at TIMESTAMP DEFAULT now());Şimdi primary node ile veritabanına bağlanıp okuma ve yazma işlemi yapalım.
psql -h 192.168.52.179 -U postgres -d postgres
INSERT INTO logs (message) VALUES ('Primary node test verisi');
SELECT * FROM logs;Standby Node - Read Only Testi
Sadece okuma işlemi yapabilir. Anlık olarak primary node'daki değişikliklerin yedeğini alır. Çökmesi durumunda patroni çalışmaya devam eder eğer birden fazla standby node varsa yükü onlara devam eder yoksa herhangi bir değişiklik olmaz ama acil olarak ayağa kaldırılması gerekir. Yukarıda oluşturduğumuz tabloya bağlanıp veri okuma işlemi yapalım. İsterseniz yazma işlemi de yapabilirsiniz ve sadece readonly olduğunu görürsünüz.
psql -h 192.168.52.80 -U postgres -d postgres
SELECT * FROM logs;ETCD Çalışmazsa Ne Olur?
- Patroni node’ları lider seçiminde ve cluster koordinasyonunda anlaşamaz.
- Aynı anda birden fazla primary olabilir, veri tutarsızlığı ortaya çıkar.
- Failover ve replikasyon yönetimi yapılamaz, yüksek erişilebilirlik sağlanamaz.
- Patroni hizmet veremez ya da istikrarsız olur
Özetle Patroni olmadan, çoklu node ortamında güvenilir ve tutarlı cluster yönetimi yapılamaz. Bu yüzden etcd zorunludur.
HAProxy Çalışmazsa Ne Olur?
HAProxy olmadan Patroni çalışabilir, ama uygulama trafiğini yönetmek için bir load balancer gerekir. Yani bağlanmaya çalışan uygulamalar direkt primary ye gider bu da çok güvensizdir.
Keepalived Kurulumu
Mimarimize yeni bir haproxy ekleyeceğiz. Çünkü haproxy den oluşabilecek muhtemel çökme sonucunda kesintisiz çalışmanın sağlanmasını için yedek ha proxy ye geçişin sağlanması gerekiyor bunu da keepalived kurulumu ile yapacağız. Yani haproxy ler arasında yüksek erişim sağlayacağız. Bunun için bir sanal ip oluşturacağız ve uygulamalar ilk önce bu sanal ip ye bağlanacak sonrasında da aktif olan haproxye ye yönlenecek.
Keepalived Kurulumu
Kuruluma başlamadan önce elimizde 2 tane haproxy sunucusu olması lazım. Önceki videoda anlattığım şekilde kurabilirsiniz.
Her iki HAProxy sunucusuna keepalived kurulmalı
sudo apt update
sudo apt install keepalived -ykeepalived.conf dosyasını yapılandırma
sudo nano /etc/keepalived/keepalived.confvrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.52.200
}
}Hangi HAProxy'nin başlangıçta ana HAProxy olacağını ayarlamak için priority değerini değiştirin. Priority değeri yüksek olan ana HAProxy seçilir. Bunun dışında iki makinede de ayarlar aynı olmalı. Son olarakta keepalived servisimizi aktif edip kurulumu tamamlayalım.
sudo systemctl enable keepalived
sudo systemctl start keepalived
Artık PostgreSQL bağlantılarında HAProxy'nin gerçek IP'si yerine VIP'yi kullanacağız.
psql -h 192.168.52.200 -U postgres -d postgresKeepalived kurulumumuz başarıyla tamamlandı. Şimdi keepalived hangi ha da aktif diye bakalım.
ip a | grep 192.168.52.200 Üstteki komutu çalıştırdıktan sonra hangi makinede çıktı oluyorsanız şuanda çalışan haproxy odur.
Videonun sonunda VIP üzerinden uygulamalarımızı kabul ettiğimizi test etmek için pgadmin üzerinden veritabanımıza bağlanmayı denedik ve sorunsuzca bağlandık. Keepalived servislerini sırayla kapatıp veritabanı bağlantısının nasıl etkilendiğini test ettik. Ana HAProxy kapatılınca otomatik olarak diğer keepalived kurulu olan HAProxy ana HAProxy oluyor ikisi birden kapatıldığında ise veritabanına erişim kesiliyor.