Kurumsal Seviye PostgreSQL HA: 5 Sunucu ile Patroni, etcd, HAProxy ve Keepalived Kurulum Rehberi

YUNUS EMRE ATAY

PostgresCluster

Bu rehberde, sektör standartlarında, gerçek anlamda “Yüksek Erişilebilir” (High Availability – HA) bir PostgreSQL kümesini sıfırdan nasıl kuracağımızı adım adım inceleyeceğiz. Geleneksel 2 sunuculu yapıların taşıdığı riskleri (split-brain, tekil hata noktaları) ortadan kaldırıp, 5 sunuculu katmanlı bir mimari inşa edeceğiz.


Bölüm 1: Mimariyi Tanıma ve Mantığını Kavrama

Kuruluma geçmeden önce ezbere komut yazmamak için kullanacağımız araçların ne işe yaradığını ve bu 5 sunucuyu neden bu şekilde konumlandırdığımızı anlamak çok önemlidir.

Neden Sadece PostgreSQL Kullanmıyoruz?

PostgreSQL kendi başına harika bir veritabanı motorudur ve verileri sunucular arasında kopyalama (replikasyon) yeteneğine sahiptir. Ancak, ana sunucu (Master) çöktüğünde yedek sunucuyu (Replica) otomatik olarak ana sunucu yapma yeteneği yoktur. Bu işlemi manuel yapmanız gerekir ki bu da ciddi bir kesinti süresi demektir. İşte burada dev devreye giriyor: Patroni.

Takım Arkadaşlarını Tanıyalım

  • Patroni: PostgreSQL’in zeki yöneticisidir. Her sunucuda çalışır, veritabanının sağlığını sürekli kontrol eder. Eğer Lider (Master) sunucu çökerse, Patroni saniyeler içinde diğer sunucularla anlaşıp yeni bir Lider seçer ve sistemi ayağa kaldırır.
  • etcd: Patroni’nin “karar defteri” ve “ortak aklı”dır (DCS – Distributed Configuration Store). Liderin kim olduğu, konfigürasyon ayarları ve cluster’ın genel durumu burada tutulur. Kararların oy çokluğuyla (Quorum) alınmasını sağlayarak “Çift Başlılık” (Split-Brain) sorununu engeller.
  • HAProxy: Yük dengeleyicimizdir (Load Balancer). Uygulamalarımız hangi sunucunun Lider olduğunu bilmek zorunda değildir. Tüm trafik HAProxy’ye gelir ve HAProxy “Yazma” isteklerini Lider’e, “Okuma” isteklerini (istenirse) yedeklere (Replica) yönlendirir.
  • Keepalived: Sanal IP (VIP – Virtual IP) yöneticisidir. Eğer tek bir HAProxy kullanırsak, o sunucu çöktüğünde sistem yine durur. Keepalived sayesinde 2 adet HAProxy sunucumuz olur ve aktif olan çökerse, Sanal IP anında saniyeler içinde diğer HAProxy sunucusuna geçer.

Neden 5 Sunuculu Katmanlı (Tiered) Mimari?

Tasarımımızda servisleri iki ayrı katmana böldük:

1. Giriş Katmanı (Sunucu 1 ve Sunucu 2):

Sadece trafiği karşılamak ve yönlendirmekle görevlidirler. Üzerlerinde veri tutulmaz. Keepalived ve HAProxy bu sunuculardadır. Böylece veritabanı sunucularının CPU/RAM kullanımındaki ani artışlar, ağ yönlendirmesini yavaşlatmaz.

2. Veri ve Karar Katmanı (Sunucu 3, Sunucu 4 ve Sunucu 5):

Sadece PostgreSQL, Patroni ve etcd barındırırlar. 3 sunucu olmasının sebebi etcd’nin sağlıklı bir “oylama” yapabilmesi için tek sayıya (3, 5, 7) ihtiyaç duymasıdır. Biri çökse bile kalan 2 sunucu “Çoğunluk bizde” diyerek sistemi kesintisiz çalıştırmaya devam eder.

Özet Veri Akışı:

Uygulama ➡ Sanal IP (Keepalived) ➡ Aktif HAProxy ➡ Patroni API (Lider Kim?) ➡ Aktif PostgreSQL Lideri.


Bölüm 2: Sunucuların Hazırlanması (Ön Hazırlık)

Yüksek erişilebilirliğe sahip bir veritabanı kümesi kurarken, sistemin üzerine inşa edileceği temel ne kadar sağlamsa, yönetim o kadar kolay olur. Bu bölümde, PostgreSQL, Patroni ve etcd bileşenlerinin birbiriyle kesintisiz konuşabilmesi için gerekli olan sunucu hazırlıklarını gerçekleştireceğiz.

1. Sunucu Envanteri ve Network Planı

Karmaşıklığı önlemek adına, kurulum boyunca kullanacağımız IP adreslerini ve sunucu rollerini aşağıdaki tabloda belirledik. Bu tabloyu projenizin ana dökümanı olarak kabul edebilirsiniz:

Sunucu AdıRolüIP AdresiÇalışacak Servisler
haproxy1Load Balancer 1150.150.150.161HAProxy, Keepalived
haproxy2Load Balancer 2150.150.150.162HAProxy, Keepalived
postgres1DB Node 1150.150.150.151Postgres, Patroni, etcd
postgres2DB Node 2150.150.150.152Postgres, Patroni, etcd
postgres3DB Node 3150.150.150.153Postgres, Patroni, etcd
VIPSanal IP150.150.150.150Küme Giriş Adresi

Hostname Ayarı: Her sunucuda kendi ismini ayarlamayı unutma:

# Örn: 150.150.150.151 üzerinde
sudo hostnamectl set-hostname pg-01

2. Yerel DNS ve Host Çözümleme

Sunucuların birbirine IP yerine isimle hitap etmesi, ileride yapılacak IP değişikliklerinde büyük kolaylık sağlar. Tüm sunucularda /etc/hosts dosyasını düzenleyerek aşağıdaki satırları ekliyoruz:

## Postgres Cluster Nodes
150.150.150.151  postgres1.cluster   postgres1
150.150.150.152  postgres2.cluster   postgres2
150.150.150.153  postgres3.cluster   postgres3

## HAProxy
150.150.150.161  haproxy1.cluster   haproxy1
150.150.150.162  haproxy2.cluster   haproxy2

## Postgres VIP
150.150.150.150  pg-vip.cluster     pg-vip

3. Gerekli Kurulum Paketleri (RHEL 8.9 Uyumlu)

İnternet erişimi olmayan veya kısıtlı olan ortamlarda, aşağıdaki paketlerin (.rpm ve .tar.gz) önceden indirilip sunucuya taşınması gerekir. İşte bizim setimiz:

  • PostgreSQL 16 Seti:
    • postgresql16-server-16.12-1PGDG.rhel8.10.x86_64.rpm
    • postgresql16-16.12-1PGDG.rhel8.10.x86_64.rpm
    • postgresql16-libs-16.12-1PGDG.rhel8.10.x86_64.rpm
    • postgresql16-contrib-16.12-1PGDG.rhel8.10.x86_64.rpm
  • Python & Bağlantı Kütüphaneleri:
    • python3-libs-3.6.8-73.el8_10.x86_64.rpm
    • python38-psycopg2-2.8.4-4.module+el8.4.0...x86_64.rpm
  • Küme Yönetim Araçları (Gelecek Adımlar İçin):
    • etcd-v3.5.15-linux-amd64.tar.gz (Binary)
    • patroni-v3.3.0 (Wheel veya Source)

4. Adım Adım Paket Kurulumu

RHEL tabanlı sistemlerde bağımlılık (dependency) hatalarını engellemek için paketleri aynı klasöre toplayıp localinstall komutuyla topluca kurmak en güvenli yoldur.

DB Sunucularında (.151, .152, .153) Kurulum:

# Paketlerin olduğu dizine gidin ve kurun
rpm -ivh postgresql16-libs-16.12-1PGDG.rhel8.10.x86_64.rpm \
postgresql16-16.12-1PGDG.rhel8.10.x86_64.rpm \
postgresql16-server-16.12-1PGDG.rhel8.10.x86_64.rpm \
postgresql16-contrib-16.12-1PGDG.rhel8.10.x86_64.rpm

Kritik Uyarı: PostgreSQL paketlerini kurduktan sonra sakın postgresql-setup initdb komutunu çalıştırmayın ve servisi başlatmayın! Veritabanı kümesinin oluşturulması ve başlatılması tamamen Patroni tarafından yönetilecektir. Manuel yapılan bir initdb işlemi, Patroni’nin kurulum sürecini bozabilir.

Önce Python-3.8.19.tar.xz (veya .gz) dosyasını açıp derleme işlemini başlatın:

# Arşivi çıkartın
tar xvf Python-3.8.19.tar.xz
cd Python-3.8.19

# Derleme hazırlığı (Sistemi kirletmemek için /usr/local altına kuruyoruz)
./configure --enable-optimizations --prefix=/usr/local

# Derleme ve kurulum (Altinstall kullanarak sistem python3'ünü ezmiyoruz)
make -j $(nproc)
sudo make altinstall

Python 3.8 artık /usr/local/bin/python3.8 yolunda hazır. Şimdi elindeki psycopg2 ve libs RPM’lerini sisteme dahil et:

# Bağımlılık döngüsünü kırmak için --nodeps ile kurulum
rpm -ivh python38-psycopg2-2.8.4-*.rpm --nodeps
rpm -ivh python38-libs-*.rpm --nodeps

Python 3.8’in PostgreSQL kütüphanesini (psycopg2) başarıyla görüp görmediğini şu komutla test edin:

/usr/local/bin/python3.8 -c "import psycopg2; print('Psycopg2 Bağlantısı Başarılı')"


Bölüm 3: etcd Cluster Kurulumu (Karar Mekanizması)

PostgreSQL HA mimarisinde etcd, “Distributed Configuration Store” (DCS) görevini görür. Kümenin konfigürasyonunu tutar ve hangi sunucunun Lider (Leader), hangilerinin Yedek (Replica) olduğunu belirleyen oylama mekanizmasını yönetir.

Bu kurulumu 3 veritabanı sunucumuzda (pg-01, pg-02, pg-03) gerçekleştireceğiz.

1. etcd Binary Dosyalarının Yerleştirilmesi

İnternetsiz ortamda olduğumuz için indirdiğin etcd-v3.5.15-linux-amd64.tar.gz (veya elindeki sürüm) dosyasını kullanacağız.

# Arşivi açın
tar xvf etcd-v3.5.15-linux-amd64.tar.gz

# Binary dosyalarını sistem yoluna kopyalayın
sudo cp etcd-v3.5.15-linux-amd64/etcd* /usr/local/bin/

# Kontrol edin
etcd --version

2. etcd Kullanıcısı ve Veri Dizini Oluşturma

Güvenlik gereği etcd’nin root dışında kendi kullanıcısıyla çalışması gerekir:

sudo groupadd --system etcd
sudo useradd -s /sbin/nologin --system -g etcd etcd

# Veri dizini oluşturma ve yetkilendirme
sudo mkdir -p /var/lib/etcd/
sudo chown -R etcd:etcd /var/lib/etcd/

3. etcd Yapılandırması (Kritik Ayarlar)

Şimdi her sunucu için özel bir konfigürasyon dosyası oluşturacağız. Aşağıdaki ayarları her sunucuda kendi IP adresine göre güncellemeyi unutma.

sudo vi /etc/etcd.conf (veya istediğin bir dizin) dosyasını oluştur ve içeriğini şuna göre düzenle (Örnek: pg-01 – 150.150.150.151 için):

# [Member]
ETCD_NAME="pg-01"
ETCD_DATA_DIR="/var/lib/etcd/default"
ETCD_LISTEN_PEER_URLS="http://150.150.150.151:2380"
ETCD_LISTEN_CLIENT_URLS="http://150.150.150.151:2379,http://127.0.0.1:2379"

# [Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://150.150.150.151:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://150.150.150.151:2379"
ETCD_INITIAL_CLUSTER="pg-01=http://150.150.150.151:2380,pg-02=http://150.150.150.152:2380,pg-03=http://150.150.150.153:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-pg"
ETCD_INITIAL_CLUSTER_STATE="new"

Önemli: pg-02 ve pg-03 sunucularında ETCD_NAME kısmını ilgili isimle değiştirin ve 150.150.150.151 yazan yerleri o sunucunun kendi IP’si ile güncelleyin. ETCD_INITIAL_CLUSTER satırı tüm sunucularda aynı kalmalıdır.

4. Systemd Servis Dosyası Oluşturma

etcd’nin arka planda sürekli çalışması için bir servis dosyası oluşturuyoruz: sudo nano /etc/systemd/system/etcd.service

[Unit]
Description=etcd service
After=network.target

[Service]
Type=notify
User=etcd
EnvironmentFile=/etc/etcd.conf
ExecStart=/usr/local/bin/etcd
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

5. Servisi Başlatma ve Sağlık Kontrolü

Tüm sunucularda yapılandırmayı bitirdikten sonra servisleri başlatın:

sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd

Cluster Durumunu Kontrol Etme: Herhangi bir sunucuda şu komutu çalıştırarak 3 sunucunun birbirini görüp görmediğini kontrol edin:

etcdctl endpoint health --cluster --endpoints=150.150.150.151:2379,150.150.150.152:2379,150.150.150.153:2379


Bölüm 4: Patroni Kurulumu ve PostgreSQL HA Yapılandırması

PostgreSQL kümemizin “beyni” olan etcd hazır olduğuna göre, artık bu yapıyı yönetecek olan orkestra şefi Patroni‘yi sahneye alıyoruz. Patroni, veritabanı düğümlerinin durumunu izler, replikasyonu yönetir ve bir arıza durumunda otomatik olarak yeni lideri seçer.

1. Patroni ve Gerekli Kütüphanelerin Kurulumu

Tüm veritabanı sunucularında (postgres01, postgres02, postgres03) Python tabanlı Patroni bileşenlerini kurarak işe başlıyoruz:

# PostgreSQL kütüphaneleri ve Python 3.8'i birlikte kurun
rpm -ivh postgresql16-libs-*.rpm \
python38-3.8.*.rpm \
python38-libs-3.8.*.rpm \
python38-psycopg2-2.8.4-*.rpm --nodeps

# Patroni ana paketinin kurulumu
rpm -ivh patroni-*.rpm

%s için bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Hey!

Merhaba! Ben EMRE, teknoloji, yazılım veri tabanı ve veri analitiği alanlarına tutkuluyum. Bu blogda, öğrendiklerimi ve tecrübelerimi paylaşarak faydalı içerikler sunmayı hedefliyorum. Boş zamanlarımda yeni teknolojiler keşfetmeyi, yazmayı ve kendimi geliştirmeyi seviyorum.

ıletısım adreslerım