Merhaba PostgreSQL Yüksek Kullanılabilirlik serisinin önceki bölümlerinde Merkezi Consul Kümesi ve Consul Client kurulumlarından bahsetmiştik. Yazı serisinin bu bölümünde Patroni Cluster Kurulumu ile devam ediyoruz.

Patroni Nedir?

Patroni, PostgreSQL veri tabanı kümesini yönetmek için kullanılan açık kaynaklı yüksek kullanılabilirlik aracıdır. Patroni’nin temel amacı, PostgreSQL kümesinin yüksek kullanılabilirlik sağlaması ve otomatik geçiş süreçlerini yönetmesidir. Bir düğümün arızalandığı durumlarda otomatik olarak devreye girebilir ve veri tabanının kesintisiz çalışmasını sağlayabilir. Ayrıca, otomatik geri yükleme işlemlerini kolaylaştırarak veri bütünlüğünü korur.

Patroni Kurulumu

Patroninin tek başına kurulumu PostgreSQL kümesine yük devretme ve yüksek kullanılabilirlik niteliği kazandırmaya yeterli değildir. Patroni ile birlikte Dağıtık Konfigürasyon Depolama araçlarından birine ihtiyaç vardır. Bu gerekliliği gidermek içim Merkezi Consul Kümesi ve Consul Client kurulumlarını gerçekleştirmiştik. Patroni düğümlerinin kurulumunu Consul Client sunucuları üzerinde gerçekleştireceğiz.

Kuruluma başlamadan önce Consul Düğümlerinin durumlarını görüntüleyelim.

root@patroniSrv-1:~# consul members --token 759618f7-0690-6f62-b201-67160ff4c700
Node          Address              Status  Type    Build   Protocol  DC         Partition  Segment
consulSrv-1   192.168.222.11:8301  alive   server  1.11.4  2         sysdbaops  default    <all>
consulSrv-2   192.168.222.12:8301  alive   server  1.11.4  2         sysdbaops  default    <all>
consulSrv-3   192.168.222.13:8301  alive   server  1.11.4  2         sysdbaops  default    <all>
patroniSrv-1  192.168.222.14:8301  alive   client  1.11.4  2         sysdbaops  default    <default>
patroniSrv-2  192.168.222.15:8301  alive   client  1.11.4  2         sysdbaops  default    <default>
patroniSrv-3  192.168.222.16:8301  alive   client  1.11.4  2         sysdbaops  default    <default>

Patroni Kümesi İçin PostgreSQL Kurulumu

PostgreSQL ve Patroni kurulumları Consul Client sunucuları üzerinde gerçekleştirilecektir. İlk olarak PostgreSQL reposunu çekerek PostgreSQL kurulumunu gerçekleştiriyoruz.

root@patroniSrv-1:~# sudo su -
root@patroniSrv-1:~# echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
root@patroniSrv-1:~# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
root@patroniSrv-1:~# apt update
root@patroniSrv-1:~# apt install postgresql-15
root@patroniSrv-1:~# sudo su -
root@patroniSrv-1:~# echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
root@patroniSrv-1:~# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
root@patroniSrv-1:~# apt update
root@patroniSrv-1:~# apt install postgresql-15
root@patroniSrv-1:~# sudo su -
root@patroniSrv-1:~# echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
root@patroniSrv-1:~# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
root@patroniSrv-1:~# apt update
root@patroniSrv-1:~# apt install postgresql-15

Ubuntu Sunucularda PostgreSQL instance’ı /var/lib/postgresql/15/main dizini altında default olarak oluşturulmaktadır. Cluster’ı Patroni ile oluşturacağımız için ilk olarak üç sunucu üzerinde de instance’ı siliyoruz.

root@patroniSrv-1:~# pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
15  main    5432 down   postgres /var/lib/postgresql/15/main /var/log/postgresql/postgresql-15-main.log
root@patroniSrv-1:~# pg_dropcluster 15 main --stop
root@patroniSrv-1:~# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
root@patroniSrv-2:~# pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
15  main    5432 down   postgres /var/lib/postgresql/15/main /var/log/postgresql/postgresql-15-main.log
root@patroniSrv-2:~# pg_dropcluster 15 main --stop
root@patroniSrv-2:~# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
root@patroniSrv-3:~# pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
15  main    5432 down   postgres /var/lib/postgresql/15/main /var/log/postgresql/postgresql-15-main.log
root@patroniSrv-3:~# pg_dropcluster 15 main --stop
root@patroniSrv-3:~# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file

PostgreSQL instance kurulumunu gerçekleştireceğimiz dizini oluşturarak gerekli yetkilendirmeleri yapıyoruz.

root@patroniSrv-1:~ mkdir -p /var/lib/pgdata/15/main
root@patroniSrv-1:~ chown -R postgres:postgres /var/lib/pgdata
root@patroniSrv-1:~ chmod 700 -R /var/lib/pgdata
root@patroniSrv-2:~ mkdir -p /var/lib/pgdata/15/main
root@patroniSrv-2:~ chown -R postgres:postgres /var/lib/pgdata
root@patroniSrv-2:~ chmod 700 -R /var/lib/pgdata
root@patroniSrv-3:~ mkdir -p /var/lib/pgdata/15/main
root@patroniSrv-3:~ chown -R postgres:postgres /var/lib/pgdata
root@patroniSrv-3:~ chmod 700 -R /var/lib/pgdata

PostgreSQL kurulumları esnasında dikkat edilmesi gereken bir diğer husus ise Türkçe Dil Paketlerinin sunucu üzerinde aktif hale getirilmesidir. Dil paketlerini aktif hale getirelim.

root@patroniSrv-1: localectl list-locales
C.UTF-8
en_US.UTF-8
root@patroniSrv-1: vi /etc/locale.gen
   tr_TR.UTF-8 UTF-8
root@patroniSrv-1: locale-gen-gen
root@patroniSrv-1: localectl list-locales
C.UTF-8
en_US.UTF-8
tr_TR.UTF-8
root@patroniSrv-2: localectl list-locales
C.UTF-8
en_US.UTF-8
root@patroniSrv-2: vi /etc/locale.gen
   tr_TR.UTF-8 UTF-8
root@patroniSrv-2: locale-gen-gen
root@patroniSrv-2: localectl list-locales
C.UTF-8
en_US.UTF-8
tr_TR.UTF-8
root@patroniSrv-3: localectl list-locales
C.UTF-8
en_US.UTF-8
root@patroniSrv-3: vi /etc/locale.gen
   tr_TR.UTF-8 UTF-8
root@patroniSrv-3: locale-gen-gen
root@patroniSrv-3: localectl list-locales
C.UTF-8
en_US.UTF-8
tr_TR.UTF-8

PostgreSQL kurulumunun son adımı olarak postgres kullanıcısı için .bash_profile tanımlaması gerçekleştiriyoruz.

root@patroniSrv-1: vi /var/lib/postgresql/.bash_profile
      export PGDATA=/var/lib/pgdata/15/main
      export PATH=$PATH:/usr/lib/postgresql/15/bin
root@patroniSrv-2: vi /var/lib/postgresql/.bash_profile
      export PGDATA=/var/lib/pgdata/15/main
      export PATH=$PATH:/usr/lib/postgresql/15/bin
root@patroniSrv-3: vi /var/lib/postgresql/.bash_profile
      export PGDATA=/var/lib/pgdata/15/main
      export PATH=$PATH:/usr/lib/postgresql/15/bin

Patroni Kurulumu

İlk olarak Patroni için gerekli Python paketlerinin kurulumunu gerçekleştiriyoruz.

root@patroniSrv-1:~# apt install python3-pip python3-psycopg2
root@patroniSrv-1:~# pip3 install -U pip
root@patroniSrv-1:~# pip3 install patroni[consul]
root@patroniSrv-1:~# patroni --version
patroni 3.0.2
root@patroniSrv-2:~# apt install python3-pip python3-psycopg2
root@patroniSrv-2:~# pip3 install -U pip
root@patroniSrv-2:~# pip3 install patroni[consul]
root@patroniSrv-2:~# patroni --version
patroni 3.0.2
root@patroniSrv-3:~# apt install python3-pip python3-psycopg2
root@patroniSrv-3:~# pip3 install -U pip
root@patroniSrv-3:~# pip3 install patroni[consul]
root@patroniSrv-3:~# patroni --version
patroni 3.0.2

Kuruluma Patroni için gerekli dizin ve dosyaları oluşturarak devam ediyoruz.

root@patroniSrv-1:~# mkdir /etc/patroni
root@patroniSrv-1:~# mkdir /var/log/patroni
root@patroniSrv-1:~# chown -R postgres: /etc/patroni
root@patroniSrv-1:~# chown -R postgres: /var/log/patroni
root@patroniSrv-1:~# vi /etc/profile.d/patroni.sh
     export PATRONICTL_CONFIG_FILE=/etc/patroni/patroni.yml
root@patroniSrv-2:~# mkdir /etc/patroni
root@patroniSrv-2:~# mkdir /var/log/patroni
root@patroniSrv-2:~# chown -R postgres: /etc/patroni
root@patroniSrv-2:~# chown -R postgres: /var/log/patroni
root@patroniSrv-2:~# vi /etc/profile.d/patroni.sh
     export PATRONICTL_CONFIG_FILE=/etc/patroni/patroni.yml
root@patroniSrv-3:~# mkdir /etc/patroni
root@patroniSrv-3:~# mkdir /var/log/patroni
root@patroniSrv-3:~# chown -R postgres: /etc/patroni
root@patroniSrv-3:~# chown -R postgres: /var/log/patroni
root@patroniSrv-3:~# vi /etc/profile.d/patroni.sh
     export PATRONICTL_CONFIG_FILE=/etc/patroni/patroni.yml

Patroni servis dosyasını düzenleyelim.

root@patroniSrv-1:~# vi /etc/systemd/system/patroni.service
[Unit] 
Description=Runners to orchestrate a high-availability PostgreSQL 
After=network.target 
ConditionPathExists=/etc/patroni/patroni.yml 
 
[Service] 
Type=simple 
 
User=postgres 
Group=postgres 
 
Environment="PATRONI_CONFIGURATION_FILE=/etc/patroni/patroni.yml" 
 
EnvironmentFile=-/etc/patroni/env.conf 
 
ExecStart=/usr/local/bin/patroni ${PATRONI_CONFIGURATION_FILE} 
ExecReload=/bin/kill -s HUP $MAINPID 
KillMode=process 
TimeoutSec=30 
Restart=no 
LimitNOFILE=262144 
OOMScoreAdjust=-1000 
 
[Install] 
WantedBy=multi-user.target 
root@patroniSrv-2:~# vi /etc/systemd/system/patroni.service
[Unit] 
Description=Runners to orchestrate a high-availability PostgreSQL 
After=network.target 
ConditionPathExists=/etc/patroni/patroni.yml 
 
[Service] 
Type=simple 
 
User=postgres 
Group=postgres 
 
Environment="PATRONI_CONFIGURATION_FILE=/etc/patroni/patroni.yml" 
 
EnvironmentFile=-/etc/patroni/env.conf 
 
ExecStart=/usr/local/bin/patroni ${PATRONI_CONFIGURATION_FILE} 
ExecReload=/bin/kill -s HUP $MAINPID 
KillMode=process 
TimeoutSec=30 
Restart=no 
LimitNOFILE=262144 
OOMScoreAdjust=-1000 
 
[Install] 
WantedBy=multi-user.target 
root@patroniSrv-3:~# vi /etc/systemd/system/patroni.service
[Unit] 
Description=Runners to orchestrate a high-availability PostgreSQL 
After=network.target 
ConditionPathExists=/etc/patroni/patroni.yml 
 
[Service] 
Type=simple 
 
User=postgres 
Group=postgres 
 
Environment="PATRONI_CONFIGURATION_FILE=/etc/patroni/patroni.yml" 
 
EnvironmentFile=-/etc/patroni/env.conf 
 
ExecStart=/usr/local/bin/patroni ${PATRONI_CONFIGURATION_FILE} 
ExecReload=/bin/kill -s HUP $MAINPID 
KillMode=process 
TimeoutSec=30 
Restart=no 
LimitNOFILE=262144 
OOMScoreAdjust=-1000 
 
[Install] 
WantedBy=multi-user.target 

Patroni ve PostgreSQL konfigürasyonlarının tutulduğu patroni.yml dosyasını düzenleyelim.

root@patroniSrv-1:~# vi /etc/patroni/patroni.yml
namespace: "/postgres/"
scope: "sysdbaops-01"

log:
  level: INFO
  dir: /var/log/patroni

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      remove_data_directory_on_rewind_failure: true
      remove_data_directory_on_diverged_timelines: true
      parameters:
        archive_command: '/bin/true'
        archive_mode: "on"
        password_encryption : 'scram-sha-256'
        shared_preload_libraries: pg_stat_statements
        wal_compression: "on"
        wal_log_hints: "on"
      pg_hba:
        - local all             postgres                            peer
        - host  all             all             127.0.0.1/32        scram-sha-256
        - host  replication     standby         127.0.0.1/32        scram-sha-256
        - host  replication     standby         192.168.222.15/32     scram-sha-256
        - host  replication     standby         192.168.222.14/32     scram-sha-256
        - host  replication     standby         192.168.222.16/32     scram-sha-256
        - host  all             postgres        192.168.222.14/32     scram-sha-256
        - host  all             postgres        192.168.222.15/32     scram-sha-256
        - host  all             postgres        192.168.222.16/32     scram-sha-256
        - host  all             +dba            0.0.0.0/0             scram-sha-256

  initdb:
    - data-checksums

  users:
    standby:
      password: 123
      options:
        - replication
        - login

consul:
  host: 127.0.0.1:8501
  url: https://patroniSrv-1:8501
  verify: false
  cert: "/etc/ssl/certs/ssl-cert-snakeoil.pem"
  key: "/etc/ssl/private/ssl-cert-snakeoil.key"
  token: 759618f7-0690-6f62-b201-67160ff4c700
  dc: sysdbaops
  register_service: true

postgresql:
  authentication:
    superuser:
      username: postgres
      password: 123
    replication:
      username: standby
      password: 123
  connect_address: "192.168.222.14:5432"
  data_dir: /var/lib/pgdata/15/main
  config_dir: /var/lib/pgdata/15/main
  bin_dir: /usr/lib/postgresql/15/bin
  listen: "0.0.0.0:5432"
  use_unix_socket: true
  pgpass: /var/lib/postgresql/.pgpass.patroni

restapi:
  connect_address: 192.168.222.14:8009
  listen: 0.0.0.0:8009

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false
root@patroniSrv-2:~# vi /etc/patroni/patroni.yml

name: "pgdb02"
namespace: "/postgres/"
scope: "sysdbaops-01"

log:
  level: INFO
  dir: /var/log/patroni

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      remove_data_directory_on_rewind_failure: true
      remove_data_directory_on_diverged_timelines: true
      parameters:
        archive_command: '/bin/true'
        archive_mode: "on"
        password_encryption : 'scram-sha-256'
        shared_preload_libraries: pg_stat_statements
        wal_compression: "on"
        wal_log_hints: "on"
      pg_hba:
        - local all             postgres                            peer
        - host  all             all             127.0.0.1/32        scram-sha-256
        - host  replication     standby         127.0.0.1/32        scram-sha-256
        - host  replication     standby         192.168.222.15/32     scram-sha-256
        - host  replication     standby         192.168.222.14/32     scram-sha-256
        - host  replication     standby         192.168.222.16/32     scram-sha-256
        - host  all             postgres        192.168.222.14/32     scram-sha-256
        - host  all             postgres        192.168.222.15/32     scram-sha-256
        - host  all             postgres        192.168.222.16/32     scram-sha-256
        - host  all             +dba            0.0.0.0/0             scram-sha-256

  initdb:
    - data-checksums

  users:
    standby:
      password: 123
      options:
        - replication
        - login

consul:
  host: 127.0.0.1:8501
  url: https://patroniSrv-2:8501
  verify: false
  cert: "/etc/ssl/certs/ssl-cert-snakeoil.pem"
  key: "/etc/ssl/private/ssl-cert-snakeoil.key"
  token: 759618f7-0690-6f62-b201-67160ff4c700
  dc: sysdbaops
  register_service: true

postgresql:
  authentication:
    superuser:
      username: postgres
      password: 123
    replication:
      username: standby
      password: 123
  connect_address: "192.168.222.15:5432"
  data_dir: /var/lib/pgdata/15/main
  config_dir: /var/lib/pgdata/15/main
  bin_dir: /usr/lib/postgresql/15/bin
  listen: "0.0.0.0:5432"
  use_unix_socket: true
  pgpass: /var/lib/postgresql/.pgpass.patroni

restapi:
  connect_address: 192.168.222.15:8009
  listen: 0.0.0.0:8009

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false
root@patroniSrv-3:~# vi /etc/patroni/patroni.yml
name: "pgdb03"
namespace: "/postgres/"
scope: "sysdbaops-01"

log:
  level: INFO
  dir: /var/log/patroni

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      remove_data_directory_on_rewind_failure: true
      remove_data_directory_on_diverged_timelines: true
      parameters:
        archive_command: '/bin/true'
        archive_mode: "on"
        password_encryption : 'scram-sha-256'
        shared_preload_libraries: pg_stat_statements
        wal_compression: "on"
        wal_log_hints: "on"
      pg_hba:
        - local all             postgres                            peer
        - host  all             all             127.0.0.1/32        scram-sha-256
        - host  replication     standby         127.0.0.1/32        scram-sha-256
        - host  replication     standby         192.168.222.15/32     scram-sha-256
        - host  replication     standby         192.168.222.14/32     scram-sha-256
        - host  replication     standby         192.168.222.16/32     scram-sha-256
        - host  all             postgres        192.168.222.14/32     scram-sha-256
        - host  all             postgres        192.168.222.15/32     scram-sha-256
        - host  all             postgres        192.168.222.16/32     scram-sha-256
        - host  all             +dba            0.0.0.0/0             scram-sha-256

  initdb:
    - data-checksums

  users:
    standby:
      password: 123
      options:
        - replication
        - login

consul:
  host: 127.0.0.1:8501
  url: https://patroniSrv-3:8501
  verify: false
  cert: "/etc/ssl/certs/ssl-cert-snakeoil.pem"
  key: "/etc/ssl/private/ssl-cert-snakeoil.key"
  token: 759618f7-0690-6f62-b201-67160ff4c700
  dc: sysdbaops
  register_service: true

postgresql:
  authentication:
    superuser:
      username: postgres
      password: 123
    replication:
      username: standby
      password: 123
  connect_address: "192.168.222.16:5432"
  data_dir: /var/lib/pgdata/15/main
  config_dir: /var/lib/pgdata/15/main
  bin_dir: /usr/lib/postgresql/15/bin
  listen: "0.0.0.0:5432"
  use_unix_socket: true
  pgpass: /var/lib/postgresql/.pgpass.patroni

restapi:
  connect_address: 192.168.222.16:8009
  listen: 0.0.0.0:8009

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

Primary veri tabanı önce olmak üzere patroni servislerini başlatalım.

root@patroniSrv-1:~# systemctl start patroni.service
root@patroniSrv-2:~# systemctl start patroni.service
root@patroniSrv-3:~#systemctl start patroni.service

Son olarak Herhangi bir node üzerinden PostgreSQL Veri tabanlarımızın durumunu görüntüleyelim.

root@patroniSrv-1:~# su - postgres
postgres@patroniSrv-1:~# patronictl list

+ Cluster: sysdbaops-01 --+---------+---------+----+-----------+
| Member | Host           | Role    | State   | TL | Lag in MB |
+--------+----------------+---------+---------+----+-----------+
| pgdb01 | 192.168.222.14 | Leader  | running |  3 |           |
| pgdb02 | 192.168.222.15 | Replica | running |  3 |         0 |
| pgdb03 | 192.168.222.16 | Replica | running |  3 |         0 |
+--------+----------------+---------+---------+----+-----------+

Patroni ile PostgreSQL kümesi kurulumunu tamamlayarak bir yazının daha sonuna gelmiş olduk, yazı serisine ilk olarak KeepAlived ve HaProxy kurulumları ardından ise PgBouncer kurulumu ile devam edeceğiz. Ayrıca Sayfamızı Linkedin üzerinden de takip edebilirsiniz.

Paylaş
Bağlantıyı kopyala