Migration — rein und raus
Kein Lock-in ist nur dann ein Versprechen, wenn du es tatsächlich einlösen kannst. Diese Seite dokumentiert das Handover (das Verschieben eines Clusters zwischen der gehosteten Control Plane von kubehz und deiner eigenen Infrastruktur) in beide Richtungen, genau so, wie es heute funktioniert.
Was heute live ist
Hosted → Self-Hosted (Eject) ist live. Du kannst deine gehostete Control Plane auf deine eigene Hetzner-Infrastruktur verschieben und behältst dabei die kryptografische Identität des Clusters: Deine Worker, Kubeconfigs und Secrets funktionieren weiter.
Self-Hosted → Hosted (Adopt) ist live als Recreation. kubehz stellt eine frische gehostete Control Plane bereit und du ziehst deine Workloads darauf um. Der Cluster bekommt eine neue Identität. Ein identitätserhaltendes Adopt ist geplant; bis es ausgeliefert ist, sagt diese Seite das offen, statt etwas anderes vorzutäuschen.
Die Konzepte dahinter (warum die Identität das ist, was umzieht, und warum nichts ohne deine Zustimmung gelöscht wird) findest du unter So funktioniert Handover.
Die zwei Richtungen
| Richtung | Was passiert | Status |
|---|---|---|
| Eject: Hosted → deine Infrastruktur | Deine gehostete Control Plane wird auf deinen eigenen Maschinen wiederhergestellt, mit derselben Identität. Worker bleiben. | Live |
| Adopt: dein Cluster → Hosted | kubehz erstellt eine frische gehostete Control Plane; du ziehst Workloads darauf um. Neue Identität. | Live (Recreation) |
Eject ist für den Moment, in dem du volle Eigentümerschaft willst: Compliance-Anforderungen, Kostenkontrolle im großen Maßstab oder einfach, weil du es kannst. Die Ausgangstür ist der Beweis, dass Hosted eine Wahl ist und keine Falle.
Adopt ist für den Moment, in dem du keine Control Plane mehr selbst betreiben willst und nur noch Worker auf deinem Konto behältst.
Zuerst kommt das Assessment
Nichts bewegt sich, bevor du den Plan gesehen hast. Die Plattform sammelt kontinuierlich ein rein lesendes Assessment deines Clusters (Kubernetes-Version, Datastore, Storage-Klassen, Load Balancer, CAPI-Verwaltung) und leitet daraus einen Machbarkeitspfad plus einen Übersetzungsbericht ab, die Liste der Dinge, die nicht automatisch mitwandern und deine Aufmerksamkeit brauchen:
- Provider-gekoppelte Storage-Klassen: Volumes, die vom CSI-Treiber eines Providers bereitgestellt wurden, folgen der Control Plane nicht zu einem anderen.
LoadBalancer-Services: Cloud-Load-Balancer sind an den Provider gebunden, der sie erstellt hat.- CAPI-verwaltete Cluster: ein Cluster, dessen Lebenszyklus von Cluster API gesteuert wird, braucht eine pausierte Verwaltung, bevor ein Handover sinnvoll ist.
Jederzeit einsehbar über die CLI (sie liest die Registry deines Tenants und braucht deshalb KUBEHZ_TOKEN):
lo kubehz assessDas Dashboard zeigt dasselbe Assessment samt Machbarkeit auf der Cluster-Seite. Der Machbarkeitspfad ist einer von:
| Pfad | Bedeutung |
|---|---|
restore | Umzug per Snapshot + Identitäts-Seed. Was Eject heute nutzt. |
recreation | Eine frische Control Plane; Workloads ziehen per Re-Apply um. Was Adopt heute nutzt. |
graft | Ein Live-Transfer an Ort und Stelle. Wird bewertet und ausgewiesen, ist aber noch nicht ausführbar; er steht auf der Roadmap. |
Hosted → Self-Hosted (Eject)
Eject verschiebt deine gehostete Control Plane auf Infrastruktur, die dir gehört, und behält die Identität des Clusters: die Zertifizierungsstelle (CA), die Service-Account-Signaturschlüssel, den Verschlüsselungsschlüssel für Secrets und jedes Objekt im Cluster (per etcd-Snapshot). Weil die Identität erhalten bleibt:
- Deine Worker funktionieren weiter: Sie vertrauen bereits der CA des Clusters und verbinden sich nach dem Cutover mit demselben logischen Cluster.
- Bestehende Kubeconfigs und Service-Account-Tokens bleiben gültig.
- Secrets lassen sich entschlüsseln: Der Verschlüsselungsschlüssel reist mit dem Cluster.
Der Ablauf
Assessment:
lo kubehz assess(oder das Dashboard). Bestätige, dass der Pfadrestoreist, und lies den Übersetzungsbericht.Handover starten: über den Handover-Tab des Clusters im Dashboard (oder per API). Du wählst den Ziel-Treiber (
kubeadmoderkubeone) und ob der Endpoint erhalten bleibt oder rotiert wird.Die Plattform exportiert: Sie stellt das Export-Bundle zusammen (die PKI des Clusters, Service-Account-Schlüssel und Verschlüsselungsschlüssel) und erstellt einen frischen etcd-Snapshot.
Bundle herunterladen: Der Download erfordert eine erneute Authentifizierung, ist einmalig und wird audit-protokolliert. Das Bundle ist die Root-Identität deines Clusters: Behandle es wie ein Root-Credential und lösche deine lokale Kopie, sobald das Handover abgeschlossen ist.
Ziel vorbereiten: eine Maschine (oder Maschinen) in deinem Besitz, erreichbar für deine Worker. Konkret:
- Auf
6443erreichbar von jedem Worker: Das ist der API-Endpunkt, den lok8s konfiguriert. Ein Ziel hinter NAT ohne eingehenden6443ist die übliche Ursache dafür, dass ein Restore scheinbar gelingt und die Worker danach hängen bleiben. - Oberhalb der Reservierungen dimensionieren, nicht auf ihnen. Auf einem Control-Plane-Node reserviert lok8s
400mCPU und1 GiBArbeitsspeicher für System und kubelet, bevor irgendeine Workload läuft; das kubelet verdrängt Pods, sobald weniger als500 MiBverfügbar sind. 2 GB sind damit die Untergrenze, keine Arbeitsgröße. Unsere eigenen Referenzkonfigurationen nutzencx33für Control Planes. Siehe den KubeOne-Leitfaden. - Ein oder drei Nodes, niemals zwei: etcd braucht eine ungerade Anzahl für das Quorum.
- Ein Node führt höchstens 110 Pods aus. Dafür ist das Control-Plane-kubelet konfiguriert.
- lok8s auf dem Ziel installiert, mit ausreichenden Rechten.
receiveläuft auf dieser Maschine, nicht auf deiner Workstation: Es schreibt/etc/kubernetesund/var/lib/etcdund ruftkubeadmauf. - Das Bundle auf dem Ziel. Schritt 4 lädt es dort herunter, wo du ihn ausgeführt hast; übertrage es über einen vertrauenswürdigen Kanal und lösche beide Kopien, sobald Schritt 7 bestätigt ist. Es ist die Root-Identität deines Clusters während der Übertragung.
- Ein sauberer Knoten.
receiveverweigert eine Maschine, die bereits Kubernetes-Zustand trägt; führe auf einem zuvor genutzten Knoten zuerst selbstkubeadm resetaus.
- Auf
Restore auf dem Ziel:
bash# kubeadm-Treiber: direkt auf dem Ziel-Node ausführen lo kubehz handover receive --bundle ./bundle.tar.gz # kubeone-Treiber: Identität vorab einspielen, dann wie gewohnt provisionieren lo kubehz handover preseed --bundle ./bundle.tar.gz --node "<node-ip>" lo provisionreceivekennt--snapshot <file>, um einen separat heruntergeladenen etcd-Snapshot wiederherzustellen,--single-nodefür eine Control Plane mit einem Node und--force, um einen Node zu überschreiben, der bereits Kubernetes-Zustand trägt (statt deskubeadm resetoben).preseederreicht den Node per SSH:--user(Standardroot),--port(Standard22) und--ssh-keylegen fest, wie.receivespielt die exportierte Identität ein, stellt den etcd-Snapshot wieder her und startet eine Control Plane, die dein Cluster ist: dieselbe CA, dieselben Schlüssel, dieselben Objekte.Cutover: Richte den Endpoint-DNS des Clusters auf deine neue Control Plane. Worker verbinden sich von selbst neu; auf ihnen ändert sich nichts. Dann bestätige den Cutover: Die Plattform wartet auf deine ausdrückliche Bestätigung und tut davor nichts Destruktives.
Decommission: Die alte gehostete Control Plane wird erst entfernt, wenn zwei Dinge zutreffen. Die Plattform hat deine neue Control Plane lebendig gesehen (Heartbeats), und du hast das Decommissioning ausdrücklich bestätigt. Bis dahin bleibt die alte Control Plane als dein Fallback intakt.
Was du beim Cutover tust
Die eine Aktion, die allein dir gehört: den Endpoint-DNS des Clusters auf die neue Control Plane richten. Alles davor ist umkehrbar; die Plattform ändert deinen DNS niemals für dich. Wenn etwas falsch aussieht, bestätige nicht: Ein angehaltenes Handover behält den gesamten Zustand auf beiden Seiten.
Self-Hosted → Hosted (Adopt)
Adopt übergibt den Betrieb der Control Plane an kubehz: Du behältst nur Worker auf deinem Hetzner-Konto. Heute funktioniert Adopt per Recreation, und das sagen wir offen:
- kubehz erstellt eine frische gehostete Control Plane mit einer neuen Identität (neue CA, neue Schlüssel). Auf der Plattform ist es ein neuer Cluster.
- Deine Workloads ziehen per Re-Apply um (aus deinem GitOps-Repo oder deinen Manifesten) auf den neuen Cluster. Das ist der Moment, in dem sich ein deklaratives Setup auszahlt.
- Persistente Daten ziehen nicht automatisch um. Stelle sie aus deinen eigenen Backups wieder her oder provisioniere sie neu. Einen automatisierten Data Mover gibt es noch nicht, also tun wir nicht so.
- Nodes treten frisch bei: Worker starten gegen die neue Control Plane über Worker-Pools; alte Kubeconfigs und Tokens gelten nicht weiter.
Assessment und Übersetzungsbericht laufen zuerst, genau wie beim Eject. Du weißt also über provider-gekoppelten Storage, Load Balancer und CAPI-Verwaltung Bescheid, bevor irgendetwas erstellt wird.
Warum Recreation? Der verwaltete Control-Plane-Stack prägt die Identität eines Clusters bei der Erstellung. Deine bestehende Identität zuverlässig hineinzubringen erfordert einen Schritt „pausiert erstellen, dann seeden“, der entworfen und geplant ist. Sobald er ausgeliefert wird, erhält Adopt die Identität so, wie Eject es heute schon tut. Bis dahin bedeutet Adopt: frische Control Plane, Workloads neu angewendet.
Kein Lock-in: mit oder ohne Migration
Handover ist die starke Form des Versprechens, aber gebunden warst du nie:
- lok8s ist Open Source und stellt deinen Cluster auf deinem Hetzner-Konto bereit.
- Die Dashboard-Integration ist optional und nur ausgehend; kubehz hält keine eingehenden Zugangsdaten für deinen Cluster.
- kubehz von einem Self-Hosted-Cluster zu entfernen sind zwei Befehle:
lo kubehz deregistermeldet ihn ab (brauchtKUBEHZ_TOKEN), und das Löschen deskubehz-system-Namespace entfernt den clusterinternen Agenten. Das clusterweite RBAC des Agents (seineClusterRoleundClusterRoleBindingsowie eineRoleinkube-system) überlebt den Namespace; lösche auch diese Objekte, wenn du einen sauberen Cluster willst. Dein Cluster läuft genau wie zuvor weiter.
Nächste Schritte
- So funktioniert Handover: Identität vs. Infrastruktur, und warum der Prozess auf dich wartet
- Gehostete Control Plane: der Hosted-Weg
- Worker-Pools: wo deine Worker im Hosted-Modus leben
- KubeOne auf Hetzner: das Self-Hosted-Ziel, auf dem die meisten Ejects landen
Doku-Status
| Aspekt | Detail |
|---|---|
| Zustand | Eject live (restore-basiert); Adopt live als Recreation; identitätserhaltendes Adopt geplant |
| Zuletzt geprüft | 2026-09-05 |