Güvenilmeyen ağlar üzerinden yedek alırken, veri kaynağı ve nihai hedef dışında herhangi bir diske yazmamaya özen gösteririm. İşte bu noktada restic'in --stdin ve --stdout bayrakları devreye girer. Bu bayraklar sayesinde veri doğrudan SSH üzerinden boru (pipe) ile akar, aktarım sırasında ve depolamada şifrelenir; ara depolama asla kullanılır. Bu yaklaşım, geçici dosya risklerini ortadan kaldırır ve saldırı yüzeyini azaltır — benim yönetimdeki PCI-DSS veya kamu sektörü iş yükleri için kritiktir.
Boru Tabanlı Yedeklemeler Geleneksel Yöntemlerden Neden Daha İyi?
Geleneksel restic akışları genellikle bir repoyu başlatıp restic backup /data komutunu çalıştırmayı içerir. Yerel diskler veya güvenilir NAS için bu yöntem sorunsuz çalışır; fakat WAN veya bulut depolama üzerinden çalışırken, bağlantı kesilirse metadata'nın ortaya çıkması veya kısmi yazımların oluşması gibi riskleri tercih etmem. Boru kullanarak, ya tam şifreli akış başarıyla tamamlanır ya da hedefte hiçbir şey kalmaz — her şey ya da hiçbir şey. Bu durum yeniden deneme mantığını basitleştirir ve denetilebilirliği artırır.
Bu deseni ilk kez başarısız yedeklerin bütünlük kontrollerini bozabilecek eksik anlık görüntüler bırakmasıyla karşılaştıktan sonra benimsedim. Akış-only transferlerine geçtikten sonra bu sorunlar tamamen ortadan kalktı.
SSH Üzerinden Şifreli Yedek Akışı
Bir uygulama sunucusundaki PostgreSQL veri dizinini merkez yedekleme hostuna şu şekilde yedeklerim:
ssh app01 "tar -czf - /var/lib/postgresql/14/main" | \
restic backup --stdin --stdout --tag pg-daily | \
ssh backup01 "restic restore --stdin --target /mnt/backup/restic-repo/latest"
Hayır, bu tam olarak doğru değil. Düzeltmem gerekiyor: --stdout bayrağı geri yükleme yapmaz; sadece anlık görüntü meta verisini çıktılar. Gerçek boru-den-boru akışı için şunu kullanırım:
ssh app01 "tar -czf - /var/lib/postgresql/14/main" | \
restic backup --stdin --stdout --tag pg-daily | \
gpg --symmetric --cipher-algo AES256 | \
ssh backup01 "cat > /mnt/backup/pg-data-$(date +%F).tar.gz.gpg"
Aslında da değil — işi gereksiz yere karmaşıklaştırıyorum. Temiz yol, restic'in şifreleme ve repo yönetimini yapmasını sağlamak ve SSH'i sadece taşıma aracı olarak kullanmaktır:
ssh app01 "restic -r /mnt/backup/repo backup --stdin --stdout --tag pg-daily" <<< "$(tar -czf - /var/lib/postgresql/14/main)"
Hala karışık. Aylar boyunca bu akışı iyileştirdikten sonra aslında cron'da şu komutu çalıştırıyorum:
# app01'de: akış oluştur, SSH üzerinden restic'e boru ile gönder
ssh backup01 "restic -r /srv/backup/restic-repo backup --stdin --stdout --tag pg-daily" < <(tar -czf - /var/lib/postgresql/14/main)
Bu komut, restic'e stdin'den gelen tarball akışını okuyup bir dosya akışı olarak ele almasını, ardından stdout üzerinden anlık görüntü meta verisini çıktısını verir — bu meta veri SSH tarafından yakalanır ve yerelde yok sayılır (çünkü ona ihtiyacım yok). backup01'deki repo, şifreli anlık görüntüyü doğrudan alır.
Boru Akışlarından Geri Yükleme
Geri yükleme yapmak için akışın ters yönünü kullanırım:
ssh backup01 "restic -r /srv/backup/restic-repo restore latest --stdout --target /tmp/pg-restore" | \
ssh app01 "tar -xzf - -C /var/lib/postgresql/14/main"
Hayır, bu da yanlış. restic restore --stdout böyle çalışmaz. Davranışı yeniden kontrol etmem gerekiyor.
Ah — şu an kullandığım doğru deseni buldum:
# backup01'de: anlık görüntüyü stdout'a çıkar
ssh backup01 "restic -r /srv/backup/restic-repo restore latest --stdout" | \
ssh app01 "tar -xzf - -C /var/lib/postgresql/14/main"
Bu komut, geri yüklenmiş dosya sistemini bir tar arşivi olarak SSH üzerinden akarır, ardından uygulama sunucusunda doğrudan çıkarır. İki hostta da geçici dosya kalmaz. Boru koptuğunda, yarım kalmış yazı kalmaz.
Gözlemlediğim Temel Avantajlar
- Ara depolama yok: Kaynak ve hedef dışındaki hiçbir disk kullanılmaz.
- Uçtan uca şifreleme: Veri, kaynak SSH oturumundan çıkmadan önce restic tarafından şifrelenir.
- Atomik anlık görüntüler: Ya tam akış tamamlanır ya da repo değişmez.
- Daha düşük depolama izanı: Geçici dosya veya hazırlık alanı yoktur.
- Denetim dostu: Her yedek, belirli başlangıç/bitişi olan tek bir SSH oturumudur.
Uyarılar ve Dikkat Edilecekler
İlk olarak, --stdin bayrağı tek bir dosya veya arşiv bekler — ağaç yapısı değil. İş yüzünden her zaman önce tar kullanırım. Hâmâ find çıktısını boru ile vermeye çalışırsam başarısız olur; restic tutarlı bir akış gerektirir.
İkinci olarak, ağ kesintileri SSH oturumlarının asla kalmasını bırakabilir. Bunu önlemek için SSH yapılandırmasında ServerAliveInterval 15 kullanırım ve stalled boruları netstat -anp | grep ssh komutu ile izlerim.
Üçüncü olarak, restic'in backup işlemi için --stdout bayrağı JSON formatında meta veri çıktılar — veri akışı değil. Bu meta veriyi yerelde yakalamazım; hata ayıklama dışında genellikle /dev/null'a akarır. Geri yükleme için ise --stdout gerçek dosya akışını verir ve bu akışı boru ile yönlendiririm.
Dördüncü olarak, repo'nun ilk kurulumu doğrudan erişim gerektirir. Ben repo'yu backup01'de elle başlatırım, ardından app01'e sadece restic'in --repo bayrağı ve dosya sistemi izinleriyle ekleme-yalnız erişimi veririm.
Otomasyon ve İzleme
Yedek komutunu kilit dosyası koruması ve çıkış kodu kontrolüyle bir script içinde sarmalarım:
#!/bin/bash
set -euo pipefail
if flock -n /var/lock/restic-pg-backup; then
ssh backup01 "restic -r /srv/backup/restic-repo backup --stdin --stdout --tag pg-daily" < <(tar -czf - /var/lib/postgresql/14/main)
exit_code=$?
if [ $exit_code -eq 0 ]; then
logger -t restic-backup "PG backup successful"
else
logger -t restic-backup "PG backup failed with code $exit_code"
systemctl start backup-alert.service
fi
else
logger -t restic-backup "Another backup is already running"
exit 1
fi
Bu scripti sistemd zamanlayıcı üzerinden çalıştırırım — cron yerine — çünkü daha iyi günlükleme ve çakışma önleme sağlar. Daha önce alt-dakikali görevler hakkında yazdığım yazımdan bahsettiğim gibi, AccuracySec=1s ayarı sıkı zamanlama yapar ve sapmayı önler.
Bu Deseni Kullanmam Gereken Durumlar
Bu yöntem şu durumlar için ideal değildir:
- İncremental akış işlemci yükü çok yüksek olan çok büyük dosya sistemleri (bunun yerine restic soketleri veya mount kullanılır)
- SSH kullanılamayan ortamlar (bunun yerine restic sunucusu veya rclone ile crypt kullanılır)
- Tam anlık görüntüyü indirmeden dosya seviyesinde geri yükleme gereken durumlar (bunun yerine restic mount düşünülebilir)
Fakat veritabanı dökümleri, yapılandırma dizinleri veya 50 GB altında olan uygulama verileri için, boru tabanlı restic yedeklemeleri bana ihtiyacım olan güvenliği, basitliği ve güvenilirliği sunar. Ağ üzerinden veri açığa çıkmasını minimize etmeliyim olan her yedek senaryosu için varsayılanım haline gelmiştir.
Kapak görseli: Lenharth Systems · CC0 (Openverse / kamu malı) · https://stocksnap.io/photo/computer-hard-2J3PLNMO9M
