Primo cluster
Una guida dettagliata al file di configurazione cluster.lok8s.yaml.
Prerequisiti
- CLI lok8s installata
- Un account Hetzner Cloud con un token API
- Una coppia di chiavi SSH (Ed25519 consigliata)
- Un dominio che controlli: l’endpoint API e i nomi dei certificati derivano da lì (come
spec.cluster.domain;example.comsotto è un segnaposto)
Riferimento completo di configurazione
Mostra il cluster.lok8s.yaml completo
# clusters/example.com/cluster.lok8s.yaml
apiVersion: cluster.lok8s.dev/v1beta1
kind: KubeOne
metadata:
name: my-cluster
spec:
kubernetes:
version: "v1.35.5"
cluster:
# OBBLIGATORIO: un dominio che controlli; per ingress e certificati
domain: example.com
# namespace predefinito per i workload
namespace: default
provider:
name: hetzner
# Le macchine, nei termini di Hetzner. Ogni voce `server` diventa un
# `hcloud server create`; le sue chiavi sono flag di hcloud. Se preferisci
# uno spec più corto, metti lo stesso contenuto in un file separato e
# puntaci con `configRef: hetzner.json`.
config:
cluster_name: my-cluster
sshUser: root
sshPrivateKey: ~/.ssh/id_ed25519
sshPublicKey: ~/.ssh/id_ed25519.pub
ssh-key:
- name: my-cluster
public-key-from-file: ~/.ssh/id_ed25519.pub
network:
- name: my-cluster
# intervallo della rete privata
ip-range: 10.0.0.0/16
"#subnets":
- network-zone: eu-central
type: cloud
ip-range: 10.0.0.0/24
server:
# 3 control plane per l'HA; 1 basta per lo sviluppo
- name: cp-1
type: cx33
image: ubuntu-24.04
# fsn1, nbg1 o hel1
location: fsn1
ssh-key: [0]
network: 0
label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=control-plane
- name: cp-2
type: cx33
image: ubuntu-24.04
location: fsn1
ssh-key: [0]
network: 0
label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=control-plane
- name: cp-3
type: cx33
image: ubuntu-24.04
location: fsn1
ssh-key: [0]
network: 0
label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=control-plane
- name: worker-1
type: cpx31
image: ubuntu-24.04
location: fsn1
ssh-key: [0]
network: 0
label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=worker
- name: worker-2
type: cpx31
image: ubuntu-24.04
location: fsn1
ssh-key: [0]
network: 0
label: lok8s.dev/cluster=my-cluster,lok8s.dev/role=worker
# addon cluster-infra, applicati in ordine
bootstrap:
# CNI (il default se omesso)
- cilium
# cloud-controller-manager di Hetzner
- ccm
- cert-manager
- monitoring
kubehz:
# self (gestisci tutto tu) | hosted (kubehz gestisce il control plane)
# | shared (uno Space su un control plane condiviso, kind: Kubehz)
hosting: self
# none | registered | managed (Supporter+)
access: registered
# cronjob (heartbeat in sola lettura) | operator (livello managed, vista live)
agent: cronjob
apiUrl: https://api.kubehz.cloudSezioni principali
spec.kubernetes
Imposta la versione di Kubernetes. kubehz offre un elenco curato, ogni versione fissata a una patch release: oggi v1.34.8 e v1.35.5 (la predefinita). Una versione viene ritirata appena upstream smette di correggere la sua minor.
spec.provider
Chi fornisce le macchine. name: hetzner seleziona Hetzner Cloud, l’unico provider implementato. config (o configRef, il percorso di un file JSON o YAML accanto allo spec) è il descrittore del provider: l’accesso SSH usato da lok8s (sshUser, sshPrivateKey, sshPublicKey) e un elenco per ogni risorsa Hetzner (ssh-key, network, server e, facoltativi, volume e load-balancer). Ogni voce diventa un hcloud <resource> create e le sue chiavi sono i flag di quel comando. In un server, ssh-key: [0] e network: 0 indicano le voci di quegli elenchi per indice.
L’etichetta lok8s.dev/role decide cosa diventa un server: control-plane o worker. Tre control plane ti danno l’HA; uno basta per lo sviluppo. type è un tipo di server Hetzner, location il datacenter.
Bare metal. Un server dedicato Hetzner entra nello stesso descrittore come voce #cloud.root (un server Robot che lok8s reinstalla e arruola). Vedi il riferimento dei provider lok8s per la forma esatta.
Forma deprecata. Gli spec più vecchi avevano spec.ssh, spec.controlPlane e spec.workers. lok8s li legge ancora come fallback, ma non vanno usati nei nuovi spec: l’accesso SSH e la topologia dei nodi appartengono al descrittore del provider.
spec.bootstrap
Un elenco ordinato di addon cluster-infra (CNI, CCM, cert-manager, monitoring, …) applicati al momento del provisioning, prima che arrivi qualsiasi workload. Ogni voce viene applicata e attesa prima della successiva. I nomi semplici si risolvono negli addon del framework lok8s; le voci ./percorso puntano alle tue directory kustomize. Se omesso, il default è cilium: ogni cluster ha bisogno di una CNI. Vedi la guida agli addon di lok8s per l’elenco completo.
spec.kubehz
Integrazione facoltativa con la piattaforma kubehz. hosting dice chi gestisce il control plane: self (tu, sul tuo account), hosted (kubehz, vedi Hosted) o shared (uno Space su un control plane che kubehz condivide tra i clienti; questo richiede kind: Kubehz). access dice cosa vede kubehz: none, registered (salute in sola lettura) o managed (aggiunge le funzionalità di gestione: politiche di self-healing, monitoraggio della capacità, gestione dello stato desiderato; richiede un abbonamento Supporter o superiore). L’azione è pull-based: l’agent nel cluster recupera lo stato desiderato dalla piattaforma e lo applica con le credenziali del tuo cluster; kubehz non detiene mai accesso in ingresso.
Le altre chiavi sono facoltative:
| Chiave | Significato |
|---|---|
agent | Quale agent nel cluster gestisce l’heartbeat: cronjob (il default in sola lettura) o operator (la vista live del livello managed). |
apiUrl | L’API kubehz, solo HTTPS. Obbligatoria quando access non è none, e per hosted e shared. |
connectHcloudToken | true consegna alla piattaforma il tuo HCLOUD_TOKEN alla registrazione, solo via HTTPS, così un cluster hosted può fare il provisioning dei worker pool. Disattivo per default. |
upgrades | channel: none / patch / minor (fino a dove la piattaforma può aggiornare senza che tu lo chieda, default patch) e defer: window / immediate. |
maintenanceWindow | Quando può girare il lavoro avviato dalla piattaforma: daysOfWeek, startTime, durationMinutes, timezone ed exclusions (date o intervalli che bloccano tutto). |
space | Solo con hosting: shared: lo slug dello Space, il name visualizzato e i nodes per cui emettere i ticket di join al provisioning. |
Vedi Come funziona per il modello completo e il confine di fiducia, e Registrazione per attivare la visibilità.
Salva il file
lo tiene una cartella per cluster sotto clusters/, con il nome del dominio, e legge cluster.lok8s.yaml da lì. Crea la cartella, salva il file e poi segna il dominio come attivo:
mkdir -p clusters/example.com
# incolla la reference qui sopra in clusters/example.com/cluster.lok8s.yaml
lo use example.comlo use registra il dominio attivo in clusters/.active; --domain <domain> o DOMAIN_NAME lo sovrascrivono per un singolo comando.
Modifica questi prima del provisioning. La reference contiene segnaposto, non valori predefiniti:
| Campo | Segnaposto | Cosa deve essere |
|---|---|---|
metadata.name | my-cluster | il nome del tuo cluster |
spec.cluster.domain e la cartella | example.com | un dominio che controlli (viene usato per l’endpoint API) |
i percorsi SSH in provider.config | ~/.ssh/id_ed25519[.pub] | il percorso reale della tua chiave, solo se non ha il nome Ed25519 predefinito |
Dai a lok8s il tuo token Hetzner
lo provision crea infrastruttura reale e fatturabile nel tuo account Hetzner e si autentica con il token API dei prerequisiti. Esportalo nella stessa shell da cui stai per fare provisioning. Viene letto dall’ambiente, mai dal file di configurazione, quindi non finisce mai in git:
export HCLOUD_TOKEN="<il-tuo-token>"Esegui il provisioning del tuo cluster
Esegui questo dalla directory del progetto, con il dominio attivo:
lo provisionIl provisioning richiede in genere 10–15 minuti. Il kubeconfig viene scritto in .kubeconfig/my-cluster.yaml nel progetto, con il nome di metadata.name. Il tuo ~/.kube/config non viene toccato.
La configurazione di riferimento qui sopra chiede a Hetzner cinque server (3 di control plane e 2 worker), fatturati a ore ai prezzi pubblicati da Hetzner per quei tipi di server. Niente di tutto questo è irreversibile: lo destroy rimuove in qualsiasi momento ogni server creato da lok8s.
Verifica
kubectl punta ancora al contesto che usavi prima, quindi seleziona il nuovo cluster in modo esplicito; altrimenti get nodes risponde per il precedente:
export KUBECONFIG=.kubeconfig/my-cluster.yaml
kubectl get nodes
# (AGE trimmed — STATUS is what to check)
# NAME STATUS ROLES VERSION
# cp-1 Ready control-plane v1.35.5
# cp-2 Ready control-plane v1.35.5
# cp-3 Ready control-plane v1.35.5
# worker-1 Ready <none> v1.35.5
# worker-2 Ready <none> v1.35.5
kubectl get pods -A
# Elenca SOLO i pod non ancora pronti. Su un cluster sano non stampa nulla:
kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded
# No resources foundOgni nodo dovrebbe risultare Ready e la colonna VERSION dovrebbe corrispondere alla versione di Kubernetes configurata sopra.
kubectl get pods -A stampa tutti i pod di sistema, che sono molti da controllare a occhio; il secondo comando inverte la domanda e mostra solo ciò che non ha raggiunto Running o Completed. No resources found è la risposta che vuoi. Subito dopo il provisioning concedi un minuto a CNI e cloud-controller prima di considerare un errore quanto elencato lì.
Prossimi passi
- Setup della dashboard: monitora il tuo cluster
- Registrazione: collega alla dashboard kubehz
- Guida KubeOne: configurazione avanzata di KubeOne
Stato del documento
| Aspetto | Dettaglio |
|---|---|
| Stato | attivo |
| Ultima revisione | 2026-09-05 |