Bacula ile Ceph Object Storage Entegrasyonu: S3 Uyumlu Yedekleme Havuzu Oluşturma

Yedekleme altyapısını modernize etmek isteyenler için Bacula ile Ceph’i birleştirmek gerçekten güçlü bir kombinasyon sunuyor. Bacula’nın kurumsal düzeydeki yedekleme yönetimi yeteneklerini, Ceph’in ölçeklenebilir ve dayanıklı nesne depolama altyapısıyla bir araya getirdiğinizde, hem maliyet hem de performans açısından ciddi kazanımlar elde edebiliyorsunuz. Bu yazıda sıfırdan bir Ceph S3 uyumlu havuz oluşturup Bacula’ya nasıl entegre edeceğinizi adım adım anlatacağım.

Neden Bacula + Ceph Kombinasyonu?

Geleneksel tape veya NFS tabanlı yedekleme çözümleri belirli bir noktadan sonra hem yönetimsel hem de kapasite açısından ciddi darboğazlar yaratıyor. Özellikle birden fazla lokasyon olan ortamlarda NFS mount noktaları güvenilirlik sorunları çıkarıyor, tape kütüphaneleri ise hem pahalı hem de yönetimi zahmetli.

Ceph’in RadosGW bileşeni S3 uyumlu bir API sunduğu için Bacula’nın S3 eklentisiyle doğrudan konuşabiliyor. Bu sayede şunları elde ediyorsunuz:

  • Yatay ölçeklenebilirlik: Storage node ekledikçe kapasite artıyor
  • Çok kopya dayanıklılığı: Ceph’in replikasyon mekanizması verilerinizi koruyor
  • S3 uyumluluğu: Standart API sayesinde vendor lock-in yok
  • Maliyet etkinliği: Commodity donanım üzerinde enterprise storage
  • Coğrafi dağıtım: Farklı lokasyonlar arası veri senkronizasyonu

Ortam Gereksinimleri

Bu yazıda şu ortamı kullanacağım:

  • Ceph cluster: 3 node, her birinde 4 adet OSD (CentOS Stream 9)
  • Bacula Director + Storage Daemon: Ayrı bir sunucu (Ubuntu 22.04)
  • Bacula sürümü: 13.x community edition
  • Ceph sürümü: Reef (18.x)
  • Network: Dedicated storage network 10GbE

Ceph RadosGW Kurulumu ve Yapılandırması

Eğer halihazırda çalışan bir Ceph cluster’ınız varsa sadece RadosGW servisini etkinleştirmeniz yeterli. Yeni kurulum yapıyorsanız cephadm ile ilerleyin.

RadosGW Servisini Etkinleştirme

# Ceph admin node üzerinde
ceph orch apply rgw bacula-backup --realm=backups --zonegroup=default --zone=default --placement="ceph-node01"

# Servis durumunu kontrol et
ceph orch ls --service-type rgw

# RGW endpoint'ini doğrula
curl http://ceph-node01:80/

RadosGW varsayılan olarak 80 portunu kullanıyor ama production ortamında 443 üzerinden TLS ile çalıştırmanızı öneririm. Şimdilik test için 80’de devam ediyoruz.

Bacula için Dedicated User Oluşturma

Güvenlik açısından Bacula’ya özel bir S3 kullanıcısı oluşturmak kritik. Root credentials kullanmak hem güvenlik açığı hem de kaza anında felakete davetiye çıkarmak.

# Ceph admin node üzerinde
radosgw-admin user create 
  --uid="bacula-backup" 
  --display-name="Bacula Backup Service" 
  --email="[email protected]" 
  --max-buckets=50

# Çıktıdan access_key ve secret_key'i kaydedin
# Örnek çıktı:
# "access_key": "BACXYZ123ABC456DEF78",
# "secret_key": "abc123xyz789secretkeyexample"

# Kullanıcıya quota tanımla (opsiyonel ama önerilir)
radosgw-admin quota set 
  --quota-scope=user 
  --uid="bacula-backup" 
  --max-size=10T

radosgw-admin quota enable 
  --quota-scope=user 
  --uid="bacula-backup"

Yedekleme Bucket’larını Oluşturma

Farklı yedekleme tiplerini ayırt etmek için ayrı bucket’lar kullanmak yönetimi kolaylaştırıyor. Ben genellikle full, incremental ve differential için ayrı bucket tutuyorum.

# AWS CLI ile bucket oluşturma (ya da s3cmd kullanabilirsiniz)
export AWS_ACCESS_KEY_ID="BACXYZ123ABC456DEF78"
export AWS_SECRET_ACCESS_KEY="abc123xyz789secretkeyexample"
export AWS_DEFAULT_REGION="us-east-1"

# Ceph endpoint'ini belirt
aws s3 mb s3://bacula-full 
  --endpoint-url http://ceph-node01:80

aws s3 mb s3://bacula-incremental 
  --endpoint-url http://ceph-node01:80

aws s3 mb s3://bacula-differential 
  --endpoint-url http://ceph-node01:80

# Versioning aktif et (önemli! restore senaryolarında hayat kurtarıyor)
aws s3api put-bucket-versioning 
  --bucket bacula-full 
  --versioning-configuration Status=Enabled 
  --endpoint-url http://ceph-node01:80

# Bucket'ları listele ve doğrula
aws s3 ls --endpoint-url http://ceph-node01:80

Bacula S3 Eklentisi Kurulumu

Bacula’nın S3 desteği bacula-sd-cloud-driver paketi üzerinden geliyor. Bu eklenti Bacula Storage Daemon’ına S3 uyumlu herhangi bir depolama alanını kullanma yeteneği kazandırıyor.

# Ubuntu 22.04 üzerinde Bacula enterprise repo ekle
wget https://www.bacula.org/downloads/Bacula-Community-Enterprise-key.gpg
apt-key add Bacula-Community-Enterprise-key.gpg

# Community edition için
apt-get update
apt-get install bacula bacula-sd bacula-director-mysql

# S3 cloud driver'ı kur
apt-get install bacula-sd-cloud-driver

# Kurulumu doğrula
ls -la /usr/lib/bacula/libdroplet*
# veya
bacula-sd -? 2>&1 | grep -i cloud

bacula-sd.conf Yapılandırması

Storage Daemon yapılandırması bu entegrasyonun kalbi. Buradaki parametreleri doğru ayarlamak hem performans hem de güvenilirlik açısından kritik.

# /etc/bacula/bacula-sd.conf dosyasını düzenle

Storage {
  Name = bacula-sd
  SDPort = 9103
  WorkingDirectory = "/var/lib/bacula"
  Pid Directory = "/run/bacula"
  Maximum Concurrent Jobs = 20
  SDAddress = 0.0.0.0
}

# Ceph S3 Cloud Device tanımı
Device {
  Name = CephS3-Full
  Media Type = S3
  Archive Device = bacula-full
  Label Media = yes
  Random Access = yes
  Automatic Mount = yes
  Removable Media = no
  Always Open = no
  
  # S3/Cloud spesifik ayarlar
  Cloud {
    Driver = "S3"
    HostName = "ceph-node01"
    Port = 80
    BucketName = "bacula-full"
    AccessKey = "BACXYZ123ABC456DEF78"
    SecretKey = "abc123xyz789secretkeyexample"
    Protocol = HTTP
    UriStyle = Path
    
    # Upload/Download ayarları
    MaximumConcurrentUploads = 4
    MaximumConcurrentDownloads = 4
    MaximumUploadBandwidth = 500MB/s
    MaximumDownloadBandwidth = 500MB/s
    
    # Truncate Cache: local cache'i ne zaman temizleyeceğini belirler
    TruncateCache = AtEndOfJob
    
    # Upload factor: local staging alanı için çarpan
    UploadFactor = 2.0
  }
}

Device {
  Name = CephS3-Incremental
  Media Type = S3
  Archive Device = bacula-incremental
  Label Media = yes
  Random Access = yes
  Automatic Mount = yes
  Removable Media = no
  Always Open = no
  
  Cloud {
    Driver = "S3"
    HostName = "ceph-node01"
    Port = 80
    BucketName = "bacula-incremental"
    AccessKey = "BACXYZ123ABC456DEF78"
    SecretKey = "abc123xyz789secretkeyexample"
    Protocol = HTTP
    UriStyle = Path
    MaximumConcurrentUploads = 8
    MaximumConcurrentDownloads = 8
    TruncateCache = AtEndOfJob
  }
}

# Director erişim yetkisi
Director {
  Name = bacula-dir
  Password = "BURAYA_GUCLU_BIR_SIFRE_GIRIN"
}

# Local cache dizini - yeterli disk alanı olduğundan emin olun
# En büyük full backup'ın en az 2 katı kadar alan ayırın

Önemli not: UriStyle = Path ayarı Ceph RadosGW için kritik. AWS S3’te Virtual stil çalışır ama Ceph’in endpoint yapısı path-style gerektiriyor. Bu ayarı atlamak en sık yapılan hatalardan biri.

Bacula Director Yapılandırması

Director tarafında yeni storage tanımlarını, pool’ları ve job’ları yapılandırmamız gerekiyor.

# /etc/bacula/bacula-dir.conf içine eklenecek Storage tanımları

Storage {
  Name = CephS3-Full-Storage
  Address = bacula-storage-server
  SDPort = 9103
  Password = "BURAYA_GUCLU_BIR_SIFRE_GIRIN"
  Device = CephS3-Full
  Media Type = S3
  Maximum Concurrent Jobs = 5
}

Storage {
  Name = CephS3-Incremental-Storage
  Address = bacula-storage-server
  SDPort = 9103
  Password = "BURAYA_GUCLU_BIR_SIFRE_GIRIN"
  Device = CephS3-Incremental
  Media Type = S3
  Maximum Concurrent Jobs = 10
}

# Full yedekler için Pool tanımı
Pool {
  Name = CephFull-Pool
  Pool Type = Backup
  Storage = CephS3-Full-Storage
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 60 days
  Maximum Volume Bytes = 100G
  Maximum Volumes = 20
  Label Format = "Full-${Year}-${Month:p/2/0/r}-${Day:p/2/0/r}-"
}

# Incremental yedekler için Pool tanımı
Pool {
  Name = CephIncremental-Pool
  Pool Type = Backup
  Storage = CephS3-Incremental-Storage
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 20G
  Maximum Volumes = 100
  Label Format = "Inc-${Year}-${Month:p/2/0/r}-${Day:p/2/0/r}-"
}

# Production sunucuları için yedekleme job'u
Job {
  Name = "ProductionServers-Full"
  Type = Backup
  Level = Full
  Client = prod-web01-fd
  FileSet = "ProductionFileSet"
  Schedule = "WeeklyCycle"
  Storage = CephS3-Full-Storage
  Pool = CephFull-Pool
  Messages = Standard
  Priority = 10
  Write Bootstrap = "/var/lib/bacula/%c.bsr"
  SpoolData = yes
  SpoolSize = 10G
}

Job {
  Name = "ProductionServers-Incremental"
  Type = Backup
  Level = Incremental
  Client = prod-web01-fd
  FileSet = "ProductionFileSet"
  Schedule = "DailyCycle"
  Storage = CephS3-Incremental-Storage
  Pool = CephIncremental-Pool
  Messages = Standard
  Priority = 10
  Write Bootstrap = "/var/lib/bacula/%c.bsr"
}

Local Cache Yönetimi

Ceph entegrasyonunun önemli bir parçası local cache yönetimi. Bacula önce veriyi local disk’e yazar, sonra S3’e upload eder. Bu yüzden staging alanı olarak yeterli disk alanına ihtiyacınız var.

# Cache dizini oluştur ve izinleri ayarla
mkdir -p /opt/bacula/cache/full
mkdir -p /opt/bacula/cache/incremental
chown -R bacula:bacula /opt/bacula/cache
chmod 750 /opt/bacula/cache

# Cache kullanımını izlemek için script
cat > /usr/local/bin/bacula-cache-monitor.sh << 'EOF'
#!/bin/bash
CACHE_DIR="/opt/bacula/cache"
THRESHOLD=80

USAGE=$(df -h "$CACHE_DIR" | awk 'NR==2 {gsub(/%/,""); print $5}')

if [ "$USAGE" -gt "$THRESHOLD" ]; then
    echo "UYARI: Bacula cache dizini %${USAGE} dolu!" | 
    mail -s "Bacula Cache Uyarisi" [email protected]
    
    # Tamamlanan job'ların cache'ini temizle
    find "$CACHE_DIR" -name "*.cache" -mtime +1 -delete
fi

echo "Cache kullanimi: %${USAGE}"
df -h "$CACHE_DIR"
EOF

chmod +x /usr/local/bin/bacula-cache-monitor.sh

# Crontab'a ekle
echo "*/30 * * * * /usr/local/bin/bacula-cache-monitor.sh" | crontab -

Cache dizini için önerim: En büyük full backup boyutunuzun en az 2.5 katı kadar alan ayırın. Eğer production veritabanlarını yedekliyorsanız ve en büyük backup 200GB ise, cache dizini için en az 500GB alan rezerve edin.

Bağlantıyı Test Etme ve Sorun Giderme

Her şeyi yapılandırdıktan sonra sistemi production’a almadan önce kapsamlı testler yapmanız şart.

# Storage daemon'ı yeniden başlat
systemctl restart bacula-sd
systemctl status bacula-sd

# Director'ı yeniden başlat
systemctl restart bacula-dir

# bconsole ile bağlantıyı test et
bconsole << 'EOF'
status storage=CephS3-Full-Storage
quit
EOF

# Manuel label ve test job çalıştır
bconsole << 'EOF'
label storage=CephS3-Full-Storage pool=CephFull-Pool
CephTest001
run job=ProductionServers-Full level=Full yes
wait
status dir
messages
quit
EOF

# Ceph tarafında upload'u doğrula
aws s3 ls s3://bacula-full/ 
  --endpoint-url http://ceph-node01:80 
  --recursive 
  --human-readable

# RadosGW loglarını kontrol et
journalctl -u ceph-radosgw@* -f

Yaygın Sorunlar ve Çözümleri

Production’da karşılaştığım sorunlar ve çözümleri şunlar:

  • “S3 connection refused” hatası: UriStyle = Path ayarını kontrol edin, büyük ihtimalle Virtual olarak bırakılmış
  • Yavaş upload hızı: MaximumConcurrentUploads değerini artırın, network ve Ceph OSD sayısına göre 4-16 arası deneyebilirsiniz
  • Cache dolup taşma: TruncateCache = AfterUpload yerine TruncateCache = AtEndOfJob kullanın, bu daha güvenli
  • SSL sertifika hatası: Test ortamında TrustCertificate = yes ekleyin ama production’da gerçek sertifika kullanın
  • Timeout hataları: Büyük dosyalar için MaximumNetworkBufferSize = 65536 parametresini artırın

Lifecycle Policy ile Otomatik Arşivleme

Ceph’in lifecycle özellikleri sayesinde eski yedekleri otomatik olarak silebilir ya da daha ucuz storage tier’larına taşıyabilirsiniz.

# Lifecycle policy JSON dosyası oluştur
cat > /tmp/bacula-lifecycle.json << 'EOF'
{
  "Rules": [
    {
      "ID": "DeleteOldFullBackups",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "Full-"
      },
      "Expiration": {
        "Days": 90
      }
    },
    {
      "ID": "DeleteOldIncrementalBackups",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "Inc-"
      },
      "Expiration": {
        "Days": 30
      }
    }
  ]
}
EOF

# Policy'yi uygula
aws s3api put-bucket-lifecycle-configuration 
  --bucket bacula-full 
  --lifecycle-configuration file:///tmp/bacula-lifecycle.json 
  --endpoint-url http://ceph-node01:80

aws s3api put-bucket-lifecycle-configuration 
  --bucket bacula-incremental 
  --lifecycle-configuration file:///tmp/bacula-lifecycle.json 
  --endpoint-url http://ceph-node01:80

# Policy'yi doğrula
aws s3api get-bucket-lifecycle-configuration 
  --bucket bacula-full 
  --endpoint-url http://ceph-node01:80

Performans İzleme

Entegrasyonun sağlıklı çalışıp çalışmadığını düzenli olarak izlemek için basit ama etkili bir monitoring scripti hazırladım.

cat > /usr/local/bin/bacula-ceph-health.sh << 'EOF'
#!/bin/bash

echo "=== Bacula-Ceph Saglik Raporu ==="
echo "Tarih: $(date)"
echo ""

# Ceph cluster durumu
echo "--- Ceph Cluster Durumu ---"
ceph health

# Bucket boyutları
echo ""
echo "--- Bucket Boyutlari ---"
for bucket in bacula-full bacula-incremental bacula-differential; do
    SIZE=$(aws s3 ls s3://${bucket}/ 
        --endpoint-url http://ceph-node01:80 
        --recursive 
        --summarize 2>/dev/null | grep "Total Size" | awk '{print $3, $4}')
    echo "${bucket}: ${SIZE}"
done

# Son 24 saatteki Bacula job'ları
echo ""
echo "--- Son 24 Saat Job Ozeti ---"
echo "select JobId, Name, Level, JobStatus, StartTime, JobBytes/1024/1024 as MB from Job where StartTime > NOW() - INTERVAL 1 DAY order by StartTime desc limit 20;" | 
mysql -u bacula -pSIFRENIZ bacula 2>/dev/null

# Storage daemon bağlantısı
echo ""
echo "--- Storage Daemon Durumu ---"
systemctl is-active bacula-sd && echo "Storage Daemon: AKTIF" || echo "Storage Daemon: DURDU"
systemctl is-active bacula-dir && echo "Director: AKTIF" || echo "Director: DURDU"

EOF

chmod +x /usr/local/bin/bacula-ceph-health.sh

# Her sabah 8'de rapor gönder
echo "0 8 * * * /usr/local/bin/bacula-ceph-health.sh | mail -s 'Bacula-Ceph Gunluk Rapor' [email protected]" | crontab -

Felaket Kurtarma Senaryosu: Restore Test

Yedekleme sistemi kurmanın en önemli parçası restore testlerini düzenli yapmak. Pek çok sysadmin bu adımı atlıyor ve gerçek felaket anında surprise yaşıyor.

# Belirli bir tarihten restore
bconsole << 'EOF'
restore
5
prod-web01-fd
2024-01-15 02:00:00
mark /var/www/html
done
yes
EOF

# Restore durumunu izle
bconsole << 'EOF'
status dir
messages
quit
EOF

Restore testlerini ayda en az bir kez yapmanızı ve sonuçları belgelemenizi şiddetle tavsiye ederim. Ben bir Excel tablosunda tutuyorum: test tarihi, restore edilen sistem, süre, başarı/başarısızlık durumu ve notlar.

Güvenlik Hardening

Production ortamına geçmeden önce şu güvenlik adımlarını mutlaka uygulayın:

  • TLS zorunlu hale getirin: RadosGW önüne Nginx reverse proxy koyup Let’s Encrypt sertifikası ile HTTPS zorunlu tutun
  • Firewall kuralları: RadosGW portuna sadece Bacula Storage Daemon IP’sinden erişime izin verin
  • Credential rotasyonu: Bacula S3 access key ve secret key’i 90 günde bir yenileyin
  • Bucket policy: Kullanıcı yetkilerini minimum gereksinim prensibine göre kısıtlayın
  • Audit logging: RadosGW access log’larını merkezi log sistemine gönderin

Sonuç

Bacula ile Ceph Object Storage entegrasyonu başlangıçta karmaşık görünse de bir kez doğru kurduğunuzda son derece güvenilir ve ölçeklenebilir bir yedekleme altyapısı elde ediyorsunuz. Özellikle UriStyle = Path ve cache boyutlandırması gibi kritik noktalara dikkat ettiğinizde prodüksiyon ortamında ciddi sorun yaşamamanız gerekiyor.

Benim deneyimime göre bu kombinasyonun en büyük avantajı ölçeklenebilirlik. Ceph cluster’ına yeni node ekledikçe yedekleme kapasitesi ve performansı otomatik olarak artıyor. Tape’den bu sisteme geçtiğimizde hem yönetim yükümüz azaldı hem de restore sürelerimiz dramatik biçimde kısaldı.

Son olarak şunu vurgulayayım: Yedekleme sistemi ne kadar iyi kurulmuş olursa olsun, düzenli restore testi yapılmayan bir yedekleme sistemi güvenilir değildir. Monitoring scriptlerini aktif tutun, haftalık sağlık raporlarını okuyun ve aylık restore testlerini es geçmeyin.

Bir yanıt yazın

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