Come distribuire applicazioni in Kubernetes

Kubernetes si distingue come una delle piattaforme più utilizzate per l’automazione della gestione, del ridimensionamento e dell’esecuzione di applicazioni containerizzate su cluster di host o nodi.

Questo articolo esplorerà uno degli elementi fondamentali in Kubernetes: il deployment. L’obiettivo primario è comprenderne il funzionamento e come eseguire operazioni di creazione, aggiornamento e rimozione.

Cos’è un Deployment?

Un deployment è uno degli oggetti adoperati per avviare i Pod. Le linee guida di Kubernetes suggeriscono l’impiego dei deployment per applicazioni senza stato. In assenza di un deployment, la creazione, l’aggiornamento e l’eliminazione di più pod dovrebbero avvenire manualmente, risultando complessi e irrealizzabili per un elevato numero di pod.

Un deployment dichiara un singolo oggetto in formato YAML che non si limita a creare i Pod, ma ne garantisce anche l’aggiornamento e la corretta esecuzione. Inoltre, permette di scalare automaticamente le applicazioni. In sintesi, un deployment viene impiegato per il ridimensionamento, la distribuzione e il ripristino delle versioni delle applicazioni all’interno dei pod.

Un deployment comunica a Kubernetes quante istanze di un Pod devono essere in esecuzione, e Kubernetes si occupa della gestione. Il controller associato creerà un ReplicaSet a partire dalla configurazione del deployment. Il controller del ReplicaSet, a sua volta, creerà i Pod basandosi sulla configurazione del ReplicaSet.

I vantaggi nell’utilizzare un deployment anziché creare direttamente un ReplicaSet sono:

  • Storicità dell’oggetto: ogni modifica (attraverso un “apply” o un “edit”) genera un backup della versione precedente.
  • Gestione di rollout e rollback: è possibile ripristinare una configurazione precedente, grazie alla memorizzazione delle versioni.

Creazione di un Deployment

Esistono due modalità per creare un deployment in Kubernetes:

Metodo Imperativo

Le API di Kubernetes offrono un approccio più diretto e imperativo, che non richiede file di configurazione o manifest in formato YAML. In questo caso, è sufficiente indicare l’azione desiderata e Kubernetes si occupa di determinare come raggiungere il risultato.

Per utilizzare questo metodo, è sufficiente utilizzare il comando seguente:

kubectl create deployment nginx-deployment --image nginx --port=80

Metodo Dichiarativo

Con questo metodo, è necessario dichiarare ogni dettaglio. Quando si applica il codice, Kubernetes legge le definizioni e crea le risorse esattamente come specificato.

Per utilizzare il metodo dichiarativo, è necessario creare un file YAML.

Esempio di file YAML per un deployment, denominato new_deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  # Specifica il numero di copie del Pod
  replicas: 3
 # Seleziona i Pod gestiti dal deployment
  selector:
    # Abbina le etichette definite
    matchLabels:
      deploy: example
  template:
    metadata:
      # Specifica le etichette del Pod.
        labels:
          deploy: example
    spec:
      containers:
        - name: nginx
          image: nginx:1.20.2

In questo file YAML, dopo aver definito la versione dell’API Kubernetes, il tipo di oggetto da creare e il nome del deployment, si trova la sezione “spec”. In questa sezione, si definisce la chiave “replicas”, che indica il numero di istanze Pod che il deployment deve mantenere attive.

Si utilizza un selettore di etichette per identificare i pod all’interno del deployment. Si può utilizzare l’etichetta “deploy”, che raggruppa tutti i pod che corrispondono a queste etichette nel deployment.

Successivamente, si trova l’oggetto “template”, che contiene un modello di Pod all’interno della specifica del deployment. Quando il deployment crea i pod, li crea utilizzando questo modello. Le specifiche di un normale pod sono contenute nella chiave “template”.

Con questo deployment, le immagini Nginx con le etichette verranno distribuite nei pod. È importante tenere presente che il Pod è l’unità di scalabilità in Kubernetes, quindi è necessario riflettere attentamente sul modello da adottare nel caso si inseriscano più container nello stesso pod.

Per applicare il file YAML new_deployment.yaml, si utilizza il comando seguente:

kubectl apply -f new_deployment.yaml

Dopo alcuni secondi, è possibile verificare lo stato del deployment utilizzando il comando:

kubectl get all

Recupero e Aggiornamento del Deployment

Si noti che sono stati creati i Pod, il deployment e anche un ReplicaSet. Un deployment, infatti, crea e gestisce sempre un ReplicaSet. È possibile utilizzare il comando seguente per descrivere il deployment:

kubectl describe deployment nginx-deployment

Ora si dispone di una descrizione completa del deployment. Viene evidenziata la strategia utilizzata per creare/ricostruire i pod durante un aggiornamento, in questo caso “RollingUpdate”.

La strategia RollingUpdate consente una migrazione graduale da una versione dell’applicazione a una versione più recente. È la strategia predefinita utilizzata in Kubernetes.

Oltre a questa, esistono anche le seguenti strategie:

  • Ricrea: termina le istanze Pod in esecuzione e le “ricrea” con la nuova versione.
  • Blu/Verde: questa strategia crea due ambienti separati ma identici. Nell’ambiente blu, l’applicazione è in esecuzione come di consueto, mentre nell’ambiente verde l’applicazione è in esecuzione nella versione futura.
  • Canary: una strategia di deployment in cui un sottoinsieme di utenti è coinvolto nel rilascio incrementale di un’applicazione o di un servizio.

Se si sceglie “aggiornamento in sequenza”, è possibile configurarne il comportamento in base al numero di repliche desiderate.

  • maxSurge permette di specificare (in percentuale o in termini assoluti) quanti Pod possono essere creati in più rispetto al numero di repliche configurato.
  • maxUnavailable permette di indicare (in percentuale o in termini assoluti) quanti Pod possono essere “non disponibili” durante l’aggiornamento, in base al numero di repliche configurato.

A seconda dell’applicazione e della sua scalabilità automatica, queste configurazioni consentono di garantire la QoS o di velocizzare i deployment.

Successivamente, è necessario ridimensionare i Pod a 10 e modificare il tag dell’immagine Nginx all’ultima versione.

kubectl scale deployment nginx-deployment --replicas=10

Si noti che 5 container sono in fase di creazione e che 5 su 10 pod sono disponibili.

Dopo alcuni secondi, si utilizzi il comando seguente:

kubectl get all

A questo punto, tutti i Pod sono stati creati e i container sono in esecuzione.

Eliminazione del Deployment

Per eliminare un deployment in Kubernetes, è possibile utilizzare i seguenti comandi:

kubectl delete deploy nginx-deployment
kubectl delete deploy new_deployment.yaml

Helm: semplificazione dei Deployment

Quando è necessario distribuire un’applicazione complessa che utilizza decine o centinaia di risorse Kubernetes, lo strumento kubectl diventa inadatto. Per questo motivo, è stato sviluppato lo strumento Helm. Helm è un gestore di pacchetti per Kubernetes che si basa su kubectl e semplifica i deployment delle applicazioni.

Nel linguaggio di Helm, un’applicazione è denominata “release”. Essa è associata a un “chart”, ovvero una raccolta di file di configurazione in formato YAML che contengono variabili globali e modelli che descrivono le risorse Kubernetes.

Conclusione

Il deployment è un oggetto fondamentale di Kubernetes. Poiché un grande potere implica una grande responsabilità, è necessario prestare attenzione alla configurazione per evitare comportamenti inattesi. Per approfondire le configurazioni dei deployment, è possibile consultare la documentazione ufficiale di Kubernetes.

Si consiglia inoltre di esplorare alcuni dei migliori tutorial su Kubernetes per imparare da zero e diventare esperti.