Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Kubernetes e deployment

Approfondiamo il Deployment in Kubernetes, cioè la componente dedicata alla gestione del rilascio di nuove versioni di un'applicazione
Approfondiamo il Deployment in Kubernetes, cioè la componente dedicata alla gestione del rilascio di nuove versioni di un'applicazione
Link copiato negli appunti

In questa lezione faremo due cose: approfondiremo il concetto di Pod, visto nella lezione precedente, ed inizieremo a parlare di deployment.

Evidenziamo subito un aspetto importante che dovrà accompagnarci nello studio di Kubernetes per sempre. Il sistema di API di questa piattaforma si basa su una serie di oggetti deputati ognuno ad un ruolo diverso. È assolutamente fondamentale comprendere bene il significato di ognuna di queste tipologie per non rischiare di fare confusione. Si vedrà infatti che in molti casi è possibile raggiungere lo stesso risultato utilizzando oggetti diversi. Ciò che cambia sono i livelli di controllo e le possibilità di gestione che si ottengono utilizzando l'uno invece che l'altro. Facciamo pertanto il punto di quelli visti sino ad ra e che vedremo in questa lezione:

  • Pod: uno o più container in esecuzione.
  • Deployment: è la componente dedicata alla gestione del rilascio di nuove versioni dell'applicazione.

Pod: un approfondimento

Un Pod è l'unità minimale di deployment in Kubernetes, ciò significa che:

  • container singoli o a gruppi non potranno essere sottoposti a deployment se non inseriti in un Pod;
  • tutti i container di un Pod saranno collocati su una medesima macchina del cluster.

Abbiamo già visto come avviare un Pod – contenente il server web NGINX – ma non ci siamo collegati ad esso in nessun modo cosa che invece impareremo adesso. Lanciamo il file di configurazione dichiarativa server-web.yaml:

apiVersion: v1
kind: Pod
metadata:
 name: server-web
spec:
 containers:
 - image: nginx
   name: nginx-instance

con il comando apply:

$ kubectl apply -f server-web.yaml

Ora che abbiamo un Pod di nome server-web (verificare con kubectl get pods) possiamo collegarci al server in esecuzione al suo interno con un port forwarding:

$ kubectl port-forward server-web 8080:80

con cui diremo che vogliamo accedere tramite la porta 8080 dell'host alla porta 80 del container. A questo punto impariamo subito un'altra cosa sui Pod: tutti i container in esecuzione nello stesso Pod condividono lo stesso indirizzo IP pertanto condivideranno anche le stesse porte IP, il che sarà utile affinché i vari container dei Pod possano invocarsi tra loro. Quest'ultimo aspetto è conseguenza del fatto che un Pod è un'unità di deployment e quindi il suo contenuto finisce sulla stessa macchina: tutto ciò tornerà utile quando inizieremo a creare delle applicazioni su Kubernetes.

Il primo deployment

Ora passiamo alla configurazione del nostro primo deployment. L'esperimento consisterà nel:

  • creare un deployment tramite configurazione dichiarativa. Al suo interno avremo un solo container con il server NGINX in esecuzione;
  • modificare la dichiarazione del deployment in modo da richiedere una modifica dell'immagine in esecuzione passando da NGINX al server Apache. Questo meccanismo serve a implementare una versione semplicistica di rollout. In realtà, dovrebbe trattarsi di un cambio tra versioni diverse della stessa applicazione, qui per rendere più macroscopico il cambiamento andiamo da un'applicazione ad un'altra del tutto diversa;
  • monitorare i rollout mediante appositi comandi di kubectl.

Ora convertiamo il Pod di prima in un deployment creando un nuovo file di configurazione in YAML. Se avete ancora attivo il Pod precedente potete abbatterlo con kubectl delete pod/server-web. Questo è il nostro deployment (file server-deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nostro-server
  labels:
    server: web
spec:
  selector:
   matchLabels:
     server: web
  template:
    metadata:
     labels:
       server: web
    spec:
      containers:
      - name: server-web
        image: nginx

La struttura del deployment somiglia a quella del Pod. Al momento, possiamo trascurare alcuni aspetti come selector e labels ma notiamo la presenza di template che contiene la definizione del container che vogliamo lanciare. Attiviamo il deployment (come si vede dai metadati, si chiama nostro-server) con il consueto comando

$ kubectl apply -f server-deployment.yaml
deployment.apps/nostro-server created

e diamo uno sguardo agli oggetti in esecuzione nel cluster:

$ kubectl get pods
NAME                             READY   STATUS    RESTARTS    AGE
nostro-server-7c5649b769-2g5rp   1/1     Running   0           10s
$ kubectl get deployments
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
nostro-server   1/1     1            1           21s

Si vede che il deployment nostro-server è attivo ed ha avviato esso stesso il Pod di cui ha bisogno. Con il port forwarding possiamo verificare se il server NGINX sta lavorando e possiamo farlo non collegandoci al Pod ma al deployment nel suo complesso:

$ kubectl port-forward deployments/nostro-server 8080:80

Potremo verificare di avere a disposizione il nostro server accessibile all'indirizzo localhost:8080. Proviamo ora ad aggiornare il deployment modificando solo l'ultima riga del file server-deployment.yaml impostandola a image: httpd.

Lanciando di nuovo kubectl apply -f server-deployment.yaml avremo non più il server NGINX in esecuzione bensì un Apache Server ed il tutto potrà essere verificato sempre tramite port forwarding.

Monitorare i rollout

Modificando il file YAML e chiamando ancora kubectl apply abbiamo eseguito un rollout del nostro programma. I rollout possono essere monitorati mediante l'apposito comando kubectl rollout chiedendone lo stato di completamento:

$ kubectl rollout status deployment/nostro-server
deployment "nostro-server" successfully rolled out

verificando quante sue revisioni esistono (nel nostro caso la numero 1 corrisponde al lancio con NGINX e la numero 2 al rollout con Apache Web Server):

$ kubectl rollout history deployment/nostro-server
deployment.apps/nostro-server
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

ed infine chiedendo i dettagli di una specifica revisione con il flag --revision:

$ kubectl rollout history deployment/nostro-server --revision=2
…
  Containers:
   server-web:
    Image:      httpd
…

Il campo CHANGE-CAUSE che si vede nell'output è un'annotazione che può essere usata per descrivere a parole proprie l'azione di rollout: al momento non ci è interessato impostarla. Eseguendo quest'ultimo comando avremo conferma, tra l'altro di quale immagine sia in esecuzione.

Nota interessante: volessimo tornare alla revisione 1 (NGINX) potremmo fare un rollback ma succederebbe quello che vediamo qui:

$ kubectl rollout undo deployments nostro-server --to-revision=1
deployment.apps/nostro-server rolled back
$ kubectl rollout history deployment/nostro-server
deployment.apps/nostro-server
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
$ kubectl rollout history deployment/nostro-server --revision=3
...
  Containers:
   server-web:
    Image:      nginx
...

Nonostante sia andato in porto il rollback, dalla storia dei rollout è scomparsa la revisione 1: essendo uguale alla 3, Kubernetes non l'ha duplicata bensì la rinominata assegnandole un nuovo identificativo!

Ti consigliamo anche