Stateful vs. Stateless: PostgreSQL Konteynerlerinde Kalıcı Depolama (Persistent Storage) Rehberi
- 6 gün önce
- 4 dakikada okunur
Konteyner teknolojileri (özellikle Docker ve Kubernetes), yazılım geliştirme ve dağıtım süreçlerini devrimsel bir şekilde değiştirdi. Hafif yapıları, taşınabilirliği ve saniyeler içinde başlatılabilmeleri, onları modern mikroservis mimarilerinin vazgeçilmezi haline getirdi.

Ancak, konteynerlerin en temel özelliklerinden biri olan "ephemeral" (geçici) yapıları, veritabanları gibi veriyi uzun süre saklaması gereken uygulamalar için ciddi bir zorluk teşkil eder. Bu makalede, PostgreSQL konteynerlerinde veri kalıcılığını (persistent storage) sağlamanın neden kritik olduğunu, "stateful" ve "stateless" kavramları arasındaki farkları ve Docker/Kubernetes ortamlarında verilerinizi nasıl güvene alacağınızı inceleyeceğiz.
1. Temel Kavramlar: Stateless ve Stateful Nedir?
PostgreSQL'i konteynerde çalıştırmayı anlamadan önce, uygulama mimarilerindeki bu iki temel ayrımı netleştirmeliyiz.
Stateless (Durumsuz) Mimariler
Bir stateless uygulama, geçmiş etkileşimlere ait hiçbir veriyi (state) kendi içinde saklamaz. Her istek bağımsızdır. Konteyner silinip yeniden başlatıldığında, uygulama sanki ilk kez çalışıyormuş gibi başlar ve bu durum operasyonel bir kayba neden olmaz.
Örnekler: Nginx web sunucusu, stateless REST API'ler, imaj işleme servisleri.
Konteyner Uyumu: Mükemmeldir. Konteynerler istenildiği zaman yok edilebilir ve çoğaltılabilir (scaling).
Stateful (Durum bilgisi saklayan) Mimariler
Stateful uygulamalar, istemci etkileşimlerine veya sistemin çalışmasına ait verileri kalıcı bir depolama alanında saklamak zorundadır. Konteyner silinirse veya çökerse, yeniden başlatıldığında bu verilere tekrar erişebilmesi gerekir. Aksi takdirde veri kaybı yaşanır.
Örnekler: PostgreSQL, MySQL, Redis, Kafka.
Konteyner Uyumu: Zordur. Konteynerin ephemeral yapısı ile uygulamanın kalıcılık ihtiyacı arasında bir köprü kurulmalıdır.
2. PostgreSQL Neden Doğası Gereği Stateful'dur?
Bir ilişkisel veritabanı yönetim sistemi (RDBMS) olarak PostgreSQL'in temel görevi veriyi güvenli bir şekilde saklamak, güncellemek ve sunmaktır. Bu veriler (tablolar, indeksler, prosedürler vb.) fiziksel olarak disk üzerindeki dosyalarda saklanır.
Docker konteynerleri, süreçleri (processes) izole etmek için kendi geçici dosya sistemlerine sahiptir. Bir Docker konteynerini docker run ile başlattığınızda, PostgreSQL verilerini bu geçici katmana yazar.
Büyük Risk: Konteyner Silindiğinde Ne Olur?
Eğer özel bir yapılandırma yapmazsanız, veritabanınız konteyner içinde çalışır. Ancak konteyner çökerse veya siz docker rm komutuyla konteyner sistemini silerseniz, içindeki tüm veritabanı dosyaları da sonsuza dek silinir. Bu durum üretim ortamları (production) için kabul edilemez bir felakettir.
Bu nedenle, PostgreSQL'i konteyner ortamında kullanırken Kalıcı Depolama (Persistent Storage) kullanmak zorunludur.
3. Docker Ortamında PostgreSQL Kalıcılığı Nasıl Sağlanır?
Docker, verileri konteynerin yaşam döngüsünden ayırmak için birkaç depolama seçeneği sunar. PostgreSQL için en yaygın kullanılanlar Named Volumes ve Bind Mounts'tur.
PostgreSQL Veri Dizini
PostgreSQL, tüm verilerini varsayılan olarak konteyner içinde /var/lib/postgresql/data dizininde saklar. Amacımız, host makinemizdeki (sunucumuzdaki) bir klasörü bu dizine "bağlamak" (mount etmek) ve konteyner veriyi yazdığında aslında host makinesine yazmasını sağlamaktır.
Seçenek 1: Docker Named Volumes (Önerilen)
Named Volumes, Docker tarafından yönetilen, host dosya sisteminde spesifik bir konumu olan (genellikle /var/lib/docker/volumes/ altında) ancak Docker CLI ile yönetilebilen depolama alanlarıdır.
Avantajları: Portable (taşınabilir), Docker CLI ile yönetimi kolay (backup, restore), performanslı.
PostgreSQL ile Kullanımı:
Bash
# named volume oluşturalım
docker volume create my_pg_data
# Konteyneri named volume ile başlatalım (-v parametresi)
docker run -d \
--name postgres-container \
-e POSTGRES_PASSWORD=mysecretpassword \
-v my_pg_data:/var/lib/postgresql/data \
postgres:16
Konteyner silinse bile my_pg_data volume'u silinmez. Yeni bir konteyner başlatıp aynı volume'u bağladığınızda verileriniz geri gelir.
Seçenek 2: Bind Mounts
Host makinenizdeki mevcut, spesifik bir klasörü (örneğin ./data/postgres) konteyner içindeki veri dizinine bağlar.
Avantajları: Host makinesindeki dosyalara doğrudan erişim (geliştirme ortamları için kullanışlı), mevcut klasör yapılarını kullanma.
PostgreSQL ile Kullanımı:
# Host makinesinde klasör oluşturalım
mkdir -p /home/user/project/pgdata
# Konteyneri bind mount ile başlatalım
docker run -d \
--name postgres-container \
-e POSTGRES_PASSWORD=mysecretpassword \
-v /home/user/project/pgdata:/var/lib/postgresql/data \
postgres:16
Host makinenizdeki /home/user/project/pgdata klasörüne gittiğinizde, PostgreSQL'in oluşturduğu tüm klasör ve dosyaları görebilirsiniz.
Karşılaştırma Tablosu
Özellik | Named Volumes | Bind Mounts | tmpfs (Memory) |
Yönetim | Docker tarafından yönetilir | Kullanıcı tarafından yönetilir | Host belleğinde saklanır |
Kalıcılık | Evet | Evet | Hayır (Restartta silinir) |
Taşınabilirlik | Yüksek | Düşük (Host path'e bağımlı) | Yok |
Hız | Yüksek | Yüksek | Çok Yüksek |
Kullanım Alanı | Üretim (Production) | Geliştirme (Development) | Geçici cache, performans testleri |
4. Kubernetes ve Daha Karmaşık Ortamlar
Docker Compose ile Named Volumes kullanmak, tek sunuculu yapılar için yeterlidir. Ancak Kubernetes gibi orkestrasyon araçlarında, konteynerler (Pod'lar) farklı sunuculara (Node'lara) taşınabilir.
Kubernetes'te PostgreSQL gibi stateful uygulamaları yönetmek için daha gelişmiş konseptler gerekir:
1. PersistentVolumes (PV) ve PersistentVolumeClaims (PVC)
Kubernetes dosya sisteminden bağımsız, ağ tabanlı depolama alanları (AWS EBS, Google Persistent Disk, NFS vb.) PV olarak tanımlanır. PostgreSQL Pod'u, PVC kullanarak bu depolama alanından yer talep eder. Pod başka bir Node'a taşınsa bile, ağ üzerindeki PV'ye tekrar bağlanarak verisine erişebilir.
2. StatefulSets
Kubernetes'te stateless uygulamalar Deployments ile yönetilirken, PostgreSQL gibi veritabanları StatefulSets ile yönetilir. StatefulSets, Pod'lara kalıcı ve benzersiz kimlikler (hostname-0, hostname-1 gibi) verir ve ordered (sıralı) dağıtım sağlar. Bu, veritabanı replikasyonu ve PVC eşleştirmesi için kritiktir.
3. Kubernetes Operators
StatefulSets bile PostgreSQL'in yedeklenmesi, failover (arıza anında yedek veritabanına geçme), update gibi DBA (Veritabanı Yöneticisi) görevlerini otomatikleştirmez. Bu karmaşık işlemleri otomatikleştirmek için Crunchy PostgreSQL Operator veya Zalando Postgres Operator gibi Kubernetes Operator'leri kullanılır.
5. Özet ve en iyi pratikler
PostgreSQL'i konteynerde çalıştırmak, kurulum ve ölçeklendirme kolaylığı sağlar, ancak veri kalıcılığı doğru yapılandırılmazsa felaketle sonuçlanabilir.
Temel DBA Kuralları:
Üretim Ortamında Asla Volume'süz Çalışmayın: PostgreSQL verilerini asla konteynerin geçici (writable) katmanına yazmayın.
Önerilen Seçenek Named Volumes: Docker'da veri kalıcılığı için öncelikli olarak Named Volumes kullanın.
Performans: Üretim ortamlarında kullanılan Named Volume'ların veya PV'lerin arkasındaki fiziksel disklerin (SSD/NVMe) yüksek I/O performansına sahip olduğundan emin olun. Ağ tabanlı depolamalarda gecikme süresine (latency) dikkat edin.
Yedekleme Stratejisi: Volume kullanmak veriyi kalıcı kılar ama veri bozulmasına veya yanlışlıkla silinmesine karşı korumaz. Volume'larınızın periyodik olarak yedeğini alın (pg_dump veya volume snapshot).
Karmaşık Yapılarda Orkestrasyon: Kubernetes ortamında veritabanı yönetimi için Deployments yerine StatefulSets ve tercihen Operator'leri kullanın.
