💾 Backup & Recovery — Arkalia-LUNA¶
Stratégie complète de sauvegarde et récupération pour Arkalia-LUNA — Protection des données critiques, snapshots automatisés et récupération d'urgence.
🎯 Stratégie de Sauvegarde Arkalia-LUNA¶
Architecture 3-2-1 Adaptée IA¶
- 3 copies des données critiques
- 2 supports de stockage différents
- 1 copie hors site (cloud chiffré)
- + Validation automatique intégrité
Données Critiques Identifiées¶
Type de Données | Localisation | Criticité | Fréquence Backup |
---|---|---|---|
États IA | modules/*/state/*.toml |
🔴 CRITIQUE | Temps réel |
Configurations | config/*.toml , .env |
🔴 CRITIQUE | 6h |
Modèles LLM | /var/lib/ollama/models/ |
🟧 ÉLEVÉE | 24h |
Logs Audit | logs/*.log |
🟧 ÉLEVÉE | 12h |
Code Source | Git repository | 🟨 MOYENNE | Push temps réel |
Base de données | States JSON/TOML | 🔴 CRITIQUE | 1h |
🔄 Snapshots Automatisés¶
Snapshot États IA (Temps Réel)¶
#!/bin/bash
# scripts/ark_realtime_snapshot.sh
SNAPSHOT_DIR="/backup/realtime"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Fonction snapshot atomique
create_atomic_snapshot() {
local source="$1"
local dest="$2"
local temp_file="${dest}.tmp.${TIMESTAMP}"
# Copie atomique avec validation
cp "$source" "$temp_file" && \
python -c "import toml; toml.load('$temp_file')" && \
mv "$temp_file" "$dest" && \
echo "✅ Snapshot: $(basename $dest)"
}
# Snapshot tous états critiques
for state_file in modules/*/state/*.toml state/*.toml global_state/*.toml; do
if [ -f "$state_file" ]; then
relative_path=${state_file#*/}
backup_path="$SNAPSHOT_DIR/$relative_path.$TIMESTAMP"
mkdir -p "$(dirname "$backup_path")"
create_atomic_snapshot "$state_file" "$backup_path"
fi
done
# Nettoyage snapshots > 7 jours
find "$SNAPSHOT_DIR" -name "*.toml.*" -mtime +7 -delete
echo "📸 Snapshot temps réel terminé: $TIMESTAMP"
Snapshot Système Complet (Journalier)¶
#!/bin/bash
# scripts/ark_full_backup.sh
BACKUP_ROOT="/backup/daily"
DATE=$(date +%Y%m%d)
BACKUP_DIR="$BACKUP_ROOT/arkalia_$DATE"
echo "🏗️ BACKUP COMPLET ARKALIA-LUNA - $DATE"
# Création répertoire horodaté
mkdir -p "$BACKUP_DIR"
# 1. États et configurations (priorité max)
echo "💾 Sauvegarde états IA..."
tar -czf "$BACKUP_DIR/arkalia_states_$DATE.tar.gz" \
modules/*/state/ \
state/ \
global_state/ \
config/ \
.env 2>/dev/null
# 2. Logs système et audit
echo "📋 Sauvegarde logs..."
tar -czf "$BACKUP_DIR/arkalia_logs_$DATE.tar.gz" \
logs/ \
modules/*/logs/ 2>/dev/null
# 3. Modèles LLM (si modifiés)
if [ -d "/var/lib/ollama/models" ]; then
echo "🧠 Sauvegarde modèles LLM..."
tar -czf "$BACKUP_DIR/ollama_models_$DATE.tar.gz" \
-C /var/lib/ollama models/ 2>/dev/null
fi
# 4. Configurations Docker et scripts
echo "🐳 Sauvegarde infrastructure..."
tar -czf "$BACKUP_DIR/arkalia_infra_$DATE.tar.gz" \
docker-compose.yml \
Dockerfile* \
scripts/ \
.github/ \
requirements.txt \
pyproject.toml 2>/dev/null
# 5. Génération checksums intégrité
cd "$BACKUP_DIR"
sha256sum *.tar.gz > "checksums_$DATE.sha256"
# 6. Métadonnées backup
cat > "backup_manifest_$DATE.json" << EOF
{
"backup_date": "$(date -Iseconds)",
"arkalia_version": "$(cat version.toml | grep current_version | cut -d'"' -f2)",
"backup_size_mb": $(du -sm "$BACKUP_DIR" | cut -f1),
"files_count": $(find "$BACKUP_DIR" -type f | wc -l),
"git_commit": "$(git rev-parse HEAD)",
"host": "$(hostname)",
"backup_type": "full_daily"
}
EOF
echo "✅ Backup complet terminé: $BACKUP_DIR"
# Nettoyage backups > 30 jours
find "$BACKUP_ROOT" -name "arkalia_*" -type d -mtime +30 -exec rm -rf {} \;
🔐 Chiffrement et Sécurité¶
Chiffrement Backups Sensibles¶
#!/bin/bash
# scripts/ark_encrypted_backup.sh
GPG_RECIPIENT="arkalia-backup@system.local"
ENCRYPTED_DIR="/backup/encrypted"
# Fonction chiffrement GPG
encrypt_backup() {
local source="$1"
local encrypted_name="${source##*/}.gpg"
gpg --trust-model always --encrypt \
--recipient "$GPG_RECIPIENT" \
--output "$ENCRYPTED_DIR/$encrypted_name" \
"$source"
# Vérification intégrité
if gpg --decrypt "$ENCRYPTED_DIR/$encrypted_name" | sha256sum > /tmp/verify.sha; then
echo "✅ Backup chiffré validé: $encrypted_name"
else
echo "❌ Erreur chiffrement: $encrypted_name"
return 1
fi
}
# Chiffrement états critiques
for backup in /backup/daily/arkalia_*/arkalia_states_*.tar.gz; do
if [ -f "$backup" ]; then
encrypt_backup "$backup"
fi
done
Stockage Sécurisé Distant¶
#!/bin/bash
# scripts/ark_remote_sync.sh
REMOTE_BACKUP="user@backup-server:/secure/arkalia/"
ENCRYPTED_DIR="/backup/encrypted"
# Synchronisation chiffrée vers site distant
rsync -avz --progress --delete \
--exclude="*.tmp" \
"$ENCRYPTED_DIR/" \
"$REMOTE_BACKUP"
echo "🌐 Synchronisation distante terminée"
🚀 Procédures de Récupération¶
Récupération État IA Critique¶
#!/bin/bash
# scripts/ark_emergency_restore.sh
restore_critical_state() {
local module="$1"
local backup_date="$2"
echo "🔄 RESTAURATION URGENTE: $module"
# Arrêt service concerné
docker stop "$module" 2>/dev/null
# Sauvegarde état actuel (corrompu)
cp "modules/$module/state/${module}_state.toml" \
"/tmp/${module}_corrupted_$(date +%s).toml" 2>/dev/null
# Recherche backup le plus récent
if [ -n "$backup_date" ]; then
BACKUP_FILE="/backup/daily/arkalia_$backup_date/arkalia_states_$backup_date.tar.gz"
else
BACKUP_FILE=$(find /backup/daily -name "arkalia_states_*.tar.gz" | sort -r | head -1)
fi
if [ ! -f "$BACKUP_FILE" ]; then
echo "❌ Aucun backup trouvé"
return 1
fi
# Extraction et restauration
cd /tmp
tar -xzf "$BACKUP_FILE" "modules/$module/state/" 2>/dev/null
if [ -f "/tmp/modules/$module/state/${module}_state.toml" ]; then
# Validation avant restauration
python -c "import toml; toml.load('/tmp/modules/$module/state/${module}_state.toml')" || {
echo "❌ Backup TOML invalide"
return 1
}
# Restauration effective
cp "/tmp/modules/$module/state/${module}_state.toml" \
"modules/$module/state/${module}_state.toml"
# Redémarrage service
docker start "$module"
sleep 5
echo "✅ $module restauré depuis: $(basename $BACKUP_FILE)"
docker logs "$module" --tail 10
else
echo "❌ État $module non trouvé dans backup"
return 1
fi
}
# Usage: restore_critical_state zeroia 20241225
restore_critical_state "$1" "$2"
Récupération Complète Système¶
#!/bin/bash
# scripts/ark_disaster_recovery.sh
echo "💥 RÉCUPÉRATION COMPLÈTE ARKALIA-LUNA"
# 1. Validation prérequis
if [ ! -d "/backup/daily" ]; then
echo "❌ Répertoire backup inaccessible"
exit 1
fi
# 2. Arrêt tous services
docker-compose down --remove-orphans
# 3. Récupération backup le plus récent
LATEST_BACKUP=$(find /backup/daily -name "arkalia_*" -type d | sort -r | head -1)
echo "📦 Restauration depuis: $LATEST_BACKUP"
# 4. Extraction états critiques
cd "$LATEST_BACKUP"
tar -xzf arkalia_states_*.tar.gz -C /
tar -xzf arkalia_infra_*.tar.gz -C /
# 5. Validation intégrité
echo "🔍 Validation intégrité..."
sha256sum -c checksums_*.sha256 || {
echo "❌ Checksums invalides"
exit 1
}
# 6. Reconstruction environnement
echo "🏗️ Reconstruction conteneurs..."
docker-compose build --no-cache
# 7. Tests prédémarrage
echo "🧪 Tests validation..."
python -m pytest tests/unit/test_state_writer.py -v
# 8. Redémarrage graduel
echo "🚀 Redémarrage graduel..."
docker-compose up -d reflexia
sleep 10
docker-compose up -d zeroia helloria
sleep 10
docker-compose up -d assistantia
# 9. Validation finale
echo "✅ Validation post-récupération..."
sleep 30
curl -f http://localhost:8000/status || echo "⚠️ API non disponible"
docker ps --format "table {.Names}\t{.Status}"
echo "🎯 Récupération terminée - monitoring requis"
💽 Récupération Perte Disque Totale¶
Procédure Disaster Recovery¶
#!/bin/bash
# scripts/ark_disk_recovery.sh
echo "💽 RÉCUPÉRATION PERTE DISQUE TOTAL"
# 1. Installation environnement minimal
install_base_system() {
# Installation Docker, Git, Python
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
apt-get update && apt-get install -y git python3 python3-pip
pip3 install docker-compose
}
# 2. Clonage repository
clone_arkalia() {
git clone https://github.com/arkalia-luna-system/arkalia-luna-pro.git
cd arkalia-luna-pro
git checkout main
}
# 3. Récupération backups distants
restore_from_remote() {
# Téléchargement backups chiffrés depuis site distant
rsync -avz backup-server:/secure/arkalia/encrypted/ /backup/encrypted/
# Déchiffrement backup le plus récent
LATEST_ENCRYPTED=$(find /backup/encrypted -name "arkalia_states_*.tar.gz.gpg" | sort -r | head -1)
gpg --decrypt "$LATEST_ENCRYPTED" > /tmp/arkalia_states_latest.tar.gz
# Extraction dans structure projet
tar -xzf /tmp/arkalia_states_latest.tar.gz
}
# 4. Validation et démarrage
validate_and_start() {
# Tests intégrité basiques
./scripts/ark-sec-check.sh --basic-validation
# Construction environnement
docker-compose build
# Démarrage contrôlé
docker-compose up -d
echo "✅ Récupération perte disque terminée"
echo "⚠️ Surveillance accrue recommandée pendant 48h"
}
# Exécution complète
install_base_system
clone_arkalia
restore_from_remote
validate_and_start
🧪 Tests de Récupération¶
Tests Automatisés Backup/Restore¶
# tests/backup/test_backup_recovery.py
import pytest
import os
import subprocess
import tempfile
import toml
class TestBackupRecovery:
def test_state_backup_integrity(self):
"""Teste l'intégrité des backups d'états"""
# Création état test
test_state = {
"decision": {
"last_decision": "test_backup",
"confidence_score": 0.9,
"timestamp": "2024-01-01T12:00:00"
}
}
with tempfile.NamedTemporaryFile(mode='w', suffix='.toml') as f:
toml.dump(test_state, f)
f.flush()
# Test backup
result = subprocess.run(['scripts/ark_realtime_snapshot.sh'],
capture_output=True, text=True)
assert result.returncode == 0
def test_emergency_restore(self):
"""Teste la restauration d'urgence"""
# Simulation corruption fichier
corrupt_file = "modules/zeroia/state/zeroia_state.toml"
# Sauvegarde original
with open(corrupt_file, 'r') as f:
original = f.read()
# Corruption simulation
with open(corrupt_file, 'w') as f:
f.write("invalid toml content {[}")
# Test restauration
result = subprocess.run(['scripts/ark_emergency_restore.sh', 'zeroia'],
capture_output=True, text=True)
# Validation restoration
assert result.returncode == 0
assert toml.load(corrupt_file) is not None
def test_full_backup_cycle(self):
"""Teste cycle complet backup/restore"""
# Lancement backup complet
result = subprocess.run(['scripts/ark_full_backup.sh'],
capture_output=True, text=True)
assert result.returncode == 0
# Vérification fichiers générés
backup_files = subprocess.run(['find', '/backup/daily', '-name', '*.tar.gz'],
capture_output=True, text=True)
assert len(backup_files.stdout.strip().split('\n')) >= 3
Simulation Panne Disque¶
#!/bin/bash
# tests/chaos/disk_failure_simulation.sh
echo "💽 SIMULATION PANNE DISQUE (Test contrôlé)"
# 1. Sauvegarde état actuel
backup_current_state() {
cp -r modules/*/state /tmp/test_backup_states/
cp -r state /tmp/test_backup_global/
}
# 2. Simulation "perte" données
simulate_disk_loss() {
# Renommage temporaire (simulation perte)
mv modules/zeroia/state modules/zeroia/state.hidden
mv state state.hidden
echo "🚨 Simulation: Données état perdues"
}
# 3. Test procédure récupération
test_recovery() {
./scripts/ark_disaster_recovery.sh --test-mode
}
# 4. Restauration état test
restore_test_state() {
mv modules/zeroia/state.hidden modules/zeroia/state
mv state.hidden state
echo "✅ État test restauré"
}
# Exécution test complet
backup_current_state
simulate_disk_loss
test_recovery
restore_test_state
📊 Monitoring et Alertes Backup¶
Métriques Prometheus Backup¶
# modules/monitoring/backup_metrics.py
from prometheus_client import Gauge, Counter, Histogram
# Métriques backup
backup_last_success = Gauge('arkalia_backup_last_success_timestamp',
'Timestamp du dernier backup réussi')
backup_size_bytes = Gauge('arkalia_backup_size_bytes',
'Taille backup en bytes', ['type'])
backup_duration_seconds = Histogram('arkalia_backup_duration_seconds',
'Durée backup en secondes', ['type'])
backup_failures_total = Counter('arkalia_backup_failures_total',
'Nombre échecs backup', ['type', 'reason'])
def update_backup_metrics():
"""Met à jour métriques backup"""
import os
import time
# Dernière réussite backup
latest_backup = max([os.path.getmtime(f) for f in
glob.glob('/backup/daily/arkalia_*')])
backup_last_success.set(latest_backup)
# Taille backups par type
for backup_type in ['states', 'logs', 'models', 'infra']:
pattern = f'/backup/daily/*/arkalia_{backup_type}_*.tar.gz'
files = glob.glob(pattern)
if files:
total_size = sum([os.path.getsize(f) for f in files])
backup_size_bytes.labels(type=backup_type).set(total_size)
Alertes Grafana Backup¶
# configs/grafana_backup_alerts.yml
groups:
- name: arkalia_backup_alerts
rules:
- alert: BackupTooOld
expr: time() - arkalia_backup_last_success_timestamp > 86400
for: 1h
labels:
severity: critical
annotations:
summary: "Backup Arkalia-LUNA trop ancien"
description: "Dernier backup réussi il y a {value}s"
- alert: BackupSizeAnomalous
expr: increase(arkalia_backup_size_bytes[1d]) > 1.5 * increase(arkalia_backup_size_bytes[7d]) / 7
for: 30m
labels:
severity: warning
annotations:
summary: "Taille backup anormale"
description: "Augmentation backup inhabituelle détectée"
- alert: BackupFailures
expr: increase(arkalia_backup_failures_total[1h]) > 0
for: 5m
labels:
severity: high
annotations:
summary: "Échecs backup détectés"
description: "Échecs backup dernière heure: {value}"
📋 Checklist Maintenance Backup¶
Quotidienne¶
- ✅ Vérification exécution backups automatiques
- ✅ Contrôle taille et nombre fichiers backup
- ✅ Validation checksums backup journalier
- ✅ Test accessibilité stockage distant
Hebdomadaire¶
- ✅ Test restauration état sur environnement test
- ✅ Nettoyage backups expirés (> 30 jours)
- ✅ Vérification capacité stockage disponible
- ✅ Audit logs backup et erreurs
Mensuelle¶
- ✅ Test récupération complète environnement test
- ✅ Rotation clés chiffrement GPG
- ✅ Validation intégrité backups distants
- ✅ Exercice disaster recovery complet
📞 Contacts Backup d'Urgence¶
Récupération Critique¶
- 🚨 Backup Emergency : backup-emergency@arkalia-luna.system
- 💾 Storage Admin : storage@arkalia-luna.system
- 🔐 Crypto Key Manager : keymaster@arkalia-luna.system
Fournisseurs Externes¶
- ☁️ Cloud Backup Provider : support@backup-provider.com
- 🏢 Data Center Contact : noc@datacenter.com
- 🛠️ Hardware Support : hardware@vendor.com
Documentation maintenue par Arkalia-LUNA Backup Team — Tests récupération validés mensuellement 💾 "Sauvegarde continue, récupération instantanée" — Arkalia Backup Doctrine