Snapshot ile Yazılım Güncelleme Güvenliği
Yazılım güncellemesi yapacaksın, sistem kritik, geri dönüş planın yok. Bu senaryo her sysadmin’in kâbusu. Ama snapshot teknolojisini doğru kullanırsan, bu kâbus tamamen ortadan kalkıyor. Snapshot, güncelleme öncesi sistemin tam bir fotoğrafını çekmen ve bir şeyler ters gittiğinde saniyeler içinde geri dönebilmen anlamına geliyor. Bu yazıda snapshot ile yazılım güncelleme güvenliğini nasıl sağlayacağını, hangi araçları kullanacağını ve gerçek dünya senaryolarında nasıl hareket edeceğini anlatacağım.
Snapshot Nedir ve Neden Güncelleme Öncesi Şart?
Snapshot, bir sistemin belirli bir andaki durumunu kayıt altına alan mekanizmadır. Klasik yedekten farkı şu: Yedek almak saatler sürebilir, snapshot ise genellikle saniyeler içinde tamamlanır. LVM snapshot, ZFS snapshot, Btrfs snapshot veya hypervisor seviyesinde VMware/KVM snapshot gibi farklı katmanlarda çalışabilir.
Yazılım güncellemesi sırasında en sık karşılaşılan sorunlar şunlardır:
- Bağımlılık çakışmaları: Bir paketin güncellenmesi başka bir paketi bozabilir
- Kernel güncelleme sonrası açılış sorunu: Özellikle özel kernel modülleri olan sistemlerde ciddi risk
- Konfigürasyon dosyası üzerine yazılması: Servis yapılandırmaları update sırasında sıfırlanabilir
- Uygulama uyumsuzluğu: Yeni versiyon, mevcut uygulama kodunuzla çalışmayabilir
- Veritabanı şema değişiklikleri: Bazı güncellemeler otomatik migration çalıştırır, geri almak çok zordur
Bu sorunların hepsinde snapshot yoksa saatler süren bir kurtarma operasyonuyla karşı karşıya kalabilirsin. Snapshot varsa birkaç komutla 5 dakika öncesine dönüyorsun.
LVM Snapshot ile Güncelleme Güvenliği
LVM (Logical Volume Manager) kullanan sistemlerde snapshot almak oldukça basit. Önce mevcut LVM yapını gör:
# Mevcut logical volume'leri listele
lvdisplay
vgdisplay
df -h
# Boş alan kontrolü - snapshot için alan gerekiyor
vgs --units g
Güncelleme öncesi snapshot alma işlemi:
# Root volume snapshot'ı al (10GB ayır)
lvcreate -L 10G -s -n root_before_update /dev/vg0/root
# Var/home gibi ayrı volume'ler varsa onları da al
lvcreate -L 5G -s -n var_before_update /dev/vg0/var
# Snapshot durumunu kontrol et
lvs -a
Snapshot aldıktan sonra güncellemeyi çalıştır:
# Debian/Ubuntu sistemlerde
apt update && apt upgrade -y
# RHEL/CentOS/Rocky Linux sistemlerde
dnf update -y
# Güncelleme logunu kaydet
apt upgrade -y 2>&1 | tee /var/log/update_$(date +%Y%m%d_%H%M%S).log
Eğer bir şeyler ters giderse snapshot’a geri dön:
# Sistemi kapat (live sistemde revert tehlikeli)
# Recovery mode'a gir veya başka bir sistemden mount et
# Snapshot'a geri dön
lvconvert --merge /dev/vg0/root_before_update
# Sistem yeniden başlatıldığında merge otomatik tamamlanır
reboot
Önemli not: LVM snapshot, orijinal volume üzerindeki değişiklikleri COW (Copy-on-Write) mekanizmasıyla takip eder. Bu yüzden snapshot’ı çok uzun süre aktif tutarsan performans düşüşü yaşanabilir. İşin bitince ya merge et ya da sil.
Btrfs Snapshot: Modern Yaklaşım
Btrfs kullanan sistemlerde (Fedora, openSUSE, modern Ubuntu kurulumları) snapshot işlemi çok daha entegre ve kullanışlıdır. Snapper aracı bu işlemi otomatikleştirir:
# Snapper kurulumu
dnf install snapper -y # Fedora/RHEL
apt install snapper -y # Debian/Ubuntu
# Root için snapper konfigürasyonu oluştur
snapper -c root create-config /
# Mevcut konfigürasyonları listele
snapper list-configs
Güncelleme öncesi manuel snapshot:
# Güncelleme öncesi snapshot
snapper -c root create --description "Before system update $(date +%Y%m%d)"
# Snapshot listesini görüntüle
snapper -c root list
# Güncellemeyi çalıştır
dnf update -y
# Güncelleme sonrası snapshot (opsiyonel, karşılaştırma için iyi)
snapper -c root create --description "After system update $(date +%Y%m%d)"
Snapper’ın en güzel özelliği iki snapshot arasındaki farkı göstermesi:
# İki snapshot arasındaki değişiklikleri görüntüle
# Snapshot numaralarını snapper list ile öğren
snapper -c root diff 1 2
# Sadece değişen dosyaların listesi
snapper -c root status 1 2
Geri dönüş senaryosu:
# Btrfs snapshot'a undochange ile geri dön
snapper -c root undochange 1..2
# Ya da snapper rollback ile
snapper rollback 1
# Sistem yeniden başlatıldığında rollback tamamlanır
reboot
openSUSE sistemlerde zypper (paket yöneticisi) otomatik olarak snapper ile entegre çalışır. Her zypper install veya zypper update komutu öncesinde otomatik snapshot alınır. Bu, production sistemler için ideal bir yaklaşım.
ZFS Snapshot: Kurumsal Güç
ZFS kullanan sistemler (FreeBSD, TrueNAS, bazı Linux kurulumları) için snapshot yönetimi son derece güçlüdür:
# Mevcut ZFS pool ve dataset'leri listele
zpool list
zfs list
# Güncelleme öncesi snapshot al
zfs snapshot rpool/ROOT/ubuntu@before_update_$(date +%Y%m%d)
# Tüm dataset'leri recursive olarak snapshotle
zfs snapshot -r rpool@before_update_$(date +%Y%m%d)
# Snapshot listesi
zfs list -t snapshot
ZFS rollback işlemi:
# Son snapshot'a geri dön
zfs rollback rpool/ROOT/ubuntu@before_update_20240115
# Eski bir snapshot'a geri dönmek için -r flag gerekebilir
# Bu aradaki tüm snapshot'ları siler, dikkatli kullan
zfs rollback -r rpool/ROOT/ubuntu@before_update_20240115
ZFS’in harika bir özelliği de snapshot’ları başka bir sisteme göndermek:
# Snapshot'ı başka bir sunucuya gönder (felaket kurtarma)
zfs send rpool/ROOT/ubuntu@before_update_20240115 |
ssh backup-server "zfs receive backup/server01"
VMware ve KVM Hypervisor Seviyesinde Snapshot
Sanal makine çalıştırıyorsan hypervisor seviyesinde snapshot almak çoğu zaman en pratik yaklaşım. Guest OS’da hiçbir şey yapman gerekmiyor.
VMware ESXi için:
# VMware PowerCLI ile snapshot al
Connect-VIServer -Server esxi01.company.com
# VM snapshot'ı
New-Snapshot -VM "WebServer01" -Name "Before_Update_$(Get-Date -Format 'yyyyMMdd')"
-Description "Pre-update snapshot" -Memory -Quiesce
# Snapshot listesi
Get-Snapshot -VM "WebServer01"
# Snapshot'a geri dön
Set-VM -VM "WebServer01" -Snapshot (Get-Snapshot -VM "WebServer01" -Name "Before_Update_20240115")
KVM/libvirt ile:
# KVM VM snapshot'ı (internal snapshot)
virsh snapshot-create-as --domain webserver01
--name "before_update_$(date +%Y%m%d)"
--description "Pre-update snapshot"
--atomic
# Snapshot listesi
virsh snapshot-list webserver01
# Snapshot bilgisi
virsh snapshot-info webserver01 before_update_20240115
# Snapshot'a geri dön
virsh snapshot-revert webserver01 before_update_20240115
# VM'yi başlat
virsh start webserver01
External disk snapshot’ı (daha güvenli, disk aktifken de çalışır):
# External snapshot oluştur
virsh snapshot-create-as --domain webserver01
--name "before_update_ext"
--diskspec vda,snapshot=external,file=/var/lib/libvirt/images/webserver01_snap.qcow2
--disk-only
--atomic
# Snapshot durumunu kontrol et
virsh domblklist webserver01
Pratik Güncelleme Workflow’u
Gerçek bir production ortamında güncelleme güvenliğini nasıl sağlarsın? İşte benim kullandığım pratik bir script:
#!/bin/bash
# pre_update_snapshot.sh - Güncelleme öncesi güvenlik scripti
set -euo pipefail
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/update_snapshot_${TIMESTAMP}.log"
SNAPSHOT_NAME="pre_update_${TIMESTAMP}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# Disk alanı kontrolü
check_disk_space() {
local available=$(df / | awk 'NR==2 {print $4}')
local minimum=5242880 # 5GB in KB
if [ "$available" -lt "$minimum" ]; then
log "HATA: Yetersiz disk alanı. Minimum 5GB gerekli."
exit 1
fi
log "Disk alanı yeterli: $(df -h / | awk 'NR==2 {print $4}') boş"
}
# Snapshot türünü tespit et ve al
take_snapshot() {
# LVM kontrolü
if command -v lvdisplay &>/dev/null && lvdisplay /dev/vg0/root &>/dev/null; then
log "LVM tespit edildi, snapshot alınıyor..."
lvcreate -L 10G -s -n "${SNAPSHOT_NAME}" /dev/vg0/root
log "LVM snapshot alındı: ${SNAPSHOT_NAME}"
# Btrfs kontrolü
elif df -T / | grep -q btrfs; then
log "Btrfs tespit edildi, snapper ile snapshot alınıyor..."
snapper -c root create --description "pre_update_${TIMESTAMP}"
log "Btrfs snapshot alındı"
# ZFS kontrolü
elif command -v zfs &>/dev/null; then
log "ZFS tespit edildi, snapshot alınıyor..."
zfs snapshot -r "rpool@${SNAPSHOT_NAME}"
log "ZFS snapshot alındı: ${SNAPSHOT_NAME}"
else
log "UYARI: Snapshot destekli dosya sistemi bulunamadı!"
log "rsync ile yedek alınıyor..."
rsync -aAX --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*"}
/ "/backup/${SNAPSHOT_NAME}/"
fi
}
# Sistem bilgilerini kaydet
save_system_info() {
log "Sistem bilgileri kaydediliyor..."
# Kurulu paket listesi
if command -v dpkg &>/dev/null; then
dpkg -l > "/var/log/packages_before_${TIMESTAMP}.txt"
elif command -v rpm &>/dev/null; then
rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}n' | sort >
"/var/log/packages_before_${TIMESTAMP}.txt"
fi
# Çalışan servisler
systemctl list-units --state=running > "/var/log/services_before_${TIMESTAMP}.txt"
log "Sistem bilgileri kaydedildi"
}
# Ana akış
log "=== Güncelleme Öncesi Hazırlık Başlıyor ==="
check_disk_space
save_system_info
take_snapshot
log "=== Hazırlık Tamamlandı. Güncellemeye devam edebilirsiniz ==="
log "Geri dönüş gerekirse snapshot adı: ${SNAPSHOT_NAME}"
Bu script’i çalıştır, sonra güvenle güncellemeye devam et:
chmod +x pre_update_snapshot.sh
sudo ./pre_update_snapshot.sh
# Güncellemeyi çalıştır
sudo apt upgrade -y # veya dnf update -y
# Sistem sağlıklıysa snapshot'ı temizle
sudo lvremove /dev/vg0/pre_update_20240115_143022
Kernel Güncelleme Senaryosu: En Riskli Durum
Kernel güncellemesi özel dikkat gerektirir. DKMS modülleri olan sistemlerde (NVIDIA driver, VirtualBox, WireGuard vs.) kernel güncellemesi sonrası sistem açılmayabilir.
# Güncelleme öncesi mevcut kernel ve modülleri kaydet
uname -r > /var/log/kernel_before_update.txt
lsmod >> /var/log/kernel_before_update.txt
# DKMS modüllerini kontrol et
dkms status
# Snapshot al (yukarıdaki yöntemlerden birini kullan)
# Sadece kernel güncellemesi yap
apt-get install --only-upgrade linux-image-generic linux-headers-generic
# Ya da belirli bir kernel versiyon
apt-get install linux-image-6.5.0-15-generic
# Güncelleme sonrası GRUB yapılandırmasını kontrol et
grep -A5 "menuentry" /boot/grub/grub.cfg | head -20
Kernel güncellemesi sonrası açılış sorunu yaşarsan:
# GRUB menüsünden eski kernel'ı seç
# Veya GRUB komut satırından:
# linux /boot/vmlinuz-<eski_versiyon> root=/dev/sda1
# initrd /boot/initrd.img-<eski_versiyon>
# boot
# Eski kernel'a boot ettikten sonra snapshot'a dön
# LVM için:
lvconvert --merge /dev/vg0/pre_update_snapshot
# Sonra yeni kernel'ı blacklist'e al (geçici)
echo "blacklist <problematic_module>" >> /etc/modprobe.d/blacklist.conf
Otomatik Snapshot Politikası Oluşturma
Production ortamda her güncelleme öncesi manuel snapshot almak unutulabilir. Bunu otomatik hale getirmen lazım:
# /etc/apt/apt.conf.d/80pre-update-snapshot dosyası oluştur
# APT hook ile her apt upgrade öncesi snapshot al
cat > /etc/apt/apt.conf.d/80pre-update-snapshot << 'EOF'
DPkg::Pre-Invoke {"/usr/local/bin/apt_pre_snapshot.sh";};
EOF
# Basit hook scripti
cat > /usr/local/bin/apt_pre_snapshot.sh << 'EOF'
#!/bin/bash
# Sadece upgrade/install işlemlerinde çalış
if [ "$1" = "upgrade" ] || [ "$1" = "install" ]; then
SNAP_NAME="apt_pre_$(date +%Y%m%d_%H%M%S)"
# Btrfs sistemlerde
if df -T / | grep -q btrfs; then
snapper -c root create --description "$SNAP_NAME" 2>/dev/null
fi
# LVM sistemlerde (eğer yeterli yer varsa)
if lvdisplay /dev/vg0/root &>/dev/null; then
FREE=$(vgs --units g --noheadings -o vg_free vg0 | tr -d ' g')
if [ $(echo "$FREE > 5" | bc) -eq 1 ]; then
lvcreate -L 5G -s -n "$SNAP_NAME" /dev/vg0/root 2>/dev/null
fi
fi
fi
EOF
chmod +x /usr/local/bin/apt_pre_snapshot.sh
Eski snapshot’ları otomatik temizle:
# Snapper için retention policy
cat >> /etc/snapper/configs/root << 'EOF'
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="5"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_MONTHLY="2"
TIMELINE_LIMIT_YEARLY="0"
EOF
# LVM snapshot'ları için cron ile temizlik
cat > /etc/cron.daily/cleanup-lvm-snapshots << 'EOF'
#!/bin/bash
# 7 günden eski LVM snapshot'ları sil
# Snapshot ismine göre filtrele
lvs --noheadings -o lv_name,lv_time | while read name time; do
if [[ "$name" == *"_before_update_"* ]]; then
# Tarih karşılaştırması yap ve 7 günden eskiyse sil
echo "Kontrol ediliyor: $name"
fi
done
EOF
chmod +x /etc/cron.daily/cleanup-lvm-snapshots
Snapshot Sonrası Doğrulama
Güncelleme tamamlandıktan sonra snapshot’a ihtiyaç duyup duymadığını anlamak için hızlı doğrulama:
#!/bin/bash
# post_update_verify.sh
echo "=== Güncelleme Sonrası Doğrulama ==="
# Kritik servislerin durumu
CRITICAL_SERVICES=("nginx" "mysql" "postgresql" "redis" "docker")
for service in "${CRITICAL_SERVICES[@]}"; do
if systemctl is-active --quiet "$service" 2>/dev/null; then
echo "OK: $service çalışıyor"
elif systemctl is-enabled --quiet "$service" 2>/dev/null; then
echo "UYARI: $service aktif ama çalışmıyor!"
systemctl status "$service" --no-pager -l
fi
done
# Hatalı paket var mı?
if command -v dpkg &>/dev/null; then
broken=$(dpkg -l | grep -c "^.F" || true)
if [ "$broken" -gt 0 ]; then
echo "HATA: $broken kırık paket tespit edildi"
dpkg -l | grep "^.F"
else
echo "OK: Kırık paket yok"
fi
fi
# Yeniden başlatma gerekiyor mu?
if [ -f /var/run/reboot-required ]; then
echo "BİLGİ: Sistem yeniden başlatma bekliyor"
cat /var/run/reboot-required.pkgs 2>/dev/null
fi
# Disk doluluk kontrolü
echo ""
echo "=== Disk Kullanımı ==="
df -h | grep -v tmpfs
Gerçek Dünya Senaryosu: PostgreSQL Sunucusunda Güncelleme
Diyelim ki PostgreSQL çalıştıran bir production sunucusunda major versiyon güncellemesi yapıyorsun. Bu en riskli senaryolardan biri:
- Major versiyon geçişi (örn. PG 14 to 15) otomatik değil
- pg_upgrade çalıştırmak gerekiyor
- Veri formatı değişebilir, geri almak zor
# 1. Snapshot al
lvcreate -L 20G -s -n pgserver_before_pg15 /dev/vg0/root
lvcreate -L 50G -s -n pgdata_before_pg15 /dev/vg0/pgdata
# 2. PostgreSQL'i durdur ve pg_dumpall ile de yedek al (çift güvence)
systemctl stop postgresql
sudo -u postgres pg_dumpall > /backup/pgdump_before_update_$(date +%Y%m%d).sql
# 3. Güncellemeyi yap
apt install postgresql-15
# 4. pg_upgrade çalıştır
sudo -u postgres /usr/lib/postgresql/15/bin/pg_upgrade
-b /usr/lib/postgresql/14/bin
-B /usr/lib/postgresql/15/bin
-d /var/lib/postgresql/14/main
-D /var/lib/postgresql/15/main
# 5. Test et
systemctl start postgresql@15-main
sudo -u postgres psql -c "SELECT version();"
# 6. Her şey yolundaysa snapshot'ları temizle
lvremove -f /dev/vg0/pgserver_before_pg15
lvremove -f /dev/vg0/pgdata_before_pg15
Sonuç
Snapshot olmadan güncelleme yapmak, emniyet kemeri takmadan araba kullanmak gibi. Belki yüzlerce kez sorunsuz geçersin, ama bir kere kötü gittiğinde keşke snapshot alsaydım dersin.
Uygulamada dikkat etmen gereken birkaç kritik nokta var. Snapshot, yedek değildir. Disk arızasına karşı koruma sağlamaz, sadece yazılım güncellemesi gibi logic hatalardan kurtarır. Gerçek yedek ayrıca olmalı. Snapshot almak için yeterli boş alan olduğundan emin ol; LVM COW mekanizması değişiklikler büyüdükçe yer kaplar. Snapshot’ları sonsuza kadar bırakma; bittikten sonra temizle, yoksa performans etkisi yaratır. Kritik sistemlerde güncelleme öncesi snapshot alma işlemini otomatize et ve bunu standart operasyon prosedürüne yaz.
Hangi teknolojiyi kullanırsan kullan, LVM, Btrfs, ZFS veya hypervisor snapshot, önemli olan bu adımı routine haline getirmek. Bir süre sonra güncelleme öncesi snapshot almak sana diş fırçalamak kadar doğal gelecek.
