Block Image

Cos'è Kubernetes

Nella sezione di Docker abbiamo visto sia cosa sono i container in generale, sia cos'è Docker.

Docker è sicuramente la tecnologia più conosciuta per quanto riguarda i container.
Tuttavia, in un ambiente di produzione, serve uno strumento che orchestri i container, cioè uno strumento che permette di gestire automaticamente ciclo di vita dei container, gestire repliche di questi ultimi, risorse, etc.
Utile è la descrizione che riporta il sito kubernetes.io:

"I container sono un buon modo per distribuire ed eseguire applicazioni. In un ambiente di produzione, è necessario gestire i container che eseguono applicazioni e garantire che non si verifichino interruzioni dei servizi. Per esempio, se un container si interrompe, è necessario avviarne una nuova istanza. Non sarebbe più facile se questo comportamento fosse gestito direttamente da un sistema? [...] È proprio qui che Kubernetes viene in soccorso!"

Kubernetes (conosciuto anche come K8S) è quindi un orchestratore di container, cioè uno strumento che automatizza il deployment, lo scaling e altre operazioni sui container. Inoltre, gestisce automaticamente il ciclo di vita di questi ultimi.

Cluster Kubernetes

Un cluster Kubernetes è un insieme di nodi dove vengono distribuiti i vari container.
Più precisamente, un cluster Kubernetes è formato da almeno un nodo master, e dai nodi slave.

Il nodo master (chiamato anche Control Plane) è colui che gestisce i nodi slave. Si preoccupa di mantenere il cluster in uno stato desiderato (cioè, verifica che il cluster rispetti i settaggi secondo dei file manifest che creiamo). L'utente per gestire i container e altre risorse di Kubernetes, utilizzerà la macchina master (ad esempio per leggere i log di un container, vedere lo stato di un container o in generale lo stato del cluster).

Gli slave sono i nodi di lavoro, cioè i nodi che eseguono concretamente i nostri container.
Per scopi di test è possibile utilizzare un solo nodo che faccia sia da master che da slave.

Block Image
Esempio di cluster Kubernetes, con un master e due worker node

Cosa si intende per stato desiderato

L'utente, attraverso dei manifest, decide qual è lo stato desiderato per un particolare Deployment.
Cioè attraverso un file yaml, l'utente decide quel particolare container quante repliche deve avere, quante risorse può consumare, quale immagine deve essere utilizzata ed altre impostazioni.
Di seguito un esempio di file di Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Qui stiamo dicendo a Kubernetes che vogliamo tre Pod (per ora possiamo associarli al concetto di container, nel prossimo articolo parleremo però del dettaglio di quest'ultimo), utilizzando l'immagine di NGINX versione 1.14.2.
Eseguendo il comando kubectl apply -f <nome_file_yam>, Kubernetes creerà i container NGINX, distribuiti sulle varie macchine slave, e si assicurerà che saranno Up & Running e che si rispetti sempre queste impostazioni (ad esempio che siano up sempre tre istanze).
Se per qualche motivo un nodo slave, dove è running una delle tre repliche, dovesse guastarsi, Kubernetes provvederà a creare la terza istanza in un altro nodo, per rispettare lo stato desiderato del manifest.

Lo stato desiderato non si applica solo ai Deployment, ma anche ad altri oggetti di Kubernetes, che vedremo nei prossimi articoli.

Oggetti di Kubernetes

Gli oggetti più importanti di Kubernetes sono:

  • Pod
  • ReplicaSet
  • Deployment
  • StatefulSet
  • Service
  • PersistentVolume

Ogni oggetto ha una propria struttura del file manifest.
Negli prossimi articoli, vedremo un esempio di alcuni di questi oggetti.

Componenti del nodo Control Plane

Abbiamo detto che il Control Plane è il nodo master di Kubernetes. I componenti più importanti di quest'ultimo sono:

  • kube-apiserver: è il frontend del control plane, accessibile sia tramite API REST che tramite linea di comando con kubectl.
  • kube-scheduler: si occupa di capire se il cluster è in grado di ospitare altri Pod, monitorando le risorse dei nodi, e in caso positivo, decide su che nodo avviare il Pod.
  • kube-controller-manager: si preoccupa di mantenere lo stato desiderato del cluster, come ad esempio verificare che sia rispettato il numero di repliche dei Pod. Per fare ciò, comunica con i nodi slave tramite il kube-apiserver che a sua volta utilizza un database distribuito, etcd.
  • etcd: database distribuito di tipo chiave-valore, che contiene informazioni di configurazione del cluster come indirizzi IP dei vari noi.
  • cloud-controller-manager: aggiunge logica di controllo specifiche per Cloud Provider. Permette di collegare il cluster con le API del cloud provider. In un'installazione on premise, questo componente non è presente.

Componenti di un nodo Kubernetes

Ogni nodo contiene i seguenti componenti:

  • kube-proxy: un proxy eseguito su ogni nodo e responsible della gestione delle regole di rete del nodo per la comunicazione all'interno e all'esterno del cluster. Comunica costantemente col control plane attraverso il kube-apiserver, che gli comunica quali Service (un oggetto Kubernetes che vedremo più avanti) deve aggiungere o rimuovere.
  • container runtime: è il componente che permette di eseguire i container. Kubernetes supporta diversi container runtime come containerd, ma ha da poco deprecato Docker.
  • kubelet: agent che comunica col master e verifica che i container vengono eseguiti correttamente nel Pod. Esegue anche vari tipi di controlli sui container, come readinessProbe e livenessProbe.
Kubernetes ha deprecato Docker, vero. Ma questo ha conseguenze solo sull'installazione del cluster. Per quanto riguarda le vostre applicazioni containerizzate, potete tranquillamente creare ancora le immagini tramite Docker, visto che rispetta lo standard OCI. Per saperne di più: https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker.

Installazione di K8S

Possiamo eseguire Kubernetes in diversi modi:

  • istallandolo fisicamente sui nodi master e slave (macchine Linux)
  • utilizzando Docker Desktop
  • utilizzando tool come minikube e kind (per scopi di test)
  • utilizzando un servizio Kubernetes gestito dai vari Cloud Providers (EKS di AWS, GKE su Google Cloud, AKS di Azure)

Nei prossimi articoli utilizzeremo kind, che permette di creare un cluster Kubernetes tramite container Docker (crea un container che rappresenta il master, crea N containers che rappresentano gli slaves).
Tramite un file di configurazione, possiamo decidere quanti master e quanti slave Kind deve creare.
Inoltre Kind pùo essere installato sia per Linux, sia per Windows sia per Mac.
Qui per saperne di più: kind.sigs.k8s.io

Il mio consiglio è, se possibile, installare Kind su Linux, visto he Docker Desktop è una virtualizzazione di Docker, quindi ad esempio non sarà possibile eseguire un ping sui nodi creati da Kind.

Installazione di Kind e primo Cluster Kubernetes Up & Running in locale

Innanzitutto, se non l'avete già fatto, dovete installare Docker o Docker Desktop:
docs.docker.com/engine/install/.

Poi dovete installare il command line tool "kubectl" (kubernetes.io/docs/tasks/tools/)

Infine, possiamo installare kind seguendo la guida ufficiale, disponibile per tutti i sistemi operativi: kind.sigs.k8s.io/docs/user/quick-start.

Una volta installato, possiamo creare il cluster Kubernetes col seguente comando:
kind create cluster.
Questo comando creerà un Cluster formato da un solo nodo, che farà sia da master che da slave.
Se volessimo avere una configurazione diversa, potremmo creare un file di configurazione di kind come questo:

# three node (two workers) cluster config - file name kind-example-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

ed eseguire questa configurazione con il seguente comando:
kind create cluster --config kind-example-config.yaml.
In questo caso, verrà creato un nodo master e due nodi slave.

Una volta creato il cluster, come suggeritoci da Kind, eseguiamo il comando:
kubectl cluster-info --context kind-kind.

Infine, verifichiamo che il nodo o i nodi del cluster siano up & running, eseguendo il comando:
kubectl get nodes.

Dovremmo avere una schermata del genere:

Block Image
Esempio di creazione di un cluster Kubernetes tramite il tool Kind

Per cancellare il cluster, basta eseguire il seguente comando:
kind delete cluster.

Conclusioni

Complimenti, hai creato in pochi minuti il tuo primo cluster Kubernetes!
Nel prossimo articolo vedremo cos'è un Pod, e faremo degli esempi mettendoci all'opera col nostro cluster!

Articoli su Docker: Docker
Libri consigliati: