K3s ile Kubernetes Kurulumu: Hafif Konteyner Orkestrasyonu
K3s ile tek node ve çok node Kubernetes cluster kurulumu, kubectl kullanımı, deployment ve service oluşturma, Helm ile uygulama yönetimi. VPS üzerinde Kubernetes rehberi.
Docker volume yedekleme, konteyner state yedekleme, Kubernetes persistent volume yedekleme, Velero ile K8s yedekleme, otomatik yedekleme scriptleri ve disaster recovery planlaması.
Konteyner ortamlarında yedekleme, geleneksel sunucu yedeklemesinden farklı bir yaklaşım gerektirir. Konteynerler geçici olduğundan, yedeklenmesi gereken şey konteyner kendisi değil, içindeki verilerdir. Bu rehberde Docker ve Kubernetes ortamları için kapsamlı yedekleme stratejilerini ele alacağız.
| Strateji | Uygun Durum | Araç |
|---|---|---|
| Volume yedekleme | Veritabanı, dosya depolama | tar, rsync |
| Image yedekleme | Uygulama durumu | docker save |
| Snapshot | Hızlı kurtarma | LVM, ZFS |
| K8s yedekleme | Tüm cluster | Velero |
| Uzak yedekleme | Disaster recovery | Restic, Rclone |
# Volume'u tar arşivine yedekle
docker run --rm \
-v VOLUME_ADI:/data \
-v $(pwd):/backup \
alpine tar czf /backup/volume-backup-$(date +%Y%m%d).tar.gz -C /data .
# Örnek: MySQL volume yedekleme
docker run --rm \
-v mysql-data:/data \
-v /backups:/backup \
alpine tar czf /backup/mysql-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
# Volume'u geri yükle
docker run --rm \
-v mysql-data:/data \
-v /backups:/backup \
alpine tar xzf /backup/mysql-20240101-120000.tar.gz -C /data
# MySQL dump (konteyner çalışırken)
docker exec mysql-db mysqldump \
-u root -pGucluSifre123! \
--all-databases \
--single-transaction \
> /backups/mysql-dump-$(date +%Y%m%d).sql
# PostgreSQL dump
docker exec postgres-db pg_dumpall \
-U postgres \
> /backups/postgres-dump-$(date +%Y%m%d).sql
# Redis dump
docker exec redis-db redis-cli BGSAVE
docker cp redis-db:/data/dump.rdb /backups/redis-$(date +%Y%m%d).rdb
#!/bin/bash
# /usr/local/bin/docker-backup.sh
BACKUP_DIR="/backups/docker"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=7
# Yedekleme dizini oluştur
mkdir -p "$BACKUP_DIR"
# Tüm volume'ları yedekle
for volume in $(docker volume ls -q); do
echo "Yedekleniyor: $volume"
docker run --rm \
-v "$volume":/data \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/${volume}-${DATE}.tar.gz" -C /data . 2>/dev/null
if [ $? -eq 0 ]; then
echo "Başarılı: $volume"
else
echo "HATA: $volume yedeklenemedi" >&2
fi
done
# MySQL veritabanlarını yedekle
if docker ps --format '{{.Names}}' | grep -q mysql; then
docker exec mysql-db mysqldump \
-u root -pGucluSifre123! \
--all-databases \
--single-transaction \
> "$BACKUP_DIR/mysql-${DATE}.sql"
echo "MySQL yedeklendi"
fi
# Eski yedekleri temizle
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.sql" -mtime +$RETENTION_DAYS -delete
echo "Yedekleme tamamlandı: $DATE"
# Script'i çalıştırılabilir yap
chmod +x /usr/local/bin/docker-backup.sh
# Cron ile günlük yedekleme
crontab -e
# 0 2 * * * /usr/local/bin/docker-backup.sh >> /var/log/docker-backup.log 2>&1
# Restic kur
apt install -y restic
# Repository başlat (yerel)
restic init --repo /backups/restic-repo
# Repository başlat (S3 uyumlu)
export AWS_ACCESS_KEY_ID=ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=SECRET_KEY
restic init --repo s3:https://s3.example.com/bucket-name
# Volume yedekle
docker run --rm \
-v mysql-data:/data \
-v /tmp/mysql-backup:/backup \
alpine tar czf /backup/mysql.tar.gz -C /data .
restic backup /tmp/mysql-backup \
--repo /backups/restic-repo \
--password-file /etc/restic/password \
--tag mysql,docker
# Yedekleri listele
restic snapshots --repo /backups/restic-repo
# Geri yükle
restic restore SNAPSHOT_ID \
--repo /backups/restic-repo \
--target /tmp/restore
# Eski yedekleri temizle (7 günden eski)
restic forget \
--repo /backups/restic-repo \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 3 \
--prune
# Image'ı tar dosyasına kaydet
docker save myapp:latest | gzip > /backups/myapp-$(date +%Y%m%d).tar.gz
# Birden fazla image
docker save myapp:latest nginx:1.25 mysql:8.0 | gzip > /backups/images-$(date +%Y%m%d).tar.gz
# Image'ı geri yükle
docker load < /backups/myapp-20240101.tar.gz
# Tüm image'ları yedekle
for image in $(docker images --format '{{.Repository}}:{{.Tag}}' | grep -v '<none>'); do
filename=$(echo $image | tr '/:' '_')
docker save $image | gzip > "/backups/images/${filename}-$(date +%Y%m%d).tar.gz"
done
# Velero CLI kur
wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz
tar xzf velero-v1.12.0-linux-amd64.tar.gz
mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/
# MinIO (S3 uyumlu) ile Velero kur
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket velero-backups \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--backup-location-config region=minio,s3ForcePathStyle=true,s3Url=http://minio:9000
# Tüm cluster'ı yedekle
velero backup create full-backup --wait
# Belirli namespace'i yedekle
velero backup create production-backup \
--include-namespaces production \
--wait
# Belirli kaynakları yedekle
velero backup create app-backup \
--include-namespaces production \
--include-resources deployments,services,configmaps,secrets \
--wait
# Yedekleri listele
velero backup get
# Yedek detaylarını görüntüle
velero backup describe full-backup
# Yedekten geri yükle
velero restore create --from-backup full-backup
# Belirli namespace'i geri yükle
velero restore create \
--from-backup production-backup \
--include-namespaces production
# Günlük yedekleme (gece 2'de)
velero schedule create daily-backup \
--schedule="0 2 * * *" \
--ttl 168h # 7 gün saklama
# Haftalık tam yedekleme
velero schedule create weekly-backup \
--schedule="0 1 * * 0" \
--ttl 720h # 30 gün saklama
# Zamanlanmış yedekleri listele
velero schedule get
# PVC'yi yedekle (pod durdurularak)
kubectl scale deployment myapp --replicas=0
# PVC'yi geçici pod ile yedekle
kubectl run backup-pod \
--image=alpine \
--restart=Never \
--overrides='{
"spec": {
"volumes": [{"name": "data", "persistentVolumeClaim": {"claimName": "myapp-data"}}],
"containers": [{
"name": "backup",
"image": "alpine",
"command": ["tar", "czf", "/backup/data.tar.gz", "-C", "/data", "."],
"volumeMounts": [{"name": "data", "mountPath": "/data"}]
}]
}
}'
# Yedek dosyasını al
kubectl cp backup-pod:/backup/data.tar.gz ./data-backup.tar.gz
# Pod'u temizle
kubectl delete pod backup-pod
# Deployment'ı yeniden başlat
kubectl scale deployment myapp --replicas=1
# RTO (Recovery Time Objective) ve RPO (Recovery Point Objective) belirle
# RTO: Sistemin ne kadar sürede kurtarılması gerekiyor?
# RPO: En fazla ne kadar veri kaybı kabul edilebilir?
# Yedekleme doğrulama script'i
#!/bin/bash
BACKUP_FILE="$1"
if [ -z "$BACKUP_FILE" ]; then
echo "Kullanım: $0 <backup_file>"
exit 1
fi
# Arşiv bütünlüğünü kontrol et
if tar tzf "$BACKUP_FILE" > /dev/null 2>&1; then
echo "Yedek dosyası geçerli: $BACKUP_FILE"
else
echo "HATA: Yedek dosyası bozuk: $BACKUP_FILE"
exit 1
fi
# Test ortamında geri yükleme testi
docker volume create test-restore
docker run --rm \
-v test-restore:/data \
-v $(dirname $BACKUP_FILE):/backup \
alpine tar xzf "/backup/$(basename $BACKUP_FILE)" -C /data
echo "Geri yükleme testi başarılı"
docker volume rm test-restore
Konteyner yedekleme stratejisi, iş gereksinimlerinize göre şekillendirilmelidir. Küçük ortamlar için volume yedekleme + cron yeterli olabilirken, production Kubernetes cluster'ları için Velero gibi özel araçlar gereklidir. REXE sunucularında düzenli yedekleme ve geri yükleme testleri ile verilerinizi güvende tutabilirsiniz.
Yedekleme sıklığı RPO (Recovery Point Objective) hedefine göre belirlenir. Kritik veritabanları için saatlik veya daha sık, uygulama verileri için günlük, statik içerik için haftalık yedekleme önerilir. Yedekleme sıklığını artırmak disk alanı ve I/O yükünü artırır, bu dengeyi göz önünde bulundurun.
Veritabanları için mümkünse durdurulmadan yedekleme önerilir: MySQL için mysqldump --single-transaction, PostgreSQL için pg_dump kullanın. Dosya sistemi yedeklemelerinde tutarlılık için kısa süreli durdurma gerekebilir. Kritik sistemlerde read replica üzerinden yedekleme alın.
velero backup describe BACKUP_ADI komutu ile yedek durumunu kontrol edin. Düzenli olarak test ortamında velero restore create --from-backup BACKUP_ADI ile geri yükleme testi yapın. Velero ayrıca yedek bütünlüğünü otomatik olarak doğrular.
3-2-1 kuralını uygulayın: 3 kopya, 2 farklı medya, 1 uzak lokasyon. Yerel disk + uzak S3 uyumlu depolama (MinIO, AWS S3, Backblaze B2) kombinasyonu önerilir. Yedekleri şifreleyin (Restic varsayılan olarak şifreler). Aynı sunucuda yedek saklamaktan kaçının.
İki şeyi yedeklemeniz gerekir: 1) docker-compose.yml ve .env dosyaları (Git'te saklanmalı), 2) Volume verileri (tar ile yedekleme). Tüm stack'i yedeklemek için her volume'u ayrı ayrı yedekleyin. Geri yükleme için önce docker-compose up ile stack'i başlatın, sonra volume verilerini geri yükleyin.
K3s ile tek node ve çok node Kubernetes cluster kurulumu, kubectl kullanımı, deployment ve service oluşturma, Helm ile uygulama yönetimi. VPS üzerinde Kubernetes rehberi.
Docker volume türleri (named, bind mount, tmpfs), volume yönetimi, Docker network modları (bridge, host, overlay), özel ağ oluşturma ve konteyner iletişimi. Kapsamlı rehber.
Docker log sürücüleri, docker logs komutu, Kubernetes pod logları, merkezi log toplama (Loki, ELK Stack), log rotasyonu ve production ortamında log yönetimi en iyi pratikleri.