PostgreSQL kümelemede Patroni kullanımı
Tags: postgres, patroni, sql
Published: 2021-03-14 16:54:55

PostgreSQL'i kümelenmiş bir şekilde kullanmak için bir çok yöntem bulunmaktadır. Bunlarla ilgili başka bir yazı da yazabilirim ama bu yazıda tercih ettiğimiz bir yöntemi anlatmak istedim.

Bahsedeceğim PostgreSQL kümeleme yönteminde, kümede bulunacak her bir postgresql düğüm(node)'ünde patroni servisini de kuracağız. Bu yapıyı HAProxy ile yüksek erişilebilir yük dengelemesi sağlayacağız. Ayrıca dağıtık yapılandırma için ayrı bir küme oluşturup onu da kendi içerisinde HAProxy ile yüksek erişilebilir yük dengelemesini sağlayacağız. Ama bu yazıda şimdilik o kısmı tek düğüm üzerinde bahsedeceğiz.

Bugünkü senaryomuzda Pardus 19.x sunucu yani Debian 10 ile paralel bir kurulum yapacağız. Ubuntu üzerinde de çok benzer bir çalışma yapmak yeterli olacaktır.

# PostgreSQL kurulumu

Pardus 19 ve Debian 10 sistemlerde kurulum için aşağıdaki gibi deponun ve depo anahtarının eklenmesi sağlanmalıdır.

```bash
sudo apt update
sudo apt -y install gnupg2 curl
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
sudo apt -y install postgresql-13
```

Bu komutlardan sonra debian sisteminize Postgresql 13 sisteminizde kurulmuş olacaktır.

# Patroni kurulumu

İnternette genellikle python pip deposundan Patroni kurulumunu gördüm fakat bu yöntem Patroni'nin güncel sürümünü kullanmanıza fakat bazı geliştirici paketlerini de yüklemesinden dolayı PostgreSQL deposunda bulunan patroni kurulumunu daha sağlıklı bulmaktayım. Bu nedenle o şekilde bir kurulum yapacağım.

```bash
sudo apt -y install patroni
```

Patroni, PostgreSQL'in bazı ikili dosyalarına erişmesi gerektiği için daha standart bir yere bağlamak (linklemek) için aşağıdaki komut yazılması gerekmektedir.

```bash
ln -s /usr/lib/postgresql/13/bin/* /usr/sbin/
```

# Patroni'nin ayarlanması

Patroni paketini kurduktan sonra en önemli nokta ayarlarının yapılmasıdır. Yapılandırma dosyasını incelediğinizde 3 IP adresi göreceksiniz
- **10.20.30.1**: kendi üzerindeki postgresql düğümü
- **10.20.30.2**: diğer postgresql düğümü (istenilirse artırılacak)
- **10.20.30.3**: etcd sunucusu (istenirse çoğaltılacak)

Ayrıca yapılandırma dosyasında 2 postgreSQL hesabı görülmektedir. Bu hesapların belirtilen parolalarda oluşturulmuş olması gerekmektedir.
- replicator:Parola01.!
- postgres:Parola01.!

Bu yüzden ilk olarak kullanıcılar ve parolalarını düzenleyebiliriz:

```bash
sudo -u postgres psql
```

Bu komut ile postgresql kabuğuna geçtikten sonra aşağıdaki gibi kullanıcı ve parolalar oluşturulabilinir:

```sql
ALTER USER postgres PASSWORD 'Parola01.!';
CREATE USER replicator WITH ENCRYPTED PASSWORD 'Parola01.!';
\q
```

Bu adımdan sonra yapılandırma dosyası düzenlenebilir. "10.20.30.1" sunucusundaki değişiklikler yapıldıktan sonra 10.20.30.2 sunucusunda da bu kısımda çapraz değişiklik yapılarak aynısı yapılmalıdır. Bunun için **/etc/patroni.yml** dosyası oluşturup aşağıdaki gibi hazırlamak gerekmektedir.

```
scope: postgreskume
namespace: /db/
name: patroni01

restapi:
    listen: 10.20.30.1:8008
    connect_address: 10.20.30.1:8008

etcd:
    host: 10.20.30.3:2379

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 10.20.30.1/0 md5
    - host replication replicator 10.20.30.2/0 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 10.20.30.1:5432
    connect_address: 10.20.30.1:5432
    data_dir: /data/patroni
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: replicator
            password: Parola01.!
        superuser:
            username: postgres
            password: Parola01.!
    parameters:
        unix_socket_directories: '.'

tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

```

Bu dosya oluşturulduktan sonra aşağıdaki komutlarla veri dizini oluşturulmuş olması gerekmektedir.

```bash
sudo mkdir -p /data/patroni
sudo chown -R postgres:postgres /data/
sudo chmod -R 700 /data/
```

# Patroni'nin servis dosyasının hazırlanması

Patroninin ayarlarının da yapılmasından sonra sürekli çalışabilmesi için servis dosyasının oluşturulması gerekmektedir. Bunun için **/etc/systemd/system/patroni.service** isimli bir dosya oluşturup içeriğini aşağıdaki gibi hazırlamak germektedir. Servis dosyasında herhangi bir değişiklik yapmanız gerekmektedir.

```
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target

[Service]
Type=simple

User=postgres
Group=postgres

ExecStart=/usr/bin/patroni /etc/patroni.yml
KillMode=process
TimeoutSec=30
Restart=no

[Install]
WantedBy=multi-user.targ
```

Dosya oluştuktan sonra her iki servisi de başlatmak gerekmektedir. Tabi ki açılışta otomatik başlaması için enable parametresi de verilebilir.

```bash
systemctl daemon-reload
systemctl stop postgresql
systemctl restart patroni
systemctl status patroni
systemctl enable patroni
```

# Patroni'de kimin master olacağının belirlenmesi için etcd sunucu kurulumu

10.20.30.1 ve 10.20.30.2 gibi belirttiğimiz 2 sunucudan başka 3. bir sunucuda yani örneğin 10.20.30.3 sunucusunda etcd kurabilirsiniz. Tabi ki bu kurulumu da önüne HAProxy kurarak yük dengeleyicisi ile de yapabilirsiniz ama bu dokümanda tek etcd kuracağız.

```bash
sudo apt install etcd
```

Paket kurulumu yapıldıktan sonra kümeleme yapılandırma dosyası, **/etc/default/etcd** dosyası oluşturularak hazırlanır.

```
ETCD_LISTEN_PEER_URLS="http://10.20.30.3:2380"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://10.20.30.3:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.20.30.3:2380"
ETCD_INITIAL_CLUSTER="default=http://10.20.30.3:2380,"
ETCD_ADVERTISE_CLIENT_URLS="http://10.20.30.3:2379"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
```

Yapılandırma ayarlarını tamamladıktan sonra servis yeniden başlatılır. Ve servis kontrol edilir.

```bash
systemctl restart etcd
systemctl status etcd
```

# PostgreSQL'in yüksek erişilebilir yük dengesi için HAProxy ile kullanımı

Biraz önce belirttiğimiz sunuculardan başka ayrı bir sunucuda aşağıdaki gibi haproxy sunucu kurup yapılandırma dosyasında PostgreSQL düğümlerini tek tek eklemek gerekmektedir.

```bash
sudo apt install haproxy
```

Paket kurulumu sonrasında yapılandırma dosyasında IP adresleri düzeltilecek şekilde aşağıdaki gibi eklenebilir. Bu yapılandırma ayarı ile HAProxy'yi kurduğunuz sunucu üzerinden 5000 portu kullanarak aslında arkada kurulan 2 postgreSQL sunucusunun varsayılan 5432 portuna sorgu atacak şekilde kullanabilirsiniz. (/etc/haproxy/haproxy.cfg)

```
global
    maxconn 1000

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 postgresql_10.20.30.1_5432 10.20.30.1:5432 maxconn 100 check port 8008
    server postgresql_10.20.30.2_5432 10.20.30.2:5432 maxconn 100 check port 8008
```

Yapılandırma ayarını yaptıktan sonra servisi yeniden başlatıp servis durumunu kontrol edebilirsiniz.

```bash
systemctl restart haproxy
systemctl status haproxy
```

Bu ayarlardan sonra HAProxy sunucunuzun 7000 portuna web tarayıcınızla bağlandığınızda, hangi sunucunuzun master olduğu bilgisine de ulaşabilirsiniz.


***************************

PostgreSQL ve Patroni'nin kurulduğu sunucular 2'den fazla da kurabilirsiniz ve bu şekilde kümeleme genişletilebilir. 

"_Kutadgu Bilig - 2401 : Eri översen bak eliyle aslan tutar, Atı okşarsan koşar uçan kuşa yetişir_"