277 lines
12 KiB
Markdown
277 lines
12 KiB
Markdown
# Backup-Automation Architektur
|
||
|
||
## Überblick
|
||
|
||
Das System automatisiert Backups aller in Netbox gekennzeichneten Systeme mit:
|
||
- **Borg Backup** für deduplizierte, verschlüsselte Backups
|
||
- **Kestra** für Workflow-Orchestrierung
|
||
- **Ansible** für standardisierte Installation
|
||
- **Rclone** für S3-Replication
|
||
- **Hetzner S3** für Offsite-Storage
|
||
|
||
## Komponenten
|
||
|
||
### 1. Netbox Integration
|
||
- **Quelle der Wahrheit**: Netbox IPAM + Inventar
|
||
- **Markierung**: TAG `backup=true` auf Systemen
|
||
- **API**: REST für dynamische Abfragen
|
||
- **Update-Frequenz**: Täglich
|
||
|
||
### 2. Kestra Orchestration
|
||
- **Rolle**: Zentrale Workflow-Engine
|
||
- **Auslöser**: Systemd Timer (02:00 Uhr täglich)
|
||
- **Aufgaben**:
|
||
1. Netbox abfragen → Liste Backup-Systeme
|
||
2. SSH-Keys prüfen/generieren
|
||
3. Ansible Playbook starten
|
||
4. Status erfassen
|
||
- **Fehlerbehandlung**: Retry-Logik, Notifications
|
||
|
||
### 3. Ansible Automation
|
||
- **Playbooks**:
|
||
- `install-borg-client.yaml` - Clients Setup
|
||
- `configure-backup-server.yaml` - Server Setup
|
||
- `update-backup-config.yaml` - Config Updates
|
||
|
||
- **Roles**:
|
||
- `borg-client` - Borg Installation
|
||
- `backup-server` - Server + Rclone
|
||
|
||
- **Inventory**: Dynamisch aus Netbox (via Kestra)
|
||
|
||
### 4. Borg Backup
|
||
- **Format**: Deduplicating, Encrypting, Compressing Backup
|
||
- **Encryption**: AES-256-CTR
|
||
- **Compression**: LZ4 (schnell) oder Zstd (besser)
|
||
- **Retention**: 7 tägl., 4 wöchentl., 12 monatl.
|
||
- **Repository-Struktur**:
|
||
```
|
||
/backup/repos/{hostname}/
|
||
├── data/
|
||
├── index.*/
|
||
├── hints
|
||
└── nonce
|
||
```
|
||
|
||
### 5. Backup-Server
|
||
- **Rolle**: Zentrale Sammelstelle aller Backups
|
||
- **User**: `backup:backup` mit restricted SSH
|
||
- **Verzeichnis**: `/backup/repos/{hostname}`
|
||
- **SSH-Zugang**: Nur für `borg serve`
|
||
|
||
### 6. Docker-Spezifika
|
||
- **Pre-Backup Hooks**: MySQL/PostgreSQL Dumps
|
||
- **Named Volumes**: Automatisch exportiert
|
||
- **Compose-Dateien**: Backup als YAML
|
||
- **Cleanup**: Alte Dumps regelmäßig löschen
|
||
|
||
### 7. Rclone S3-Sync
|
||
- **Quelle**: `/backup/repos` (Backup-Server)
|
||
- **Ziel**: `hetzner:mbo-backups/production/repos/`
|
||
- **Strategie**: Incremental Sync
|
||
- **Timing**: 04:00 Uhr täglich (nach Borg)
|
||
- **Paralleler**: 4 Transfers, 8 Checkers
|
||
|
||
### 8. Hetzner S3
|
||
- **Bucket**: `mbo-backups`
|
||
- **Struktur**: `production/repos/{hostname}/{archive}`
|
||
- **Versionierung**: Optional aktivierbar
|
||
- **Lifecycle**: Optional für alte Versionen
|
||
|
||
## Datenfluss
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ KESTRA TIMER │
|
||
│ Täglich 02:00 Uhr │
|
||
└────────────────┬─────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ NETBOX API QUERY │
|
||
│ GET /api/dcim/devices/?tag=backup:true │
|
||
│ → [{name, ip, os, status}, ...] │
|
||
└────────────────┬─────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ ANSIBLE INVENTORY GENERATION │
|
||
│ group_vars, host_vars aus Netbox-Daten │
|
||
└────────────────┬─────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ ANSIBLE PLAYBOOK (PARALLEL) │
|
||
│ • install-borg-client.yaml │
|
||
│ • Per Host: SSH-Key, Scripts, Systemd Timer │
|
||
└────────────────┬─────────────────────────────────────────────┘
|
||
│
|
||
┌─────────┴─────────┐
|
||
│ │
|
||
▼ ▼
|
||
┌──────────────────┐ ┌──────────────────────┐
|
||
│ CLIENT HOST 1 │ │ CLIENT HOST 2 │
|
||
│ • borg --version│ │ • borg --version │
|
||
│ • systemd timer │ │ • systemd timer │
|
||
│ • SSH configured│ │ • SSH configured │
|
||
└────────┬─────────┘ └──────────┬───────────┘
|
||
│ │
|
||
│ 03:00 Uhr │
|
||
│ (Systemd Timer) │
|
||
│ │
|
||
▼ ▼
|
||
┌────────────────────────────────────┐
|
||
│ Borg Backup Execution (LOKAL) │
|
||
│ • pre-backup-docker.sh │
|
||
│ • MySQL/PostgreSQL Dumps │
|
||
│ • Volume Exports │
|
||
│ • borg create --stats │
|
||
│ • borg prune (retention) │
|
||
└────────┬─────────────────────────────┘
|
||
│
|
||
│ SSH zum Backup-Server
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ BACKUP-SERVER │
|
||
│ SSH: backup@{BACKUP_SERVER_HOSTNAME} │
|
||
│ Repos: /backup/repos/{hostname}/ │
|
||
│ • Empfängt Borg Archive via SSH │
|
||
│ • Speichert in lokalen Repositories │
|
||
│ • Pre-checks für Deduplizierung │
|
||
└────────────────┬─────────────────────────────────────────────┘
|
||
│
|
||
│ 04:00 Uhr (Systemd Timer)
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ RCLONE SYNC │
|
||
│ rclone sync /backup/repos hetzner:mbo-backups/... │
|
||
│ • Incremental: nur neue/veränderte Blöcke │
|
||
│ • Parallel: 4 transfers │
|
||
│ • Log: /var/log/mbo-backup/rclone-sync.log │
|
||
└────────────────┬─────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ HETZNER S3 │
|
||
│ Bucket: mbo-backups │
|
||
│ Struktur: production/repos/{hostname}/{archive-name} │
|
||
│ • Redundant in mindestens 2 Datacentern │
|
||
│ • Optional: Versioning, Lifecycle Policies │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Timing & Ablauf
|
||
|
||
| Zeit | Komponente | Aktion |
|
||
|------|------------|--------|
|
||
| **02:00** | Kestra Timer | Startet Workflow |
|
||
| 02:05-02:30 | Netbox API | Lädt Liste aller zu backupenden Hosts |
|
||
| 02:30-02:45 | Ansible | Deployed/Updated Borg auf allen Clients |
|
||
| **03:00** | Systemd Timer | Startet Backup auf allen Clients |
|
||
| 03:00-03:45 | Borg | Backups laufen parallel auf allen Hosts |
|
||
| - | Docker Hooks | MySQL/PG Dumps, Volume Exports |
|
||
| - | SSH | Archivs gehen an Backup-Server |
|
||
| **04:00** | Rclone Timer | Startet S3-Sync |
|
||
| 04:00-04:30 | Rclone | Sync zu Hetzner S3 |
|
||
|
||
## Skalierbarkeit
|
||
|
||
### Horizontal (mehr Hosts)
|
||
- **Borg**: Parallelisierung via SSH
|
||
- **Kestra**: Workflow-Engine skaliert linear
|
||
- **Rclone**: Multi-threaded, weitere --transfers falls nötig
|
||
- **S3**: Unbegrenzt
|
||
|
||
### Vertikal (größere Datenmengen)
|
||
- **Borg**: Kompression + Deduplizierung spart 50-70%
|
||
- **Backup-Server**: NVMe für Speed, großes Volume für Speicher
|
||
- **S3**: Skalierung automatic
|
||
|
||
### Parallelität
|
||
```yaml
|
||
Max parallel Backups: Anzahl der Clients × CPU-Kerne
|
||
Empfehlung: Nice-Priorität senken, CPU-Limits setzen
|
||
```
|
||
|
||
## Sicherheit
|
||
|
||
### Verschlüsselung
|
||
- **Borg**: AES-256-CTR Encryption
|
||
- **Passphrase**: Via Ansible Vault gespeichert
|
||
- **Transport**: SSH (Ed25519 Keys)
|
||
|
||
### Zugriffskontrolle
|
||
- **SSH Keys**: Pro Client eindeutig
|
||
- **SSH Restrictions**: `restrict,command=...` auf Server
|
||
- **Backup-User**: Minimal privileges
|
||
- **S3 Credentials**: Via Vault/Secrets
|
||
|
||
### Audit & Logging
|
||
- **Journald**: Alle Backup-Logs in Systemd
|
||
- **Dateilogging**: `/var/log/mbo-backup/*.log`
|
||
- **Rclone**: Detailed Logs für S3-Sync
|
||
- **Kestra**: Workflow Execution History
|
||
|
||
## Fehlerbehandlung
|
||
|
||
### Backup-Fehler
|
||
1. Borg versucht 3x neu (systemd Restart)
|
||
2. Fehler geht in Log
|
||
3. Kestra prüft Exit-Code
|
||
4. Optional: Notification an Admin
|
||
|
||
### SSH-Fehler
|
||
1. SSH retry mit exponential backoff
|
||
2. Key-Rotation wenn nötig
|
||
3. Fallback: Manual trigger
|
||
|
||
### S3-Fehler
|
||
1. Rclone retry mit backoff
|
||
2. Partial sync wird fortgesetzt
|
||
3. Alert bei persistent failure
|
||
|
||
## Monitoring & Observability
|
||
|
||
### Metriken
|
||
- Backup-Größe pro Host
|
||
- Deduplizierung-Ratio
|
||
- Execution-Zeit
|
||
- S3-Upload-Speed
|
||
- Retention-Policy Compliance
|
||
|
||
### Logs
|
||
- Systemd Journal: `journalctl -u mbo-backup`
|
||
- File-basiert: `/var/log/mbo-backup/*.log`
|
||
- Kestra: Execution History
|
||
- Rclone: `--log-level INFO/DEBUG`
|
||
|
||
### Alerting
|
||
- Backup Failure → Alert
|
||
- S3-Sync Failed → Alert
|
||
- Disk Space Low → Alert
|
||
- SSH Key Expiry → Alert (optional)
|
||
|
||
## Disaster Recovery
|
||
|
||
### RTO/RPO Zielsetzungen
|
||
- **RTO** (Recovery Time Objective): < 2 Stunden
|
||
- **RPO** (Recovery Point Objective): < 24 Stunden
|
||
|
||
### Restore-Optionen
|
||
1. **Lokal vom Backup-Server**: Schnell, kein Internet nötig
|
||
2. **Von Hetzner S3**: Geo-redundant, asynchron
|
||
3. **Selective Restore**: Einzelne Dateien/Volumes
|
||
|
||
### Test-Strategie
|
||
- Monatlich: Restore-Drill eines Vollsystems
|
||
- Quarterly: S3-Restore-Test
|
||
- Nach Major Changes: Schnell-Sanity-Check
|
||
|
||
---
|
||
|
||
**Version**: 1.0
|
||
**Stand**: 2026-09-09
|
||
**Nächste Review**: 2026-12-09
|