Bacula ile Çoklu İstemci Yedekleme Yönetimi

Birden fazla sunucuyu yönetiyorsanız ve her birinin yedeklenmesi gerekiyorsa, Bacula’nın çoklu istemci mimarisi tam size göre. Tek bir Director üzerinden onlarca, hatta yüzlerce istemciyi merkezi olarak yönetmek mümkün. Bu yazıda gerçek dünya senaryolarıyla birlikte çoklu istemci yedekleme yönetimini ele alacağız.

Mimariyi Anlamak

Bacula’da çoklu istemci yönetimi şu bileşenler üzerine kuruludur:

  • Bacula Director: Merkezi yönetim birimi, tüm işleri koordine eder
  • File Daemon (fd): Her istemci üzerinde çalışan ajan
  • Storage Daemon (sd): Yedeklerin depolandığı birim
  • Catalog: PostgreSQL veya MySQL tabanlı meta veri veritabanı

Tipik bir kurumsal ortamda Director tek bir sunucuda çalışırken, her Linux veya Windows makinesine File Daemon kurulur. Storage Daemon ise genellikle ayrı bir depolama sunucusunda ya da Director ile aynı makinede barındırılır.

İlk İstemci Ekleme Adımları

Yeni bir istemci eklemeden önce o makinede bacula-fd paketinin kurulu ve çalışır durumda olması gerekiyor.

# Debian/Ubuntu tabanlı sistemlerde
apt-get install bacula-fd

# RHEL/CentOS tabanlı sistemlerde
yum install bacula-client

# Servisi başlatın ve otomatik başlayacak şekilde ayarlayın
systemctl enable bacula-fd
systemctl start bacula-fd

File Daemon yapılandırma dosyası genellikle /etc/bacula/bacula-fd.conf konumundadır. Bu dosyada Director’ın istemciye bağlanırken kullanacağı parolayı ve dinleme ayarlarını belirliyorsunuz.

# /etc/bacula/bacula-fd.conf - İstemci tarafı yapılandırma
Director {
  Name = bacula-dir
  Password = "GizliParola123!"
}

FileDaemon {
  Name = webserver01-fd
  FDport = 9102
  WorkingDirectory = /var/lib/bacula
  Pid Directory = /run/bacula
  Maximum Concurrent Jobs = 20
}

Messages {
  Name = Standard
  director = bacula-dir = all, !skipped, !restored
}

Director Tarafında İstemci Tanımlama

Director yapılandırma dosyasına (/etc/bacula/bacula-dir.conf) istemciyi eklemeniz gerekiyor. Büyük ortamlarda bu dosyayı ayrı include dosyalarına bölmek iyi bir pratiktir.

# /etc/bacula/clients/webserver01.conf
Client {
  Name = webserver01-fd
  Address = 192.168.10.51
  FDPort = 9102
  Catalog = MyCatalog
  Password = "GizliParola123!"
  File Retention = 60 days
  Job Retention = 6 months
  AutoPrune = yes
}

Director ana yapılandırmasına bu dosyayı dahil etmek için:

# /etc/bacula/bacula-dir.conf içine ekleyin
@/etc/bacula/clients/webserver01.conf
@/etc/bacula/clients/dbserver01.conf
@/etc/bacula/clients/fileserver01.conf

Bu yaklaşım sayesinde her istemci için ayrı bir dosya tutabilir, değişiklik yapmanız gerektiğinde ana yapılandırmayı karıştırmazsınız.

Gerçek Dünya Senaryosu: 10 Sunuculu Bir Ortam

Diyelim ki şirketinizde şu yapı var:

  • 3 web sunucusu (webserver01, webserver02, webserver03)
  • 2 veritabanı sunucusu (dbserver01, dbserver02)
  • 1 dosya sunucusu (fileserver01)
  • 1 uygulama sunucusu (appserver01)
  • 2 test sunucusu (testserver01, testserver02)
  • 1 monitoring sunucusu (monserver01)

Her grup için farklı yedekleme politikaları uygulamak mantıklı. Web sunucuları için günlük tam yedek gerekmeyebilir ama veritabanı sunucuları için saatlik artımlı yedek kritik olabilir.

FileSet Tanımlamaları

Her sunucu grubu için uygun FileSet tanımları oluşturun:

# Web sunucuları için FileSet
FileSet {
  Name = "WebServer-FileSet"
  Include {
    Options {
      signature = MD5
      compression = GZIP
    }
    File = /var/www
    File = /etc/nginx
    File = /etc/apache2
    File = /etc/ssl/certs
  }
  Exclude {
    File = /var/www/cache
    File = /var/www/tmp
    File = /var/www/logs
  }
}

# Veritabanı sunucuları için FileSet
FileSet {
  Name = "DBServer-FileSet"
  Include {
    Options {
      signature = MD5
      compression = GZIP
    }
    File = /etc/mysql
    File = /etc/postgresql
    File = /var/lib/mysql/backups
    File = /var/backups/postgresql
  }
  Exclude {
    File = /var/lib/mysql
    File = /var/lib/postgresql
  }
}

Veritabanı dosyalarını doğrudan yedeklemek yerine önce dump almak ve o dump’ı yedeklemek en güvenli yaklaşım. Canlı veritabanı dosyalarını kopyalamak tutarsız veriye yol açabilir.

Schedule Tanımlamaları

# Kritik sunucular için yoğun yedekleme takvimi
Schedule {
  Name = "CriticalServers"
  Run = Full 1st sun at 01:00
  Run = Differential 2nd-5th sun at 01:00
  Run = Incremental mon-sat at 02:00
}

# Test sunucuları için hafif takvim
Schedule {
  Name = "TestServers"
  Run = Full fri at 23:00
  Run = Incremental mon-thu at 23:00
}

Job Tanımlamaları

Her sunucu veya sunucu grubu için Job tanımı oluşturun:

# Web sunucusu job tanımı - template yaklaşımı
JobDefs {
  Name = "WebServerJobDef"
  Type = Backup
  Level = Incremental
  FileSet = "WebServer-FileSet"
  Schedule = "CriticalServers"
  Storage = File1
  Messages = Standard
  Pool = WebPool
  Priority = 10
  Write Bootstrap = "/var/lib/bacula/%c.bsr"
}

# Her web sunucusu için ayrı job
Job {
  Name = "Backup-webserver01"
  JobDefs = "WebServerJobDef"
  Client = webserver01-fd
}

Job {
  Name = "Backup-webserver02"
  JobDefs = "WebServerJobDef"
  Client = webserver02-fd
}

JobDefs kullanmak büyük ortamlarda hayat kurtarır. Ortak ayarları bir kez tanımlayıp her job’da sadece farklı olan kısmı belirtirsiniz.

Pool Yönetimi

Farklı istemci grupları için ayrı pool’lar oluşturmak, yedek rotasyonunu ve saklama sürelerini yönetmeyi kolaylaştırır.

Pool {
  Name = WebPool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 50G
  Maximum Volumes = 100
  Label Format = "Web-"
}

Pool {
  Name = DBPool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 90 days
  Maximum Volume Bytes = 100G
  Maximum Volumes = 200
  Label Format = "DB-"
}

Pool {
  Name = TestPool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 7 days
  Maximum Volume Bytes = 20G
  Maximum Volumes = 30
  Label Format = "Test-"
}

Bconsole ile Toplu Yönetim

Birden fazla istemciyle çalışırken bconsole komut satırı aracınız olacak.

# Tüm istemcilerin durumunu kontrol etmek
bconsole << EOF
status client=webserver01-fd
status client=webserver02-fd
status client=dbserver01-fd
quit
EOF

Daha pratik bir yaklaşım olarak durum kontrolünü otomatize eden bir script yazabilirsiniz:

#!/bin/bash
# /usr/local/bin/bacula-check-all-clients.sh

CLIENTS=(
  "webserver01-fd"
  "webserver02-fd"
  "dbserver01-fd"
  "dbserver02-fd"
  "fileserver01-fd"
)

LOG_FILE="/var/log/bacula/client-status-$(date +%Y%m%d).log"

echo "=== Bacula İstemci Durum Raporu - $(date) ===" > "$LOG_FILE"

for client in "${CLIENTS[@]}"; do
  echo "" >> "$LOG_FILE"
  echo "--- $client ---" >> "$LOG_FILE"
  
  result=$(bconsole << EOF 2>/dev/null
status client=$client
quit
EOF
)
  
  if echo "$result" | grep -q "Daemon started"; then
    echo "[OK] $client - Çalışıyor" >> "$LOG_FILE"
  else
    echo "[HATA] $client - Bağlantı Problemi!" >> "$LOG_FILE"
    # E-posta bildirimi gönder
    echo "$client istemcisi yanıt vermiyor!" | mail -s "Bacula Alarm: $client" [email protected]
  fi
done

echo "" >> "$LOG_FILE"
echo "Rapor tamamlandı: $(date)" >> "$LOG_FILE"

cat "$LOG_FILE"

Bu scripti crontab’a ekleyerek her sabah çalıştırabilirsiniz:

# Crontab girişi
0 7 * * * /usr/local/bin/bacula-check-all-clients.sh

Veritabanı Sunucuları için Özel Yaklaşım

Veritabanı yedeklerinde en kritik nokta tutarlılık. MySQL/MariaDB için dump script’i:

#!/bin/bash
# /usr/local/bin/mysql-backup-prepare.sh
# Bu script bacula job'undan önce çalıştırılır

BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
MYSQL_USER="backup_user"
MYSQL_PASS="BackupParolasi"

mkdir -p "$BACKUP_DIR"

# Tüm veritabanlarını dışa aktar
mysqldump 
  --user="$MYSQL_USER" 
  --password="$MYSQL_PASS" 
  --all-databases 
  --single-transaction 
  --flush-logs 
  --master-data=2 
  --compress 
  | gzip > "$BACKUP_DIR/full_backup_$DATE.sql.gz"

# Eski yedekleri temizle (7 günden eski)
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete

echo "MySQL yedeği tamamlandı: $BACKUP_DIR/full_backup_$DATE.sql.gz"

Bacula job’unda bu script’i RunBeforeJob direktifi ile çalıştırabilirsiniz:

Job {
  Name = "Backup-dbserver01"
  JobDefs = "DBServerJobDef"
  Client = dbserver01-fd
  RunBeforeJob = "/usr/local/bin/mysql-backup-prepare.sh"
  RunAfterJob = "/usr/local/bin/cleanup-old-dumps.sh"
}

Bandwidth ve Kaynak Yönetimi

Çok sayıda istemci aynı anda yedeklendiğinde ağ trafiği sorun yaratabilir. Bacula’nın bant genişliği sınırlama özelliğini kullanın:

Client {
  Name = webserver01-fd
  Address = 192.168.10.51
  FDPort = 9102
  Catalog = MyCatalog
  Password = "GizliParola123!"
  # Maksimum 50 MB/s bant genişliği
  Maximum Bandwidth Per Job = 50 mb/s
  File Retention = 60 days
  Job Retention = 6 months
  AutoPrune = yes
}

Ayrıca job’lara öncelik atayarak kritik sistemlerin önce yedeklenmesini sağlayabilirsiniz:

Job {
  Name = "Backup-dbserver01"
  # ...
  Priority = 5  # Düşük sayı = Yüksek öncelik
}

Job {
  Name = "Backup-testserver01"
  # ...
  Priority = 20  # Daha az kritik
}

Maximum Concurrent Jobs parametresiyle aynı anda çalışabilecek iş sayısını da sınırlayabilirsiniz. Director, Storage ve Client seviyelerinde bu parametreyi ayarlayın.

Restore Testi Otomasyonu

Yedek almak yeterli değil, düzenli olarak geri yükleme testleri yapmalısınız. Bconsole ile otomatik restore testi:

#!/bin/bash
# /usr/local/bin/bacula-restore-test.sh

TEST_CLIENT="testserver01-fd"
RESTORE_DIR="/tmp/bacula-restore-test"
DATE=$(date +%Y%m%d)
REPORT="/var/log/bacula/restore-test-$DATE.log"

echo "Restore testi başlıyor: $(date)" > "$REPORT"

# Son başarılı job ID'sini bul
LAST_JOB=$(bconsole << EOF 2>/dev/null
list jobs client=webserver01-fd status=T
quit
EOF
)

echo "Son job bilgisi:" >> "$REPORT"
echo "$LAST_JOB" >> "$REPORT"

# Belirli dosyaların restore testi
bconsole << EOF >> "$REPORT" 2>&1
restore client=webserver01-fd where=$RESTORE_DIR select current all done yes
wait
quit
EOF

# Restore edilen dosyaları kontrol et
if [ -d "$RESTORE_DIR" ]; then
  FILE_COUNT=$(find "$RESTORE_DIR" -type f | wc -l)
  echo "Restore edilen dosya sayısı: $FILE_COUNT" >> "$REPORT"
  
  if [ "$FILE_COUNT" -gt 0 ]; then
    echo "[BASARILI] Restore testi tamamlandı" >> "$REPORT"
  else
    echo "[BASARISIZ] Restore sonrası dosya bulunamadı!" >> "$REPORT"
    echo "Restore testi başarısız!" | mail -s "Bacula Restore Alarm" [email protected]
  fi
  
  # Test dosyalarını temizle
  rm -rf "$RESTORE_DIR"
else
  echo "[BASARISIZ] Restore dizini oluşturulamadı!" >> "$REPORT"
fi

echo "Test tamamlandı: $(date)" >> "$REPORT"

Reporting ve Monitoring

Günlük özet rapor almak için aşağıdaki yapılandırmayı kullanabilirsiniz:

# bacula-dir.conf içinde Messages tanımı
Messages {
  Name = Standard
  mailcommand = "/usr/sbin/bsmtp -h mail.sirket.com -f [email protected] -s "Bacula: %t %e of %c %l" %r"
  operatorcommand = "/usr/sbin/bsmtp -h mail.sirket.com -f [email protected] -s "Bacula: Intervention needed for %j" %r"
  mail = [email protected] = all, !skipped
  operator = [email protected] = mount
  console = all, !skipped, !saved
  append = "/var/log/bacula/bacula.log" = all, !skipped
  catalog = all
}

Hata durumlarını hızlı tespit etmek için basit bir log analiz scripti:

#!/bin/bash
# /usr/local/bin/bacula-daily-report.sh

LOG="/var/log/bacula/bacula.log"
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)

echo "=== Bacula Günlük Rapor: $YESTERDAY ==="
echo ""

echo "Başarılı Joblar:"
grep "$YESTERDAY" "$LOG" | grep "Termination.*OK" | awk '{print "  - " $0}'

echo ""
echo "Hatalı Joblar:"
grep "$YESTERDAY" "$LOG" | grep -E "Error|Failed|Termination.*Error" | awk '{print "  - " $0}'

echo ""
echo "Uyarılar:"
grep "$YESTERDAY" "$LOG" | grep "Warning" | awk '{print "  - " $0}'

echo ""
echo "Toplam yedeklenen veri:"
grep "$YESTERDAY" "$LOG" | grep "SD Bytes Written" | awk '{sum += $NF} END {print "  " sum/1024/1024/1024 " GB"}'

Yaygın Sorunlar ve Çözümleri

Çok istemcili ortamlarda sık karşılaşılan sorunlara ve çözümlerine bakalım:

Bağlantı Zaman Aşımı: İstemci job başlamadan önce timeout alıyorsa FDConnectTimeout parametresini artırın.

Katalog Büyümesi: Yüzlerce istemciyle katalog veritabanı hızla büyür. Düzenli dbcheck ve prune işlemleri yapın.

Eşzamanlı Job Çakışmaları: Aynı storage’a çok fazla job yazılırsa performans düşer. Storage’daki Maximum Concurrent Jobs değerini dikkatli ayarlayın.

İstemci Parolası Uyuşmazlığı: Director ve File Daemon tarafındaki parolalar birebir aynı olmalı. Büyük/küçük harf ve özel karakterlere dikkat edin.

Firewall Kuralları: Director’dan istemcilere 9102 portu, istemcilerden storage’a 9103 portu açık olmalı. Her yeni istemci eklendiğinde firewall kurallarını güncellemeyi unutmayın.

İstemci Gruplandırma ve Etiketleme

Bacula’nın yerel olarak bir “grup” konsepti yoktur, ancak isimlendirme konvansiyonları ve Pool kullanımıyla mantıksal gruplama yapabilirsiniz. Tüm web sunucuları için WebPool, tüm veritabanları için DBPool kullanmak hem yönetimi kolaylaştırır hem de saklama politikalarını doğru uygulamanızı sağlar.

Ayrıca istemci ve job isimlerinde tutarlı bir yapı kullanın. Backup-[sunucu_adi] formatı, bconsole’da iş ararken ve raporlarda büyük kolaylık sağlar.

Sonuç

Bacula ile çoklu istemci yönetimi başlangıçta karmaşık görünebilir ama doğru yapılandırma ve isimlendirme konvansiyonlarıyla son derece ölçeklenebilir bir altyapı kurabilirsiniz. En önemli nokta şu: yapılandırmayı modüler tutun. Her istemciyi ayrı dosyaya, her grubu ayrı pool’a ve job template’e bağlayın.

Restore testlerini ihmal etmeyin. Bazen sysadmin olarak en zor öğrenilen ders budur. Yıllarca mükemmel çalışan bir yedekleme sistemi, restore gerekinceye kadar test edilmezse o anın şokuyla yüz yüze gelebilirsiniz. Ayda en az bir kez, kritik verilerin gerçekten geri yüklenip yüklenmediğini doğrulayın.

Raporlama altyapısını da güçlü tutun. Günlük e-posta özetleri, başarısız job’lar için anlık alarmlar ve haftalık kapasite raporları sayesinde sorunları büyümeden yakalarsınız. Bacula kendi başına güvenilir bir araç, ama onu etkin şekilde izlemek sizin sorumluluğunuz.

Bir yanıt yazın

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