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

Kubernetes e Service

Parliamo di Service, il componente di Kubernetes che ci consente di pubblicare un deployment come servizio in rete
Parliamo di Service, il componente di Kubernetes che ci consente di pubblicare un deployment come servizio in rete
Link copiato negli appunti

Con i deployment abbiamo imparato a gestire l'esecuzione di un'applicazione compreso l'importantissimo ciclo di vita delle sue versioni. Quello che ci serve ora introdurre è la possibilità di esporre tale workload come servizio all'interno della nostra architettura: ciò di cui abbiamo bisogno è una componente Kubernetes detta Service.

Con un Service potremo pubblicare un deployment come servizio in rete e, a seconda dell'architettura in cui lo inseriremo, potremo offrirlo come servizio interno della nostra applicazione (ad esempio, un backend a disposizione di un frontend) oppure offrirlo come interfaccia diretta verso l'utenza.

Con un po' di fantasia possiamo immaginare quanto il service possa essere importante. Al giorno d'oggi, si parla di architetture a microservizi in cui il software non è più costituito da un unico blocco monolitico bensì da una rete di servizi che collaborano tra loro e che nel loro complesso costituiscono l'applicazione finale. In quest'ottica, possiamo immaginare ognuno di questi servizi come un deployment che espone le proprie funzionalità mediante Service con tutta l'affidabilità che Kubernetes garantisce.

Service con comandi imperativi

Come primo esempio, vediamo l'attivazione di un deployment e la sua esposizione mediante Service non tramite configurazione dichiarativa ma con un approccio più immediato basato su comandi imperativi. Come nelle lezioni precedenti anche le sperimentazioni che qui proponiamo potranno essere svolte sull'ambiente minikube.

In questo caso abbiamo avviato un deployment con un server Web nginx:

$ kubectl create deployment my-server-web --image=nginx
deployment.apps/my-server-web created
$ kubectl expose deployment my-server-web --type=NodePort --port=80
service/my-server-web exposed

Ci siamo limitati ad impostare il minimo indispensabile. Per il deployment, abbiamo indicato solo l'immagine da usare mentre per il Service - attivato mediante il comando expose -
abbiamo identificato:

  • il deployment da esporre ovvero my-server-web;
  • il tipo di Service, NodePort, che indica che la porta su cui verrà esposto il servizio sarà una delle porte del nodo nel cluster (approfondiremo nelle prossime lezioni le tipologie di Service esistenti);
  • la porta su cui l'applicazione è in ascolto (trattandosi di un server Web nel nostro caso sarà la 80).

Con alcune interrogazioni tramite kubectl potremo avere certezza delle componenti avviate:

$ kubectl get deployments
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-server-web   1/1     1            1           10m
$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
my-server-web-7845995b58-l5j2t   1/1     Running   0          11m
$ kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.96.0.1               443/TCP        11m
my-server-web   NodePort    10.99.122.115           80:30599/TCP   10m

Come possiamo vedere abbiamo un deployment che ha attivato a sua volta un Pod e due Service: uno è my-server-web che abbiamo appena creato, l'altro di nome kubernetes è un Service di default che offre l'interazione con le API della piattaforma Kubernetes.

Per provare il tutto nell'ambiente minikube possiamo richiedere informazioni in merito al Service appena creato:

$ minikube service my-server-web
|-----------|---------------|-------------|---------------------------|
| NAMESPACE |     NAME      | TARGET PORT |            URL            |
|-----------|---------------|-------------|---------------------------|
| default   | my-server-web |          80 | http://192.168.49.2:30599 |
|-----------|---------------|-------------|---------------------------|

Viene mostrato l'indirizzo e la porta locale su cui il servizio è in esecuzione: http://192.168.49.2:30599. Trattandosi di un server Web potremo svolgere rapidamente un'interrogazione con un browser o con client curl per verificare il funzionamento del deployment.

Configurazione dichiarativa

Procedendo alla realizzazione di un esempio analogo mediante configurazione dichiarativa scriviamo quanto segue nel file myserverweb.yaml (abbiamo volutamente usato per le componenti nomi simili ai precedenti ma senza trattini al fine di evitare conflitti):

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

Abbiamo così impostato un deployment mentre la configurazione del Service sarà collocata nel file myserverweb-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: myserverweb
spec:
  selector:
    server: web
  type: NodePort
  ports:
    - port: 80

Anche in queste configurazioni abbiamo indicato gli aspetti essenziali che sono principalmente quelli utilizzati nel paragrafo precedente. Notiamo in questo caso però l'impiego di label. Queste sono caratteristiche che in Kubernetes hanno un'estrema importanza. Permettono di collegare tra loro le componenti mantenendo al contempo un elevato disaccoppiamento. Nel deployment abbiamo il template che specifica che ogni Pod che da esso sarà creato verrà etichettato con la proprietà di nome server e valore web: le etichette hanno essenzialmente una struttura chiave/valore.

Quanto indicato sempre nel deployment sotto la voce spec - selector - matchLabels indica che a tale componente si faranno corrispondere tutti i Pod dotati dell'etichetta server: web. A questo punto diventa chiaro il perché anche nel Service sia presente la medesima etichetta, sarebbe un po' come dirgli "I Pod che forniranno le funzionalità che esponi sono caratterizzati dall'etichetta server: web che è quella con cui il deployment che li ha attivati li marchia".

Una volta avviate entrambe le componenti potremo vedere che il Service è in esecuzione e si potrà procedere a prove analoghe a quelle svolte nel precedente paragrafo:

$ kubectl apply -f myserverweb.yaml
deployment.apps/myserverweb created
$ kubectl apply -f myserverweb-service.yaml
service/myserverweb created
$ kubectl get services
NAME          TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes    ClusterIP   10.96.0.1             443/TCP        21s
myserverweb   NodePort    10.96.17.61           80:30822/TCP   5s

A questo punto saremmo già pronti per creare più workload esposti da Service e portarli a dialogare tra loro ma lo vedremo nel prosieguo della guida.

Ti consigliamo anche