Setup Cluster Kubernetes su Ubuntu 22.04
In questa guida cercherò di illustrare i principali passaggi per configurare un Cluster di Kubernetes, le versioni che useremo al momento della guida sono:
- OS: ubuntu 22.04.2 LTS
- Cluster: kubernetes v1.26.1
- Container: containerd v1.6.18
In ordine, spendo due parole per spiegare Kubernetes, quest’ultimo si pone l’obbiettivo di orchestrare la gestione dei container, con molte funzionalità automatizzate, tra cui le principali: distribuzione del carico su più istanze, aggiornamenti dinamici con possibilità di rollback rapidi e una estrema sicurezza intrinseca nel dna dello stesso Kubernetes.
Vediamo quali sono gli elementi principali che compongono Kubernetes:
- Nodi Master
- Nodi Worker
- Pods
- Deployment
- Services
- Ingress
Questo elenco indica solo una piccola parte degli elementi che compongono il nostro Cluster ma sono sicuramente quelli che useremo più spesso, andiamo a vedere un piccolo dettaglio per ogni di questi elementi:
Nodi Master: sono gli host che gestiscono tutte le funzionalità di Kubernetes, possono essere fisici o virtuali, in un cluster ne serve minimo 1, fino a un massimo di quanti ne abbiamo bisogno per questione di affidabilità e ripartizione di carico, per avere i nodi Master in modalità di HA ne servono almeno 3.
Nodi Worker: sono gli host dove vengono eseguite le istanze, in pratica dove vengono accesi i container.
Pods: sono l’unità più piccola che Kubernetes può gestire, possono contenere da uno a più container, vengono accesi su un singolo nodo worker, i containers all’interno condividono lo strato Network e l’eventuale Storage.
Deployment, Services e Ingress: sono tutte elementi, normalmente creati utilizzano file yaml che permettono la configurazione del nostro Cluster, non mi soffermo sulla spiegazione dettagliata in quanto servirebbe un altra guida per spiegarli, eventualmente se ci fosse l’interesse ci tornerò in un altro articolo.
Inizio ora con la vera configurazione, installiamo 2 server Ubuntu 22.04.4 LTS completamente aggiornati, con i seguenti comandi su entrambi i servers:
$ sudo apt update ##aggiorna i repository
$ sudo apt full-upgrade -y ##procede al completo aggiornamento del server
Terminato l’aggiornamento dobbiamo aggiungere il repository di Kubernetes per installare i primi pacchetti:
$ sudo apt install apt-transport-https -y ##permette l'inserimento di un repository https
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/k8s.gpg ##aggiungo key per repository Kubernetes
$ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list ##aggiungo repository Kubernetes
A questo punto devo aggiornare l’indice dei repository e procedere con l’installazione dei principali pacchetti:
$ sudo apt update ##aggiorno indice repository
$ sudo apt install kubelet kubeadm kubectl -y ##installo i principali pacchetti per Kubernetes
$ sudo apt-mark hold kubelet kubeadm kubectl ##metto in hold per evitare aggiornamenti non previsti
Installati i pacchetti sopra, controllo un primo funzionamento visualizzando le versioni con i seguenti comandi:
$ kubectl version --client
$ kubeadm version
A questo punto procedo alla disattivazione della partizione di swap e alla configurazione di alcune funzionalità del sistema operativo per permettere il coretto funzionamento di Kubernetes:
$ sudo swapoff -a ##disabilito la swap
$ sudo nano /etc/fstab ##edito il file disattivando la riga della partizione di swap
$ sudo mount -a ##procedo al nuovo mount seguendo il file /etc/fstab
$ free -h ##controllo che la swap sia disattivata
##abilito questi due moduli nel kernel
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
##gestisco l'abilitazione dei due moduli anche in caso di riavvio
sudo tee /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF
##aggiungo queste impostazioni al systemctl
$ sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
##riavvio il systemctl
$ sudo sysctl --system
Iniziamo l’installazione del runtime del Container nel nostro caso ho scelto “Containerd”:
##installo dei pacchetti necessari ai prossimi passi
$ sudo apt install -y gnupg2 software-properties-common ca-certificates
##installo la key per aggiungere il repository del Containerd
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
##installo il pacchetto containerd
$ sudo apt update
$ sudo apt install -y containerd.io
##configuro containerd e avvio il servizio
$ sudo su -
$ mkdir -p /etc/containerd
$ containerd config default>/etc/containerd/config.toml
##riavvio containerd
$ sudo systemctl restart containerd
$ sudo systemctl enable containerd
$ systemctl status containerd
Nel file /etc/containerd/config.toml dobbiamo andare a modificare la variabile SystemdCgroup = true, attenzione che nello stesso file c’è una variabile identica scritta però tutta in minuscolo che va lasciata a false.
A questo punto possiamo inizializzare il nostro Cluster andando sul primo server quello che abbiamo destinato a funzionalità di nodo Master e lanciamo i seguenti comandi:
$ sudo systemctl enable kubelet
$ sudo kubeadm config images pull
##il seguente comando inizializza il Cluster
$ sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket /run/containerd/containerd.sock \
--upload-certs \
--control-plane-endpoint=k8scluster.example.com
Attenzione, prima di lanciare l’inizializzazione dobbiamo avere il DNS configurato con almeno i seguenti Records:
192.168.200.110 k8scluster.example.com
192.168.200.110 - k8smas01.example.com
192.168.200.120 - k8swkr01.example.com
chiaramente dobbiamo impostare gli Indirizzi IP compatibili con la nostra rete e un dominio risolvibile dal nostro DNS Server.
Quando il processo di inizializzazione è terminato riceveremo un messaggio simile a questo:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join k8scluster.egsinetworks.com:6443 --token ... \
--discovery-token-ca-cert-hash sha256:... \
--control-plane --certificate-key ...
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join k8scluster.egsinetworks.com:6443 --token ... \
--discovery-token-ca-cert-hash sha256:...
Il prossimo passaggio serve per abilitare la cli di “kubectl”, come indicato sopra bisogna eseguire i seguenti comandi:
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
utilizzando ad esempio il comando “kubectl get nodes” se tutto funziona a dovere riceviamo il dettaglio del nodo master con funzione di “control-plane” che abbiamo appena installato.
A questo punto possiamo ripercorrere tutti i passaggi sul server con funzione di Nodo Worker tranne per i comandi che abbiamo usato per creare il cluster, ed eseguiamo il join:
$ kubeadm join k8scluster.egsinetworks.com:6443 --token ... \
--discovery-token-ca-cert-hash sha256:...
per fare invece il join di un altro nodo con funzione di “control-plane” dobbiamo lanciare il seguente comando:
$ kubeadm join k8scluster.egsinetworks.com:6443 --token ... \
--discovery-token-ca-cert-hash sha256:... \
--control-plane
--certificate-key ...
considerate che il token e i certificati generati durante la creazione del cluster hanno una durata di 24h, quindi se eseguirete questi join dopo questo tempo andranno rigenerati.
Andrò prossimamente a scrivere una guida dove inserirò i comandi maggiormente usati per gestire un cluster di Kubernetes tra cui quelli per generare un nuove Token e Certificati.
Rilanciando il comando “kubectl get nodes” potremmo vedere il join dei nuovi nodi e il loro stato, all’inizio potrà essere “Not Ready” ma entro qualche minuto diventerà a “Ready”.
Il nostro Cluster è ufficialmente pronto, spero di essere stato esaustivo e piuttosto chiaro nella descrizione, se ci fossero dei dubbi potete scrivermi nei contatti.