Umberto D'Ovidio

Kubernetes su Hetzner con Talos: Parte 1 - Bootstrap dei Nodi Control Plane

Panoramica

Questo è il primo articolo della serie su come configurare un cluster Kubernetes su Hetzner Cloud utilizzando Talos. In questo articolo, ci concentreremo sul bootstrap di 3 nodi control plane che possono anche eseguire workload.

Il motivi che mi hanno spinto ad addentrarmi in questo viaggio sono i seguenti:

  1. Apprendimento - Imparare Kubernetes costruendo un cluster da zero
  2. Self-hosting - Avere un cluster dove eseguire le app che uso quotidianamente (come Navidrome per la musica)
  3. Progetti personali - Un cluster dove effettuare il deployment dei miei progetti e sperimentare.

Se non hai requisiti simili, questa serie probabilmente non fa per te. Ma se sei un hobbista che vuole imparare e hostare i propri servizi a basso costo, continua a leggere. Tieni inoltre presente che non amministro cluster Kubernetes per lavoro - questo è un progetto per hobby. Se stai cercando una guida enterprise-level da un professionale amministratore Kubernetes, questa potrebbe non essere la serie giusta per te. Potresti anche voler leggere l’eccellente serie di Mathias Pius che ho consultato frequentemente quando rimanevo bloccato, così come il tutorial ufficiale di Talos per Hetzner.

Perché Talos + Hetzner?

Talos OS è una distribuzione Linux minimale e hardenizzata progettata specificamente per Kubernetes. Combinata con l’infrastruttura cloud economica di Hetzner, ottieni un cluster sicuro e gestibile a una frazione del costo dei principali provider cloud. Per mantenere i costi ulteriormente bassi, useremo una configurazione a tre nodi, dove ogni nodo esegue sia il control plane che i workload effettivi. Il compromesso è una leggermente minore isolazione tra control plane e workload, ma per molti casi d’uso, questo è perfettamente accettabile. Il costo totale stimato e’ meno di 20 euro al mese.

Prerequisiti

  • Account Hetzner Cloud e token API con permessi di lettura/scrittura. Imposta la variabile d’ambiente HCLOUD_TOKEN con il token API. Inoltre, assicurati di avere installato lo strumento hcloud di Hetzner
  • talosctl installato
  • Comprensione di base dei concetti di Kubernetes. Per principianti assoluti puoi comunque seguire, ma suggerisco di integrare questo tutorial con l’eccellente libro Kubernetes Up & Running
  • packer per creare lo snapshot iniziale dell’immagine.

Passo 1: Creare l’Immagine Talos con Packer

Per prima cosa, abbiamo bisogno di un’immagine Talos utilizzabile in seguito da Hetzner. Useremo Packer per buildare e caricare questa immagine.

 1packer {
 2  required_plugins {
 3    hcloud = {
 4      source  = "github.com/hetznercloud/hcloud"
 5      version = "~> 1"
 6    }
 7  }
 8  }
 9
10  variable "talos_version" {
11  type    = string
12  default = "v1.11.3"
13  }
14
15  variable "arch" {
16  type    = string
17  default = "amd64"
18  }
19
20  variable "server_type" {
21  type    = string
22  default = "cx23"
23  }
24
25  variable "server_location" {
26  type    = string
27  default = "nbg1"
28  }
29
30  locals {
31  image = "https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/${var.talos_version}/hcloud-${var.arch}.raw.xz"
32  }
33
34  source "hcloud" "talos" {
35  rescue       = "linux64"
36  image        = "debian-11"
37  location     = "${var.server_location}"
38  server_type  = "${var.server_type}"
39  ssh_username = "root"
40
41  snapshot_name   = "talos system disk - ${var.arch} - ${var.talos_version}"
42  snapshot_labels = {
43    type    = "infra",
44    os      = "talos",
45    version = "${var.talos_version}",
46    arch    = "${var.arch}",
47  }
48  }
49
50  build {
51  sources = ["source.hcloud.talos"]
52
53  provisioner "shell" {
54    inline = [
55      "apt-get install -y wget",
56      "wget -O /tmp/talos.raw.xz ${local.image}",
57      "xz -d -c /tmp/talos.raw.xz | dd of=/dev/sda && sync",
58    ]
59  }
60  }

Builda l’immagine:

1# Naviga nella tua directory infrastructure (adatta il percorso secondo necessità)
2cd infrastructure
3packer build hcloud.pkr.hcl

Questo comando farà alcune cose:

  1. Avvia un server Debian su Hetzner
  2. Abilita la modalità rescue e riavvia il server
  3. Scarica l’immagine Talos dalla factory Talos per sovrascrivere l’immagine Debian
  4. Spegne il server e crea lo snapshot
  5. Carica lo snapshot su Hetzner

L’intero processo mi ha richiesto 7 minuti, quindi sentiti libero di fare una pausa mentre l’automazione compie il suo dovere. Una volta terminato, tieni traccia dell’ID dello snapshot dall’output di Packer - lo useremo nei passaggi seguenti.

1export SNAPSHOT_ID=<id dello snapshot>

Passo 2: Configurare il Load Balancer

Useremo un load balancer per l’endpoint dell’API Kubernetes, così come per l’ingress. Questo non è strettamente necessario all’inizio e potresti risparmiare $5 al mese non usandolo, ma ho deciso di usarlo dato che mi servirà comunque per i miei progetti personali.

 1# Crea load balancer
 2hcloud load-balancer create \
 3  --name talos-control-plane \
 4  --network-zone eu-central \
 5  --type lb11 \
 6  --label 'type=controlplane'
 7
 8# Aggiungi servizio per Kubernetes API
 9hcloud load-balancer add-service \
10  --name talos-control-plane \
11  --protocol tcp \
12  --listen-port 6443 \
13  --destination-port 6443
14
15# Aggiungi target usando label
16hcloud load-balancer add-target talos-control-plane --label-selector 'type=controlplane'

Prima creiamo il load balancer. Dopodiché esponiamo la porta 6443 e usiamo la stessa porta come destinazione. Creiamo un target group usando il selettore di label, così che ogni volta che avviamo un nuovo nodo con quella label, verrà automaticamente aggiunto al gruppo.

Ora possiamo trovare l’IP del nostro load balancer appena creato con il seguente comando

1hcloud loadbalancer list

Aggiungiamolo a una variabile d’ambiente, ci servirà nei passaggi seguenti

1export LB_IP=<ip del tuo load balancer>

Passo 3: Generare la Configurazione Talos

Ora siamo pronti per generare la configurazione talos, che useremo per connetterci al cluster e per avviare nuovi nodi.

1# Genera configurazione cluster
2talosctl gen config talos-k8s-hcloud-tutorial https://$LB_IP:6443 \
3  --with-examples=false \
4  --with-docs=false

Questo crea diversi file, inclusi controlplane.yaml, worker.yaml, e talosconfig.

Passo 4: Patch della Configurazione per l’Integrazione con Hetzner

Applicheremo alcune modifiche alla configurazione. Per farlo, useremo delle patch. Creiamo una cartella patches dove possiamo tenere traccia di tutte le patch. Inizieremo patchando il cluster per permettere externalCloudProviders. Questo sarà richiesto per usare l’hetzner cloud controller manager.

1# patches/external_cloud_providers.yaml
2cluster:
3  externalCloudProvider:
4    enabled: true

Successivamente, creeremo una patch per permettere ai workload di essere schedulati sui nodi control plane. Questo impedirà ai nodi di essere taintati, che fermerebbe lo scheduling dei workload.

1# patches/allow_controlplane_workloads.yaml
2cluster:
3  allowSchedulingOnControlPlanes: true

Applica la patch:

1talosctl machineconfig patch controlplane.yaml --patch @patches/allow_controlplane_workloads.yaml --patch @patches/external_cloud_providers.yaml -o controlplane.yaml

Passo 5: Deploy dei Nodi Control Plane

Ora creiamo i nostri 3 nodi control plane usando la configurazione patchata:

 1# Crea tre nodi control plane
 2for i in 1 2 3; do
 3  hcloud server create \
 4    --name talos-control-plane-$i \
 5    --image $SNAPSHOT_ID \
 6    --type cx23 \
 7    --location nbg1 \
 8    --label 'type=controlplane' \
 9    --user-data-from-file controlplane.yaml
10done

Per il mio cluster sto usando le istanze più piccole disponibili dato che sono più che sufficienti per le mie necessità.

Passo 6: Bootstrap del Cluster

Troviamo l’IP del primo nodo usando hcloud server list | grep talos-control-plane ed esportiamolo come variabile d’ambiente:

1export FIRST_NODE_IP=<ip del tuo nodo control-plane>

Ora configuriamo il client Talos per connettersi a questo nodo impostando sia l’endpoint che il nodo:

1talosctl --talosconfig talosconfig config endpoint $FIRST_NODE_IP
2talosctl --talosconfig talosconfig config node $FIRST_NODE_IP

Siamo pronti per fare il bootstrap di etcd sul nostro primo nodo control plane

1talosctl --talosconfig talosconfig bootstrap

Dovresti quindi essere in grado di vedere tutti e tre i nodi con il seguente comando:

1talosctl --talosconfig talosconfig get members

Possiamo quindi recuperare il kubeconfig e usarlo con kubectl

1talosctl --talosconfig talosconfig kubeconfig .
2export KUBECONFIG=./kubeconfig
3kubectl get nodes -o wide

Verifica che tutto funzioni:

1# Controlla stato nodi
2kubectl get nodes -o wide

Possiamo dare un’occhiata alla salute del cluster usando il comando talosctl dashboard

1talosctl --talosconfig talosconfig dashboard

Passo 7: Hetzner Cloud Controller Manager

Configurare l’Hetzner cloud controller manager è stato abbastanza semplice, ho appena seguito il suo quickstart.md ufficiale.

Crea un secret contenente il tuo token API Hetzner:

1kubectl -n kube-system create secret generic hcloud --from-literal=token=<hcloud API token>

Aggiungi il repository helm

1helm repo add hcloud https://charts.hetzner.cloud
2helm repo update hcloud

Installa il chart

1helm install hccm hcloud/hcloud-cloud-controller-manager -n kube-system

Dovresti essere in grado di vedere hcloud-cloud-controller-manager nei deployments

1kubectl get deployments -n kube-system

Prossimi passi?

Nelle prossime parti di questa serie, tratteremo:

Abbiamo bootstrapato con successo un cluster Kubernetes a 3 nodi usando Talos su Hetzner Cloud. I nostri nodi control plane possono anche eseguire workload, ottenendo una configurazione economica e altamente disponibile.