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)
Server | Yüklenecek Uygulamalar | IP |
psql01 | Postgresql, Patroni | 172.16.16.101 |
psql02 | Postgresql, Patroni | 172.16.16.102 |
etcd | etcd | 172.16.16.103 |
haproxy | HAProxy | 172.16.16.104 |
Postgresql kurulumu için bu yazıma göz atabilirsin.
ETCD Kurulumu
Not: Sadece etcd için belirlenen node için bu kurulumu yap.
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.
apt install etcd
etcd kurulumu tamamlandıktan sonra conf dosyasını oluşturalım
vim /etc/default/etcd
ETCD_LISTEN_PEER_URLS="http://172.16.16.103:2380"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://172.16.16.103:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.16.103:2380"
ETCD_INITIAL_CLUSTER="default=http://172.16.16.103:2380,"
ETCD_ADVERTISE_CLIENT_URLS="http://172.16.16.103:2379"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
vim 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
Not: Sadece haproxy için belirlenen node için bu kurulumu yap.
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.
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
Not: Sadece postgresql için belirlenen nodelar için bu kurulumu yap.
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
Not: Postgresql ve Patroni kurulan bütün node’larda bu işlemleri yapın.
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.
su - 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/12/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.
vim /etc/patroni.yml
scope: prodcluster # Cluster ismi
namespace: /db/
name: prodpsql01 # Node ismi
restapi:
listen: 172.16.16.101:8008 # Node IP'si
connect_address: 172.16.16.101:8008 # Node IP'si
etcd:
host: 172.16.16.103: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 172.16.16.101/0 md5 # psql01 IP'si
- host replication replicator 172.16.16.102/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
password: sifre123
superuser:
username: postgres
password: sifre321
parameters:
unix_socket_directories: '.'
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
PSQL02 Node’una bağlanıp işlemlere başlayalım.
vim /etc/patroni.yml
scope: prodcluster # Cluster ismi
namespace: /db/
name: prodpsql01 # Node ismi
restapi:
listen: 172.16.16.102:8008 # Node IP'si
connect_address: 172.16.16.102:8008 # Node IP'si
etcd:
host: 172.16.16.103: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 172.16.16.102/0 md5 # psql01 IP'si
- host replication replicator 172.16.16.101/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
password: sifre123
superuser:
username: postgres
password: sifre321
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.
vim /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 # Patroni servisinin server başladığında çalışması için.
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 Konfigurasyon
HAProxy node’unda gerekli config dosyasını düzenleyeceğiz. Ben configimde database endpoint için 5000 portunu kullandım siz değiştirebilirsiniz.
vim /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 172.16.16.101:5432 maxconn 100 check port 8008
server PSQL02 172.16.16.102: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://haproxy_ıp:7000 url’inden haproxy status sayfasını ziyaret edelim ve clusterı görüntüleyelim.
Resimde göründüğü gibi cluster nodelarımız listeleniyor. Listede PSQL02 node’u down görünmesi Master/Slave yapısı ile alakalıdır hatalı bir durum değildir.
Kurulumu tamamladık artık herşeyi hazır ve çalışır durumda. haproxy_ip:5000 database bağlantı noktası olarak kullanabilirsiniz artık. Birde Patronictl kullanarak clusterımızı inceliyelim.
patronictl -c /etc/patroni.yml list
Çıktı:
+------------+---------------+---------+---------+----+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+ Cluster: prodcluster (7138377709122875960) ----+----+-----------+
| prodpsql01 | 172.16.16.101 | Leader | running | 20 | |
| prodpsql02 | 172.16.16.102 | Replica | running | 20 | 0 |
+------------+---------------+---------+---------+----+-----------+
Bu şekildede clusterı izleyebilirsiniz.
Evet 4 Node’lu Postgresql HA Cluster kurulumunu tamamladık. Kullanıma hazır 🙂