Setup di un Cluster Kubernetes: Dalla Teoria alla Pratica

Come creare un cluster Kubernetes da zero. Opzioni a confronto, setup passo-passo, e decisioni da prendere prima di iniziare.

Vuoi creare un cluster Kubernetes. La domanda e: come? Le opzioni sono tante, e la scelta giusta dipende dal contesto. Cloud managed? Self-hosted? Quale distribuzione? Quanti nodi?

Questa guida copre le opzioni principali e ti aiuta a decidere. Poi vediamo un setup concreto con kubeadm per chi vuole sporcarsi le mani.

Prima Decisione: Managed vs Self-Hosted

La prima scelta e se gestire Kubernetes tu stesso o lasciarlo fare a qualcun altro.

Kubernetes Managed (Cloud)

I cloud provider offrono Kubernetes as a Service:

  • EKS (AWS)
  • GKE (Google Cloud)
  • AKS (Azure)
  • DOKS (DigitalOcean)

Pro:

  • Control plane gestito — non devi preoccuparti di etcd, API server, scheduler
  • Upgrade semplificati
  • Integrazione nativa con servizi cloud (load balancer, storage, IAM)
  • Supporto dal provider

Contro:

  • Costo — paghi per il control plane oltre ai worker node
  • Vendor lock-in — le integrazioni native ti legano al provider
  • Meno controllo — alcune configurazioni non sono possibili

Quando sceglierlo: Se sei su cloud e non vuoi gestire l'infrastruttura Kubernetes. Per la maggior parte dei casi produzione enterprise, e la scelta ragionevole.

Self-Hosted

Installi e gestisci tutto tu. Le opzioni:

  • kubeadm — Tool ufficiale per bootstrap cluster
  • K3s — Kubernetes leggero (ne ho parlato in un altro articolo)
  • RKE2 (Rancher) — Kubernetes enterprise-ready
  • Kubespray — Ansible playbook per deployment

Pro:

  • Controllo totale
  • Nessun costo per il control plane
  • Funziona ovunque (cloud, on-premise, bare metal)

Contro:

  • Responsabilita di upgrade, backup, high availability
  • Piu complessita operativa
  • Niente supporto (a meno di non pagare per una distribuzione commerciale)

Quando sceglierlo: On-premise, edge computing, requisiti di controllo specifici, o quando vuoi imparare come funziona Kubernetes davvero.

Architettura del Cluster

Prima di creare il cluster, alcune decisioni architetturali.

Quanti Control Plane Node?

  • 1 nodo: Ok per sviluppo e test. Se muore, perdi il cluster.
  • 3 nodi: Minimo per produzione con HA. Quorum etcd richiede dispari.
  • 5 nodi: Per cluster molto critici. Piu di 5 raramente serve.

Quanti Worker Node?

Dipende dal workload. Inizia con quello che ti serve, scala dopo. Kubernetes rende facile aggiungere nodi.

Considera:

  • Risorse necessarie per i tuoi pod
  • Margine per scheduling (non vuoi nodi al 100%)
  • Fault tolerance (se un nodo muore, gli altri reggono?)

Networking CNI

Il Container Network Interface (CNI) gestisce il networking tra pod. Opzioni comuni:

  • Calico — Il piu usato. Network policy, BGP, flessibile.
  • Cilium — Basato su eBPF, performance eccellenti, feature avanzate.
  • Flannel — Semplice, leggero, niente network policy.
  • Weave — Facile da configurare, encryption built-in.

Per la maggior parte dei casi, Calico va bene. Se hai requisiti di performance o sicurezza avanzati, guarda Cilium.

Setup con kubeadm

Vediamo un setup pratico con kubeadm su Ubuntu 22.04. Questo e il metodo "ufficiale" per creare cluster self-hosted.

Prerequisiti (Tutti i Nodi)

# Disabilita swap (Kubernetes lo richiede)
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

# Carica moduli kernel necessari
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# Configura sysctl
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

sudo sysctl --system

Installa Container Runtime (containerd)

# Installa containerd
sudo apt-get update
sudo apt-get install -y containerd

# Configura containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# Abilita SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

sudo systemctl restart containerd
sudo systemctl enable containerd

Installa kubeadm, kubelet, kubectl

# Aggiungi repository Kubernetes
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# Installa i pacchetti
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Inizializza il Control Plane

Sul primo nodo control plane:

sudo kubeadm init \
  --control-plane-endpoint="LOAD_BALANCER_IP:6443" \
  --upload-certs \
  --pod-network-cidr=10.244.0.0/16

Se hai un solo control plane, puoi omettere --control-plane-endpoint. Il --pod-network-cidr dipende dal CNI che userai (10.244.0.0/16 e per Flannel, per Calico puoi usare altri range).

Dopo il completamento, kubeadm ti da:

  1. Comando per configurare kubectl
  2. Comando per joinare altri control plane
  3. Comando per joinare worker
# Configura kubectl per il tuo utente
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Installa CNI (Calico)

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml

Aspetta che i pod Calico siano running:

kubectl get pods -n kube-system

Joina i Worker Node

Su ogni worker node, esegui il comando che kubeadm ti ha dato:

sudo kubeadm join CONTROL_PLANE_IP:6443 \
  --token TOKEN \
  --discovery-token-ca-cert-hash sha256:HASH

Se il token e scaduto, generane uno nuovo sul control plane:

kubeadm token create --print-join-command

Verifica il Cluster

kubectl get nodes

Dovresti vedere tutti i nodi in stato Ready.

High Availability

Per HA del control plane servono almeno 3 nodi. La configurazione e simile ma con alcuni accorgimenti.

Load Balancer

Serve un load balancer davanti ai control plane. Opzioni:

  • HAProxy
  • Nginx
  • Cloud load balancer
  • kube-vip (software load balancer per Kubernetes)

Il load balancer deve bilanciare la porta 6443 (API server) su tutti i control plane.

Setup HA

# Primo control plane
sudo kubeadm init \
  --control-plane-endpoint="LOAD_BALANCER_IP:6443" \
  --upload-certs \
  --pod-network-cidr=10.244.0.0/16

# Altri control plane
sudo kubeadm join LOAD_BALANCER_IP:6443 \
  --token TOKEN \
  --discovery-token-ca-cert-hash sha256:HASH \
  --control-plane \
  --certificate-key CERT_KEY

Il --certificate-key viene mostrato nell'output del primo kubeadm init.

Storage

Kubernetes ha bisogno di storage per i volumi persistenti. Opzioni:

Cloud: Usa il CSI driver del tuo provider (EBS per AWS, PD per GCP, etc.)

Self-hosted:

  • Longhorn — Storage distribuito, facile da installare
  • Rook/Ceph — Potente ma complesso
  • OpenEBS — Piu semplice di Ceph, varie opzioni di backend
  • Local Path Provisioner — Storage locale, niente replica

Per iniziare, Local Path Provisioner va bene:

kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml

Per produzione, considera Longhorn o il driver CSI del tuo storage.

Monitoring e Logging

Un cluster senza monitoring e una bomba a orologeria.

Metrics Server

Necessario per kubectl top e autoscaling:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Prometheus + Grafana

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack

Questo installa Prometheus, Grafana, e dashboard pre-configurate per Kubernetes.

Upgrade del Cluster

Kubernetes rilascia versioni ogni 4 mesi circa. Come aggiornare:

Control Plane

# Trova la versione disponibile
apt-cache madison kubeadm

# Upgrade kubeadm
sudo apt-mark unhold kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm=1.30.0-1.1
sudo apt-mark hold kubeadm

# Verifica il piano di upgrade
sudo kubeadm upgrade plan

# Applica l'upgrade
sudo kubeadm upgrade apply v1.30.0

# Upgrade kubelet e kubectl
sudo apt-mark unhold kubelet kubectl
sudo apt-get update && sudo apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
sudo apt-mark hold kubelet kubectl

sudo systemctl daemon-reload
sudo systemctl restart kubelet

Worker Node

# Sul control plane: drain il nodo
kubectl drain NODE_NAME --ignore-daemonsets

# Sul worker: upgrade
sudo apt-mark unhold kubeadm kubelet kubectl
sudo apt-get update && sudo apt-get install -y kubeadm=1.30.0-1.1 kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
sudo apt-mark hold kubeadm kubelet kubectl

sudo kubeadm upgrade node
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# Sul control plane: uncordon il nodo
kubectl uncordon NODE_NAME

Ripeti per ogni worker, uno alla volta.

Backup

Backup di etcd e critico. Se perdi etcd, perdi il cluster.

# Backup
ETCDCTL_API=3 etcdctl snapshot save backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# Verifica
ETCDCTL_API=3 etcdctl snapshot status backup.db

Automatizza questo backup con un CronJob o script esterno. Conserva i backup off-site.

Alternative a kubeadm

kubeadm e il metodo standard ma non l'unico.

Kubespray: Ansible playbook che automatizza tutto. Buono se conosci gia Ansible e vuoi deployment ripetibili.

RKE2: Distribuzione Rancher. Include hardening di sicurezza, piu facile da gestire di vanilla kubeadm.

K3s: Se non hai bisogno di tutte le feature di Kubernetes standard. Molto piu semplice.

Talos Linux: OS immutabile fatto apposta per Kubernetes. Interessante per chi vuole sicurezza e immutabilita.

Conclusione

Creare un cluster Kubernetes non e difficile, ma richiede attenzione ai dettagli. Le decisioni prese all'inizio (HA, networking, storage) influenzano tutto quello che viene dopo.

Se sei su cloud e non hai requisiti particolari, usa il managed Kubernetes del tuo provider. E la scelta pragmatica.

Se devi andare self-hosted, kubeadm e il punto di partenza standard. Investi tempo in automazione (Ansible, Terraform) cosi puoi ricreare il cluster velocemente se qualcosa va storto.

E soprattutto: testa gli upgrade e i recovery prima di andare in produzione. Scoprire che il tuo backup non funziona durante un'emergenza e un'esperienza che vuoi evitare.

Un cluster Kubernetes e facile da creare. Un cluster Kubernetes affidabile richiede pianificazione e manutenzione continua.