Kubernetes su Ubuntu 18.04 si installa senza magie, ma richiede ordine: prima prepari il nodo, poi il runtime container, infine i componenti del cluster. La differenza tra una installazione che funziona e una che ti lascia con un control plane instabile sta quasi sempre nei dettagli iniziali: swap, kernel modules, rete, versioni dei pacchetti e allineamento tra kubeadm, kubelet e kubectl.
Questa guida segue un approccio pratico: una macchina Ubuntu 18.04 pulita, un cluster minimale con kubeadm, e un percorso che puoi usare sia per un laboratorio sia come base per ambienti più seri. Ubuntu 18.04 è vecchio abbastanza da richiedere attenzione su repository e compatibilità, quindi conviene evitare procedure “creative” prese a metà da guide diverse.
Scelta architetturale: kubeadm, non installazioni manuali
Se l’obiettivo è imparare o creare un cluster standard, kubeadm è la strada giusta. Ti lascia il controllo sui nodi, ma evita la manutenzione inutile di un’installazione completamente manuale. Su Ubuntu 18.04, inoltre, è il metodo che meglio si allinea alla documentazione e alla diagnostica comune della community.
La logica è semplice: il nodo deve offrire un runtime container compatibile, il kernel deve avere i moduli giusti, il networking deve non interferire con il routing dei pod, e i pacchetti Kubernetes devono essere installati da repository ufficiali o coerenti. Se salti uno di questi passaggi, il cluster può anche partire, ma poi ti ritrovi con pod in Pending, servizi irraggiungibili o kubelet che non riesce a registrarsi.
Requisiti minimi del nodo Ubuntu 18.04
Prima di installare qualsiasi cosa, verifica che il nodo abbia risorse sufficienti e una configurazione di base sensata. Per un control plane minimo, considera almeno 2 vCPU, 2 GB di RAM e disco con margine reale, non solo teorico. Per un worker singolo da laboratorio, puoi stare più basso, ma appena inizi a usare add-on di rete e storage la memoria sale rapidamente.
Controlla anche che il sistema sia aggiornato e che l’orologio sia coerente. Un cluster con differenze di tempo marcate crea problemi meno ovvi del previsto, soprattutto con certificati e componenti distribuiti.
Preparazione del sistema: swap, moduli kernel e sysctl
Kubernetes richiede lo swap disattivato. Non è un capriccio: kubelet e scheduler ragionano sulle risorse in modo diverso da un sistema generalista. Se lasci lo swap attivo, puoi avere comportamento instabile o blocchi già in fase di bootstrap.
Disattiva lo swap subito e rendilo permanente commentando la riga in /etc/fstab.
sudo swapoff -a
sudo sed -i.bak '/\sswap\s/s/^/#/' /etc/fstab
free -h
Il comando free -h deve mostrare swap a zero o comunque non montato. Se resta attivo, fermati qui: il problema è nel file /etc/fstab o in un mount non standard.
Ora carica i moduli kernel necessari e rendili persistenti. I due classici sono br_netfilter e overlay. Il primo serve per filtrare il traffico bridged; il secondo è usato dal runtime container e dal filesystem overlay.
sudo modprobe br_netfilter
sudo modprobe overlay
cat <<'EOF' | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
overlay
EOF
Imposta poi i parametri sysctl richiesti per il forwarding e il traffico bridge. Senza questi valori, il nodo può sembrare sano ma i pod non comunicano come previsto.
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
La verifica minima è questa: sysctl net.ipv4.ip_forward deve restituire 1, e i parametri bridge devono essere attivi. Se non lo sono, di solito manca il modulo br_netfilter o c’è un file sysctl sovrascritto da un altro snippet.
Container runtime: Docker o containerd
Su Ubuntu 18.04 puoi usare Docker come runtime o andare direttamente su containerd. Oggi containerd è la scelta più pulita per kubeadm, ma su 18.04 molte installazioni storiche usano ancora Docker con cri-dockerd o configurazioni precedenti. Se parti da zero, evita di complicarti la vita: usa containerd.
Installa containerd dai repository ufficiali del sistema o da sorgenti coerenti con la tua versione. Su 18.04 spesso è disponibile il pacchetto containerd o containerd.io a seconda del repository usato. L’obiettivo non è avere “l’ultima versione a caso”, ma un runtime compatibile con i pacchetti Kubernetes scelti.
sudo apt update
sudo apt install -y containerd
containerd --version
Genera una configurazione base e imposta SystemdCgroup = true. Questo dettaglio evita il classico disallineamento tra cgroup driver del runtime e quello del kubelet.
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
Verifica con systemctl status containerd e controlla che non ci siano errori di parsing nel file /etc/containerd/config.toml. Se il servizio non parte, il primo sospetto è proprio la configurazione appena modificata.
Repository Kubernetes su Ubuntu 18.04
Per i pacchetti Kubernetes conviene usare il repository ufficiale. Su Ubuntu 18.04 la parte delicata è che alcune guide vecchie puntano a chiavi o repository deprecati. Se segui materiale datato, rischi errori di firma o pacchetti non trovati.
La sequenza tipica è installare dipendenze, aggiungere la chiave del repository e registrare la sorgente pacchetti. In ambienti moderni la gestione delle chiavi è cambiata, quindi evita i comandi che usano apt-key se puoi farne a meno. Se il tuo ambiente è bloccato su una procedura storica, documenta bene la scelta e limita il perimetro della chiave.
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl
sudo mkdir -p /etc/apt/keyrings
curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
Qui c’è un punto importante: la versione del repository deve essere coerente con la versione di Kubernetes che vuoi installare. Su Ubuntu 18.04 non ha senso inseguire release troppo recenti se il nodo è vecchio e il resto dello stack non è allineato. Se hai dubbi, scegli una versione stabile e mantienila identica su tutti i nodi.
Installazione di kubelet, kubeadm e kubectl
Installa i tre pacchetti principali: kubelet, kubeadm e kubectl. Il primo è il servizio che gira sul nodo, il secondo inizializza il cluster, il terzo è la CLI operativa. Tieni presente che kubectl è utile anche sul control plane, ma non è obbligatorio su ogni worker.
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
kubeadm version
kubelet --version
kubectl version --client
Il pin con apt-mark hold serve a evitare upgrade automatici non coordinati. Su Kubernetes è una buona abitudine: aggiornare un nodo alla volta e non lasciare che il gestore pacchetti decida da solo. Se il cluster è in produzione, questo dettaglio ti risparmia parecchie ore di debugging.
Inizializzazione del control plane
Arrivati qui, il nodo è pronto per l’init. Prima di lanciare kubeadm init, decidi la pod CIDR in base al plugin di rete che userai. Se scegli Flannel, ad esempio, la rete pod tipica è 10.244.0.0/16. Se scegli Calico, puoi usare un range diverso, ma devi restare coerente con la configurazione del CNI.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Al termine, kubeadm stampa il comando di join per gli altri nodi e indica come configurare kubectl per l’utente corrente. Salva quell’output: è il punto da cui dipende l’espansione del cluster.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes
All’inizio il nodo control plane può comparire come NotReady. Non è necessariamente un errore: spesso manca il plugin di rete. Prima di inseguire problemi inesistenti, installa il CNI scelto.
Installazione del plugin di rete
Il cluster senza CNI non fa molto. Per una installazione semplice, Flannel è una scelta lineare. Se invece vuoi policy di rete più robuste, Calico è spesso più adatto. Qui l’importante è non mescolare configurazioni diverse: scegli un plugin e applica solo quello.
Esempio con Flannel:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.25.0/Documentation/kube-flannel.yml
kubectl get pods -n kube-flannel
kubectl get nodes
Il nodo dovrebbe passare a Ready dopo il rollout del CNI. Se resta NotReady, controlla i log del pod CNI e il fatto che la pod CIDR di kubeadm init coincida con quella prevista dal manifest del plugin.
Aggiunta di worker al cluster
Per aggiungere un worker, usa il comando kubeadm join generato in fase di init. Non reinventarlo a mano se non sei costretto: il token, il ca hash e l’endpoint del control plane devono combaciare esattamente.
sudo kubeadm join 192.0.2.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Se il token è scaduto, rigeneralo dal control plane con kubeadm token create --print-join-command. Se il join fallisce con errori di rete, verifica prima il firewall e poi la raggiungibilità della porta 6443.
Verifiche operative dopo l’installazione
Una volta che il cluster è su, non limitarti a vedere “qualcosa” in esecuzione. Controlla almeno tre cose: stato dei nodi, stato dei pod di sistema e raggiungibilità dell’API server. Queste verifiche ti dicono se il cluster è davvero utilizzabile o solo formalmente avviato.
kubectl get nodes -o wide
kubectl get pods -A
kubectl cluster-info
Se vuoi una prova semplice, lancia un deployment minimale e un service di test. In questo modo controlli che scheduling, rete e DNS interni funzionino davvero.
kubectl create deployment nginx --image=nginx:1.25
kubectl expose deployment nginx --port=80 --type=ClusterIP
kubectl get pods -o wide
kubectl describe svc nginx
Se il pod resta in Pending, la causa più comune è una rete non pronta o un problema di risorse. Se il pod parte ma il service non risponde, controlla DNS interno, kube-proxy e il CNI.
Errori tipici su Ubuntu 18.04 e come leggerli
Su questa release i problemi ricorrenti sono abbastanza prevedibili. Il primo è lo swap lasciato attivo. Il secondo è il mismatch tra cgroup driver del runtime e kubelet. Il terzo è il repository Kubernetes configurato male o non più valido. C’è poi il classico caso del nodo che resta NotReady perché il plugin di rete non è stato installato o è incoerente con la CIDR scelta.
Per leggere bene gli errori, guarda i log di kubelet e lo stato dei servizi di sistema. Non partire subito con reinstallazioni complete: spesso basta un dettaglio di configurazione.
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 100 --no-pager
sudo journalctl -u containerd -n 100 --no-pager
Un errore utile da cercare è quello legato al cgroup driver: se kubelet e containerd non parlano la stessa lingua, il nodo non si registra correttamente. In quel caso la correzione non è “riavvia tutto”, ma allineare la configurazione del runtime e del kubelet.
Hardening minimo prima di usare il cluster davvero
Se il cluster non è solo un laboratorio, vale la pena fare un hardening minimo. Non serve trasformare tutto in un esercizio di compliance, ma ci sono tre cose da non ignorare: accesso SSH, esposizione dell’API server e gestione degli aggiornamenti.
Limita l’accesso al control plane, proteggi la porta 6443 solo ai client necessari e gestisci i certificati con attenzione. Inoltre, evita di lasciare credenziali o file di configurazione Kubernetes in percorsi accessibili a utenti non autorizzati. Il file $HOME/.kube/config contiene molto più del necessario per un accesso generico.
Per gli aggiornamenti, non fare salti di versione casuali. Kubernetes è tollerante fino a un certo punto, ma la regola pratica resta: aggiorna un componente alla volta e verifica la compatibilità tra control plane, kubelet e plugin di rete. Su Ubuntu 18.04, dove il sistema base è già datato, la disciplina sulle versioni conta ancora di più.
Quando Ubuntu 18.04 non è più la scelta giusta
Vale la pena dirlo chiaramente: per un cluster nuovo, Ubuntu 18.04 non è la prima scelta. Funziona, ma è una base vecchia, e il costo della compatibilità cresce con il tempo. Se stai progettando qualcosa che deve restare vivo, è più sensato partire da una release LTS più recente, così riduci attriti su repository, kernel, container runtime e supporto generale.
Se però hai già 18.04 in produzione o in un ambiente vincolato, questa procedura resta valida come linea di partenza. L’importante è mantenere coerenza: stesso metodo di installazione, stessa versione dei componenti sui nodi, stessa configurazione di rete e stessi criteri di verifica.
Sequenza riassuntiva da eseguire senza perdere pezzi
Se vuoi una traccia rapida, la logica operativa è questa: disattiva swap, abilita i moduli kernel, configura sysctl, installa containerd, aggiungi il repository Kubernetes, installa kubelet/kubeadm/kubectl, inizializza il control plane, applica il CNI e poi aggiungi i worker. Ogni passaggio ha una verifica associata; se salti la verifica, scopri il problema dopo, quando costa di più.
free -h
sysctl net.ipv4.ip_forward
systemctl status containerd
systemctl status kubelet
kubectl get nodes
kubectl get pods -A
Questo insieme di controlli copre la maggior parte dei casi reali. Se qualcosa non torna, il punto giusto da guardare è quasi sempre il layer immediatamente precedente a quello che mostra il sintomo: rete prima dei pod, runtime prima del kubelet, repository prima dei pacchetti, swap prima di tutto il resto.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.