Rsync ile Sunucu Göçü: Canlı Sistem Taşıma Rehberi
Sunucu taşıma işlemi, çoğu sysadmin’in en çok ertelediği görevlerden biridir. “Şimdi bir şeyler bozulursa ne olur?” korkusu, eski donanımda çürümeye bırakılan sistemlerin en büyük nedenidir. Oysa rsync ile yapılan canlı sistem taşıması, bu işi hem güvenli hem de nispeten stressiz hale getirebilir. Bu yazıda gerçek bir üretim sunucusunu yeni makineye nasıl taşıyacağımızı, adım adım ve hiçbir şeyi atlamadan ele alacağız.
Rsync ile Sunucu Göçü Neden Mantıklı?
Klasik yaklaşım şudur: sunucuyu kapat, disk imajını al, yeni makineye yaz, bekle, uyu. Bu yöntem işe yarar ama büyük sistemlerde downtime saatler sürebilir. Rsync tabanlı göç ise farklı çalışır.
Temel mantık şu: Sistemi çalışır durumdayken rsync ile yeni sunucuya kopyalarsın. İlk senkronizasyon tamamlandıktan sonra, production trafiğini kesmeden önce ikinci ve üçüncü senkronizasyonları çalıştırırsın. Değişen dosyalar azaldıkça maintenance window’un da kısalır. Sonunda sadece birkaç dakikalık bir kesinti ile geçişi tamamlarsın.
Bu yöntemin avantajları:
- Minimal downtime: Asıl kesinti süresi dakikalar mertebesine iner
- Geri dönüş imkanı: Bir şeyler ters giderse eski sunucuya hemen dönebilirsin
- Büyük sistemlerde bile uygulanabilir: 2 TB veri olsa bile ilk sync gece çalışırken ilerler
- Doğrulama fırsatı: Yeni sistemin çalışıp çalışmadığını geçişten önce test edebilirsin
Hazırlık: Geçişe Başlamadan Önce
Rsync komutunu çalıştırmadan önce yapman gereken birkaç kritik hazırlık var.
Yeni Sunucunun Hazırlanması
Yeni sunucuda aynı işletim sistemi versiyonunu kullanmanı öneririm. Farklı distro versiyonları arasında geçiş yapıyorsan, servis konfigürasyonlarında beklenmedik sorunlar çıkabilir.
# Yeni sunucuda SSH erişimini test et
ssh root@yeni-sunucu "uname -a && df -h"
# Yeni sunucunun disk kapasitesini kontrol et
ssh root@yeni-sunucu "df -h /"
# Kaynak sunucunun kullandığı disk alanını kontrol et
df -h /
du -sh /* 2>/dev/null | sort -rh | head -20
SSH Key Tabanlı Erişim Kur
Parola ile rsync çalıştırmak hem güvensiz hem de otomasyonu imkansız kılar. Mutlaka key tabanlı erişim kur:
# Kaynak sunucuda SSH key oluştur (eğer yoksa)
ssh-keygen -t ed25519 -C "migration-key" -f ~/.ssh/migration_key
# Public key'i yeni sunucuya kopyala
ssh-copy-id -i ~/.ssh/migration_key.pub root@yeni-sunucu
# Test et
ssh -i ~/.ssh/migration_key root@yeni-sunucu "echo 'Baglanti basarili'"
Hariç Tutulacak Dizinleri Belirle
Her şeyi kopyalamak istemezsin. Bazı dizinler sanal dosya sistemi içerir ve bunları kopyalamak hem hatalara yol açar hem de anlamsızdır:
# Hariç tutulacak dizinler için exclude dosyası oluştur
cat > /root/rsync-exclude.txt << 'EOF'
/proc/*
/sys/*
/dev/*
/run/*
/tmp/*
/mnt/*
/media/*
/lost+found
/var/log/journal/*
EOF
İlk Büyük Senkronizasyon
İlk sync işlemi en uzun süren adımdır. Bu yüzden bunu sistemi kapatmadan, gece saatlerinde çalıştırıyoruz. screen veya tmux içinde başlatmayı unutma, SSH bağlantısı kopsa bile devam etsin.
# tmux oturumu başlat
tmux new-session -s migration
# İlk büyük rsync'i başlat
rsync -aHAXxvz
--exclude-from=/root/rsync-exclude.txt
--progress
--stats
--log-file=/var/log/migration-sync.log
-e "ssh -i ~/.ssh/migration_key -o StrictHostKeyChecking=no"
/ root@yeni-sunucu:/
# tmux'tan çık (oturumu öldürmeden)
# Ctrl+B, ardından D
Kullandığımız parametrelerin ne işe yaradığını açıklayalım:
- -a: Archive modu; sembolik linkler, izinler, zaman damgaları, sahiplik bilgilerini korur
- -H: Hard link’leri korur
- -A: ACL’leri (Access Control List) korur
- -X: Extended attribute’ları korur
- -x: Farklı dosya sistemlerine geçme (bind mount’ları kopyalama)
- -v: Verbose çıktı
- -z: Aktarım sırasında sıkıştırma kullan
- –progress: Her dosya için ilerleme göster
- –stats: Özet istatistikler göster
- –log-file: Log dosyasına yaz
Senkronizasyon İlerlemesini İzleme
İlk sync çalışırken, ilerlemeyi izlemek istersin:
# Log dosyasını canlı takip et
tail -f /var/log/migration-sync.log
# Rsync işleminin ne kadar veri aktardığını izle
watch -n 5 "cat /var/log/migration-sync.log | tail -20"
# Ağ kullanımını izle
iftop -i eth0
# Kaç dosyanın kopyalandığını hızlıca öğren
grep -c "^sent" /var/log/migration-sync.log
İkinci ve Üçüncü Senkronizasyon: Delta Sync
İlk büyük sync tamamlandıktan sonra, aradan geçen sürede değişen dosyaları göndermek için ek senkronizasyonlar çalıştırıyoruz. Her geçişte aktarılan veri miktarı dramatik biçimde düşer.
#!/bin/bash
# /root/incremental-sync.sh
LOGFILE="/var/log/migration-incremental-$(date +%Y%m%d-%H%M%S).log"
NEW_SERVER="yeni-sunucu"
SSH_KEY="/root/.ssh/migration_key"
echo "Incremental sync basliyor: $(date)" | tee -a $LOGFILE
rsync -aHAXxvz
--exclude-from=/root/rsync-exclude.txt
--delete
--delete-excluded
--stats
--log-file=$LOGFILE
-e "ssh -i $SSH_KEY"
/ root@$NEW_SERVER:/
echo "Sync tamamlandi: $(date)" | tee -a $LOGFILE
echo "Aktarilan veri:"
grep "Total transferred" $LOGFILE
--delete parametresi önemli: Kaynak sistemden silinmiş dosyaları hedef sistemden de siler. Bu sayede iki sistem arasındaki farklar zamanla kapanır.
Bu script’i birkaç kez çalıştır ve her çalıştırmada aktarılan veri miktarının nasıl düştüğünü gözlemle. Birinci delta sync 50 GB aktarıyorsa, ikincisi belki 5 GB, üçüncüsü ise yalnızca birkaç yüz MB aktarır.
Yeni Sistemi Test Etme
Asıl geçişi yapmadan önce, yeni sunucunun düzgün çalışıp çalışmadığını test etmek kritik önem taşır.
# Yeni sunucuda temel servislerin durumunu kontrol et
ssh -i ~/.ssh/migration_key root@yeni-sunucu << 'ENDSSH'
echo "=== Servis Durumu ==="
systemctl list-units --state=failed
echo "=== Disk Kullanimi ==="
df -h
echo "=== Ag Arayuzleri ==="
ip addr show
echo "=== Kritik Servisler ==="
for service in nginx apache2 mysql postgresql redis; do
if systemctl list-unit-files | grep -q "$service"; then
echo "$service: $(systemctl is-active $service)"
fi
done
ENDSSH
Eğer web sunucusu çalıştırıyorsan, yeni sunucuya /etc/hosts üzerinden geçici erişim kurarak uygulamanı test edebilirsin:
# Yerel bilgisayarında /etc/hosts'a ekle (test için)
# 192.168.1.200 uygulama.sirketim.com
# Curl ile test et
curl -H "Host: uygulama.sirketim.com" http://192.168.1.200/
# Veritabanı bağlantısını test et
ssh root@yeni-sunucu "mysql -e 'SHOW DATABASES;'"
Bootloader Sorununu Çözmek
Rsync sistem dosyalarını kopyalar ama bootloader’ı kopyalamaz. Yeni sunucuda GRUB’u yeniden yüklemen gerekiyor:
# Yeni sunucuda chroot ortamı kur ve GRUB'u yükle
ssh root@yeni-sunucu << 'ENDSSH'
# Hangi diskin kullanıldığını kontrol et
lsblk
# GRUB'u yükle (disk adına göre değiştir)
grub-install /dev/sda
update-grub
# initramfs'ı yenile
update-initramfs -u -k all
echo "Bootloader guncellendi"
ENDSSH
fstab Güncellemesi
Yeni sunucunun disk UUID’leri farklı olacağından, /etc/fstab dosyasını güncellemelisin:
# Yeni sunucudaki gerçek UUID'leri öğren
ssh root@yeni-sunucu "blkid"
# fstab'ı kontrol et
ssh root@yeni-sunucu "cat /etc/fstab"
# Yeni UUID'leri fstab'a yansıt
# Bu adımı dikkatli yap, hata olursa sistem boot etmez
ssh root@yeni-sunucu "nano /etc/fstab"
Maintenance Window: Asıl Geçiş
Hazırlıklar tamam, testler başarılı, artık gerçek geçişe hazırız. Bu adımları hızlı ama dikkatli uygulamalısın. Hedef, downtime’ı 15 dakikanın altında tutmak.
#!/bin/bash
# /root/final-migration.sh
# Bu script'i maintenance window başında çalıştır
set -e # Hata olursa dur
NEW_SERVER="yeni-sunucu"
SSH_KEY="/root/.ssh/migration_key"
LOGFILE="/var/log/final-migration-$(date +%Y%m%d-%H%M%S).log"
echo "=== FINAL MIGRATION BASLIYOR: $(date) ===" | tee $LOGFILE
# Adım 1: Kritik servisleri durdur
echo "Servisler durduruluyor..." | tee -a $LOGFILE
systemctl stop nginx 2>/dev/null || true
systemctl stop apache2 2>/dev/null || true
systemctl stop mysql 2>/dev/null || true
# Adım 2: Bekleyen yazma işlemlerini tamamlat
sync
echo "Disk sync tamamlandi" | tee -a $LOGFILE
# Adım 3: Son delta sync
echo "Son senkronizasyon basliyor..." | tee -a $LOGFILE
rsync -aHAXxvz
--exclude-from=/root/rsync-exclude.txt
--delete
--delete-excluded
--stats
--log-file=$LOGFILE
-e "ssh -i $SSH_KEY"
/ root@$NEW_SERVER:/
echo "Son senkronizasyon tamamlandi: $(date)" | tee -a $LOGFILE
# Adım 4: Yeni sunucuda servisleri başlat
echo "Yeni sunucuda servisler baslatiliyor..." | tee -a $LOGFILE
ssh -i $SSH_KEY root@$NEW_SERVER << 'ENDSSH'
systemctl daemon-reload
systemctl start mysql 2>/dev/null || true
sleep 3
systemctl start nginx 2>/dev/null || true
systemctl start apache2 2>/dev/null || true
systemctl status nginx mysql --no-pager 2>/dev/null || true
ENDSSH
echo "=== MIGRATION TAMAMLANDI: $(date) ===" | tee -a $LOGFILE
DNS Geçişi ve Rollback Planı
Son sync tamamlandıktan sonra DNS kaydını değiştir. Değişiklikten önce TTL değerini düşürmüş olman gerekiyor (ideal olarak 24 saat önce 300 saniyeye çekmiş olmalısın).
Rollback planın şu olmalı: Eğer yeni sunucuda 30 dakika içinde ciddi bir sorunla karşılaşırsan, DNS’i eski IP’ye geri çevir. Eski sunucudaki servisleri yeniden başlat. Rsync tabanlı göçün güzelliği burada, eski sunucu hala ayakta ve veri kaybı minimal.
# Rollback senaryosu - eski sunucuda çalıştır
# DNS geri çevrildi, eski sunucuda servisleri başlatıyoruz
systemctl start nginx
systemctl start mysql
# Servislerin durumunu kontrol et
systemctl status nginx mysql
# Log'lara bak
journalctl -u nginx --since "1 hour ago"
Büyük Veritabanı Olan Sistemler İçin Ek Önlemler
Eğer MySQL ya da PostgreSQL gibi büyük bir veritabanı çalıştırıyorsan, dosyaları rsync ile kopyalamak bazen tutarsız bir durum yaratabilir. Bu durumlar için iki farklı yaklaşım var.
Yaklaşım 1 – Veritabanını Ayrı Yedekle:
# MySQL dump al ve yeni sunucuya aktar
mysqldump --all-databases --single-transaction --flush-logs
--master-data=2 > /tmp/full-backup.sql
# Yeni sunucuya gönder
rsync -avz --progress
-e "ssh -i ~/.ssh/migration_key"
/tmp/full-backup.sql root@yeni-sunucu:/tmp/
# Yeni sunucuda restore et
ssh root@yeni-sunucu "mysql < /tmp/full-backup.sql"
Yaklaşım 2 – MySQL’i Durdurarak Kopyala:
# Veritabanını durdur, veritabanı dizinini rsync et, başlat
systemctl stop mysql
rsync -aHXxvz
-e "ssh -i ~/.ssh/migration_key"
/var/lib/mysql/ root@yeni-sunucu:/var/lib/mysql/
systemctl start mysql
Sık Karşılaşılan Sorunlar ve Çözümleri
Sorun: rsync SELinux context hatası veriyor
# SELinux context'lerini sıfırla (yeni sunucuda)
ssh root@yeni-sunucu "restorecon -Rv /"
Sorun: Bazı dosyalar “Operation not permitted” hatası veriyor
# Hangi dosyaların kopyalanamadığını logla
rsync -aHAXxvz
--exclude-from=/root/rsync-exclude.txt
--log-file=/var/log/rsync-errors.log
-e "ssh -i ~/.ssh/migration_key"
/ root@yeni-sunucu:/ 2>&1 | grep "failed|error|permission"
Sorun: Ağ bant genişliği aşımını önlemek
# Bant genişliğini sınırla (örneğin 50 MB/s)
rsync -aHAXxvz
--bwlimit=51200
--exclude-from=/root/rsync-exclude.txt
-e "ssh -i ~/.ssh/migration_key"
/ root@yeni-sunucu:/
Geçiş Sonrası Doğrulama
Geçiş tamamlandı, ama işin bitmedi. Sistematik bir doğrulama yapman şart:
#!/bin/bash
# post-migration-check.sh - Yeni sunucuda çalıştır
echo "=== POST-MIGRATION KONTROLLER ==="
# Servis durumları
echo "--- Servis Durumu ---"
systemctl list-units --state=failed
# Disk doluluk oranı
echo "--- Disk Kullanimi ---"
df -h
# Kritik loglar
echo "--- Son Hatalar ---"
journalctl -p err --since "1 hour ago" --no-pager | tail -30
# Ağ bağlantısı
echo "--- Ag Baglantisi ---"
ss -tlnp | grep LISTEN
# Açık dosya sayısı
echo "--- Sistem Yuklemesi ---"
uptime
free -h
# Veritabanı ping
echo "--- Veritabani ---"
mysqladmin ping 2>/dev/null && echo "MySQL: OK" || echo "MySQL: SORUN VAR"
echo "=== KONTROL TAMAMLANDI ==="
Monitoring sisteminizde yeni sunucunun IP’sini güncelleyin. Nagios, Zabbix veya Prometheus kullanıyorsanız, agent konfigürasyonlarını da kontrol edin.
Gerçek Dünya Senaryosu: E-ticaret Sitesi Taşıması
Geçen yıl bir e-ticaret müşterisi için bu yöntemi uyguladık. Eski sunucu 8 yıllık bir fiziksel makine, 1.2 TB veri, MySQL ve 3 adet WordPress kurulumu vardı.
Takvim şöyle ilerledi:
- 3 gün önce: DNS TTL’i 86400’den 300’e çektik
- 2 gün önce: Yeni sunucu hazırlandı, ilk büyük sync başlatıldı (6 saat sürdü)
- 1 gün önce: İkinci delta sync çalıştırıldı (45 dakika, sadece 23 GB değişiklik)
- Gecesi: Üçüncü delta sync (8 dakika, 2.1 GB değişiklik)
- Maintenance window: Servisler durduruldu, son sync çalıştırıldı (3 dakika), DNS değiştirildi
Toplam downtime: 11 dakika. Müşteri bir akşam yemeği sırasında geçişi bile fark etmedi.
Sonuç
Rsync ile canlı sistem taşıması, iyi planlanmış bir yaklaşımla büyük ölçüde risksiz bir operasyon haline gelir. Temel prensip basit: çok önceden başla, kademeli senkronizasyon yap, maintenance window’u en aza indir.
Birkaç kritik noktayı aklında tut. İlk olarak, her zaman bir rollback planın olsun ve eski sunucuyu en az birkaç gün açık tut. İkinci olarak, maintenance window sırasında acele etme ama odaklanmış kal. Üçüncü olarak, her adımı logla, sorun yaşarsan bu loglar hayat kurtarır. Son olarak, büyük bir üretim sistemini taşımadan önce aynı prosedürü bir test ortamında mutlaka dene.
Rsync’i sadece yedekleme aracı olarak görmek büyük bir fırsat kaybı. Doğru parametreler ve iyi bir plan ile, rsync canlı sistem göçünün en güvenilir araçlarından biri haline gelir. Bir sonraki sunucu taşıma projenizde bu yöntemi deneyin, farkı kendiniz göreceksiniz.
