Als MinIO die Community-Edition Ende 2025 in den Maintenance-Modus überführte und das öffentliche Repository Anfang 2026 archivierte, stellte sich für viele Self-Hosting-Setups dieselbe Frage: Womit ersetzt man einen S3-kompatiblen Object Storage, der jahrelang gesetzt war? In meinem Beitrag MinIO-Alternative SeaweedFS: S3-Storage auf Kubernetes migrieren hatte ich mit SeaweedFS eine Antwort auf Kubernetes gezeigt. Nicht jede Umgebung bringt aber einen Cluster mit – und nicht jede braucht einen.

Dieser Beitrag geht den anderen Weg: Garage ist eine schlanke S3-Alternative, die bewusst ohne Kubernetes auskommt und sich auf ein paar klassische Linux-VMs verteilen lässt. Wir skizzieren ein hochverfügbares Drei-Knoten-Cluster, das sich mit einem Ansible-Playbook weitgehend automatisiert aufsetzen lässt, und gehen dabei besonders auf das Layout ein – den Punkt, an dem Garage sich am deutlichsten von anderen Object Stores unterscheidet.

Warum Garage

Garage stammt vom französischen Kollektiv Deuxfleurs und ist explizit für kleine, geografisch verteilte Deployments gebaut – nicht für das Rechenzentrum mit Hunderten Platten, sondern für eine Handvoll Knoten, die auch über Standorte hinweg zusammenarbeiten. Das Projekt ist quelloffen, in Rust geschrieben und kommt mit einem einzigen statischen Binary aus. Es gibt keinen externen Koordinationsdienst wie ZooKeeper oder etcd: Die Knoten sprechen direkt miteinander und einigen sich selbst auf die Datenverteilung.

Für den hier gezeigten Aufbau sind drei Eigenschaften entscheidend: Garage repliziert Daten über mehrere Knoten und Zonen hinweg, es ist S3-kompatibel (bestehende Clients und SDKs funktionieren unverändert), und der Ressourcenbedarf ist so gering, dass drei kleine VMs für ein vollwertiges HA-Cluster genügen.

Die Zielarchitektur

Das Setup besteht aus drei identisch aufgebauten VMs. Auf jeder läuft dieselbe Kombination aus drei Komponenten:

– Garage-Instanz – speichert Daten und Metadaten und hält über den internen RPC-Port Verbindung zu den beiden anderen Knoten.
– Nginx davor – terminiert TLS und leitet die S3- und Web-Requests an die lokale Garage-Instanz weiter. Garage selbst spricht kein TLS nach außen; das übernimmt bewusst der Reverse Proxy.
– Keepalived – vergibt eine virtuelle IP (VIP), die immer auf einen der drei Knoten zeigt. Fällt ein Knoten aus, wandert die VIP automatisch auf einen der verbleibenden.

Jede VM bekommt zusätzlich eine eigene Daten-Disk, getrennt vom System-Volume, an einem definierten Mountpoint. Das hält die Nutzdaten sauber von der VM getrennt und erlaubt es, den Storage unabhängig zu dimensionieren oder später zu vergrößern.

Ein Detail lohnt dabei die Aufmerksamkeit: Garage trennt intern zwischen Metadaten-Store und Daten-Store. Der Daten-Store hält die eigentlichen Objekt-Chunks, während der Metadaten-Store das Verzeichnis darüber führt – welche Partition auf welchem Knoten liegt, welche Buckets und Keys existieren, welche Chunks zu welchem Objekt gehören. Als Metadaten-Engine kommt seit Garage v1.0 standardmäßig LMDB zum Einsatz; die früher genutzte Sled-Engine ist entfallen. Der Metadaten-Store ist deutlich kleiner als der Daten-Store, aber weit häufiger im Zugriff und latenzempfindlicher. Auf jedem Knoten liegen beide Stores; für kleinere Setups genügt es, sie gemeinsam auf der Daten-Disk zu halten. Wer maximale Performance will, legt den Metadaten-Store bewusst auf schnellen NVMe-Speicher und trennt ihn vom Bulk-Storage der Objekte.

Clients – ob S3-SDK oder die Garage-Web-UI für statisches Hosting – sprechen ausschließlich mit der VIP. Sie wissen nichts von den drei Knoten dahinter; für sie sieht das Cluster aus wie ein einzelner Endpoint. Dieselbe VIP-Logik gilt für die Web-UI: Auch sie ist über die virtuelle IP erreichbar und übersteht den Ausfall eines Knotens.

Architektur-Skizze: Garage-S3 auf drei Knoten
Architektur Skizze Garage S3 auf drei Knoten

Aufbau per Ansible

Statt jede VM von Hand einzurichten, übernimmt die Ansible-Rolle eddster2309.garage die Arbeit. Sie installiert das Garage-Binary, verbindet die Knoten miteinander, richtet Nginx als Load Balancer ein und setzt Keepalived für die VIP auf. Zusätzlich kann sie Buckets samt Quotas und Web-Zugriff sowie Access Keys anlegen.

ansible-galaxy install eddster2309.garage

Die gesamte Konfiguration läuft über Variablen. Wichtig ist, den garage_version-Wert auf eine feste Version zu setzen statt auf latest – so bleibt der Rollout reproduzierbar und ein Upgrade wird zur bewussten Entscheidung. Ebenso gilt: Alle Secrets, insbesondere den clusterweiten RPC-Secret und die Access Keys, unbedingt aus den Defaults heraus anpassen.

Beim TLS setzt die Rolle auf bereits vorhandene Zertifikate – das lässt bewusst offen, wie diese erzeugt werden. Wer Let’s Encrypt nutzen möchte, kombiniert die Rolle mit einer Certbot-Rolle und hinterlegt die ausgestellten Zertifikate an den erwarteten Pfaden.

Das Layout – der Kern von Garage

Hier lohnt sich der genaue Blick, denn das Layout ist Garages zentrales Konzept und hat kein direktes Gegenstück bei MinIO. Garage zerlegt den gesamten Datenraum intern in viele Partitionen und verteilt diese anhand des Layouts auf die Knoten. Das Layout beschreibt dabei für jeden Knoten zwei Dinge: seine Zone und seine Kapazität.

Die Zone ist eine frei wählbare Ausfalldomäne – typischerweise ein Rechenzentrum, ein Standort oder ein Rack. Garage nutzt sie, um Kopien bewusst über Zonen zu streuen: Bei drei Knoten in drei Zonen und dreifacher Replikation landet jede Partition genau einmal pro Zone. Die Kapazität ist der Speicherplatz in Bytes, den ein Knoten beisteuert; sie steuert, wie viele Partitionen ein Knoten anteilig übernimmt. Bei drei gleich großen Daten-Disks vergibt man schlicht dieselbe Kapazität an alle drei.

Der zentrale Parameter ist der replication_factor. Für ein echtes HA-Cluster ist 3 die empfohlene Wahl:

replication_factor = 3 – jede Partition liegt auf drei verschiedenen Knoten, nach Möglichkeit in drei verschiedenen Zonen. Das Cluster verkraftet den Ausfall von bis zu zwei Knoten (bzw. Ausfälle in höchstens zwei Zonen), bevor Daten unerreichbar werden. Solange nur ein Knoten ausfällt, laufen Lese- und Schreibzugriffe normal weiter.

Die Ansible-Rolle nimmt einem diese Wahl im Standardfall ab: Der Default garage_replication_factor: "{{ ansible_play_hosts | length }}" leitet den Faktor aus der Anzahl der bespielten Hosts ab. Bei unserem Drei-VM-Inventar ergibt das automatisch 3 – ohne dass man den Wert von Hand setzen muss. Wer bewusst abweichen will, überschreibt die Variable einfach; sie muss am Ende aber auf allen Knoten identisch sein, sonst verweigert Garage den Betrieb.

Zum Vergleich: Bei replication_factor = 2 bleibt das Cluster beim Ausfall eines Knotens zwar lesbar, akzeptiert aber keine Schreibzugriffe mehr. Für unser Drei-Knoten-Setup ist 3 deshalb die naheliegende Wahl.

Nachdem die Rolle die Knoten verbunden hat, weist man die Rollen im Layout zu und wendet es an:

# Node-IDs auflisten
garage status

# Jedem Knoten Zone und Kapazität zuweisen
garage layout assign -z dc1 -c 500G
garage layout assign -z dc2 -c 500G
garage layout assign -z dc3 -c 500G

# Änderungen prüfen und aktivieren
garage layout show
garage layout apply --version 1

Das Schöne am Layout-Ansatz: Er macht das Cluster nachträglich wandelbar. Kommt später ein vierter Knoten hinzu oder wird eine Disk größer, ändert man einfach die Zuweisung und wendet eine neue Layout-Version an – Garage berechnet daraufhin eine neue Partitionsverteilung, die möglichst wenige Daten verschiebt, und rebalanciert im Hintergrund.

Verifikation

Nach dem Rollout zeigt ein Blick auf Status und Layout, ob alle drei Knoten verbunden sind und die Partitionen sauber verteilt wurden:

garage status
garage layout show

Ein schneller Funktionstest über die VIP – mit angelegtem Bucket und Access Key – bestätigt, dass der S3-Endpoint durch Nginx und Keepalived hindurch erreichbar ist:

aws --endpoint-url https://s3.example.com s3 mb s3://test-bucket
aws --endpoint-url https://s3.example.com s3 cp datei.txt s3://test-bucket/
aws --endpoint-url https://s3.example.com s3 ls s3://test-bucket/

Wer die Hochverfügbarkeit wirklich prüfen will, fährt testweise einen Knoten herunter: Die VIP wandert auf einen verbleibenden Knoten, und Lese- wie Schreibzugriffe laufen weiter – genau das, was ein dreifach repliziertes Cluster leisten soll.

Fazit

Nicht jede S3-Migration führt über Kubernetes. Garage zeigt, dass sich ein hochverfügbarer Object Storage auch mit drei schlanken VMs, einem Reverse Proxy und einer virtuellen IP aufbauen lässt – reproduzierbar per Ansible und ohne die Betriebslast eines Clusters. Der Layout-Ansatz mit Zonen, Kapazitäten und dreifacher Replikation macht die Ausfallsicherheit dabei explizit und das Cluster nachträglich erweiterbar.

Und noch ein Gedanke über die Technik hinaus: Nach dem Rückzug von MinIO aus dem quelloffenen Raum lohnt es sich, bei der Nachfolge auch auf Herkunft und Governance zu schauen. Garage wird von einem europäischen Kollektiv unter einer offenen Lizenz entwickelt. In einer Zeit, in der digitale Souveränität und die Unabhängigkeit von außereuropäischen Anbietern zunehmend zum Thema werden, ist eine europäische Open-Source-Lösung nicht nur technisch, sondern auch strategisch eine überlegenswerte Wahl.


Alles aus dieser Blogserie

Alle Beiträge von Philipp Kürsten

Philipp Kürsten arbeitet als Lead Consultant bei der OPITZ CONSULTING Deutschland GmbH. Er hat mehrjährige Projekterfahrung in der Applikationsentwicklung innerhalb von Microservice-Architekturen und beschäftigt sich mit modernen Architekturen für die gestiegenen Anforderungen im Zeitalter der Digitalisierung.

Schreibe einen Kommentar