Tutorial > Creare ed etichettare oggetti Kubernetes

Creare ed etichettare oggetti Kubernetes

Pubblicato il: 13 maggio 2021

kubernetes labels microservices objects selectors

Cosa sono gli oggetti Kubernetes

In generale, gli oggetti sono entità persistenti del sistema che Kubernetes usa per rappresentare lo stato di un cluster. In particolare, un oggetto può descrivere:
  • Quali container sono in esecuzione e su quali nodi
  • Quali sono le risorse disponibili
  • Le policy dell’applicazione, ovvero le istruzioni che regolano il riavvio, l’aggiornamento e la tolleranza ai guasti
Tra gli oggetti di base di Kubernetes troviamo:
  • Pod
  • Service
  • Volumi
  • Namespace
Queste astrazioni costituiscono una sorta di basso livello, in quanto descrivono singole componenti del sistema. Tra gli oggetti di Kubernetes però possiamo trovare anche astrazioni di livello più alto, dette Controller. I controller non sono altro che insiemi di oggetti di base, come pod e servizi, con funzionalità aggiuntive. Esempi di controller sono:
  • Deployment
  • ReplicaSet
  • Job
  • DaemonSet
Abbiamo visto, nei capitoli precedenti, che con oggetti di questo tipo è possibile rendere scalabile la nostra applicazione orchestrata da Kubernetes. Comunque, ognuno di questi oggetti ha una specifica rappresentazione all’interno dell’API Kubernetes. Tipicamente, ogni oggetto possiede due campi innestati che determinano la configurazione di quell’oggetto: si tratta degli oggetti spec e status. Il campo spec specifica lo stato desiderato dell’oggetto, stabilito dal programmatore, mentre lo status indica lo stato corrente dell’oggetto e viene continuamente gestito e aggiornato dal Control Plane di Kubernetes, in maniera tale da rispettare le specifiche definite nel campo spec. Possiamo quindi definire lo spec come un campo statico, specificato ad esempio all’interno del file YAML del Deployment, e lo status come un oggetto dinamico, che rappresenta a ogni istante lo stato attuale dell’istanza dell’oggetto a cui si riferisce.

Definire oggetti Kubernetes

Tutti gli oggetti Kubernetes possono essere definiti in un manifesto YAML. Quando immettiamo un nuovo file .yaml da console kubectl, Kubernetes converte il file in formato JSON, formando una API request per la creazione dell’oggetto. In alternativa, è possibile definire un oggetto direttamente in un file JSON, anche se YAML è il formato più comune. Tutti i campi del manifesto YAML sono del tipo <chiave valore=""> e un valore può a sua volta corrispondere a un ulteriore campo <chiave valore="">, andando a determinare la struttura innestata tipica dei formati yaml e json. Il file .yaml deve contenere i seguenti campi:
  • apiVersion: definisce la versione dell’API Kubernetes da usare per creare l’oggetto
  • kind: specifica il tipo di oggetto da creare
  • metadata: sono i dati rappresentativi dell’oggetto, come il nome o un codice identificativo univoco
  • spec: lo stato desiderato per l’oggetto
Il formato del campo spec è differente per ogni tipo di oggetto Kubernetes e contiene diversi campi innestati. Un esempio di oggetto specificato in .yaml è il seguente oggetto Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
    name: nginx-deployment
spec:
    selector:
        matchLabels:
            app: nginx
    replicas: 3
    template:
        metadata:
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx
                  image: nginx:9.0

Come si vede, all’interno del primo campo spec si trovano diverse specifiche, tra cui due particolari: selector e labels. Analizziamole in dettaglio.  

Labels e selector

Le label sono coppie < chiave – valore > che vengono usate al fine di specificare determinati attributi identificativi degli oggetti, che possono essere significativi sia per gli utenti che per il sistema. In ogni caso, le label non impattano sulla semantica del sistema, in quanto non definiscono, ad esempio, degli identificativi univoci per gli oggetti. Infatti, una stessa label può essere specificata per più oggetti, in modo da definire dei sottoinsiemi di oggetti che hanno, per esempio, medesime caratteristiche o scopi. I selector sono invece i criteri che permettono di distinguere gli oggetti in base alle label specificate. Facciamo un esempio. All’interno del nostro cluster possiamo avere più risorse di calcolo come di storage, su cui i nodi possono essere eseguiti. Supponiamo di voler specificare che un particolare insieme di nodi debba essere eseguito su una risorsa piuttosto che su un’altra. Per specificare un tipo di risorsa, bisogna creare una label con chiave NodeStorage. Definiamo, per gli oggetti interessati, una label di questo tipo che abbia valore, ad esempio, SSD. Questo perché vorremmo fare girare degli specifici microservizi solo su SSD. Allora in questo caso il campo label appena definito non fa altro che specificare un discriminante per il tipo di storage. Quello che dobbiamo fare è quindi utilizzare un selector all’interno del deployment che indichi a Kubernetes la nostra intenzione di eseguire i nodi etichettati con label SSD su quella specifica risorsa. Abbiamo visto quindi che questo procedimento si compone di 2 passi:
  • Creare la Label
  • Applicare il Selector
Vediamoli singolarmente con un esempio.  

Creazione della Label

Visualizziamo i nodi del cluster eseguendo:  
$ kubectl get nodes

Output:

NAME       				 STATUS   ROLES     AGE     VERSION
node23842-env-0427797…aruba.cloud        Ready    master   3d23h   v1.18.10
node23843-env-0427797…aruba.cloud        Ready             3d23h   v1.18.10
node23844-env-0427797…aruba.cloud        Ready    master   3d23h   v1.18.10
node23845-env-0427797…aruba.cloud        Ready    master   3d23h   v1.18.10
node23846-env-0427797…aruba.cloud        Ready             3d23h   v1.18.10
Etichettiamo un nodo con la label di storage, settando il valore SSD:  
$ kubectl label node nome_nodo storageType=ssd

Output:

node/node23843-env…aruba.cloud labeled
Verifichiamo l’assegnazione dell’etichetta eseguendo:  
$ kubectl describe node nome_nodo
Vediamo che all’interno dell’output, nella voce Labels, comparirà anche:  
storageType=ssd
 

Uso del Selector

Anche il Selector deve essere definito all’interno del Deployment. Modifichiamo come segue il file deployment.yaml visto in precedenza:  
apiVersion: apps/v1
kind: Deployment
metadata:
    name: nginx-deployment
spec:
    selector:
        matchLabels:
            app: nginx
    replicas: 3
    template:
        metadata:
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx
                  image: nginx:9.0
            nodeSelector:
                storageType: ssd
Aggiungendo le ultime due righe, abbiamo fatto in modo che l’applicativo venga deployato solo nei nodi (nodeSelector) che hanno come Label storageType: ssd. L’applicativo non verrà deployato da nessun’altra parte. Per applicare le modifiche, eseguiamo:  
$ kubectl apply -f ./deployment.yaml
In questa serie abbiamo visto cosa sono gli oggetti Kubernetes e come questi vengono creati, analizzando i campi dei file .yaml che vengono usati per definire tali oggetti. Nei prossimi capitoli, parleremo della persistenza in Kubernetes e per questo studieremo un’altra classe importante di oggetti: i Volumi.