Regeln von Rediacc
Jedes Rediacc-Repository läuft in einer isolierten Umgebung mit eigenem Docker-Daemon, verschlüsseltem LUKS-Volume und dediziertem IP-Bereich. Diese Regeln stellen sicher, dass Ihre Anwendung innerhalb dieser Architektur korrekt funktioniert.
Rediaccfile
- Jedes Repository benötigt ein Rediaccfile, ein Bash-Skript mit Lifecycle-Funktionen.
- Lifecycle-Funktionen:
up(),down(). Optional:info(). up()startet Ihre Dienste.down()stoppt sie.info()liefert Statusinformationen (Container-Zustand, aktuelle Logs, Health).- Rediaccfile wird von renet gesourced, es hat Zugriff auf Shell-Variablen, nicht nur auf Umgebungsvariablen.
Verfügbare Umgebungsvariablen im Rediaccfile
| Variable | Beispiel | Beschreibung |
|---|---|---|
REDIACC_WORKING_DIR | /mnt/rediacc/mounts/abc123/ | Wurzelpfad des gemounteten Repos |
REDIACC_NETWORK_ID | 6336 | Netzwerkisolations-Kennung |
REDIACC_REPOSITORY | abc123-... | Repository-GUID |
{SVCNAME}_IP | HEARTBEAT_IP=127.0.24.195 | Loopback-IP pro Dienst (Dienstname in Großbuchstaben) |
Minimales Rediaccfile
#!/bin/bash
_compose() {
renet compose -- "$@"
}
up() {
_compose up -d
}
down() {
_compose down
}
Compose
- Verwenden Sie
renet compose, niemalsdocker compose, renet injiziert Netzwerkisolation, Host-Networking, Loopback-IPs und Service-Labels. - Setzen Sie KEIN
network_modein Ihrer Compose-Datei, renet erzwingtnetwork_mode: hostfür alle Dienste. Jeder von Ihnen gesetzte Wert wird überschrieben. - Setzen Sie KEINE
rediacc.*-Labels, renet injiziert automatischrediacc.network_id,rediacc.service_ipundrediacc.service_name. ports:-Mappings werden ignoriert im Host-Networking-Modus. Fügen Sie das Labelrediacc.service_portfür HTTP-Routing hinzu (Dienste ohne dieses Label erhalten keine HTTP-Routen). Verwenden Sierediacc.tcp_ports/rediacc.udp_ports-Labels für TCP/UDP-Weiterleitung.- Restart-Richtlinien (
restart: always,on-failureusw.) sind sicher zu verwenden, renet entfernt sie automatisch für CRIU-Kompatibilität. Der Router-Watchdog stellt gestoppte Container automatisch wieder her, basierend auf der in.rediacc.jsongespeicherten ursprünglichen Richtlinie. - Gefährliche Einstellungen sind standardmäßig blockiert,
privileged: true,pid: host,ipc: hostund Bind-Mounts zu System-Pfaden werden abgelehnt. Verwenden Sierenet compose --unsafe, um dies auf eigenes Risiko zu überschreiben.
Umgebungsvariablen innerhalb von Containern
Renet injiziert diese automatisch in jeden Container:
| Variable | Beschreibung |
|---|---|
SERVICE_IP | Die dedizierte Loopback-IP dieses Containers |
REDIACC_NETWORK_ID | Netzwerkisolations-ID |
Dienstnamen und Routing
- Der Compose-Dienstname wird zum Auto-Route-URL-Präfix.
- Grand-Repos:
https://{service}.{repo}.{machine}.{baseDomain}(z. B.https://myapp.marketing.server-1.example.com). - Fork-Repos:
https://{service}-fork-{tag}.{repo}.{machine}.{baseDomain}(z. B.https://myapp-fork-staging.marketing.server-1.example.com). Der-fork--Trenner verhindert URL-Kollisionen mit Grand-Repo-Dienstnamen. Die Fork-URL verwendet stets das vorhandene Wildcard-Zertifikat des Eltern-Repos, sodass kein neues Zertifikat benötigt wird. - Für benutzerdefinierte Domains verwenden Sie Traefik-Labels (Hinweis: Benutzerdefinierte Domains sind NICHT fork-kompatibel, die Domain gehört zum Grand-Repo).
Netzwerk
- Jedes Repository erhält seinen eigenen Docker-Daemon unter
/var/run/rediacc/docker-<networkId>.sock. - Jeder Dienst erhält eine eindeutige Loopback-IP innerhalb eines /26-Subnetzes (z.B.
127.0.24.192/26). - Binden ist automatisch: Dienste können an
0.0.0.0oderlocalhostbinden, der Kernel schreibt die Adresse transparent auf die dem Dienst zugewiesene Loopback-IP um. Explizites Binden an${SERVICE_IP}funktioniert weiterhin, ist aber nicht mehr erforderlich. - Health Checks können
localhostoder${SERVICE_IP}verwenden. Beispiel:healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] - Cross-Repo-Verbindungen werden vom Kernel blockiert: Der Kernel blockiert automatisch Verbindungen zu Loopback-IPs außerhalb des
/26-Subnetzes des Repositorys. Ein Dienst in einem Repo kann keine Dienste in einem anderen Repo erreichen. - Inter-Service-Kommunikation: Verwenden Sie Dienstnamen (z. B.
db,redis), renet injiziert automatisch jeden Dienstnamen als Hostnamen, der auf die korrekte IP auflöst. Docker-DNS-Namen funktionieren im Host-Modus NICHT, aber Dienstnamen über/etc/hostsschon. Vermeiden Sie es,${DB_IP}oder Ähnliches in persistente Konfigurationsdateien (z. B. Verbindungszeichenfolgen in einer Datenbank) einzubetten, bei Forks wird die rohe IP mitgenommen und zeigt auf das falsche Repo. Dienstnamen werden immer korrekt pro Repo aufgelöst. - Portkonflikte sind unmöglich zwischen Repositories, jedes hat seinen eigenen Docker-Daemon und IP-Bereich.
- TCP/UDP-Portweiterleitung: Fügen Sie Labels hinzu, um Nicht-HTTP-Ports freizugeben:
labels: - "rediacc.tcp_ports=5432,3306" - "rediacc.udp_ports=53"
Speicher
- Alle Docker-Daten werden im verschlüsselten Repo gespeichert, Dockers
data-rootbefindet sich unter{mount}/.rediacc/docker/datainnerhalb des LUKS-Volumes. Named Volumes, Images und Container-Layer sind alle verschlüsselt, gesichert und werden automatisch geforkt. - Bind Mounts zu
${REDIACC_WORKING_DIR}/...werden der Übersichtlichkeit halber empfohlen, aber Named Volumes funktionieren ebenfalls sicher.volumes: - ${REDIACC_WORKING_DIR}/data:/data # bind mount (empfohlen) - pgdata:/var/lib/postgresql/data # named volume (ebenfalls sicher) - Das LUKS-Volume wird unter
/mnt/rediacc/mounts/<guid>/gemountet. - BTRFS-Snapshots erfassen die gesamte LUKS-Backing-Datei, einschließlich aller bind-gemounteten Daten.
- Der Datenspeicher ist eine fest dimensionierte BTRFS-Pool-Datei auf der Systemfestplatte. Verwenden Sie
rdc machine query --name <name> --system, um den effektiven freien Speicher zu sehen. Erweitern Sie mitrdc datastore resize.
CRIU (Live-Migration)
- Opt-in per Label: Fügen Sie
rediacc.checkpoint=truezu Containern hinzu, die Sie checkpointen möchten. Container ohne dieses Label (Datenbanken, Caches) starten frisch und erholen sich über eigene Mechanismen (WAL, LDF, AOF). repo down --checkpointspeichert den Prozesszustand vor dem Stoppen, beim nächstenrepo upwird automatisch wiederhergestellt. Dies ist der primäre Flow auf derselben Maschine, verifiziert funktionsfähig.backup push --checkpointerfasst den Arbeitsspeicher laufender Prozesse + Festplattenzustand für markierte Container und überträgt das Volume anschließend auf eine andere Maschine. Wiederherstellung auf der Zielmaschine überrepo up.repo fork --checkpointerfasst den Prozesszustand vor dem Forken und CoW-klont den Checkpoint zusammen mit dem Fork. ⚠️ Auf derselben Maschine schlägt das darauf folgenderepo upauf dem Fork derzeit fehl mitcriu failed: type RESTORE errno 0, solange das Eltern-Repository noch läuft. Upstream-CRIU-Bugs checkpoint-restore/criu#478 / #514. Verwenden Sierepo down --checkpointfür In-Place-Speichern/Wiederherstellen oderbackup push --checkpointfür maschinenübergreifende Migration.repo uperkennt Checkpoint-Daten automatisch und stellt wieder her, wenn vorhanden. Verwenden Sie--skip-checkpointfür einen Neustart.- Abhängigkeitsbewusste Wiederherstellung: Nutzt compose
depends_on, um Datenbanken zuerst zu starten (auf healthy warten), dann CRIU-Wiederherstellung der App-Container. - TCP-Verbindungen werden nach der Wiederherstellung ungültig, Anwendungen müssen
ECONNRESETbehandeln und sich neu verbinden. CRIU bewahrt aktive TCP-Verbindungszustände bei der Wiederherstellung in keinem unterstützten Flow. - Docker Experimental Mode wird automatisch auf den pro-Repository-Daemons aktiviert.
- CRIU wird installiert während
rdc config machine setup. /etc/criu/runc.confwird standardmäßig mittcp-establishedkonfiguriert.- Container-Sicherheitseinstellungen werden automatisch für markierte Container injiziert,
renet composefügt Folgendes zu Containern mitrediacc.checkpoint=truehinzu:cap_add:CHECKPOINT_RESTORE,SYS_PTRACE,NET_ADMIN(Minimalsatz für CRIU auf Kernel 5.9+)security_opt:apparmor=unconfined(CRIUs AppArmor-Unterstützung ist upstream noch nicht stabil)userns_mode: host(CRIU benötigt Init-Namespace-Zugriff für/proc/pid/map_files)
- Container ohne Label laufen mit saubererem Sicherheitsprofil (keine zusätzlichen Capabilities).
- Das Standard-Seccomp-Profil von Docker wird beibehalten, CRIU verwendet
PTRACE_O_SUSPEND_SECCOMP(Kernel 4.3+), um Filter während Checkpoint/Restore vorübergehend auszusetzen. - Setzen Sie CRIU-Capabilities NICHT manuell in Ihrer Compose-Datei, renet übernimmt das basierend auf dem Label.
- Siehe die Heartbeat-Vorlage für eine CRIU-kompatible Referenzimplementierung.
CRIU-kompatible Anwendungsmuster
- Behandeln Sie
ECONNRESETbei allen persistenten Verbindungen (Datenbank-Pools, WebSockets, Message Queues). - Verwenden Sie Connection-Pool-Bibliotheken, die automatische Neuverbindung unterstützen.
- Fügen Sie
process.on("uncaughtException")als Sicherheitsnetz für veraltete Socket-Fehler von internen Bibliotheksobjekten hinzu. - Restart-Richtlinien werden automatisch von renet verwaltet (für CRIU entfernt, Watchdog übernimmt die Wiederherstellung).
- Verlassen Sie sich nicht auf Docker-DNS, verwenden Sie Loopback-IPs für die Inter-Service-Kommunikation.
Host-Sicherheitsrichtlinien nach Betriebssystem
Auf allen fünf offiziell unterstützten Server-Betriebssystemen (siehe Anforderungen) verwendet der pro-Repo-Docker-Daemon und die darin laufenden Container Standard-Container-Labels. rdc config machine setup installiert keine eigene SELinux-Richtlinie und kein eigenes AppArmor-Profil.
- Ubuntu 24.04 / openSUSE Leap 16.0: AppArmor ist standardmäßig aktiviert. Container laufen unter dem Standard-Docker-Container-Profil. Die einzige Ausnahme ist CRIU (
apparmor=unconfinedfür Container mitrediacc.checkpoint=true, wie oben beschrieben). - Fedora 43 / Oracle Linux 10: SELinux läuft standardmäßig im Enforcing-Modus. Container erhalten den Standard-
container_t-Kontext. Es ist keine zusätzliche Richtlinieninstallation erforderlich. Wenn ein Setup-Schritt mit AVC-Verweigerungen fehlschlägt, lesen Sie Fehlerbehebung: SELinux-Verweigerungen. - Debian 13: AppArmor ist verfügbar, wird aber nicht standardmäßig auf allen Domains durchgesetzt. Container verwenden weiterhin das Docker-Container-Profil.
Es ist kein betriebssystemspezifisches Sicherheitspositions-Flag erforderlich; rdc und renet erkennen die laufende Umgebung und liefern auf allen fünf Distributionen dieselbe pro-Repo-Isolation.
Sicherheit
- LUKS-Verschlüsselung ist für Standard-Repositories obligatorisch. Jedes Repo hat seinen eigenen Verschlüsselungsschlüssel.
- Anmeldeinformationen werden in der CLI-Konfiguration gespeichert (
~/.config/rediacc/rediacc.json). Der Verlust der Konfiguration bedeutet den Verlust des Zugangs zu verschlüsselten Volumes. - Committen Sie niemals Anmeldeinformationen in die Versionskontrolle. Verwenden Sie
env_fileund generieren Sie Secrets inup(). - Repository-Isolation: Docker-Daemon, Netzwerk und Speicher jedes Repos sind vollständig von anderen Repos auf derselben Maschine isoliert.
- Agenten-Isolation: KI-Agenten arbeiten standardmäßig im fork-only-Modus. Jedes Repo hat seinen eigenen SSH-Schlüssel mit serverseitiger Sandbox-Durchsetzung (
sandbox-gatewayForceCommand). Alle Verbindungen werden mit Landlock LSM, OverlayFS Home-Overlay und repo-eigenem TMPDIR sandboxed. Dateisystemzugriff zwischen Repos wird durch den Kernel blockiert. sudoist innerhalb einer Repository-Sandbox bewusst deaktiviert. Die Landlock-Dateisystemisolation erfordertNoNewPrivs, was jede Rechteerhöhung unterbindet, sodasssudomitno new privileges flag is setfehlschlägt. Der Eigentümer-Benutzer des Repos besitzt bereits alle Berechtigungen, die für sämtliche Vorgänge innerhalb des Repo-Mounts und des Docker-Sockets erforderlich sind. Für echt privilegierte Operationen (Installation von Host-Paketen, Kernel-Tuning) führen Sie diese außerhalb der Sandbox aus oder über eine Rediaccfile-up()-Funktion, die vom Infrastruktur-Pfad ausgeführt wird.- Docker-Bridge-Networking ist auf jedem pro-Repo-Daemon deaktiviert. Die
daemon.jsonjedes Repos enthält"bridge": "none"und"iptables": false, sodass ein einfachesdocker run <image>einen Container nur mit Loopback-Interface und ohne ausgehende Konnektivität erzeugt. Dies ist kein Bug, sondern die Art und Weise, wie die Cross-Repo-Isolation durchgesetzt wird: Die eBPF-Kernel-Hooks, die verhindern, dass ein Repo die Loopback-IPs eines anderen Repos erreicht, greifen nur bei Containern, die im Host-Netzwerk-Namespace laufen. Verwenden Sie für Produktionsdiensterenet compose, das automatischnetwork_mode: hostinjiziert. Für ad-hoc einmalige Container in einer Shell übergeben Sie--network hostexplizit.
Deployment
rdc repo uphängt das LUKS-Volume automatisch ein, falls es nicht eingehängt ist, und führt dannup()in allen Rediaccfiles aus.rdc repo downführtdown()aus und stoppt den Docker-Daemon.rdc repo down --unmountschließt zusätzlich das LUKS-Volume (sperrt den verschlüsselten Speicher).- Forks (
rdc repo fork) erstellen einen CoW-Klon (Copy-on-Write) mit neuer GUID und networkId, in konstanter Zeit, unabhängig von der Repo-Größe. BTRFS-Reflink dupliziert die Image-Metadaten, nicht die Daten, sodass ein 100-GB-Repo in denselben wenigen Sekunden geforkt wird wie ein 1-GB-Repo. Der Fork teilt den Verschlüsselungsschlüssel des Elternteils. - Takeover (
rdc repo takeover --name <fork> -m <machine>) ersetzt die Daten des grand Repos durch die Daten eines Forks. Das grand Repo behält seine Identität (GUID, networkId, Domains, Autostart, Backup-Kette). Alte Produktionsdaten werden als Backup-Fork gesichert. Verwendung: Upgrade auf Fork testen, verifizieren, dann Takeover zur Produktion. Rückgängig machen mitrdc repo takeover --name <backup-fork> -m <machine>. - Proxy-Routen werden ca. 3 Sekunden nach dem Deploy aktiv. Die Warnung „Proxy is not running” während
repo upist informativ in Ops/Dev-Umgebungen. rdc repo upundrdc repo fork --upgeben das URL-Muster am Ende des Deploys für Dienste mit dem Labelrediacc.service_portaus. Ersetzen Sie{service}durch Ihren freigegebenen Dienstnamen, um die exakte URL zu erhalten. Dienste ohnerediacc.service_port(Datenbanken, Worker) erhalten keine Routen und werden nicht angezeigt.
Häufige Fehler
docker composestattrenet composeverwenden, Container erhalten keine Netzwerkisolation.- Restart-Richtlinien sind sicher, renet entfernt sie automatisch und der Watchdog übernimmt die Wiederherstellung.
privileged: trueverwenden, nicht nötig, renet injiziert stattdessen spezifische CRIU-Capabilities.- Rohe IPs in persistenten Konfigurationsdateien hartkodieren - verwenden Sie Dienstnamen für Verbindungen, um die Fork-Isolation intakt zu halten.
rdc term connect -cals Workaround für fehlgeschlagene Befehle verwenden, melden Sie stattdessen Bugs.repo deleteführt eine vollständige Bereinigung durch, einschließlich Loopback-IPs und systemd-Units. Führen Sierdc machine prune --name <name>aus, um Überreste aus alten Löschvorgängen zu bereinigen.