Snapshot Otomasyonu: Zamanlanmış Anlık Görüntülerle Yedeklemeyi Kolaylaştırın

Üretim ortamında bir şeyler ters gittiğinde, “keşke bir snapshot alsaydım” demekten daha can sıkıcı bir şey yoktur. Snapshot otomasyonu tam da bu noktada devreye giriyor: İnsan faktörünü ortadan kaldırarak, düzenli aralıklarla anlık görüntüler alıyor ve sizi olası felaketten koruyor. Bu yazıda hem Linux hem de Windows ortamlarında snapshot otomasyonunu nasıl kuracağınızı, hangi araçları kullanacağınızı ve gerçek dünya senaryolarında nasıl yaklaşmanız gerektiğini ele alacağız.

Snapshot Nedir ve Neden Otomatikleştirilmeli?

Snapshot, bir sistemin veya diskin belirli bir andaki durumunu kayıt altına alan anlık görüntüdür. Klasik yedeklemeden farkı, çok daha hızlı alınması ve geri dönüşün saniyeler içinde gerçekleşebilmesidir. Ancak snapshot, tam yedeklemenin yerini tutmaz; tamamlayıcısıdır.

Manuel snapshot almanın sorunları açıktır. Gece yarısı yapılan büyük güncellemeden önce kimse o snapshot’ı almayı hatırlamıyor. Bayram tatilinde kritik bir veritabanı güncellemesi yapılıyor ve ortada hiçbir anlık görüntü yok. Otomasyon bu insan hatalarını ortadan kaldırır.

Otomasyonun getirdikleri şunlardır:

  • Tutarlılık: Her gün, her hafta aynı saatte snapshot alınır
  • İzlenebilirlik: Hangi snapshot ne zaman alındı, kaç tane var, kolayca takip edilir
  • Yer yönetimi: Eski snapshot’lar otomatik silinerek disk dolmaz
  • Uyumluluk: Bazı sektörlerde düzenli yedek kanıtı zorunludur

Linux Ortamında LVM Snapshot Otomasyonu

Linux’ta en yaygın snapshot mekanizmalarından biri LVM (Logical Volume Manager) üzerinden çalışır. Üretim sunucularınızda LVM kullanıyorsanız, ekstra bir araç kurmadan snapshot alabilirsiniz.

Temel LVM Snapshot Komutu

#!/bin/bash
# lvm_snapshot.sh - Basit LVM snapshot betiği

VOLUME_GROUP="vg_production"
LOGICAL_VOLUME="lv_data"
SNAPSHOT_NAME="lv_data_snap_$(date +%Y%m%d_%H%M%S)"
SNAPSHOT_SIZE="10G"

# Snapshot al
lvcreate -L${SNAPSHOT_SIZE} -s -n ${SNAPSHOT_NAME} /dev/${VOLUME_GROUP}/${LOGICAL_VOLUME}

if [ $? -eq 0 ]; then
    echo "$(date): Snapshot basariyla alindi: ${SNAPSHOT_NAME}" >> /var/log/snapshot.log
else
    echo "$(date): HATA - Snapshot alinamadi!" >> /var/log/snapshot.log
    # Mail gonder
    echo "LVM snapshot hatasi: ${SNAPSHOT_NAME}" | mail -s "SNAPSHOT HATASI" [email protected]
fi

Bu betik tek başına işe yarasa da, eski snapshot’ları temizlemeden çalıştırırsanız diskiniz dolacaktır. Aşağıda bunu da ele alan daha kapsamlı bir betik var.

Eski Snapshot’ları Temizleyen Gelişmiş Betik

#!/bin/bash
# lvm_snapshot_manager.sh
# Cron: 0 2 * * * /usr/local/sbin/lvm_snapshot_manager.sh

VOLUME_GROUP="vg_production"
LOGICAL_VOLUME="lv_data"
SNAP_PREFIX="lv_data_snap_"
MAX_SNAPSHOTS=7  # Son 7 snapshot tut
LOG_FILE="/var/log/lvm_snapshot.log"
ALERT_EMAIL="[email protected]"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> ${LOG_FILE}
}

# Yeni snapshot al
SNAPSHOT_NAME="${SNAP_PREFIX}$(date +%Y%m%d_%H%M%S)"
SNAPSHOT_SIZE="15G"

log "Snapshot aliniyor: ${SNAPSHOT_NAME}"
lvcreate -L${SNAPSHOT_SIZE} -s -n ${SNAPSHOT_NAME} /dev/${VOLUME_GROUP}/${LOGICAL_VOLUME} >> ${LOG_FILE} 2>&1

if [ $? -ne 0 ]; then
    log "KRITIK HATA: Snapshot alinamadi!"
    echo "$(date): LVM snapshot hatasi - ${SNAPSHOT_NAME}" | mail -s "[KRITIK] Snapshot Hatasi" ${ALERT_EMAIL}
    exit 1
fi

log "Snapshot basariyla alindi: ${SNAPSHOT_NAME}"

# Eski snapshot'lari temizle
EXISTING_SNAPS=$(lvs --noheadings -o lv_name ${VOLUME_GROUP} | grep "^  ${SNAP_PREFIX}" | sort)
SNAP_COUNT=$(echo "${EXISTING_SNAPS}" | grep -c "${SNAP_PREFIX}")

log "Mevcut snapshot sayisi: ${SNAP_COUNT}"

if [ ${SNAP_COUNT} -gt ${MAX_SNAPSHOTS} ]; then
    DELETE_COUNT=$((SNAP_COUNT - MAX_SNAPSHOTS))
    OLD_SNAPS=$(echo "${EXISTING_SNAPS}" | head -n ${DELETE_COUNT})
    
    for snap in ${OLD_SNAPS}; do
        snap=$(echo $snap | xargs)  # bosluk temizle
        log "Eski snapshot siliniyor: ${snap}"
        lvremove -f /dev/${VOLUME_GROUP}/${snap} >> ${LOG_FILE} 2>&1
        
        if [ $? -eq 0 ]; then
            log "Silindi: ${snap}"
        else
            log "UYARI: Silinemedi: ${snap}"
        fi
    done
fi

log "Islem tamamlandi. Aktif snapshot sayisi: $(lvs --noheadings -o lv_name ${VOLUME_GROUP} | grep -c ${SNAP_PREFIX})"

Bu betiği crontab’a eklemek için:

# Crontab'i duzenle
crontab -e

# Her gece saat 02:00'de calistir
0 2 * * * /usr/local/sbin/lvm_snapshot_manager.sh

# Her Pazar saat 01:00'de haftalik snapshot (farkli prefix ile)
0 1 * * 0 SNAP_PREFIX="lv_data_weekly_" MAX_SNAPSHOTS=4 /usr/local/sbin/lvm_snapshot_manager.sh

BTRFS ile Snapshot Otomasyonu

Modern Linux dağıtımlarında BTRFS giderek yaygınlaşıyor. openSUSE, Fedora ve bazı Ubuntu kurulumlarında varsayılan dosya sistemi olarak geliyor. BTRFS snapshot’ları LVM’e göre çok daha az yer kaplıyor çünkü copy-on-write mimarisini kullanıyor.

snapper, BTRFS snapshot yönetimi için en olgun araçtır. openSUSE’da varsayılan gelir, diğer dağıtımlara kurulumu şöyledir:

# Ubuntu/Debian
apt install snapper

# Fedora/RHEL
dnf install snapper

# /home icin snapper konfigurasyonu olustur
snapper -c home create-config /home

# Otomatik timeline snapshot'lari aktif et
snapper -c home set-config 
    TIMELINE_CREATE=yes 
    TIMELINE_CLEANUP=yes 
    TIMELINE_LIMIT_HOURLY=6 
    TIMELINE_LIMIT_DAILY=7 
    TIMELINE_LIMIT_WEEKLY=4 
    TIMELINE_LIMIT_MONTHLY=6 
    TIMELINE_LIMIT_YEARLY=2

# snapper-timeline.timer servisini aktif et
systemctl enable --now snapper-timeline.timer
systemctl enable --now snapper-cleanup.timer

# Mevcut snapshot'lari listele
snapper -c home list

Snapper’ın güzel yanı, “pre” ve “post” snapshot çifti oluşturabilmesidir. Bir yazılım güncellemesi yapmadan önce ve sonra snapshot alıp, aralarındaki farkı görebilirsiniz.

VMware ve KVM Ortamlarında Snapshot Otomasyonu

Sanallaştırma ortamlarında snapshot yönetimi biraz daha karmaşık ama çok daha güçlüdür.

VMware vSphere: PowerCLI ile Otomatik Snapshot

Windows üzerinde çalışan PowerShell ortamında PowerCLI kullanarak vSphere snapshot otomasyonu yapabilirsiniz:

# vmware_snapshot.ps1
# Gereksinim: VMware.PowerCLI modulu

param(
    [string]$vCenterServer = "vcenter.sirket.local",
    [string]$VMPattern = "PROD-*",
    [int]$MaxSnapshots = 3
)

# vCenter'a baglan
Connect-VIServer -Server $vCenterServer -Credential (Get-Credential) | Out-Null

$SnapDate = Get-Date -Format "yyyyMMdd_HHmmss"
$LogFile = "C:LogsVMware_Snapshots_$SnapDate.log"

function Write-Log {
    param([string]$Message)
    $LogEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $Message"
    Add-Content -Path $LogFile -Value $LogEntry
    Write-Host $LogEntry
}

# Pattern ile eslesen VM'leri al
$VMs = Get-VM -Name $VMPattern

foreach ($VM in $VMs) {
    Write-Log "Snapshot aliniyor: $($VM.Name)"
    
    try {
        # Yeni snapshot al
        New-Snapshot -VM $VM `
            -Name "AutoSnap_$SnapDate" `
            -Description "Otomatik zamanlanmis snapshot - $SnapDate" `
            -Memory:$false `
            -Quiesce:$true | Out-Null
        
        Write-Log "BASARILI: $($VM.Name) snapshot alindi"
        
        # Eski snapshot'lari temizle
        $AllSnaps = Get-Snapshot -VM $VM | 
                    Where-Object { $_.Name -like "AutoSnap_*" } | 
                    Sort-Object -Property Created
        
        $SnapCount = $AllSnaps.Count
        Write-Log "$($VM.Name) icin toplam snapshot: $SnapCount"
        
        if ($SnapCount -gt $MaxSnapshots) {
            $ToDelete = $AllSnaps | Select-Object -First ($SnapCount - $MaxSnapshots)
            foreach ($Snap in $ToDelete) {
                Write-Log "Siliniyor: $($Snap.Name) - $($Snap.Created)"
                Remove-Snapshot -Snapshot $Snap -Confirm:$false | Out-Null
            }
        }
        
    } catch {
        Write-Log "HATA: $($VM.Name) - $($_.Exception.Message)"
        Send-MailMessage -To "[email protected]" `
            -From "[email protected]" `
            -Subject "[HATA] VM Snapshot Hatasi: $($VM.Name)" `
            -Body $_.Exception.Message `
            -SmtpServer "mail.sirket.com"
    }
}

Disconnect-VIServer -Confirm:$false
Write-Log "Tum islemler tamamlandi"

KVM/libvirt ile Snapshot Otomasyonu

Linux üzerinde KVM kullanıyorsanız, virsh komutu ve küçük bir betik işinizi görür:

#!/bin/bash
# kvm_snapshot_auto.sh
# Cron: 30 1 * * * /usr/local/sbin/kvm_snapshot_auto.sh

SNAP_DATE=$(date +%Y%m%d_%H%M%S)
LOG="/var/log/kvm_snapshots.log"
MAX_SNAPS=5

log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> ${LOG}; }

# Calisan tum VM'leri al
RUNNING_VMS=$(virsh list --name --state-running)

for VM in ${RUNNING_VMS}; do
    log "--- VM: ${VM} ---"
    
    # Snapshot al (disk-only, bellek dahil etme - daha hizli)
    SNAP_NAME="autosnap_${SNAP_DATE}"
    
    virsh snapshot-create-as 
        --domain "${VM}" 
        --name "${SNAP_NAME}" 
        --description "Otomatik snapshot: $(date)" 
        --disk-only 
        --atomic >> ${LOG} 2>&1
    
    if [ $? -eq 0 ]; then
        log "BASARILI: ${VM} -> ${SNAP_NAME}"
    else
        log "HATA: ${VM} snapshot alinamadi"
        continue
    fi
    
    # Eski snapshot'lari sil
    SNAP_LIST=$(virsh snapshot-list ${VM} --name | grep "^autosnap_" | sort)
    SNAP_COUNT=$(echo "${SNAP_LIST}" | grep -c "autosnap_")
    
    if [ ${SNAP_COUNT} -gt ${MAX_SNAPS} ]; then
        DELETE_COUNT=$((SNAP_COUNT - MAX_SNAPS))
        echo "${SNAP_LIST}" | head -n ${DELETE_COUNT} | while read OLD_SNAP; do
            log "Siliniyor: ${VM}/${OLD_SNAP}"
            virsh snapshot-delete ${VM} ${OLD_SNAP} --metadata >> ${LOG} 2>&1
        done
    fi
done

log "Tum VM snapshot islemi tamamlandi"

Bulut Ortamlarında Snapshot Otomasyonu

AWS, Azure veya GCP kullanıyorsanız, her platformun kendi snapshot mekanizmaları var. AWS EBS için örnek bir Lambda fonksiyonu veya AWS Data Lifecycle Manager kullanabilirsiniz. Ancak hızlı ve taşınabilir bir çözüm için AWS CLI yeterlidir.

#!/bin/bash
# aws_ebs_snapshot.sh
# Ortam degiskenleri: AWS_DEFAULT_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

RETENTION_DAYS=7
LOG="/var/log/aws_snapshots.log"
TAG_KEY="AutoBackup"
TAG_VALUE="true"

log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a ${LOG}; }

# AutoBackup=true etiketi olan tum EBS volumelerini bul
VOLUMES=$(aws ec2 describe-volumes 
    --filters "Name=tag:${TAG_KEY},Values=${TAG_VALUE}" 
    --query 'Volumes[*].VolumeId' 
    --output text)

for VOL_ID in ${VOLUMES}; do
    log "Snapshot aliniyor: ${VOL_ID}"
    
    SNAP_ID=$(aws ec2 create-snapshot 
        --volume-id "${VOL_ID}" 
        --description "AutoSnap-$(date +%Y%m%d_%H%M%S)" 
        --tag-specifications "ResourceType=snapshot,Tags=[{Key=AutoCreated,Value=true},{Key=VolumeId,Value=${VOL_ID}}]" 
        --query 'SnapshotId' 
        --output text)
    
    if [ $? -eq 0 ]; then
        log "BASARILI: ${VOL_ID} -> ${SNAP_ID}"
    else
        log "HATA: ${VOL_ID} snapshot alinamadi"
    fi
done

# Retention politikasina gore eski snapshot'lari sil
CUTOFF_DATE=$(date -d "${RETENTION_DAYS} days ago" +%Y-%m-%dT%H:%M:%S)

OLD_SNAPS=$(aws ec2 describe-snapshots 
    --filters "Name=tag:AutoCreated,Values=true" 
    --query "Snapshots[?StartTime<='${CUTOFF_DATE}'].SnapshotId" 
    --output text)

for SNAP_ID in ${OLD_SNAPS}; do
    log "Eski snapshot siliniyor: ${SNAP_ID}"
    aws ec2 delete-snapshot --snapshot-id "${SNAP_ID}" >> ${LOG} 2>&1
done

log "AWS EBS snapshot islemi tamamlandi"

Snapshot İzleme ve Raporlama

Snapshot alındı, güzel. Peki düzgün çalışıyor mu? Boyutlar ne durumda? Bunları izlemek için basit bir kontrol betiği faydalı olur:

#!/bin/bash
# snapshot_health_check.sh
# Her sabah 08:00'de calistir, raporla

REPORT_FILE="/tmp/snapshot_report_$(date +%Y%m%d).txt"
REPORT_EMAIL="[email protected]"
VG="vg_production"
MAX_SNAP_AGE_HOURS=26  # 24 saat + 2 saat tolerans

{
echo "=== SNAPSHOT SAGLIK RAPORU ==="
echo "Tarih: $(date)"
echo ""

# LVM Snapshot durumu
echo "--- LVM Snapshot Durumu ---"
lvs -o lv_name,lv_size,data_percent,lv_time ${VG} 2>/dev/null | grep -i snap

echo ""
echo "--- Son Snapshot Zamanlari ---"

# Son snapshot'in kac saat once alindigi
LATEST_SNAP=$(lvs --noheadings -o lv_name,lv_time ${VG} 2>/dev/null | 
    grep "snap" | sort -k2 | tail -1)

if [ -z "${LATEST_SNAP}" ]; then
    echo "UYARI: Hic snapshot bulunamadi!"
else
    echo "Son snapshot: ${LATEST_SNAP}"
fi

echo ""
echo "--- Disk Kullanim Ozeti ---"
df -h | grep -E "(Filesystem|vg_|data)"

echo ""
echo "=== RAPOR SONU ==="
} > ${REPORT_FILE}

# Mail gonder
mail -s "Gunluk Snapshot Raporu - $(date +%Y-%m-%d)" 
    ${REPORT_EMAIL} < ${REPORT_FILE}

# Eski raporlari temizle (30 gundan eski)
find /tmp -name "snapshot_report_*.txt" -mtime +30 -delete

Gerçek Dünya Senaryoları ve İpuçları

Senaryo 1: Veritabanı güncellemesi öncesi snapshot

Bir müşterimizde PostgreSQL 13’ten 14’e yükseltme yapacaktık. Standart prosedür gereği önce LVM snapshot aldık. Yükseltme sırasında extension uyumsuzluğu çıktı, uygulama çöktü. Snapshot’tan geri dönüş 4 dakika sürdü. Keşke olmasaydı ama olduğu için kurtardı.

Senaryo 2: Uygulama çökmesi sonrası

Snapshot’lar çalışırken alınır ve bu bazen tutarsız veri anlamına gelebilir. Veritabanları için quiesce (dondurma) özelliğini kullanın. VMware’de -Quiesce:$true parametresi bunu yapıyor. Linux’ta fsfreeze komutu işe yarıyor:

# Snapshot oncesi dosya sistemini dondur
fsfreeze -f /var/lib/postgresql

# Snapshot al
lvcreate -L10G -s -n pg_snap_$(date +%Y%m%d) /dev/vg_data/lv_postgres

# Dosya sistemini serbest birak
fsfreeze -u /var/lib/postgresql

Senaryo 3: Snapshot boyutu yönetimi

LVM snapshot’larında boyut kritiktir. Eğer snapshot dolu kalırsa, geçersiz hale gelir. Kural olarak, değişim hızı yüksek sistemlerde volume boyutunun yüzde 20-30’u kadar snapshot alanı ayırın. Aktif yazma yapan production veritabanlarında bu oran yüzde 50’ye çıkabilir.

Snapshot doluluk oranını izlemek için:

# Snapshot doluluk yuzdesini goster
lvs -o lv_name,data_percent vg_production | grep snap

# Yuzde 80'i asan snapshot'lar icin uyari
lvs --noheadings -o lv_name,data_percent vg_production | 
    awk '{if ($2 > 80) print "UYARI: " $1 " doluluk: " $2 "%"}' | 
    mail -s "Snapshot Doluluk Uyarisi" [email protected]

Snapshot Alırken Sık Yapılan Hatalar

  • Çok fazla snapshot biriktirmek: Her snapshot disk alanı ve I/O performansı tüketir. LVM’de özellikle, çok sayıda aktif snapshot yazma performansını ciddi düşürür
  • Snapshot’ı yedek sanmak: Snapshot ile orijinal veri aynı fiziksel diskteyse, disk arızasında ikisi de gider. Snapshot, yedek değil kısa vadeli geri alım mekanizmasıdır
  • Eski snapshot’ları silmeyi unutmak: Otomasyonda retention politikası olmadan çalışmak, er ya da geç disk dolmasına yol açar
  • Test etmemek: Ayda bir snapshot’tan geri dönüş testi yapın. Almak yetmez, çalıştığını kanıtlayın

Sonuç

Snapshot otomasyonu, sysadmin araç kutusunun olmazsa olmazlarından biridir. LVM, BTRFS, VMware, KVM veya bulut ortamı fark etmeksizin temel prensipler aynıdır: düzenli al, eski olanları temizle, izle ve test et.

Bu yazıda ele aldığımız betikleri doğrudan production’a almayın. Önce test ortamında deneyin, log dosyalarını inceleyin, retention politikalarını kendi ihtiyacınıza göre ayarlayın. Her ortam birbirinden farklıdır; disk büyüklüğü, değişim hızı, retention ihtiyacı hepsini göz önünde bulundurmanız gerekir.

En önemlisi: Snapshot almak yeterli değil, geri dönebilmek önemlidir. Ayda en az bir kez snapshot restore testini gerçek ortamda yapın. Felaket anında işe yaramayan bir snapshot sistemi, hiç olmamasından farklı değildir.

Bir yanıt yazın

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