256 lines
14 KiB
Markdown
256 lines
14 KiB
Markdown
# MinIO → SeaweedFS: betreuter Pilot auf einer Installer-Instanz
|
|
|
|
Stand: 28. September 2026. Dieser Ablauf ergänzt das
|
|
[Austauschkonzept](minio-austausch-konzept.md) um ausführbare Werkzeuge.
|
|
Er übernimmt den Speicher einer vorhandenen Installation, beispielsweise 3.3.0,
|
|
mit unveränderten Anwendungsimages und ohne Datenbankschemamigration.
|
|
|
|
**Vor dem ersten Wartungsfenster nur `load-images` und `plan` ausführen.**
|
|
Die Vorprüfung ermittelt die bislang unbekannten Größen und liefert eine
|
|
kompakte Ausgabe zum gemeinsamen Prüfen. Sie stoppt keine Anwendungscontainer.
|
|
Die fachliche Abnahme erfolgt zusätzlich auf der konkreten Instanz.
|
|
|
|
## Was der Pilot leistet und wo seine Grenze liegt
|
|
|
|
- Vorhandenes MinIO verwenden; kein Abruf von `minio/minio` oder `mc` erforderlich.
|
|
- SeaweedFS 4.47 mit dokumentierter FEDEO-Metadatenkorrektur; Offline-Images,
|
|
SHA-256-geprüftes Paket.
|
|
- Alle Objekte des einzigen FEDEO-Buckets übernehmen, inklusive Exporte und
|
|
Objekte ohne aktuellen Datenbankverweis. Schlüssel und Metadaten bleiben erhalten.
|
|
- Alle bekannten Schreiber anhalten, ihre automatischen Neustarts sperren,
|
|
PostgreSQL dumpen und MinIO kalt sichern. Die alten Daten bleiben erhalten.
|
|
- Kopie, vollständigen Inhaltsvergleich und tatsächlichen SeaweedFS-Restore in
|
|
ein frisches Verzeichnis prüfen. Unbekannte Zielobjekte werden nicht gelöscht.
|
|
- Den S3-Vertrag zusätzlich mit dem **tatsächlich installierten Backendimage**
|
|
ausführen. Dabei startet nur das Prüfprogramm, kein FEDEO-Backend.
|
|
- Erst nach diesen Prüfungen den Alias `minio` exklusiv an SeaweedFS vergeben
|
|
und die unveränderte Anwendung wieder starten.
|
|
|
|
**Der Pilot ist noch kein neuer Standardinstaller und kein reguläres
|
|
FEDEO-Release.** Der bisherige Anwendungs-Updater kennt nur MinIO. Seine Aufträge
|
|
bleiben nach der Umstellung bewusst über `recoveryRequired` gesperrt, bis ein
|
|
getesteter Provider-Adapter installiert wird. Diesen Zustand nicht mit dem alten
|
|
`resolve` oder durch Löschen der Statusdatei aufheben. Ein alter Installer oder
|
|
ein altes Release-Compose darf die umgestellte Installation nicht überschreiben.
|
|
|
|
FEDEO 3.3.0 kann im Systemstatus weiterhin den MinIO-spezifischen Health-Endpunkt
|
|
abfragen und dadurch den Dateispeicher als gestört anzeigen. Die tatsächliche
|
|
Funktionsprüfung erfolgt im Pilot über signierte S3-Operationen. Herstellerneutrale
|
|
Oberflächenchecks, eine Migrationskarte in der Oberfläche, automatische Updates
|
|
auf SeaweedFS und der Standardinstaller sind nachfolgende Arbeitspakete.
|
|
Wer diese Einschränkungen noch nicht im Betrieb tragen möchte, führt zunächst
|
|
nur die Vorprüfung durch und bleibt mit der Instanz auf MinIO.
|
|
|
|
### Warum das Pilotimage eine gezielte Korrektur enthält
|
|
|
|
Das unveränderte SeaweedFS 4.47 entfernt beim Speichern den expliziten MIME-Typ
|
|
`application/octet-stream`. Bei einem `.pdf`-Schlüssel liefern HEAD und GET
|
|
dadurch später `application/pdf`. Diese Abweichung wurde beim ersten betreuten
|
|
Versuch durch den strengen Metadatenvergleich erkannt; die Instanz wurde vor
|
|
Schreibfreigabe erfolgreich auf MinIO zurückgeführt.
|
|
|
|
`scripts/storage/Dockerfile.seaweedfs` baut deshalb die feste Herstellerrevision
|
|
`c5073360007d28385a33426a42ac3e4ec504c5a3` mit
|
|
`preserve-s3-content-type.patch` als `4.47-fedeo.1`. Die Korrektur bewahrt den
|
|
expliziten Typ für S3-Einträge; die Normalisierung gewöhnlicher Dateisystemeinträge
|
|
bleibt erhalten. Quellarchiv, Go-Buildimage und Hersteller-Basisimage sind per
|
|
SHA-256 festgelegt. Gezielte Go-Tests laufen beim Build; das Paket enthält den
|
|
Buildplan und Patch mit Prüfsummen. Der S3-Vertrag prüft den generischen MIME-Typ
|
|
zusätzlich mit HEAD, GET und dem Original-Backend-SDK.
|
|
|
|
Dies ist eine eigene Buildvariante. Bei einem späteren SeaweedFS-Update muss die
|
|
Korrektur weitergeführt oder durch einen nachgewiesenen Herstellerfix ersetzt
|
|
werden; das ungeänderte Herstellerimage ist für diese 1:1-Übernahme nicht freigegeben.
|
|
|
|
## Voraussetzungen, die der Plan prüft
|
|
|
|
Linux amd64, Python ab 3.10, lokaler Docker-Daemon, Docker Compose und `tar`/`du`.
|
|
Die Installation muss laufen und aus dem Installer stammen: lokale Verzeichnisse
|
|
`postgres/` und `minio/`, interner Endpunkt `http://minio:9000`, S3-Zugang wie beim
|
|
Installer aus `MINIO_ROOT_*`, keine externen Secret-Provider, keine zusätzlichen
|
|
MinIO-Ports, Datenmounts oder unbekannten Container im internen Netz.
|
|
Bekannte lokale Matrix-Dienste werden erhalten, während der Kopie angehalten und
|
|
mit ihren Daten kalt gesichert. Andere Zusatzdienste/Compose-Overrides blockieren
|
|
den Pilot und benötigen einen angepassten Plan.
|
|
|
|
Bereits durch ein früheres Update stillgelegte Matrix-Container dürfen weiterhin
|
|
zum Compose-Projekt gehören, obwohl sie nicht mehr in dessen Konfiguration stehen.
|
|
Der Pilot akzeptiert sie nur gestoppt und mit Neustartrichtlinie `no`, erhält ihre
|
|
Container und Images und nimmt sie nicht wieder in Compose auf. Ihre lokalen
|
|
Matrix-Bind-Verzeichnisse werden ebenfalls kalt gesichert. Die alten anonymen
|
|
Redis-/Coturn-Volumes bleiben unverändert an ihren stillgelegten Containern;
|
|
sie gehören nicht zum neuen Speicherdienst oder dessen Restore-Test.
|
|
|
|
Der S3-Prüfer blockiert zusätzliche Buckets, Versionierung einschließlich alter
|
|
Versionen/Delete-Marker, Object Lock, konfigurierte Serververschlüsselung,
|
|
Objekt-/Bucket-Tags, eigene Policies/ACLs, Lifecycle, Replikation, Benachrichtigungen,
|
|
CORS und offene Multipart-Uploads. Unklare S3-Fehler werden nicht als „nicht vorhanden“
|
|
gewertet. Datei-/Verzeichniskonflikte und normalisierungsgefährdete Schlüssel wie
|
|
`a//b`, `a/../b` und Verzeichnismarker blockieren ebenfalls.
|
|
|
|
Die bekannten lokalen MinIO-Metadaten werden zusätzlich geprüft (`xl-single`,
|
|
Metadatenformat 3). MinIO kann bei gleichzeitigem `a` und `a/b` einen Schlüssel
|
|
aus der S3-Liste verbergen, obwohl er per GET erreichbar bleibt. Bei gestopptem
|
|
MinIO muss deshalb die Menge lokaler `xl.meta`-Objektpfade exakt mit dem S3-Inventar
|
|
übereinstimmen. Andere Speicherformate oder Abweichungen blockieren die Umschaltung.
|
|
|
|
Getestete Pilotgrenzen: **200.000 Objekte, höchstens 1 GiB je Objekt**.
|
|
Die Kapazitätsabschätzung berücksichtigt Quellsicherung, neues und wiederhergestelltes
|
|
Ziel, Metadatenreserve pro Objekt, DB-Dump, Offline-Images, Spool und 5 GiB Reserve.
|
|
Nach dem Schreibstopp wird das Inventar erneut ermittelt. Es gibt keine Annahme,
|
|
dass eine unbekannte freie Kapazität ausreichend ist.
|
|
|
|
Externe Schreiber lassen sich nicht allein anhand von Docker erkennen. Vor
|
|
`migrate --writers-exclusive` muss feststehen, dass keine anderen Anwendungen,
|
|
direkten DB-/S3-Clients oder manuellen Compose-Aufträge parallel schreiben.
|
|
|
|
## Paket erstellen und auf den Host übertragen
|
|
|
|
Im Entwicklungscheckout mit Docker:
|
|
|
|
```sh
|
|
bash scripts/storage/build-pilot.sh
|
|
```
|
|
|
|
Ergebnis: `.release/storage-pilot.tar.gz` samt `.sha256` und entpacktem Paket.
|
|
Das Archiv enthält Hostprogramme, Dokumentation und beide benötigten Zielimages.
|
|
Es enthält keine Instanz-Zugangsdaten, keine Kundendateien und kein neues MinIO.
|
|
Die Build-Phase darf Images herunterladen; alle Schritte auf dem Zielhost starten
|
|
Container mit `--pull never`.
|
|
|
|
Archiv und Prüfsumme über den üblichen Administrationsweg auf den Docker-Host
|
|
kopieren. Dort die tatsächliche Prüfsumme mit der mitgelieferten vergleichen,
|
|
beispielsweise bei Ablage unter `/root`:
|
|
|
|
```sh
|
|
cd /root
|
|
sha256sum storage-pilot.tar.gz
|
|
tar -xzf storage-pilot.tar.gz
|
|
cd storage-pilot
|
|
sudo python3 pilot.py load-images
|
|
sudo python3 pilot.py plan --directory /opt/fedeo
|
|
```
|
|
|
|
Die Ausgabe von `plan` kann in den Supportdialog kopiert werden. Sie enthält
|
|
Phase, Anwendungsversion, Objektanzahl, Objektbytes und benötigten/verfügbaren
|
|
Platz; keine Passwörter oder Dateinamen. Falls der Installer in ein anderes
|
|
Verzeichnis installiert wurde, bei jedem Befehl denselben Pfad angeben.
|
|
|
|
Ein Plan verändert keine Quelldateien oder fachlichen Daten. Er legt geschützte
|
|
Migrationsdateien unter `.updates/storage-migration/` und einen lokalen Image-Tag
|
|
zur Aufbewahrung des Hilfsimages an. Die `storage/`-Datenablage entsteht erst beim
|
|
Migrationslauf. Das Paket bleibt bis zum Abschluss verfügbar; nicht mitten im
|
|
Auftrag neu bauen oder austauschen.
|
|
|
|
## Wartungsfenster: kopieren, prüfen, dann freigeben
|
|
|
|
Erst nach Prüfung der Planausgabe und Abstimmung des Wartungsfensters:
|
|
|
|
```sh
|
|
sudo python3 pilot.py migrate --directory /opt/fedeo --writers-exclusive
|
|
sudo python3 pilot.py status --directory /opt/fedeo
|
|
```
|
|
|
|
`migrate` endet bei `phase: verified`. Die Anwendung ist dann **weiter angehalten**.
|
|
Es hat noch keine fachlichen Schreibzugriffe auf SeaweedFS gegeben.
|
|
Der Lauf besitzt dieselbe exklusive Sperre wie der Host-Updater.
|
|
|
|
Die Umschaltung ist ein eigener Befehl:
|
|
|
|
```sh
|
|
sudo python3 pilot.py activate --directory /opt/fedeo
|
|
```
|
|
|
|
`activate` liest Quelle und Ziel nochmals vollständig, stoppt MinIO, entfernt
|
|
dessen internen Netzwerkanschluss, sichert SeaweedFS kalt und startet einen
|
|
separaten Restore-Container mit frisch entpackten Daten. Alle Objekt-Hashes und
|
|
Metadaten müssen dort stimmen. Danach erhält das aktive Ziel allein den Alias
|
|
`minio`, und die S3-Vertragstests laufen erneut, auch mit dem Original-Backend-SDK.
|
|
|
|
**Vor dem Start irgendeines fachlichen Schreibers** persistiert das Programm
|
|
`writesReleased: true`. Erst danach werden Backend/Hintergrunddienste und zuletzt
|
|
der öffentliche Proxy gestartet. Ein Fehler beim Neustart führt nicht zu einem
|
|
automatischen Rückfall auf den nun möglicherweise veralteten Quellspeicher.
|
|
|
|
Anschließend auf der Instanz prüfen: Anmeldung, bestehender Download, PDF-Vorschau,
|
|
neuer Upload mit erneutem Download, WebDAV, DATEV/SEPA und Mandantenexport/-import.
|
|
Bei zwei Testmandanten auch die unveränderten Zugriffsgrenzen kontrollieren.
|
|
Bereits ausgegebene S3-Links sind zusätzlich über ihren tatsächlichen Zugriffsweg
|
|
zu prüfen; ein interner Docker-Alias macht interne URLs nicht öffentlich erreichbar.
|
|
|
|
## Fehler und Wiederaufnahme
|
|
|
|
| Zustand | Vorgehen |
|
|
| --- | --- |
|
|
| `planned` | Instanz läuft noch; Wartungsfenster vorbereiten. |
|
|
| `freezing`, `backing_up`, `backed_up`, `copying`, `verifying`, `verified` | `migrate --writers-exclusive` setzt fort. Quelle, Schreibstopp, Backups und Inhalte werden erneut geprüft. |
|
|
| `cutover`, `restore_testing` | `activate` setzt die noch nicht freigegebene Umschaltung fort; alternativ Rückkehr. |
|
|
| `released` nach fehlgeschlagenem Start | `resume-start` versucht denselben Zielstand erneut. Keine einfache Rückkehr mehr. |
|
|
| `complete` | SeaweedFS aktiv; alte Daten und Backups weiter aufbewahren. |
|
|
| `rolled_back` | MinIO wieder aktiv. Vor einem neuen Versuch einen neuen betreuten Plan anlegen; bestehende Beweise nicht löschen. |
|
|
|
|
Vor der Schreibfreigabe ist die Rückkehr ausführbar:
|
|
|
|
```sh
|
|
sudo python3 pilot.py rollback --directory /opt/fedeo
|
|
```
|
|
|
|
Sie stoppt das Ziel, stellt Compose, den alten exklusiven Netzwerkanschluss und
|
|
die ursprünglichen Neustartrichtlinien wieder her und startet die vorher laufenden
|
|
Container. Quelldaten und DB bleiben unverändert. Nach `writesReleased: true`
|
|
verweigert das Programm diesen Befehl. Dann braucht eine Rückkehr eine gesonderte
|
|
Rückmigration einschließlich Löschungen oder die bewusste Wiederherstellung eines
|
|
zusammengehörigen Backups.
|
|
|
|
## Protokolle, Sicherungen und Betriebsdaten
|
|
|
|
`status` ist die kompakte Ausgabe ohne Geheimnisse. Geschützte Einzelheiten liegen
|
|
unter `/opt/fedeo/.updates/storage-migration/`:
|
|
|
|
- `state.json`: Phase, Container-/Image-Identitäten und dauerhafte Schreibgrenze.
|
|
- `commands.log`, `progress.jsonl`: Hostfehler und letzter Werkzeugfortschritt.
|
|
- `copy/inventory.json`, `copy/objects.jsonl`, `copy/verified.json`: vollständiges
|
|
Inventar und überprüfte Objekt-Hashes. Diese Dateien enthalten Dateinamen/Metadaten.
|
|
- `backup/database.dump`, `globals.sql`, `files.tar`, `images.tar`, `complete.json`:
|
|
zusammengehörige Quellsicherung mit Prüfsummen. Der DB-Dump wird mit `pg_restore --list`
|
|
geprüft; ein vollständiger fachlicher DB-Restore bleibt eine gesonderte DR-Prüfung.
|
|
- `backup/seaweedfs.tar`: kalt gesicherter neuer Speicher samt Konfiguration;
|
|
sein SHA-256 und erfolgreicher echter Restore werden im Zustand festgehalten.
|
|
|
|
Die neue persistente Ablage ist `storage/seaweedfs/`, die geschützte Konfiguration
|
|
`storage/config/`. SeaweedFS bindet Verwaltung, Filer und Volume-APIs an Loopback
|
|
im Container; im internen Docker-Netz liegt ausschließlich S3 auf Port 9000.
|
|
Ein Startwrapper verweigert fehlende oder veränderte Zugangskonfiguration.
|
|
Die Anwendungsidentität erhält nur Lese-, Schreib- und Listenrechte für ihren Bucket.
|
|
|
|
Für spätere Sicherungen **SeaweedFS anhalten und `storage/` vollständig sichern**,
|
|
einschließlich Filer-Metadaten, Masterzustand, Objektdaten, Konfiguration und passendem
|
|
Image. Die DB-Sicherung muss zum selben Schreibstopp gehören. Die Sicherungen auf
|
|
demselben Host anschließend auf das vorgesehene externe Backupziel übernehmen.
|
|
MinIO-Daten, alte Container, Test-Restores und Offline-Images werden vom Pilot
|
|
nicht automatisch gelöscht.
|
|
|
|
## Nachgewiesene Tests und ausstehende Freigaben
|
|
|
|
Der lokale S3-Test verwendet das offizielle MinIO-Release-Binary vom 7. September
|
|
2025 und SeaweedFS 4.47 mit der dokumentierten MIME-Korrektur. 1.005 Objekte / 1.073.752.750 Bytes,
|
|
einschließlich 1-GiB-Grenzdatei, Pagination, Sonderzeichen, Metadaten, leeren
|
|
Dateien, Streaming, 24-Stunden-Signaturen, fremdem Bucket und ungültigen Zugängen
|
|
werden geprüft. Beschädigte Zielobjekte werden erkannt und beim Fortsetzen
|
|
erneut kopiert; der kalte Restore wird vollständig gelesen und verglichen.
|
|
Testhost: Linux, 16 logische CPUs, rund 29 GiB RAM für Docker, lokaler NVMe-Speicher.
|
|
Die Laufzeit hängt von Objektanzahl, Datenmenge und Host ab.
|
|
|
|
Das Hilfs-Lockfile enthält den übernommenen vollständigen SDK-Abhängigkeitsbaum
|
|
des Backends, nicht nur dieselbe oberste Versionsnummer. Beim Pilot wird außerdem
|
|
das konkrete installierte Backendimage gegen das Ziel geprüft.
|
|
|
|
Die Host-Integrationstests verwenden echte Speicher- und PostgreSQL-Container,
|
|
aber künstliche Anwendungsprozesse. Rückkehr vor Schreibfreigabe sowie vollständige
|
|
Umschaltung mit Restore und gesperrter Rückkehr nach Schreibfreigabe wurden erfolgreich
|
|
durchlaufen. Die fachliche Abnahme von FEDEO auf der
|
|
konkreten Instanz, ein physischer Hostneustart während jeder Phase, das reguläre
|
|
Anwendungsupdate auf SeaweedFS und die vollständige Wiederherstellung auf einem
|
|
anderen Host sind damit noch nicht nachgewiesen. Deshalb bleibt dieser Stand ein
|
|
betreuter Pilot; die allgemeinen Freigabekriterien des Konzepts gelten weiter.
|