Back openDesk Edu for a sovereign, open-source education — every vote counts.
Vote nowSave products you love by clicking the heart icon.
Produktionsmuster für Edge Computing mit k3s — Multi-Cluster-Management, Offline-First-Deployments, GitOps und Observability in großem Maßstab.
Disaster Recovery für k3s besteht nicht nur aus Backups – es geht darum, genau zu wissen, wie lange die Wiederherstellung dauern wird, und diesen Prozess zu testen, bevor er tatsächlich benötigt wird. Dieser Artikel behandelt k3s-spezifische DR-Testverfahren, Edge-Computing-Patterns und Tools, die automatisierte Backups und die Wiederherstellung vereinfachen.
k3s enthält den etcd-snapshot-schedule-cron Befehl für automatisierte, periodische Backups des eingebetteten etcd.
Planen Sie Backups alle 6 Stunden mit einer Aufbewahrungsfrist von 7 Tagen:
sudo nano /etc/rancher/k3s/config.yaml
# Add or modify:
etcd-snapshot-schedule-cron: "0 */6 * * *"
etcd-snapshot-retention: 168 # Keep snapshots for 168 hours (7 days)
Starten Sie k3s neu, um die Änderungen zu übernehmen:
sudo systemctl restart k3s
Überprüfen Sie, ob die Snapshots erstellt werden:
# List all snapshots
sudo k3s etcd-snapshot ls
# Example output:
# /var/lib/rancher/k3s/server/db/snapshots/etcd-snapshot-2026-07-11_06-00-00.db
# /var/lib/rancher/k3s/server/db/snapshots/etcd-snapshot-2026-07-11_12-00-00.db
# /var/lib/rancher/k3s/server/db/snapshots/etcd-snapshot-2026-07-11_18-00-00.db
Für unterschiedliche Backup-Intervalle (stündlich für aktuelle Daten, täglich für längere Aufbewahrung):
etcd-snapshot-schedule-cron: |
- "0 * * * *" # Every hour
- "0 0 * * *" # Every day at midnight
etcd-snapshot-retention:
hourly: 24 # Keep hourly snapshots for 24 hours
daily: 30 # Keep daily snapshots for 30 days
Hinweis: Diese erweiterte Syntax erfordert möglicherweise k3s v1.30+.
Konfigurieren Sie den automatischen Upload zu einem S3-kompatiblen Speicher:
# k3s server config
etcd-snapshot-name: "k3s-server-01"
etcd-snapshot-s3: true
etcd-snapshot-s3-endpoint: "s3.amazonaws.com"
etcd-snapshot-s3-bucket: "k3s-backups"
etcd-snapshot-s3-region: "us-east-1"
etcd-snapshot-s3-skip-ssl-verify: false
Setzen Sie die AWS-Credentials:
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"
Starten Sie k3s neu:
sudo systemctl restart k3s
Überprüfen Sie den S3-Upload:
aws s3 ls s3://k3s-backups/
# Example output:
# 2026-07-11 12:00:00 2097152 k3s-server-01-2026-07-11_12-00-00.db
# 2026-07-11 18:00:00 2097152 k3s-server-01-2026-07-11_18-00-00.db
Sicherheitshinweis: etcd-Snapshots enthalten Cluster-Secrets (Service Accounts, Tokens, Zertifikate). Aktivieren Sie die serverseitige S3-Verschlüsselung auf dem Bucket (SSE-S3 oder SSE-KMS) und beschränken Sie einen dedizierten IAM-Benutzer nur auf s3:PutObject/s3:GetObject für das Backup-Präfix. Ein öffentlicher Backup-Bucket ist eine Sicherheitslücke, die nur darauf wartet, ausgenutzt zu werden.
Das Testen des Failovers für das eingebettete etcd validiert, dass Ihr k3s-Cluster sich von einem vollständigen Ausfall der Control Plane erholen kann.
Ziel: Wiederherstellung des k3s-Servers aus einem etcd-Snapshot und Verifizierung des Cluster-Zustands.
Voraussetzungen:
k3s etcd-snapshot ls)Vorgehensweise:
# Create test namespace and deployment
kubectl create namespace dr-test
kubectl create deployment nginx-test --image=nginx -n dr-test
kubectl get pods -n dr-test
# Take snapshot before failure
sudo k3s etcd-snapshot save --name "pre-failure-test"
# Stop k3s
sudo systemctl stop k3s
# Backup corrupted etcd (for recovery attempt)
sudo cp /var/lib/rancher/k3s/server/db/etcd /var/lib/rancher/k3s/server/db/etcd.corrupted
# Corrupt etcd data
sudo rm /var/lib/rancher/k3s/server/db/etcd
# Restore from snapshot
sudo k3s server \
--cluster-reset \
--cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/pre-failure-test.db
# Start k3s
sudo systemctl start k3s
# Verify cluster health
sudo k3s kubectl get nodes
sudo k3s kubectl get pods -n dr-test
Readynginx-test Pod existiert und läuft# Time from failure start to restore completion
# Typical RTO: 2-5 minutes for embedded etcd on small clusters
Ziel: Test des etcd HA Failovers in einem k3s-Cluster mit 3 Servern.
Voraussetzungen:
Vorgehensweise:
# Check all nodes
kubectl get nodes -o wide
# Check etcd members
sudo k3s etcd-snapshot status
# Verify k3s cluster-ID consistency across servers
sudo k3s kubectl get configmap -n kube-system cluster-config -o yaml
# On server 1
sudo systemctl stop k3s
# On server 2 or 3 (surviving server)
kubectl get nodes
# Expected: server1 shows NotReady, server2 and server3 Ready
# Verify etcd quorum
sudo k3s etcd-snapshot status
# Expected: 2/3 members healthy (quorum maintained)
# Create test resource
kubectl create namespace failover-test
kubectl run test-pod --image=nginx -n failover-test
# Verify pod scheduled
kubectl get pods -n failover-test -o wide
# Expected: Pod scheduled on surviving node
# On server 1
sudo systemctl start k3s
# Verify cluster re-joins
kubectl get nodes
# Expected: All 3 nodes Ready
# Verify etcd membership
sudo k3s etcd-snapshot status
# Expected: 3/3 members healthy
# Time from server1 stop to cluster quorum maintained
# Typical RTO: 30-90 seconds for embedded etcd HA
Für k3s-Cluster, die ein externes PostgreSQL anstelle von eingebettetem etcd verwenden.
Ziel: Testen des k3s-Verhaltens beim Ausfall des PostgreSQL-Primärknotens.
Voraussetzungen:
Vorgehensweise:
# Check k3s cluster health
kubectl get nodes
sudo k3s kubectl get pods -A
# Check PostgreSQL cluster status
patronictl -c /etc/patroni/patroni.yml list
# Stop PostgreSQL primary
sudo systemctl stop postgresql
# On PostgreSQL replica (now primary)
# Verify automatic failover occurred
patronictl -c /etc/patroni/patroni.yml list
# Expected: New primary elected, replica promoted
# Create test deployment
kubectl create deployment test-deploy --image=nginx
# Verify deployment succeeds
kubectl get pods
# Expected: Pods scheduled successfully
# Time from PostgreSQL primary stop to k3s operations resume
# Typical RTO: 1-3 minutes (depends on Patroni failover time)
Ziel: Wiederherstellung von PostgreSQL aus einem Backup und Recovery des k3s-Clusters.
Voraussetzungen:
Vorgehensweise:
# Stop k3s servers
sudo systemctl stop k3s
# Drop and recreate PostgreSQL database
sudo -u postgres psql -c "DROP DATABASE IF EXISTS k3s;"
sudo -u postgres psql -c "CREATE DATABASE k3s;"
# Restore from backup
sudo -u postgres psql k3s < /backup/k3s-postgres-backup.sql
# Start k3s servers
sudo systemctl start k3s
# Verify cluster recovery
kubectl get nodes
kubectl get pods -A
Edge Computing bringt spezifische Herausforderungen für das Disaster Recovery (DR) mit sich: intermittierende Konnektivität, begrenzte Bandbreite und physisch verteilte Standorte.
Rancher Fleet verwaltet mehrere k3s-Cluster zentral. Die DR-Patterns unterscheiden sich hierbei von Single-Cluster-Szenarien.
Alle Edge-Cluster übertragen ihre Backups an ein zentrales Repository, um ein zentralisiertes Recovery-Management zu ermöglichen.
Architektur:
Edge Site 1 (k3s) ----\
Edge Site 2 (k3s) ----+--> S3 Central Repository ----> Recovery Workstation
Edge Site 3 (k3s) ----/ |
Backup Validation
Implementierung:
# Fleet cluster template for edge sites
apiVersion: v1
kind: ConfigMap
metadata:
name: k3s-backup-config
namespace: cattle-system
data:
config.yaml: |
etcd-snapshot-schedule-cron: "0 */4 * * *"
etcd-snapshot-retention: 96 # 4 days
etcd-snapshot-s3: true
etcd-snapshot-s3-endpoint: "s3.eu-central-1.amazonaws.com" etcd-snapshot-s3-bucket: "edge-k3s-backups" etcd-snapshot-s3-region: "eu-central-1"
**Deployment via Fleet**:
```bash
# Auf alle Edge-Cluster anwenden
fleetctl apply -f fleet-cluster-template.yaml
# Backup über alle Standorte hinweg überprüfen
aws s3 ls s3://edge-k3s-backups/ --recursive
# Beispielausgabe:
# 2026-07-11 08:00:00 2097152 edge-site-01/k3s-etcd-snapshot.db
# 2026-07-11 08:00:00 2097152 edge-site-02/k3s-etcd-snapshot.db
# 2026-07-11 12:00:00 2097152 edge-site-01/k3s-etcd-snapshot.db
# 2026-07-11 12:00:00 2097152 edge-site-02/k3s-etcd-snapshot.db
For edge sites with intermittent connectivity, local backups with periodic sync ensures durability.
Implementation:
#!/bin/bash
# /usr/local/bin/edge-backup-sync.sh
# 1. Lokalen etcd-Snapshot erstellen
sudo k3s etcd-snapshot save --name "$(date +%Y-%m-%d_%H-%M-%S)"
# 2. Konnektivität zum zentralen Repository prüfen
if ping -c 1 central-repo.example.com &> /dev/null; then
# 3. Aktuelle Snapshots hochladen
for snapshot in /var/lib/rancher/k3s/server/db/snapshots/*.db; do
aws s3 cp "$snapshot" "s3://edge-k3s-backups/$(hostname)/" --only-newer
done
else
logger "Zentrales Repository nicht erreichbar, lokale Backups werden beibehalten"
fi
# 4. Alte lokale Snapshots bereinigen (24 Stunden aufbewahren)
find /var/lib/rancher/k3s/server/db/snapshots/ -name "*.db" -mtime +1 -delete
Add to cron:
# crontab -e
# Alle 2 Stunden
0 */2 * * * /usr/local/bin/edge-backup-sync.sh
Edge computing requires careful RPO (Recovery Point Objective) and RTO (Recovery Time Objective) planning due to connectivity constraints. Derive the targets from business numbers, not defaults: estimate the cost of an hour of downtime, compare it with the cost of more frequent snapshots, and pick targets you can actually meet and measure. As a rule of thumb, 99.9% availability allows ~8.8 hours of downtime per year; 99.99% allows ~53 minutes. The scenarios below assume targets are measured, not aspirational.
| Scenario | Network | RPO | RTO | Strategy |
|---|---|---|---|---|
| Urban edge | Fiber 1Gbps | 15 min | 30 min | Frequent snapshots + S3 sync |
| Rural edge | LTE 10Mbps | 2 hours | 4 hours | Local backup + daily sync |
| Offline edge | No connectivity | 24 hours | Manual | Local backup + on-site recovery kit |
| Satellite edge | Satellite 2Mbps | 4 hours | 8 hours | Compressed backups + scheduled sync |
Complete site recovery from scratch (hardware failure, natural disaster).
Recovery Kit Preparation:
# /opt/dr-recovery-kit/README.md
# Inhalt des Recovery Kits:
# 1. Aktuellste k3s-Binary und Konfiguration
# 2. etcd-Snapshot aus S3
# 3. Backups persistenter Volumes (falls vorhanden)
# 4. Netzwerk-Konfigurationsskripte
# 5. DR-Runbook mit Schritt-für-Schritt-Anleitungen
# Recovery-Verfahren:
# 1. Neue Hardware oder VM bereitstellen
# 2. k3s aus dem Recovery Kit installieren
# 3. etcd aus Snapshot wiederherstellen
# 4. Persistente Volumes wiederherstellen (falls vorhanden)
# 5. Cluster-Health überprüfen
# 6. Applikations-Konnektivität testen
Automated Recovery Script:
#!/bin/bash
# /opt/dr-recovery-kit/recover-site.sh
set -e
SITE_ID="edge-site-01"
K3S_VERSION="v1.30.0+k3s1"
SNAPSHOT_NAME="k3s-latest.db"
S3_BUCKET="edge-k3s-backups"
echo "Starte Site-Recovery für $SITE_ID..."
# 1. Aktuellsten Snapshot herunterladen
aws s3 cp "s3://$S3_BUCKET/$SITE_ID/$SNAPSHOT_NAME" /tmp/
# 2. k3s installieren
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="$K3S_VERSION" sh -
# 3. k3s für Recovery konfigurieren
cat <<EOF | sudo tee /etc/rancher/k3s/config.yaml
cluster-reset: true
cluster-reset-restore-path: /tmp/$SNAPSHOT_NAME
EOF
# 4. k3s starten
sudo systemctl start k3s
# 5. Warten, bis k3s bereit ist
until sudo k3s kubectl get nodes &> /dev/null; do
echo "Waiting for k3s to start..."
sleep 5
done
# 6. Cluster-Health überprüfen
sudo k3s kubectl get nodes
sudo k3s kubectl get pods -A
echo "Site recovery complete!"
etcd snapshots only cover cluster state. For application data in persistent volumes, use Restic for backup and recovery.
# Install restic
wget https://github.com/restic/restic/releases/download/v0.16.0/restic_0.16.0_linux_amd64.bz2
bunzip2 restic_0.16.0_linux_amd64.bz2
sudo mv restic_0.16.0_linux_amd64 /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic
# Initialize restic repository (S3)
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/k3s-pv-backups"
export RESTIC_PASSWORD="your-secure-password"
restic init
# Exclude k3s system directories (no need to backup)
cat <<EOF > /tmp/restic-excludes.txt
/var/lib/rancher/k3s/server/db/etcd
/var/lib/rancher/k3s/agent/containerd/io.containerd.content.v1.content
/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs
EOF
# Backup k3s persistent volumes
restic backup /var/lib/rancher/k3s/agent/pv --exclude-file=/tmp/restic-excludes.txt --tag "pv-backup"
#!/bin/bash
# /usr/local/bin/k3s-pv-backup.sh
set -e
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/k3s-pv-backups"
export RESTIC_PASSWORD="your-secure-password"
# Backup only mounted PVs
for mount in $(findmnt -l | grep /var/lib/rancher/k3s/agent/pv | awk '{print $1}'); do
pod_name=$(echo "$mount" | cut -d/ -f7)
pv_name=$(echo "$mount" | cut -d/ -f6)
echo "Backing up PV: $pv_name (pod: $pod_name)"
restic backup "$mount" \
--exclude-file=/tmp/restic-excludes.txt \
--tag "pv-backup" \
--tag "pv:$pv_name" \
--tag "pod:$pod_name"
done
# Prune old backups (keep 30 days)
restic forget --keep-daily 30 --prune
# Check repository integrity
restic check
Schedule daily backups:
# crontab -e
0 2 * * * /usr/local/bin/k3s-pv-backup.sh >> /var/log/k3s-pv-backup.log 2>&1
# Find backup snapshot
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/k3s-pv-backups"
export RESTIC_PASSWORD="your-secure-password"
# List snapshots
restic snapshots --tag "pv:my-app-pv"
# Restore specific PV
restic restore latest --tag "pv:my-app-pv" --target /var/lib/rancher/k3s/agent/pv/my-app-pv
# Restart affected pods to pick up restored data
kubectl delete pod -l app=my-app --force --grace-period=0
Die oben beschriebenen Verfahren sind nur so gut wie ihre letzte Ausführung. Ein Backup, das noch nie wiederhergestellt wurde, ist kein Backup. DR-Tests sind Chaos Engineering für die Infrastruktur: Man injiziert bewusst Fehler (den falschen Node stoppen, die falsche Datei korrumpieren, den falschen Snapshot ziehen) und beobachtet, ob sich das System erholt. Dieselbe Lektion, die für Software-Engines gilt, gilt auch hier — beispielbasiertes Testen findet das, woran man gedacht hat; Fault Injection findet das, woran man nicht gedacht hat. Ein geplanter Snapshot, der nie auf seine Wiederherstellbarkeit geprüft wurde, ist genau die Falle der „existierenden, aber nicht durchgesetzten Konfiguration“: Er erzeugt falsches Vertrauen.
„Typisches RTO: 2–5 Minuten“ ist eine Behauptung, kein Fakt. Messen Sie die tatsächliche Wiederherstellungszeit in Ihrer Umgebung, auf Ihrer Hardware und mit Ihrem Netzwerk:
time jeden Wiederherstellungsschritt und dokumentieren Sie ihn im RunbookEin Restore-Verfahren muss idempotent sein: Wenn es zweimal auf demselben Host ausgeführt wird, darf dies den Zustand nicht korrumpieren. Wenn ein Restore-Skript von einem sauberen Zustand ausgeht, ein vorheriger Restore jedoch Artefakte hinterlassen hat, wird dieser Vertragsbruch um 3 Uhr morgens während eines echten Vorfalls auftreten und nicht während einer Routineübung im „Happy-Path“. Testen Sie diesen Vertrag explizit: Führen Sie den Restore aus, führen Sie ihn erneut aus und stellen Sie sicher, dass der Cluster-Health in beiden Fällen identisch ist.
Die folgende Checkliste sollte durch Automatisierung erzwungen werden, nicht durch das Gedächtnis:
restic check läuft jede Nacht und meldet Fehler (Repository-Integrität)Bevor die DR-Strategie als produktionsbereit erklärt wird, führen Sie die vollständige Übung dreimal mit drei aufeinanderfolgenden erfolgreichen Durchläufen durch – einschließlich mindestens eines Restores auf einen frischen Host (nicht dieselbe VM, die Sie korrumpiert haben). Zwei Durchläufe können Glück sein; drei sind ein Muster.
Quartalsweise Übungen verifizieren Ihre Verfahren; ein wöchentlich geplanter Restore verifiziert Ihre Snapshots. Richten Sie einen Cron-Job ein, der den neuesten etcd-Snapshot nimmt, einen temporären k3s-Cluster (gleiche Version) bereitstellt, die Daten dort wiederherstellt, Health-Checks durchführt und den Cluster anschließend wieder löscht. Wenn ein Snapshot korrupt ist – was Stunden später durch das Scheitern von kubectl get nodes in der Sandbox entdeckt wird –, haben Sie eine Woche an Snapshots, auf die Sie zurückgreifen können, anstatt ein Quartal voller falscher Sicherheit. Der Sandbox-Restore ist zudem das perfekte Übungsfeld für recover-site.sh: Jede Woche wird genau das Skript trainiert, das Sie während eines echten Vorfalls ausführen werden.
Bevor Sie Ihre DR-Strategie als produktionsbereit erklären, validieren Sie jede Komponente.
Standardisieren Sie Ihre DR-Verfahren mit einer Runbook-Vorlage.
# k3s Disaster Recovery Runbook
## 1. Incident Detection
**Triggers**:
- k3s server down
- etcd corruption detected
- PostgreSQL primary unavailable
- Complete site outage
**Verification**:
```bash
sudo systemctl status k3s
sudo k3s kubectl get nodes
sudo k3s etcd-snapshot status
```
Business Impact:
Technischer Impact:
RTO: 2-5 Minuten Anwendungsfall: Embedded etcd, aktueller Snapshot verfügbar
Schritte:
sudo systemctl stop k3s]sudo k3s server --cluster-reset --cluster-reset-restore-path=/path/to/snapshot.db]sudo systemctl start k3s]kubectl get nodes]RTO: 5-10 Minuten Anwendungsfall: Externes PostgreSQL, Patroni Failover fehlgeschlagen
Schritte:
sudo systemctl stop k3s]psql k3s < /backup/k3s-backup.sql]sudo systemctl start k3s]kubectl get pods -A]RTO: 30-60 Minuten Anwendungsfall: Vollständiger Standortausfall, Hardware-Austausch erforderlich
Schritte:
/opt/dr-recovery-kit/recover-site.sh]Validierungsschritte:
Incident Timeline:
Ursache (Root Cause):
Präventivmaßnahmen:
Benachrichtigte Stakeholder:
Kommunikationskanäle:
Was gut lief:
Was verbessert werden kann:
Updates für das DR-Runbook:
## Further Reading
- [k3s in Production: Upgrades, Backup, and Disaster Recovery](/content/devops/k3s-production-upgrades-backup-dr/) — Comprehensive production patterns for k3s
- [Disaster Recovery Self-Hosted](/content/devops/disaster-recovery-self-hosted/) — Generic DR patterns for self-hosted infrastructure
- [Edge Computing Patterns with k3s](/content/devops/edge-computing-patterns-k3s/) — Multi-cluster management with Rancher Fleet
---
Regular DR testing is the difference between a minor outage and a catastrophic failure. Schedule quarterly DR drills, measure your actual RTO, and update your runbook with lessons learned.