Skip to content

Migrazione — dentro e fuori

Il no-lock-in è una promessa solo se puoi davvero esercitarla. Questa pagina documenta l’handover (lo spostamento di un cluster tra il control plane hosted di kubehz e la tua infrastruttura) in entrambe le direzioni, esattamente come funziona oggi.

Cosa è attivo oggi

Hosted → self-hosted (eject) è attivo. Puoi spostare il tuo control plane hosted sulla tua infrastruttura Hetzner mantenendo l’identità crittografica del cluster: i tuoi worker, i kubeconfig e i secret continuano a funzionare.

Self-hosted → hosted (adopt) è attivo come recreation. kubehz avvia un control plane hosted nuovo e tu vi sposti i tuoi workload. Il cluster riceve una nuova identità. Un adopt che preserva l’identità è pianificato; finché non arriva, questa pagina lo dice chiaramente invece di fingere il contrario.

Per i concetti dietro tutto questo (perché a spostarsi è l’identità, e perché nulla viene eliminato senza il tuo consenso), vedi Come funziona l’handover.

Le due direzioni

DirezioneCosa succedeStato
Eject: hosted → la tua infrastrutturaIl tuo control plane hosted viene ripristinato su macchine di tua proprietà, con la stessa identità. I worker restano.Attivo
Adopt: il tuo cluster → hostedkubehz crea un control plane hosted nuovo; tu vi sposti i workload. Nuova identità.Attivo (recreation)

Eject è per quando vuoi la piena proprietà: esigenze di compliance, controllo dei costi su larga scala, o semplicemente perché puoi. La porta d’uscita è la prova che hosted è una scelta, non una trappola.

Adopt è per quando non vuoi più gestire un control plane da solo e vuoi tenere sul tuo account soltanto i worker.

Prima viene l’assessment

Nulla si muove finché non hai visto il piano. La piattaforma raccoglie in continuo un assessment in sola lettura del tuo cluster (versione Kubernetes, datastore, storage class, load balancer, gestione CAPI) e ne deriva un percorso di fattibilità più un report di traduzione, l’elenco delle cose che non si trasferiscono automaticamente e richiedono la tua attenzione:

  • Storage class legate al provider: i volumi provisionati dal driver CSI di un provider non seguono il control plane verso un altro.
  • Service di tipo LoadBalancer: i load balancer cloud sono legati al provider che li ha creati.
  • Cluster gestiti da CAPI: un cluster il cui ciclo di vita è guidato da Cluster API richiede che quella gestione sia messa in pausa prima che un handover abbia senso.

Consultabile in qualsiasi momento dalla CLI (legge il registro del tuo tenant, quindi richiede KUBEHZ_TOKEN):

bash
lo kubehz assess

La dashboard mostra lo stesso assessment e la fattibilità sulla pagina del cluster. Il percorso di fattibilità è uno tra:

PercorsoSignificato
restoreSpostamento via snapshot + seed dell’identità. Ciò che eject usa oggi.
recreationUn control plane nuovo; i workload si spostano riapplicandoli. Ciò che adopt usa oggi.
graftUn trasferimento live, sul posto. Valutato e riportato, ma non ancora eseguibile; è nella roadmap.

Hosted → self-hosted (eject)

Eject sposta il tuo control plane hosted su infrastruttura di tua proprietà, mantenendo l’identità del cluster: la certificate authority (CA), le chiavi di firma dei service account, la chiave di cifratura dei secret e ogni oggetto del cluster (tramite uno snapshot di etcd). Poiché l’identità è preservata:

  • I tuoi worker continuano a funzionare: si fidano già della CA del cluster e dopo il cutover si riconnettono allo stesso cluster logico.
  • I kubeconfig e i token dei service account esistenti restano validi.
  • I secret si decifrano: la chiave di cifratura viaggia con il cluster.

Il flusso

  1. Assessment: lo kubehz assess (o la dashboard). Conferma che il percorso sia restore e leggi il report di traduzione.

  2. Avvia l’handover: dalla scheda Handover del cluster nella dashboard (o via API). Scegli il driver di destinazione (kubeadm o kubeone) e se mantenere o ruotare l’endpoint.

  3. La piattaforma esporta: assembla l’export bundle (la PKI del cluster, le chiavi dei service account e la chiave di cifratura) e crea uno snapshot fresco di etcd.

  4. Scarica il bundle: il download richiede una nuova autenticazione, è monouso ed è registrato nell’audit log. Il bundle è l’identità radice del tuo cluster: trattalo come una credenziale root ed elimina la copia locale una volta completato l’handover.

  5. Prepara la destinazione: una macchina (o più macchine) di tua proprietà, raggiungibile dai tuoi worker. Nel concreto:

    • Raggiungibile su 6443 da ogni worker: è l’endpoint API che lok8s configura. Una destinazione dietro NAT senza 6443 in ingresso è la causa tipica di un restore che sembra riuscito e poi lascia i worker bloccati.
    • Dimensiona sopra le riserve, non su di esse. Su un nodo control plane lok8s riserva 400m di CPU e 1 GiB di memoria per sistema e kubelet prima di qualsiasi workload, e il kubelet inizia a sfrattare i pod quando la memoria disponibile scende sotto 500 MiB. 2 GB sono quindi il minimo, non una taglia di lavoro. Le nostre configurazioni di riferimento usano cx33 per i control plane. Vedi la guida KubeOne.
    • Uno o tre nodi, mai due: etcd ha bisogno di un numero dispari per mantenere il quorum.
    • Un nodo esegue al massimo 110 pod, il valore per cui è configurato il kubelet del control plane.
    • lok8s installato sul target, con i privilegi per usarlo. receive gira su quella macchina, non dalla tua workstation: scrive /etc/kubernetes e /var/lib/etcd e invoca kubeadm.
    • Il bundle sul target. Il passo 4 lo scarica dove lo hai eseguito; trasferiscilo su un canale di cui ti fidi ed elimina entrambe le copie una volta confermato il passo 7. In transito è l’identità root del tuo cluster.
    • Un nodo pulito. receive rifiuta una macchina che porta già stato Kubernetes; su un nodo già usato esegui prima tu kubeadm reset.
  6. Ripristina sulla destinazione:

    bash
    # driver kubeadm: esegui direttamente sul nodo di destinazione
    lo kubehz handover receive --bundle ./bundle.tar.gz
    
    # driver kubeone: prima semina l'identità, poi effettua il provisioning come al solito
    lo kubehz handover preseed --bundle ./bundle.tar.gz --node "<node-ip>"
    lo provision

    receive accetta --snapshot <file> per ripristinare uno snapshot di etcd scaricato a parte, --single-node per un control plane a nodo singolo e --force per sovrascrivere un nodo che porta già stato Kubernetes (al posto del kubeadm reset qui sopra). preseed raggiunge il nodo via SSH: --user (default root), --port (default 22) e --ssh-key scelgono come.

    receive semina l’identità esportata, ripristina lo snapshot di etcd e avvia un control plane che è il tuo cluster: stessa CA, stesse chiavi, stessi oggetti.

  7. Cutover: punta il DNS dell’endpoint del cluster al nuovo control plane. I worker si riconnettono da soli; su di loro non cambia nulla. Poi conferma il cutover: la piattaforma attende la tua conferma esplicita e prima di essa non fa nulla di distruttivo.

  8. Decommission: il vecchio control plane hosted viene rimosso solo quando due cose sono vere. La piattaforma deve aver visto il tuo nuovo control plane vivo (heartbeat), e devi aver confermato esplicitamente il decommissioning. Fino ad allora il vecchio control plane resta intatto come tua rete di sicurezza.

Cosa fai al cutover

L’unica azione che spetta solo a te: ripuntare il DNS dell’endpoint del cluster al nuovo control plane. Tutto ciò che viene prima è reversibile; la piattaforma non tocca mai il tuo DNS al posto tuo. Se qualcosa non convince, non confermare: un handover fermato mantiene tutto lo stato su entrambi i lati.

Self-hosted → hosted (adopt)

Adopt affida a kubehz la gestione del control plane: sul tuo account Hetzner tieni solo i worker. Oggi adopt funziona per recreation, e lo diciamo chiaramente:

  • kubehz crea un control plane hosted nuovo con una nuova identità (nuova CA, nuove chiavi). Sulla piattaforma è un nuovo cluster.
  • I tuoi workload si spostano riapplicandoli (dal tuo repo GitOps o dai manifest) sul nuovo cluster. È il momento in cui una configurazione dichiarativa ripaga.
  • I dati persistenti non si spostano automaticamente. Ripristinali dai tuoi backup o riprovisionali. Un data mover automatico non esiste ancora, quindi non fingeremo che esista.
  • I nodi si uniscono da zero: i worker partono contro il nuovo control plane tramite i pool di worker; i vecchi kubeconfig e token non valgono più.

L’assessment e il report di traduzione girano prima, esattamente come per eject, così sai di storage legato al provider, load balancer e gestione CAPI prima che qualcosa venga creato.

Perché recreation? Lo stack del control plane gestito conia l’identità di un cluster al momento della creazione. Inserirvi in modo affidabile la tua identità esistente richiede un passaggio “crea in pausa, poi semina” che è progettato e pianificato. Quando arriverà, adopt preserverà l’identità come eject fa già oggi. Fino ad allora, adopt significa: control plane nuovo, workload riapplicati.

Nessun lock-in, con o senza migrazione

L’handover è la forma forte della promessa, ma vincolato non lo sei mai stato:

  • lok8s è open source ed esegue il provisioning del tuo cluster sul tuo account Hetzner.
  • L’integrazione con la dashboard è opt-in e solo in uscita; kubehz non detiene alcuna credenziale in ingresso verso il tuo cluster.
  • Rimuovere kubehz da un cluster self-hosted sono due comandi: lo kubehz deregister annulla la registrazione (richiede KUBEHZ_TOKEN), e l’eliminazione del namespace kubehz-system rimuove l’agent nel cluster. L’RBAC a livello di cluster dell’agent (il suo ClusterRole e ClusterRoleBinding, più un Role in kube-system) sopravvive al namespace; elimina anche quegli oggetti se vuoi un cluster pulito. Il tuo cluster continua a funzionare esattamente come prima.

Prossimi passi


Stato del documento

AspettoDettaglio
Statoeject attivo (basato su restore); adopt attivo come recreation; adopt con identità preservata pianificato
Ultima revisione2026-09-05