Rsync ile Bulut Depolama Entegrasyonu: rclone Köprüsüyle Hibrit Yedekleme
Yedekleme stratejileri söz konusu olduğunda çoğu sysadmin ya tamamen yerel çözümlere ya da tamamen buluta gömülü servislere yönelir. Oysa en sağlam yaklaşım, ikisini birden kullanan hibrit modeldir. Rsync’in yerel ağdaki ham hızını ve delta aktarım zekasını, rclone’un bulut depolama evrenselliğiyle birleştirdiğinizde ortaya gerçekten güçlü ve esnek bir yedekleme altyapısı çıkıyor. Bu yazıda bu iki aracı nasıl köprüleyeceğimizi, gerçek dünya senaryolarıyla adım adım ele alacağız.
Hibrit Yedekleme Neden Mantıklı?
Klasik 3-2-1 yedekleme kuralını hatırlayalım: 3 kopya, 2 farklı medya, 1 uzak lokasyon. Rsync bu denklemin ilk iki ayağını mükemmel biçimde karşılar; yerel diskler ve NAS cihazları arasında hızlı, verimli senkronizasyon yapar. Ama “1 uzak lokasyon” kısmı için bulut depolamaya ihtiyaç duyarsınız.
İşte tam burada rclone devreye giriyor. rclone, 40’tan fazla bulut depolama sağlayıcısını (S3, Google Cloud Storage, Backblaze B2, Azure Blob Storage, Wasabi ve daha fazlası) tek bir arayüzden yönetmenizi sağlayan bir araç. Rsync’i rclone ile birleştirdiğinizde şu iş akışını kurabilirsiniz:
- Yerel sunucu üzerinde rsync ile artımlı yedekler alırsınız
- Yerel yedek deposu rclone üzerinden buluta senkronize edilir
- Bulut tarafında versiyon geçmişi ve şifreleme devreye girer
- Tüm süreç cron ile tamamen otomatik hale gelir
Bu yaklaşımın en büyük avantajı bağımsızlık. Bulut sağlayıcınızı değiştirmeniz gerektiğinde rclone konfigürasyonunu güncellemeniz yeterli; yedekleme scriptlerinize dokunmanıza gerek yok.
rclone Kurulumu ve İlk Konfigürasyon
rclone kurulumu son derece basit. Resmi kurulum scriptini kullanmak en pratik yol:
curl https://rclone.org/install.sh | sudo bash
Ya da paket yöneticisiyle kurabilirsiniz:
# Debian/Ubuntu
sudo apt install rclone
# RHEL/CentOS/Rocky Linux
sudo dnf install rclone
# Versiyon kontrolü
rclone version
Kurulumun ardından bir bulut depolama sağlayıcısı yapılandırmanız gerekiyor. Wasabi S3 uyumlu olduğu için bütçe dostu bir seçenek olarak sık kullanılıyor. Konfigürasyon için interaktif modu açalım:
rclone config
Bu komut sizi adım adım yönlendirir. Ama büyük ortamlarda elle konfigürasyon dosyası oluşturmak daha pratik. ~/.config/rclone/rclone.conf dosyasını şu şekilde yapılandırabilirsiniz:
cat > ~/.config/rclone/rclone.conf << 'EOF'
[wasabi-backup]
type = s3
provider = Wasabi
access_key_id = BURAYA_ACCESS_KEY
secret_access_key = BURAYA_SECRET_KEY
region = eu-central-1
endpoint = s3.eu-central-1.wasabisys.com
acl = private
[gdrive-backup]
type = drive
client_id = BURAYA_CLIENT_ID
client_secret = BURAYA_CLIENT_SECRET
scope = drive
root_folder_id =
token = {"access_token":"..."}
EOF
Konfigürasyonu doğrulamak için basit bir bağlantı testi yapın:
# Bucket listesini çek
rclone lsd wasabi-backup:
# Test dosyası yükle
echo "rclone connection test" | rclone rcat wasabi-backup:yedek-bucket/test.txt
# Dosyayı doğrula
rclone ls wasabi-backup:yedek-bucket/
Rsync ile Yerel Yedekleme Katmanı
Hibrit modelin ilk katmanı, rsync ile yerel yedek deposu oluşturmak. Buradaki strateji, yerel ağdaki hızı kullanarak ham verileri önce yakın bir hedefe çekmek, ardından rclone ile buluta taşımak.
Tipik bir senaryo: Web sunucularınızın /var/www, /etc ve veritabanı dump dizinlerini NAS’a rsync ile yedekliyorsunuz.
#!/bin/bash
# /usr/local/bin/local-backup.sh
# Değişkenler
SOURCE_DIRS=("/var/www" "/etc" "/home" "/var/backups/db-dumps")
DEST_BASE="/mnt/nas/backups"
HOSTNAME=$(hostname -s)
DATE=$(date +%Y-%m-%d)
LOG_FILE="/var/log/rsync-backup.log"
RETENTION_DAYS=30
# Log fonksiyonu
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Yerel yedekleme başlıyor: $HOSTNAME ==="
for SOURCE in "${SOURCE_DIRS[@]}"; do
DIR_NAME=$(basename "$SOURCE")
DEST="$DEST_BASE/$HOSTNAME/$DATE/$DIR_NAME"
# Hardlink tabanlı artımlı yedek için önceki günün yedek dizini
LINK_DEST="$DEST_BASE/$HOSTNAME/latest/$DIR_NAME"
mkdir -p "$DEST"
log "Yedekleniyor: $SOURCE -> $DEST"
rsync -avz
--delete
--link-dest="$LINK_DEST"
--exclude="*.tmp"
--exclude="*.log"
--exclude=".cache"
--exclude="node_modules"
--stats
"$SOURCE/"
"$DEST/" >> "$LOG_FILE" 2>&1
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
log "Başarılı: $SOURCE (çıkış kodu: $EXIT_CODE)"
# Latest symlink güncelle
ln -sfn "$DEST_BASE/$HOSTNAME/$DATE/$DIR_NAME" "$LINK_DEST"
else
log "HATA: $SOURCE yedeklemesi başarısız (çıkış kodu: $EXIT_CODE)"
fi
done
# Eski yedekleri temizle
log "30 günden eski yedekler siliniyor..."
find "$DEST_BASE/$HOSTNAME" -maxdepth 1 -type d
-name "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"
-mtime +$RETENTION_DAYS
-exec rm -rf {} ; 2>/dev/null
log "=== Yerel yedekleme tamamlandı ==="
Bu scriptte --link-dest parametresi kritik öneme sahip. Hardlink tabanlı artımlı yedekleme sayesinde, her gün tam yedek alıyormuş görünümü verirken disk kullanımı sadece değişen dosyalar kadar artıyor.
rclone ile Bulut Senkronizasyonu
Yerel yedekler hazır olduktan sonra ikinci katman devreye giriyor. rclone, rsync’in anlayışına çok benzer bir senkronizasyon mantığıyla çalışır; bu yüzden geçiş sancısız olur.
#!/bin/bash
# /usr/local/bin/cloud-sync.sh
LOCAL_BACKUP_BASE="/mnt/nas/backups"
REMOTE_NAME="wasabi-backup"
BUCKET="sirket-yedekleri"
HOSTNAME=$(hostname -s)
LOG_FILE="/var/log/rclone-sync.log"
BANDWIDTH_LIMIT="50M" # Upload bant genişliği limiti
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Bulut senkronizasyonu başlıyor ==="
# Sadece son 7 günün yedeklerini buluta gönder
# (Daha eskileri zaten orada, silinmesin)
SYNC_SOURCE="$LOCAL_BACKUP_BASE/$HOSTNAME"
SYNC_DEST="$REMOTE_NAME:$BUCKET/$HOSTNAME"
rclone sync
"$SYNC_SOURCE"
"$SYNC_DEST"
--bwlimit "$BANDWIDTH_LIMIT"
--transfers 4
--checkers 8
--retries 3
--retries-sleep 10s
--stats 60s
--stats-log-level NOTICE
--log-file "$LOG_FILE"
--log-level INFO
--exclude "*.tmp"
--min-age 0
--max-age 7d
--s3-chunk-size 64M
--s3-upload-concurrency 4
RCLONE_EXIT=$?
if [ $RCLONE_EXIT -eq 0 ]; then
log "Bulut senkronizasyonu başarılı"
else
log "HATA: Bulut senkronizasyonu başarısız (çıkış kodu: $RCLONE_EXIT)"
# Alarm gönder
echo "Bulut senkronizasyonu başarısız: $HOSTNAME" |
mail -s "[KRITIK] Yedekleme Hatası" [email protected]
fi
log "=== Bulut senkronizasyonu tamamlandı ==="
Burada dikkat etmeniz gereken birkaç önemli rclone parametresi var:
- –bwlimit: Bant genişliği limitini belirler, iş saatlerinde sunucu yükünü azaltır
- –transfers: Paralel dosya aktarım sayısı, ağ durumuna göre ayarlanmalı
- –checkers: Checksum doğrulama için kullanılan paralel işçi sayısı
- –retries: Başarısız aktarımlarda tekrar deneme sayısı
- –max-age: Sadece belirli yaştan genç dosyaları senkronize et
- –s3-chunk-size: Büyük dosyalar için multipart yükleme parça boyutu
rclone Mount ile Rsync Doğrudan Buluta Yazma
Daha gelişmiş bir senaryo: rclone mount kullanarak bulut depolamayı yerel bir dizin olarak bağlayıp, rsync’i doğrudan bu dizine yazmak. Bu yaklaşım özellikle NAS’ınız yoksa işe yarar.
Önce gerekli bağımlılığı kurun:
# FUSE kurulumu gerekli
sudo apt install fuse3 # Debian/Ubuntu
sudo dnf install fuse3 # RHEL tabanlı
# Mount noktası oluştur
sudo mkdir -p /mnt/cloud-backup
sudo chown $USER:$USER /mnt/cloud-backup
Ardından rclone mount’u bir systemd servisi olarak yapılandırın:
# /etc/systemd/system/rclone-mount.service
sudo tee /etc/systemd/system/rclone-mount.service << 'EOF'
[Unit]
Description=rclone mount - Wasabi Backup
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/rclone mount
wasabi-backup:sirket-yedekleri
/mnt/cloud-backup
--vfs-cache-mode writes
--vfs-cache-max-size 10G
--vfs-cache-max-age 24h
--buffer-size 256M
--dir-cache-time 72h
--poll-interval 15s
--allow-other
--uid 1000
--gid 1000
ExecStop=/bin/fusermount -u /mnt/cloud-backup
Restart=on-failure
RestartSec=30
User=backup-user
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable rclone-mount
sudo systemctl start rclone-mount
Mount noktası hazır olduğunda rsync’i doğrudan buraya yönlendirebilirsiniz:
# Mount üzerinden doğrudan buluta rsync
rsync -avz
--progress
--stats
/var/www/html/
/mnt/cloud-backup/web-sunucu/$(date +%Y-%m-%d)/html/
Ancak bu yaklaşımın bir dezavantajı var: Büyük dosya sayılarında VFS cache dolabilir. Üretim ortamında mount yerine rclone sync komutunu tercih etmenizi öneririm.
Şifreli Bulut Yedekleme: rclone Crypt
Buluta gönderdiğiniz verileri şifrelemeden göndermek büyük bir güvenlik açığı. rclone’un yerleşik crypt remote özelliği bu sorunu zarif biçimde çözer. Şifreleme istemci tarafında gerçekleşir; bulut sağlayıcınız şifrelenmiş veriyi görür.
# Şifreli remote oluştur
rclone config
# "n" ile yeni remote
# remote adı: wasabi-encrypted
# type: crypt
# remote: wasabi-backup:sirket-yedekleri-encrypted
# filename_encryption: standard
# directory_name_encryption: true
# password: güçlü bir parola belirle
Ya da doğrudan konfigürasyon dosyasına ekleyin:
cat >> ~/.config/rclone/rclone.conf << 'EOF'
[wasabi-encrypted]
type = crypt
remote = wasabi-backup:sirket-yedekleri-encrypted
filename_encryption = standard
directory_name_encryption = true
password = RCLONE_OBSCURE_ILE_SIFRELE
password2 = IKINCI_PAROLA_SALT
EOF
Parolayı güvenli biçimde rclone formatına çevirmek için:
rclone obscure "guclu-parolaniz-buraya"
# Çıktıyı rclone.conf dosyasına yapıştırın
Artık şifreli remote’u tıpkı normal remote gibi kullanabilirsiniz:
# Şifreli yedekleme
rclone sync /mnt/nas/backups wasabi-encrypted:
--transfers 4
--log-level INFO
# Şifreli içeriği listele (rclone otomatik deşifreler)
rclone ls wasabi-encrypted:
# Ham şifreli içeriği gör (Wasabi tarafında böyle görünür)
rclone ls wasabi-backup:sirket-yedekleri-encrypted
Tam Entegrasyon: Master Yedekleme Scripti
Şimdiye kadar anlattığımız tüm parçaları tek bir orkestrasyon scriptinde birleştirelim:
#!/bin/bash
# /usr/local/bin/hibrit-yedekleme.sh
# Cron: 0 2 * * * /usr/local/bin/hibrit-yedekleme.sh
set -euo pipefail
# ============== KONFIGÜRASYON ==============
HOSTNAME=$(hostname -s)
DATE=$(date +%Y-%m-%d)
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
LOCAL_SOURCES=("/var/www" "/etc" "/opt/apps" "/var/backups")
NAS_BASE="/mnt/nas/backups/$HOSTNAME"
CLOUD_REMOTE="wasabi-encrypted"
CLOUD_BUCKET="$HOSTNAME"
LOG_DIR="/var/log/hibrit-yedekleme"
LOG_FILE="$LOG_DIR/$DATE.log"
ALERT_EMAIL="[email protected]"
LOCAL_RETENTION=14 # Yerel yedek saklama süresi (gün)
CLOUD_RETENTION=90 # Bulut yedek saklama süresi (gün)
BANDWIDTH_LIMIT="100M"
MAX_TRANSFERS=6
RSYNC_EXCLUDES=(
"--exclude=*.tmp"
"--exclude=*.log"
"--exclude=.cache"
"--exclude=__pycache__"
"--exclude=node_modules"
"--exclude=.git"
)
# ============== FONKSİYONLAR ==============
mkdir -p "$LOG_DIR"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$1] $2" | tee -a "$LOG_FILE"; }
info() { log "INFO " "$1"; }
warn() { log "WARN " "$1"; }
error() { log "ERROR" "$1"; }
send_alert() {
local subject="$1"
local body="$2"
echo "$body" | mail -s "[YEDEKLEME] $subject - $HOSTNAME" "$ALERT_EMAIL" 2>/dev/null || true
}
check_disk_space() {
local path="$1"
local min_gb="$2"
local available_gb
available_gb=$(df -BG "$path" | awk 'NR==2 {gsub("G",""); print $4}')
if [ "$available_gb" -lt "$min_gb" ]; then
error "Yetersiz disk alanı: $path ($available_gb GB < $min_gb GB)"
send_alert "Disk Alanı Kritik" "$path üzerinde $available_gb GB kaldı, minimum $min_gb GB gerekli"
return 1
fi
info "Disk alanı yeterli: $path ($available_gb GB)"
return 0
}
# ============== AŞAMA 1: KONTROLLER ==============
info "=== Hibrit yedekleme başlıyor: $HOSTNAME / $DATE ==="
check_disk_space "$NAS_BASE" 50 || exit 1
# NAS bağlı mı kontrol et
if ! mountpoint -q /mnt/nas; then
error "NAS bağlı değil, çıkılıyor"
send_alert "NAS Bağlantı Hatası" "NAS /mnt/nas noktasında bağlı değil"
exit 1
fi
# İnternet bağlantısı kontrolü
if ! rclone lsd "$CLOUD_REMOTE:" --max-depth 0 >/dev/null 2>&1; then
warn "Bulut bağlantısı yok, sadece yerel yedekleme yapılacak"
CLOUD_SYNC=false
else
CLOUD_SYNC=true
fi
# ============== AŞAMA 2: YEREL RSYNC ==============
info "--- Aşama 2: Yerel rsync yedeklemesi ---"
BACKUP_SUCCESS=true
for SOURCE in "${LOCAL_SOURCES[@]}"; do
if [ ! -d "$SOURCE" ]; then
warn "Kaynak dizin mevcut değil, atlanıyor: $SOURCE"
continue
fi
DIR_NAME=$(basename "$SOURCE")
DEST="$NAS_BASE/$DATE/$DIR_NAME"
LINK_DEST="$NAS_BASE/latest/$DIR_NAME"
mkdir -p "$DEST"
RSYNC_OPTS=(-avz --delete --stats "${RSYNC_EXCLUDES[@]}")
if [ -d "$LINK_DEST" ]; then
RSYNC_OPTS+=(--link-dest="$LINK_DEST")
fi
info "Rsync: $SOURCE -> $DEST"
if rsync "${RSYNC_OPTS[@]}" "$SOURCE/" "$DEST/" >> "$LOG_FILE" 2>&1; then
info "Başarılı: $SOURCE"
ln -sfn "$NAS_BASE/$DATE/$DIR_NAME" "$LINK_DEST"
else
error "Başarısız: $SOURCE"
BACKUP_SUCCESS=false
fi
done
# ============== AŞAMA 3: VERİTABANI DUMP ==============
info "--- Aşama 3: Veritabanı dump ---"
if command -v mysqldump >/dev/null 2>&1; then
DB_DUMP_DIR="$NAS_BASE/$DATE/databases"
mkdir -p "$DB_DUMP_DIR"
# Tüm veritabanlarını al
mysql -u backup_user -pPAROLA -e "SHOW DATABASES;" 2>/dev/null |
grep -Ev "^(Database|information_schema|performance_schema|sys)$" |
while read -r DB; do
info "DB dump: $DB"
mysqldump -u backup_user -pPAROLA
--single-transaction
--quick
--routines
--triggers
"$DB" 2>/dev/null |
gzip > "$DB_DUMP_DIR/${DB}_${DATE}.sql.gz"
done
info "Veritabanı dumplari tamamlandı"
fi
# ============== AŞAMA 4: BULUT SENKRONIZASYONU ==============
if [ "$CLOUD_SYNC" = true ]; then
info "--- Aşama 4: Bulut senkronizasyonu ---"
if rclone sync
"$NAS_BASE"
"$CLOUD_REMOTE:$CLOUD_BUCKET"
--bwlimit "$BANDWIDTH_LIMIT"
--transfers "$MAX_TRANSFERS"
--checkers 12
--retries 5
--retries-sleep 15s
--stats 120s
--log-file "$LOG_FILE"
--log-level INFO
--exclude "*/\.git/**"
--exclude "*/node_modules/**"; then
info "Bulut senkronizasyonu başarılı"
else
error "Bulut senkronizasyonu başarısız"
send_alert "Bulut Sync Hatası" "rclone sync komutu başarısız oldu, loglara bakın: $LOG_FILE"
fi
# Bulutta eski yedekleri temizle
info "Bulutta $CLOUD_RETENTION günden eski yedekler temizleniyor..."
rclone delete "$CLOUD_REMOTE:$CLOUD_BUCKET"
--min-age "${CLOUD_RETENTION}d"
--log-file "$LOG_FILE" 2>/dev/null || true
else
warn "Bulut senkronizasyonu atlandı (bağlantı yok)"
fi
# ============== AŞAMA 5: TEMİZLİK ==============
info "--- Aşama 5: Yerel temizlik ---"
find "$NAS_BASE" -maxdepth 1 -type d
-name "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"
-mtime +"$LOCAL_RETENTION"
-exec rm -rf {} ; 2>/dev/null || true
# ============== ÖZET ==============
TOTAL_SIZE=$(du -sh "$NAS_BASE/$DATE" 2>/dev/null | cut -f1)
info "=== Yedekleme tamamlandı ==="
info "Toplam boyut: $TOTAL_SIZE"
info "Log dosyasi: $LOG_FILE"
if [ "$BACKUP_SUCCESS" = false ]; then
send_alert "Kısmi Hata" "Bazı kaynaklar yedeklenemedi, log dosyasını kontrol edin"
exit 1
fi
Cron ve İzleme Entegrasyonu
Scripti çalışmaya hazır hale getirin ve cron ile zamanlayın:
# Scripte çalıştırma izni ver
sudo chmod +x /usr/local/bin/hibrit-yedekleme.sh
# Backup kullanıcısı için crontab düzenle
sudo crontab -e -u backup-user
# Cron ifadesi: Her gece 02:00'de
# 0 2 * * * /usr/local/bin/hibrit-yedekleme.sh
# Yedekleme durumunu izlemek için basit kontrol scripti
cat > /usr/local/bin/backup-kontrol.sh << 'EOF'
#!/bin/bash
HOSTNAME=$(hostname -s)
TODAY=$(date +%Y-%m-%d)
LOG="/var/log/hibrit-yedekleme/$TODAY.log"
if [ ! -f "$LOG" ]; then
echo "KRITIK: Bugün log dosyasi oluşmamış!"
exit 2
fi
if grep -q "ERROR" "$LOG"; then
echo "UYARI: Yedekleme logunda hata bulundu"
grep "ERROR" "$LOG"
exit 1
fi
echo "OK: Yedekleme başarıyla tamamlandı"
rclone ls wasabi-encrypted:$HOSTNAME/$(date +%Y-%m-%d) --max-depth 0 2>/dev/null | head -5
exit 0
EOF
chmod +x /usr/local/bin/backup-kontrol.sh
Geri Yükleme Senaryosu
Yedekleme kadar önemli olan bir diğer konu geri yükleme sürecini test etmek. İşte temel geri yükleme adımları:
# Buluttaki yedek listesini görüntüle
rclone ls wasabi-encrypted:web-sunucu/ --max-depth 2
# Belirli bir tarihin yedeğini local'e indirmek için
rclone copy
wasabi-encrypted:web-sunucu/2024-01-15/html
/tmp/restore-test/html
--progress
--transfers 8
# Tek dosya geri yükleme
rclone copy
"wasabi-encrypted:web-sunucu/2024-01-15/etc/nginx/nginx.conf"
/tmp/restore/etc/nginx/
# İndirilen yedeği rsync ile hedef sisteme uygula
rsync -avz --dry-run
/tmp/restore-test/html/
/var/www/html/
# Dry-run sonuçları doğruysa --dry-run'ı kaldır
Önemli hatırlatma: Geri yükleme testini aylık düzenli yapın. Test etmediğiniz bir yedekleme sistemi, çalıştığını varsaydığınız ama gerçekte çalışmayan bir sistemdir.
Sonuç
Rsync ve rclone’un birlikteliği, kurumsal yedekleme çözümlerinin karmaşıklığı ve maliyeti olmadan gerçek anlamda sağlam bir hibrit yedekleme altyapısı kurmanızı sağlıyor. Yerel rsync katmanı hız ve anında erişim sunarken, rclone köprüsü coğrafi yedeklilik ve uzun süreli arşivleme ihtiyaçlarını karşılıyor.
Bu mimariyle kurumunuz için şunları elde etmiş oluyorsunuz: Yerel ağ hızında artımlı yedekleme, istemci taraflı şifreleme ile güvenli bulut depolama, sağlayıcı bağımsızlığı sayesinde esneklik ve test edilebilir geri yükleme prosedürleri.
Son olarak şunu vurgulamak isterim: En iyi yedekleme sistemi, geri yükleyebileceğiniz sistemdir. Bu yazıdaki scriptleri önce test ortamında deneyin, geri yükleme prosedürünüzü belgelendirin ve düzenli aralıklarla gerçek geri yükleme tatbikatı yapın. Felaket anında “sanırım çalışıyordu” demek istemezsiniz.
