17 Punkte von GN⁺ 11 일 전 | 1 Kommentare | Auf WhatsApp teilen
  • Eine Produktionsinfrastruktur für 1.432 US-Dollar pro Monat wurde auf einen dedizierten Server für 233 US-Dollar pro Monat umgezogen, wobei sogar das Betriebssystem gewechselt wurde und die Service-Kontinuität ohne Downtime erhalten blieb
  • 30 MySQL-Datenbanken und 34 Nginx Virtual Hosts sowie GitLab EE, Neo4J, Supervisor und Gearman wurden auf dem neuen Server identisch eingerichtet; die Migration wurde anschließend mit Replikation in Echtzeit und finaler inkrementeller Synchronisierung abgeschlossen
  • Der Kern der Datenbankmigration war die Kombination aus paralleler Verarbeitung mit mydumper·myloader und MySQL replication; dabei wurden auch Probleme mit dem sys-Schema und Berechtigungen behoben, die beim Upgrade von MySQL 5.7 auf 8.0 auftraten
  • Das Cutover erfolgte in der Reihenfolge DNS-TTL reduzieren, Nginx auf dem alten Server in einen Reverse Proxy umwandeln und A-Records gesammelt ändern, sodass Anfragen an die alte IP während der DNS-Propagation weiterhin an den neuen Server weitergeleitet wurden
  • Das Ergebnis: 1.199 US-Dollar weniger pro Monat, 14.388 US-Dollar weniger pro Jahr, dazu mehr CPU, Speicher und Storage sowie 0 Minuten Downtime

Hintergrund der Migration

  • Beim Betrieb eines Softwareunternehmens in der Türkei stieg durch rasante Inflation und die Schwäche der türkischen Lira die Belastung durch in US-Dollar abgerechnete Infrastrukturkosten stark an
  • Die bisherigen Serverkosten bei DigitalOcean lagen bei 1.432 US-Dollar pro Monat; die Konfiguration umfasste 192 GB RAM, 32 vCPU, 600 GB SSD, zwei 1-TB-Block-Volumes sowie Backups
  • Das neue Ziel war ein dedizierter Server vom Typ Hetzner AX162-R mit AMD EPYC 9454P, 48 Kernen, 96 Threads, 256 GB DDR5 und 1,92 TB NVMe Gen4 RAID1
  • Die monatlichen Kosten sanken auf 233 US-Dollar, was einer Ersparnis von 1.199 US-Dollar pro Monat bzw. 14.388 US-Dollar pro Jahr entspricht
  • Mit der Zuverlässigkeit des bisherigen Servers oder der Developer Experience gab es zwar keine Probleme, für steady-state Workloads war das Preis-Leistungs-Verhältnis jedoch nicht mehr sinnvoll

Bisherige Betriebsumgebung

  • Der Betriebs-Stack war keine einfache Testumgebung, sondern eine echte Produktionsumgebung
    • 30 MySQL-Datenbanken mit insgesamt 248 GB Daten
    • 34 Nginx Virtual Hosts über mehrere Domains hinweg
    • GitLab EE inklusive 42 GB Backups
    • Neo4J Graph DB mit 30 GB
    • Verwaltung von Dutzenden Hintergrund-Workern mit Supervisor
    • Einsatz von Gearman als Job-Queue
    • Betrieb von Live-Mobile-Apps für Hunderttausende Nutzer
  • Das Betriebssystem des alten Servers war CentOS 7, dessen Support bereits ausgelaufen war
  • Auf dem neuen Server lief AlmaLinux 9.7, eine RHEL-9-kompatible Distribution und ein naheliegender Nachfolger für CentOS
  • Die Migration diente daher nicht nur der Kostensenkung, sondern auch dem Ausstieg aus einem Betriebssystem, das seit Jahren keine Sicherheitsupdates mehr erhalten hatte

Strategie ohne Downtime

  • Ein simples Ändern des DNS und ein Neustart der Services kamen nicht infrage; stattdessen wurde die Migration in einem 6-stufigen Verfahren ohne Downtime durchgeführt
  • Schritt 1: Gesamten Stack auf dem neuen Server installieren

    • Nginx wurde mit denselben Flags wie bisher aus dem Source kompiliert und installiert
    • PHP wurde über das Remi-Repo installiert, anschließend wurden dieselben .ini-Dateien wie auf dem alten Server übernommen
    • MySQL 8.0, Neo4J Graph DB, GitLab EE, Node.js, Supervisor und Gearman wurden installiert und so konfiguriert, dass sie dem bisherigen Verhalten entsprachen
    • Noch bevor DNS-Einträge angefasst wurden, war sichergestellt, dass alle Services auf dem neuen Server genauso funktionierten wie auf dem alten
    • Die SSL-Zertifikate wurden übernommen, indem das komplette Verzeichnis /etc/letsencrypt/ per rsync vom alten Server kopiert wurde
    • Nachdem der gesamte Traffic auf den neuen Server umgeschaltet war, wurden die Zertifikate gesammelt mit certbot renew --force-renewal zwangsweise erneuert
  • Schritt 2: Web-Dateien per rsync replizieren

    • Das gesamte Verzeichnis /var/www/html mit rund 65 GB und 1,5 Millionen Dateien wurde per SSH-basiertem rsync repliziert
    • Mit der Option --checksum wurde die Integrität verifiziert
    • Unmittelbar vor dem Cutover folgte eine letzte inkrementelle Synchronisierung, um geänderte Dateien zu übernehmen
  • Schritt 3: MySQL Master-Slave-Replikation

    • Statt Datenbanken per Dump und Restore mit Unterbrechung zu migrieren, wurde Replikation in Echtzeit eingerichtet
    • Der alte Server wurde als Master, der neue als read-only Slave konfiguriert
    • Für das anfängliche Laden großer Datenmengen kam mydumper zum Einsatz; anschließend begann die Replikation exakt ab der im Dump-Metadatenfile verzeichneten binlog-Position
    • Bis zum Cutover wurden beide Datenbankseiten in Echtzeit synchron gehalten
  • Schritt 4: DNS-TTL reduzieren

    • Über ein Skript, das die DigitalOcean DNS API aufrief, wurde die TTL aller A/AAAA-Records von 3600 Sekunden auf 300 Sekunden reduziert
    • MX- und TXT-Records wurden nicht geändert
    • Die TTL der Mail-Records blieb unverändert, um keine Zustellprobleme zu riskieren
    • Nachdem die alte TTL weltweit auslaufen konnte, war das Cutover nach einer Stunde Wartezeit innerhalb von fünf Minuten vorbereitet
  • Schritt 5: Nginx auf dem alten Server in einen Reverse Proxy umwandeln

    • Ein Python-Skript analysierte die server {}-Blöcke in allen 34 Nginx-Site-Konfigurationen
    • Die bestehende Konfiguration wurde gesichert und durch Proxy-Konfigurationen ersetzt, die auf den neuen Server zeigten
    • So wurden Anfragen, die während der DNS-Propagation noch an der alten IP ankamen, unauffällig an den neuen Server weitergereicht
    • Für Nutzer gab es dadurch keine sichtbare Unterbrechung
  • Schritt 6: DNS-Cutover und Abschaltung des alten Servers

    • Ein Python-Skript rief die DigitalOcean API auf und änderte innerhalb weniger Sekunden alle A-Records auf die neue Server-IP
    • Der alte Server blieb noch eine Woche lang als cold standby erhalten und wurde erst dann abgeschaltet
    • Der Service antwortete während des gesamten Prozesses entweder direkt oder über den Proxy, sodass es keine Lücke in der Verfügbarkeit gab

MySQL-Migration

  • Der komplexeste Teil des gesamten Vorhabens war die Migration von MySQL
  • Daten-Dump

    • Statt des Standardtools mysqldump wurde mydumper verwendet
    • Durch parallelen Export/Import unter Nutzung der 48 CPU-Kerne des neuen Servers ließ sich eine Aufgabe, die mit dem Single-Thread-Tool mysqldump mehrere Tage gedauert hätte, auf wenige Stunden verkürzen
    • Zu den wichtigsten Optionen gehörten --threads 32, --compress, --trx-consistency-only, --skip-definer, --chunk-filesize 256
    • In der metadata-Datei des Haupt-Dumps wurde die binlog-Position zum Zeitpunkt des Snapshots festgehalten
      • File: mysql-bin.000004
      • Position: 21834307
    • Diese Werte dienten später als Startpunkt für die Replikation
  • Übertragung des Dumps

    • Nach Abschluss des Dumps wurde dieser per SSH-basiertem rsync auf den neuen Server übertragen
    • Insgesamt wurden 248 GB komprimierte Chunks übertragen
    • Die durch mydumper via --compress erzeugten komprimierten Chunks verbesserten die Geschwindigkeit der Netzwerkübertragung
  • Laden der Daten

    • Verwendet wurde myloader
    • Die wichtigsten Optionen waren --threads 32, --overwrite-tables, --ignore-errors 1062, --skip-definer
  • Probleme beim Wechsel von MySQL 5.7 auf 8.0

    • Wegen der CentOS-7-Umgebung war der alte Server bei MySQL 5.7 geblieben
    • Vor der Migration wurde mit mysqlcheck --check-upgrade geprüft, ob die Daten mit MySQL 8.0 kompatibel sind; das Ergebnis war unauffällig
    • Auf dem neuen Server wurde die aktuelle MySQL 8.0 Community-Version installiert
    • Projektweit verkürzten sich die Query-Laufzeiten spürbar; im Original werden dafür der verbesserte Optimizer und die InnoDB-Verbesserungen in MySQL 8.0 genannt
    • Durch den Versionssprung traten jedoch auch Probleme auf
      • Nach dem Import hatte die Tabelle mysql.user nicht wie erwartet 51, sondern nur 45 Spalten
      • In der Folge fehlte mysql.infoschema, und es kam zu Problemen bei der Benutzerauthentifizierung
    • Der erste Reparaturversuch erfolgte mit den folgenden Befehlen
      • systemctl stop mysqld
      • mysqld --upgrade=FORCE --user=mysql &
    • Der erste Versuch scheiterte mit dem Fehler ERROR: 'sys.innodb_buffer_stats_by_schema' is not VIEW
    • Ursache war, dass das sys-Schema als normale Tabelle statt als View importiert worden war
    • Gelöst wurde das Problem durch DROP DATABASE sys; und ein erneutes Ausführen des Upgrades
    • Danach lief alles korrekt durch

Einrichtung der MySQL-Replikation

  • Nachdem der Dump auf beiden Servern eingespielt war, wurde der neue Server als Replica des alten Servers eingerichtet
  • In CHANGE MASTER TO wurden die IP des alten Servers, der Replikationsbenutzer, Port 3306, MASTER_LOG_FILE='mysql-bin.000004' und MASTER_LOG_POS=21834307 angegeben
  • Anschließend wurde START SLAVE; ausgeführt
  • Fast sofort stoppte die Replikation mit error 1062 Duplicate Key
  • Der Grund: Der Dump war in zwei Durchläufen erstellt worden, und zwischen diesen wurde in einige Tabellen geschrieben, sodass der importierte Dump und das Abspielen des binlog versuchten, dieselben Zeilen doppelt einzufügen
  • Zur Behebung wurde folgende Konfiguration angewendet
    • SET GLOBAL slave_exec_mode = 'IDEMPOTENT';
    • START SLAVE;
  • Der IDEMPOTENT-Modus überspringt Duplicate-Key- und Missing-Row-Fehler stillschweigend
  • Alle wichtigen Datenbanken synchronisierten sich danach fehlerfrei, und Seconds_Behind_Master fiel innerhalb weniger Minuten auf 0

Validierung vor dem Cutover

  • Bevor DNS-Einträge geändert wurden, musste geprüft werden, ob auf dem neuen Server alle Services korrekt funktionierten
  • Dafür wurde auf dem lokalen Rechner die Datei /etc/hosts temporär angepasst, um die Domain auf die IP des neuen Servers zu mappen
  • Browser und Postman schickten dadurch Anfragen an den neuen Server, während externe Nutzer weiterhin den alten Server erreichten
  • Es wurden API-Endpunkte, Admin-Panels und der Antwortstatus der einzelnen Services geprüft
  • Erst nachdem alles bestätigt war, erfolgte das eigentliche Cutover

Problem mit SUPER-Berechtigungen

  • Nachdem die Master-Slave-Replikation vollständig synchron war, fiel auf, dass auf dem neuen Server trotz read_only = 1 INSERT-Statements erfolgreich waren
  • Der Grund war, dass allen PHP-Applikationsbenutzern die SUPER-Berechtigung erteilt worden war
  • In MySQL umgeht die SUPER-Berechtigung read_only
  • Mit SHOW GRANTS FOR 'some_db_user'@'localhost'; wurde bestätigt, dass die Berechtigung SUPER enthalten war
  • Bei insgesamt 24 Applikationsbenutzern wurde wiederholt REVOKE SUPER ON *.* FROM 'some_db_user'@'localhost'; ausgeführt
  • Anschließend wurde FLUSH PRIVILEGES; ausgeführt
  • Danach blockierte read_only = 1 Schreibzugriffe der Applikationsbenutzer korrekt, während die Replikation weiterhin erlaubt blieb

DNS-Vorbereitung

  • Alle Domains wurden über DigitalOcean DNS verwaltet, die Nameserver waren bei GoDaddy angebunden
  • Die Reduzierung der TTL wurde per Skript gegen die DigitalOcean API automatisiert
  • Geändert wurden ausschließlich A- und AAAA-Records
  • MX- und TXT-Records blieben unberührt
    • Wegen möglicher Zustellprobleme bei Google Workspace wurde die TTL mailbezogener Records nicht geändert
  • Nach einer Stunde Wartezeit zum Auslaufen der bisherigen TTL war das Cutover bereit

Umwandlung von Nginx auf dem alten Server in einen Reverse Proxy

  • Statt 34 Konfigurationsdateien manuell zu bearbeiten, wurde die Umstellung per Python-Skript automatisiert
  • Das Skript analysierte die server {}-Blöcke aller Konfigurationsdateien, identifizierte die zentralen Content-Blöcke und ersetzte sie durch Proxy-Konfigurationen
  • Die Originalkonfigurationen wurden als .backup-Dateien gesichert
  • In der Beispielkonfiguration kamen proxy_pass https://NEW_SERVER_IP;, proxy_set_header Host $host;, proxy_set_header X-Real-IP $remote_addr;, proxy_read_timeout 150; zum Einsatz
  • Die entscheidende Option war proxy_ssl_verify off
    • Denn das SSL-Zertifikat auf dem neuen Server war für die Domain gültig, aber nicht für die IP-Adresse
    • Da in diesem Umfeld beide Enden kontrolliert wurden, war das Deaktivieren der Verifikation hier akzeptabel

Cutover-Ablauf

  • Unmittelbar vor dem Cutover waren die Voraussetzungen Seconds_Behind_Master: 0 und ein vorbereiteter Reverse Proxy
  • Die Ausführungsreihenfolge war wie folgt
    • Auf dem neuen Server STOP SLAVE;
    • Auf dem neuen Server SET GLOBAL read_only = 0;
    • Auf dem neuen Server RESET SLAVE ALL;
    • Auf dem neuen Server supervisorctl start all
    • Auf dem alten Server nginx -t && systemctl reload nginx, um den Proxy zu aktivieren
    • Auf dem alten Server supervisorctl stop all
    • Auf dem lokalen Mac python3 do_cutover.py, um alle A-Records im DNS auf die IP des neuen Servers zu ändern
    • Etwa 5 Minuten auf die Propagation warten
    • Auf dem alten Server alle Crontab-Einträge auskommentieren
  • Das DNS-Cutover-Skript rief die DigitalOcean API auf und änderte alle A-Records in rund 10 Sekunden

Zusätzliche Arbeiten nach dem Cutover

  • Nach Abschluss der Migration stellte sich heraus, dass zahlreiche GitLab-Projekt-Webhooks noch immer auf die IP des alten Servers zeigten
  • Deshalb wurde ein Skript geschrieben und angewendet, das über die GitLab API alle Projekte durchsucht und die Webhooks gesammelt aktualisiert

Endergebnis

  • Die monatlichen Kosten sanken von 1.432 US-Dollar auf 233 US-Dollar
  • Die jährliche Ersparnis beträgt 14.388 US-Dollar
  • Auch bei der Performance wurde ein stärkerer Server gewonnen
    • Die CPU stieg von 32 vCPU auf 96 logische CPU
    • Der RAM stieg von 192 GB auf 256 GB DDR5
    • Der Storage wechselte von einer gemischten Konfiguration mit etwa 2,6 TB auf 2 TB NVMe RAID1
    • Die Downtime betrug 0 Minuten
  • Die gesamte Migration dauerte ungefähr 24 Stunden
  • Es gab keine Auswirkungen auf die Nutzer

Zentrale Erkenntnisse

  • MySQL replication ist das wichtigste Mittel für Migrationen ohne Downtime
    • Sinnvoll ist es, die Replikation früh einzurichten, ausreichend aufholen zu lassen und erst dann das Cutover vorzunehmen
  • Die Berechtigungen von MySQL-Benutzern sollten vor der Migration unbedingt geprüft werden
    • Mit SUPER-Berechtigung wird read_only umgangen, wodurch ein Slave-System faktisch nicht wirklich read-only ist
  • DNS-Updates, Änderungen an Nginx-Konfigurationen und Anpassungen an Webhooks sollten skriptgesteuert erfolgen
    • Wer mehr als 34 Sites manuell bearbeitet, riskiert hohen Zeitaufwand und mehr Fehler
  • Die Kombination mydumper + myloader ist bei großen Datensätzen deutlich schneller als mysqldump
    • Durch parallelen Dump und Restore mit 32 Threads wurden Aufgaben von mehreren Tagen auf wenige Stunden verkürzt
  • Bei steady-state Workloads können Cloud-Anbieter teuer sein; ein dedizierter Server kann für geringere Kosten mehr Leistung liefern

GitHub-Skripte

  • Alle für die Migration verwendeten Python-Skripte wurden auf GitHub veröffentlicht
  • Enthaltene Skripte
    • do_list_domains_ttl.py
      • Listet A-Records, IPs und TTL aller DigitalOcean-Domains auf
    • do_ttl_update.py
      • Reduziert die TTL aller A/AAAA-Records gesammelt auf 300 Sekunden
    • do_to_hetzner_bulk_dns_records_import.py
      • Migriert alle DNS-Zonen von DigitalOcean zu Hetzner DNS
    • do_cutover_to_new_ip.py
      • Stellt alle A-Records von der alten Server-IP auf die neue um
    • nginx_reverse_proxy_update.py
      • Wandelt alle nginx-Site-Konfigurationen in Reverse-Proxy-Konfigurationen um
    • mysql_compare.py
      • Vergleicht die Row Counts aller Tabellen auf beiden MySQL-Servern
    • final_gitlab_webhook_update.py
      • Aktualisiert die Webhooks aller GitLab-Projekte auf die neue Server-IP
    • mydumper
      • Die mydumper-Bibliothek
  • Alle Skripte unterstützen einen DRY_RUN = True-Modus, der vor dem tatsächlichen Anwenden eine sichere Vorschau ermöglicht

1 Kommentare

 
GN⁺ 11 일 전
Hacker-News-Kommentare
  • Ich habe vor ein paar Monaten zwei Server von Linode und DO zu Hetzner migriert und dabei die Kosten ähnlich drastisch gesenkt. Noch beeindruckender war, dass dort Dutzende Websites mit verschiedenen Sprachen, alten Bibliotheken sowie MySQL und Redis in einem chaotischen Stack zusammenhingen. Claude Code hat das alles aber komplett umgezogen und bei fehlenden Bibliotheken sogar Teile des Codes neu geschrieben. Solche komplexen Migrationen sind dadurch jetzt viel einfacher, und ich glaube, dass die Mobilität zwischen Anbietern in Zukunft deutlich zunehmen wird

    • Meiner Meinung nach haben die Leute nicht für magisches Compute bezahlt, sondern dafür, 10 Jahre angeklebten Glue-Code nicht anfassen zu müssen. Wenn Agenten anfangen, diesen Glue zu verschlingen, wird der moat der bestehenden Anbieter wohl schnell dünner werden
    • Ehrlich gesagt wirkt das wie eine Claude-Werbung mit eingebauter Hetzner-Werbung. Ich frage mich, wie tief diese Verschachtelung noch geht
    • Ich finde nicht, dass man wirklich jede Geschichte unbedingt zu einer AI-Geschichte machen muss
    • Ich werde Linode in den nächsten Monaten ebenfalls verlassen. Ich nutze es seit über 10 Jahren und habe viele Kunden dorthin vermittelt, aber sie erhöhen immer weiter die Preise, und inzwischen bekommt man bei Anbietern wie Hetzner für weniger Geld 8x mehr RAM, dediziertes NVMe und dedizierte CPU. Man verliert zwar ein wenig den Vorteil der einfachen Portierbarkeit virtueller Server, aber selbst bei Ausfällen war der Hetzner-Support immer schnell und kompetent
    • Ich nutze Claude inzwischen auch immer mehr für DevOps. Ich betreibe VMs auf Proxmox auf meiner eigenen Bare-Metal-Hardware, und Claude optimiert und konfiguriert neue Netzwerke über mehrere Maschinen hinweg extrem schnell, fast wie ein Kollege oder ein gut bezahlter Sysadmin
  • Ich plane gerade einen Umzug von AWS zu Hetzner. Amazon verlangt im Vergleich zur Konkurrenz manchmal 20x höhere Preise, drängt einen für halbwegs vernünftige Preise in langfristige Bindungen und macht auch den Datenabzug extrem teuer, was sich sehr kundenfeindlich anfühlt. Man könnte meinen, dass die Egress-Gebühren Leute festhalten sollen, aber in Wirklichkeit erzeugen sie Druck, gleich alles zu migrieren, sobald man auch nur einen Teil zur Konkurrenz verlagert. Immerhin habe ich meine Plattform nicht auf Amazon-spezifischen Services aufgebaut, dadurch ist der Umzug etwas einfacher

    • Das stimmte früher, aber im Januar 2024 hat GCP eine Richtlinie zum Erlass von Egress-Kosten eingeführt, und ein paar Monate später hat AWS mit einer ähnlichen Regelung nachgezogen. Ich will niemanden zum Bleiben überreden, ich wollte nur darauf hinweisen, dass technisch gesehen ein Waiver-Antrag möglich ist. Wie weit das in der Praxis geht, weiß ich selbst nicht genau, und nach der Formulierung von AWS zu urteilen, spielte wohl auch der EU Data Act eine Rolle
  • Jedes Mal, wenn ich solche Texte sehe, wundere ich mich, dass kaum jemand über Redundanz oder Load Balancer spricht. Wenn ein einzelner Server ausfällt, können mehrere Dienste gleichzeitig offline gehen, und ich frage mich, ob die Leute das wirklich für akzeptabel halten. Vielleicht spart man Geld, aber dafür zahlt man am Ende mehr mit Wartungszeit und künftigen Problemen

    • Ich denke, das hängt von der Art des Dienstes und seiner Kritikalität ab. Wenn ein Server 10 Jahre läuft und in dieser Zeit insgesamt nur etwa 1 Woche bis 1 Monat ausfällt, ist das in vielen Fällen völlig akzeptabel. Für kleine Unternehmen, Hobbyseiten, Foren oder Blogs, bei denen die Website nicht das Kerngeschäft ist, muss eine kurze Downtime kein großes Problem sein. Tatsächlich könnte dieser Long Tail an Low-Traffic-Sites den Großteil des Webs ausmachen. Nicht alles braucht Hochverfügbarkeit, und wenn man will, bieten solche Anbieter auch Funktionen wie Load Balancer an
    • Ich denke, solche Beiträge werden beliebt, weil sie oft eine Diskrepanz zwischen Anforderungen und Lösung sichtbar machen. Wenn ein Hobbyprojekt oder ein kleines Unternehmen mit Enterprise-Architektur überengineert wurde, obwohl ein gelegentlicher Ausfall von einem Tag völlig okay wäre, braucht man vielleicht gar kein voll ausgestattetes Cloud-Setup. In diesem Fall war es aber etwas merkwürdig, dass der Beitrag Zero-Downtime-Migration betonte, die Zielarchitektur dann aber nicht besonders ausfalltolerant wirkte. Mit nur ein wenig zusätzlicher Struktur auf Hetzner-Seite hätte man das wohl deutlich verbessern können
    • Für viele Workloads ist so ein Absicherungsniveau gar nicht nötig. Und man sollte die Zuverlässigkeit von Einfachheit nicht unterschätzen. Ich habe lange als Linux-Sysadmin gearbeitet und in komplexen Systemen deutlich mehr Downtime gesehen als in einfachen. Irgendwo zwischen Theorie und Realität hatte ich am Ende meist den Eindruck, dass die einfache Variante robuster ist
    • Fairerweise muss man sagen, dass ursprünglich ohnehin nur eine einzelne VM bei DigitalOcean lief, also wurden die Vorteile eines Cloud-Anbieters gar nicht besonders stark genutzt. Solche Geschichten teilen sich meist in Fälle, die aus den falschen Gründen in der Cloud gelandet sind und besser auf physischer Hardware laufen, und in Fälle, in denen genau so ein Wechsel katastrophal wäre. Dieser hier wirkt eher wie Ersteres. Wenn das Setup bei DO stabil lief, dürfte es bei Hetzner mit einer passenden DR-Strategie ebenfalls gut funktionieren
    • Vielleicht basiert diese Entscheidung auch einfach auf der Erfahrung, tatsächlich lange kaum Wartungshölle oder spätere Kopfschmerzen erlebt zu haben
  • Wir haben bei lithus.eu schon häufig Kunden von verschiedenen Clouds zu Hetzner migriert. Meist bauen wir Multi-Server-Setups, manchmal auch über mehrere AZs hinweg, und verteilen die Workloads mit Kubernetes, um HA bereitzustellen. Für einen einzelnen Node wäre Kubernetes womöglich zu viel, aber mit mehreren Nodes ergibt es deutlich mehr Sinn. Für Backups nutzen wir Velero zusammen mit Backups auf Anwendungsebene; bei Postgres etwa kommen WAL-Backups für PITR dazu. Zustandsdaten halten wir auf mindestens zwei Nodes, um HA sicherzustellen. Auch leistungsmäßig ist Bare Metal meistens besser, und im Vergleich zu AWS haben wir oft die Latenz halbiert. Ich glaube, das liegt weniger an der Virtualisierung selbst als an Randfaktoren wie NVMe, niedriger Netzwerklatenz und geringerer Cache Contention. Mehr dazu hatte ich schon einmal in einem HN-Beitrag geschrieben

    • Ich habe das vor ein paar Jahren auch selbst gemessen und seitdem keine virtuellen Server mehr angerührt. CPU-Zeit wird im Gegensatz zu RAM nicht wirklich reserviert, daher war die Leistung gegenüber echter Hardware ziemlich schwach. Dieser Messbericht ist ebenfalls lesenswert
    • k8s-Deployments lassen sich meiner Meinung nach wirklich gut zwischen Anbietern verschieben. Im Vergleich zu Managed Services verschiedener Clouds hat man deutlich weniger Vendor Lock-in. Mein eigener Stack besteht auch nur aus k8s, gehostetem Postgres und S3-artigem Storage; Postgres könnte ich jederzeit selbst hosten, also bleiben im Kern eigentlich nur k8s und S3 übrig. Ich glaube, Hetzner hat auch etwas S3-Ähnliches, aber ich habe mir das noch nicht angesehen, und 100 TB umzuziehen wäre schon ein ziemlich großes Projekt
    • Zur Einordnung: HA steht für High Availability
    • Der Artikel war vernünftig, aber die E-Mail-Adresse am Ende wirkte leider etwas wie Werbetext
  • Dieser Text war ziemlich schwer zu lesen. Es fühlte sich an, als hätte Claude die Migration gemacht und anschließend auch noch den Bericht darüber geschrieben. Wenn dank LLMs wirklich so viel gespart wurde, ist das großartig, aber wenn man so etwas veröffentlicht, sollte man es wenigstens redigieren und Wiederholungen sowie den LLM-Stil bereinigen

    • Ich weiß, dass viele den Originaltext nicht lesen, aber dieser hier war wirklich auf einem schmerzhaften Niveau schwer lesbar
  • Bei Hetzner wäre ich vorsichtig. Früher mochte ich sie sehr, bin inzwischen aber weg. Sie haben rund 30 VMs aus unserer CI/CD-Pipeline komplett abgeschaltet wegen eines einzigen Abrechnungsstreits über 36 Dollar. Wir haben vollständige Zahlungsnachweise inklusive Bankunterlagen eingereicht, aber sie wollten sie nicht ansehen und haben uns trotz hektischer Kontaktversuche am Ende komplett ausgesperrt. Inzwischen sind wir zu Scaleway gewechselt

    • Ich finde den Kundenservice überraschend feindselig. Für nicht kritische Einsatzzwecke nutze ich sie aber noch immer
    • Die Abrechnungsabwicklung bei Hetzner ist ziemlich automatisiert, aber normalerweise bekommt man bei fehlgeschlagenen Kartenzahlungen ungefähr einen Monat Zahlungsaufschub
  • Vor ein paar Monaten habe ich für ein kleines SaaS-Nebenprojekt nach einer AWS-Alternative gesucht und mir Hetzner zunächst ernsthaft angesehen, sowohl zur Kostensenkung als auch zur Unterstützung einer EU-Cloud. Ich war bereit, mehr selbst zu machen, aber am Ende hat mich der Punkt IP-Reputation ausgebremst. Eine der gemanagten AWS-Firewall-Regeln in unserem Unternehmen blockierte viele, vielleicht sogar alle Hetzner-IPs, und selbst auf meinem Arbeitslaptop ließen sich Websites auf Hetzner-IPs wegen IT-Richtlinien nicht öffnen. Mit etwas wie Cloudflare wäre es vielleicht weniger problematisch, aber ich habe auch gelesen, dass der DDoS-Schutz schwächer sein soll. Am Ende habe ich mich für die DO App Platform in einer EU-Region entschieden, und auch die Managed-DB-Optionen waren ein großer Pluspunkt

    • Wenn Amazon Konkurrenten auf diese Weise blockiert, ist das aus deren Sicht natürlich eine ziemlich bequeme Methode
    • Ich weiß nicht, welche Firewall-Regel du meinst, aber dass DO als vertrauenswürdiger als Hetzner gilt, überrascht mich ziemlich. Wenn ich Scraper oder Hacker sehe, taucht die DO-ASN auch häufig auf, also könnte sie irgendwann genauso blockiert werden
    • Nach meiner Erfahrung waren DO-IPs noch schlimmer. Genau deshalb bin ich auch von DO weg
    • Ich hatte dieses Thema früher schon in einem Thread zu Tor erwähnt. Ich vermutete, dass Hetzner wegen seiner Tor-Freundlichkeit Probleme mit der IP-Reputation haben könnte, damals bekam ich aber auch Antworten, dass es keine Reputationsprobleme gebe. Als ich dann in das Material des Tor Project geschaut habe, sah es so aus, als würde Hetzner rund 7 % des Tor-Netzwerks stellen, also scheint die Sache nicht ganz so einfach zu sein
    • Ironischerweise habe ich 99 % der Bot-Probleme gelöst, indem ich einfach AWS und Azure blockiert habe. Es gab dabei null Schäden für echte Nutzer, und deshalb überlege ich inzwischen, ob man diesen Blockiermechanismus nicht direkt als Service verkaufen könnte
  • Solche Migrationsberichte zu teilen, ist wirklich nützlich, und ich bin dankbar dafür. Ich sehe den Vergleich zwischen DO und Hetzner ungefähr als Trade-off zwischen DoorDash oder UberEats einschalten und das Abendessen selbst kochen. Auch das Kostenverhältnis fühlt sich ähnlich an. Ich arbeite mit den drei großen Clouds und On-Prem, gehe für Kleinkram oder PoC-Tests aber immer noch gern in die DigitalOcean-Konsole. Diese Bequemlichkeit, mit ein paar Klicks einen Server oder Bucket bereitzustellen, sinnvolle Defaults zu haben und Backups per Checkbox zu aktivieren, hat bei berücksichtigtem Zeitwert definitiv ihren Platz

    • Ich bin mir nicht ganz sicher, wie genau du das meinst, aber ich finde, dass die Hetzner-Konsole ähnlich funktioniert
    • Zwei Dinge fand ich an diesem Beitrag interessant. Zum einen die eigentliche Zero-Downtime-Migrationsprozedur, die sich allgemein als Referenz eignet. Zum anderen die Entscheidung, Cloud-Instanzen durch Bare Metal zu ersetzen; bei der Kostenersparnis muss man dann aber auch langsameres Failover und mögliche Backup-Verluste mit einpreisen. Ich hätte wahrscheinlich etwa 200 Dollar mehr ausgegeben, einen Hot Spare hingestellt und alle paar Tage aktiv/passiv getauscht, um sicherzustellen, dass beide wirklich funktionieren. Für relativ wenig Zusatzkosten lässt sich so das Risiko eines Totalausfalls stark senken
    • Was du gerade beschrieben hast, entspricht in Wirklichkeit ziemlich genau der Erfahrung, die Hetzner Cloud schon seit Jahren bietet. Dazu gibt es auch die Hetzner Cloud API, sodass man sogar die Klicks überspringen und alles per IaC aufsetzen kann
    • Bei mir läuft Coolify auf Hetzner-Servern, und damit bekomme ich fast ein One-Click-Service-Erlebnis
    • Als ich das gelesen habe, musste ich einfach an dieses xkcd denken
  • Ich habe mich gefragt, wie die DB-Backups gemacht werden. Ob es Replicas oder Standbys gibt oder nur stündliche Backups. Bei so einer Einzelserver-Konfiguration kann ein Hardwaredefekt wie ein SSD-Ausfall die Anwendung sofort stoppen, und gerade wenn eine SSD stirbt, kann man schnell Stunden oder sogar Tage offline sein, während man alles neu aufsetzt

    • Hetzner bewirbt Hardware-Server meist mit 2x 1TB SSD und empfiehlt für 1 TB nutzbaren Speicher ausdrücklich ein SW-RAID1-Setup. Der Image-Installer ist standardmäßig auch in diese Richtung ausgelegt. Wenn nach ein paar Jahren die erste SSD ausfällt und das Monitoring anschlägt, kann man auf einen neuen Host umziehen, eine Zwischenlösung oder ein Replica verwenden oder auf der anderen Platte weiterlaufen und den Hot-Swap abwarten. Klar ist aber auch: Wenn man auf physische Server geht, verliert man einen Teil der Redundanzvorteile der Cloud, und das muss man zusammen mit der Ersparnis in das Risikomodell einrechnen. Und wenn es nicht einmal tägliche Backups in Remote-Storage gibt, wäre das in meinen Augen fahrlässig. Das gilt in der Cloud genauso, dort ist die Einrichtung nur leichter
    • Es könnte auch einfach sein, dass sich kaum jemand daran stört, wenn so lange etwas ausfällt. Wenn zum Beispiel die Mobile-App meiner HOA eine Woche nicht funktioniert, ist mir das ziemlich egal. Nicht alles muss ständig verfügbar sein
    • Ich hatte denselben Gedanken. Der Beitrag wirkte so, als hätte der Autor vor allem auf aggressive Kostensenkung geschaut, ohne die Sache ausreichend zu durchdenken. Die DigitalOcean-VM unterstützte wahrscheinlich Live-Migration und Snapshots, während das bei Hetzner nur im Cloud-Produkt möglich ist. Bei Hetzner Bare Metal gilt: Wenn eine Platte oder ein Bauteil stirbt, ist es eben kaputt, und selbst wenn die Platte getauscht wird, muss der Nutzer die Wiederherstellung komplett selbst übernehmen. Hetzner weist an mehreren Stellen ziemlich klar darauf hin
    • Das Einfachste, was ich je gemacht habe, war bei MongoDB; Replication, Sharding und Failover waren dort sehr simpel. Zuletzt habe ich bei PostgreSQL mit pg_auto_failover ein Setup aus 1 Monitor, 1 Primary und 1 Replica gebaut, und nachdem ich die Konfiguration und ein paar Fallstricke verstanden hatte, war auch das ziemlich einfach. Meiner Erfahrung nach war damit sogar eine Zero-Downtime-Migration möglich
    • Wenn sie entschieden haben, diese Trade-offs zu akzeptieren, kann man nicht pauschal sagen, dass das falsch ist. Nicht jede Anwendung braucht 24/7-Verfügbarkeit, und die meisten Websites verkraften einige Stunden Downtime ohne großen Schaden. Wenn die Kosteneinsparung schwerer wiegt als das Risiko, kann das eine völlig vernünftige geschäftliche Entscheidung sein. Mich würde eher interessieren, welche Backup- und Recovery-Strategie sie haben und was sich durch den Umzug zu Hetzner daran geändert hat
  • Das Meme-Bild im Header war von mir. Ich hatte es in diesem Beitrag verwendet, und ich fand es schön zu sehen, dass es jetzt schon zum zweiten Mal auftaucht