Guida Rubrica KUBE 5: Creazione di un applicazione Stateless

Kode

Utente Emerald
10 Dicembre 2013
1,226
81
371
623
kube_1.jpg

All'interno di questo capitolo della rubrica dedicata a Kubernetes, parleremo di come impostare una semplice applicazione stateless andando ad analizzare due esempi che, nel corso della rubrica, possano dare uno sbocco verso idee più avanzate impresentabili tramite un infrastruttura di base discussa all'interno di questo capitolo. Prima di sporcarci le mani con il terminal e con un pò di codice, andiamo ad identificare cosa sia un'applicazione stateless e su come esse possano contribuire per l'esecuzione di processi in vari contesti.


V. Capitoli
1. Introduzione a Kubernetes: cos'è, infrastruttura su cui si basa, vantaggi, caratteristiche e nomenclatura.
2. Architettura di Kubernetes: Architettura Cluster, Container, Pods, Admin Cluster, Storage e Scheduling.
3. Configurazione di un ambiente Kubernetes: Set up, configurazione dei container, dei pods ed esecuzione di applicazioni.
4. Creazione della prima applicazione su Kubernetes: Hello MiniKube!
5. Creazione di un'applicazione stateless su Kubernetes
(*) La rubrica potrebbe subire delle estensioni in caso il progetto riceva un buon feedback.


1. Introduzione

Per poter creare un applicazione di tipo stateless abbiamo bisogno di alcune componenti che non sono state utilizzate per l'infrastruttura di base del capitolo precedente.

La prima cosa da fare è registrarsi ad uno dei servizi di cloud provider di rete come Google Kubernetes Engine (Cloud provider ad-hoc per Kubernetes su tecnologie basate su Google Cloud) oppure su AWS (se si vuole avere un ambiente più familiare e dinamico)

La mia opinione sulla scelta verte verso Google Kubernetes Engine, anche se AWS è comunque una valida alternativa.

Un'altro aspetto da considerare è il Load Balancer Esterno che bisogna configurarlo per il Cloud Provider scelto.

IMPORTANTE: Se usate GKE o AWS (Amazon EKS) dovete configurare kubectl per il cloud provider scelto. Tutte le informazioni sono riportate nella documentazione ufficiale dei due cloud provider.

2. Load Balancer

Ciò che andremo a fare è creare un Load Balancer Esterno. Bisogna sapere che appena si ha il deploy di un servizio su un cluster in modo tale da poter accederci anche da esterno (quindi l'ambiente di esecuzione si estende anche al di fuori del cluster), si ha una configurazione di default del load balancer. Esso ha il compito di comunicare con l'esterno attraverso un IP esposto su una porta specifica in modo da gestirne le operazioni all'interno del nodo del cluster da e verso nodi esterni.

Per poter configurare un Load Balancer esterno si ha sempre bisogno del comando kubectl

Puoi verificare la presenza di questi comandi andando a digitare:

Codice:
kubectl --version && minikube --version

Se non si hanno errori dovuti all'assenza di questo comando, seguite il capitolo 3 della rubrica che troverete a questo link.

2.1 File di configurazione


Per prima cosa bisogna accedere all'interno della directory principale di Kubernetes ed entrare all'interno del file di configurazione dei servizi

- Il tipo del file è come segue:

Codice:
type: LoadBalancer

Il file di configurazione del servizio, dovrebbe avere i seguenti campi di default (ovviamente il nome del servizio è un esempio)

Codice:
apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  type: LoadBalancer

In alternativa, se non si ha un file di configurazione dei servizi, si può generare uno con il comando:

Codice:
kubectl expose rc example --port=8765 --target-port=9376 \
        --name=example-service --type=LoadBalancer

In cui rc sta per il replication controller che è nominato con "example", ovviamente siete liberi di decidere il nome del vostro RC senza alcun vincolo.

- Dopo aver analizzato il LoadBalancer o averlo generato con kubectl, bisogna trovare l'IP di ingresso del LoadBalancer, ossia l'IP di comunicazione esterna del servizio localizzato sui nodi del nostro cluster. Per farlo basta digitare il comando:

Codice:
kubectl describe services example-service

Producendo un output come:

Codice:
    Name:                   example-service
    Namespace:              default
    Labels:                 <none>
    Annotations:            <none>
    Selector:               app=example
    Type:                   LoadBalancer
    IP:                     10.67.252.103
    LoadBalancer Ingress:   192.0.2.89
    Port:                   <unnamed> 80/TCP
    NodePort:               <unnamed> 32445/TCP
    Endpoints:              10.64.0.4:80,10.64.1.5:80,10.64.2.4:80
    Session Affinity:       None
    Events:                 <none>

Analizziamo ora i campi:
1. Name - Identifica il nome del servizio
2. Namespace - Identifica il namespace di configurazione del servizio, dato che non abbiamo mai manipolato i servizi né in questo capitolo e neanche in quelli precedenti, si ha il namespace di default
3. Labels & Annotations: Sono delle annotazioni che servono per identificare lo scope del servizio sotto un punto di vista formale, non hanno nessuna valenza sul sistema se non quello di informare il programmatore o all'amministratore del sistema su come usare tale servizio.
4. Selector: Identifica il nome del nostro RC
5. Tipo: LoadBalancer
IP: Dove è localizzato fisicamente, ossia in quale store è presente il servizio in modo da poterlo richiamare all'interno del contesto distribuito (ovviamente si ha trasparenza di locazione, quindi l'utente finale non sa realmente dove si trovi tale servizio, per lui è come se fosse sul suo PC)
6. LoadBalancer Ingress: IP di ingresso al cluster per la comunicazione esterna
7. Port: Porta di ingresso/Protocollo di comunicazione di rete del cluster
8. NodePort: Dato che siamo su un cluster, bisogna definire anche la porta del nodo in cui è localizzato il servizio, ovviamente è un nodo appartenente allo stesso cluster.

Le altre informazioni non sono al momento rilevanti

- Dato che noi eseguiamo i servizi tramite minikube (come anche nel capitolo precedente), siamo in grado di filtrare i dati di configurazione e poterci ricavare l'IP direttamente tramite il comando:

Codice:
minikube service example-service --url

2. Creare una prima applicazione stateless

Dopo aver configurato il LoadBalancer, possiamo ora sporcarci le mani.
Gli obiettivi da raggiungere per poter creare una applicazione stateless di base che giri su Kubernetes sono:
1. Eseguire 5 istanze di una applicazione Hello-World in dei pods
2. Creare un oggetto Service che espone le istanze verso un indirizzo IP esterno (quello del LoadBalancer)
3. Usare il servizio per accedere alle applicazioni in runtime mantenute nei pods

2.1 Eseguire Hello-World in 5 istanze differenti nel cluster
Le applicazioni Hello-World vengono eseguite all'interno dei pods localizzati in nodi del cluster, per poter effettuare tale operazione, abbiamo bisogno di un file di configurazione YAML che dia indicazione su cosa vogliamo fare:


Codice:
# \service\load-balancer-hello-world.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: load-balancer-hello-world
  name: hello-world
spec:
  replicas: 5
  selector:
    matchLabels:
      app.kubernetes.io/name: load-balancer-hello-world
  template:
    metadata:
      labels:
        app.kubernetes.io/name: load-balancer-hello-world
    spec:
      containers:
      - image: gcr.io/google-samples/node-hello:1.0
        name: hello-world
        ports:
        - containerPort: 8080

- Successivamente alla configurazione, andiamo ad applicare tale struttura di esecuzione su Kubernetes utilizzando kubectl

Codice:
kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml

Il seguente comando non fa altro che creare il Deployment andando ad associarlo al ReplicaSet che, nel nostro caso, ha 5 pods collegati.

Per visualizzare il campo di configurazione del ReplicaSet basta visualizzare il documento precedente e analizzare nel campo spec:

Codice:
  replicas: <number-of-pods>

- Per verificare che il Deployment è avvenuto correttamente:

1. Verifichiamo lo stato del Deployment

Codice:
kubectl get deployments hello-world
kubectl describe deployments hello-world

2. Verifichiamo le informazioni relative al ReplicaSet

Codice:
kubectl get replicasets
kubectl describe replicasets

- Successivamente, andiamo a creare un oggetto Service che esponga il deployment

Codice:
kubectl expose deployment hello-world --type=LoadBalancer --name=my-service

NOTA: Il campo relativo al name del deployment si può analizzare nel file di configurazione YAML sopra indicato.

- Per verificare che il servizio sia attivo, andiamo ad eseguire:

Codice:
kubectl get services my-service

Si avrà un output simile a:

Codice:
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
my-service   LoadBalancer   10.3.245.137   104.198.205.71   8080/TCP   54s

NOTA: Se si visualizza nel campo EXTERNAL-IP la voce <pending> significa che dovete attendere 1 minuto e rieseguire il comando per verificare il servizio (a volte si ha una latenza di attivazione molto elevata, non è il nostro caso ma in situazioni in cui si ha un ReplicaSet elevato o applicazioni molto grandi, si risentono gli effetti sull'attivazione ma mai sulle prestazioni)

- Per analizzare tutte le informazioni del servizio:

Codice:
kubectl describe services my-service

Si avranno informazioni simile a:

Codice:
Name:           my-service
Namespace:      default
Labels:         app.kubernetes.io/name=load-balancer-example
Annotations:    <none>
Selector:       app.kubernetes.io/name=load-balancer-example
Type:           LoadBalancer
IP:             10.3.245.137
LoadBalancer Ingress:   104.198.205.71
Port:           <unset> 8080/TCP
NodePort:       <unset> 32377/TCP
Endpoints:      10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 more...
Session Affinity:   None
Events:         <none>

Da questo output possiamo venire a conoscenza di informazioni fondamentali:

1. IP e porte esterne:
Rappresentato dal campo del LoadBalancer Ingress, nel caso indicato è 104.198.205.71, per le porte da utilizzare abbiamo quelle del cluster indicate dal campo Port e quelle del nodo indicato con il campo NodePort che, nel nostro caso, sono rispettivamente 8080 e 32377

2. Nome del servizio: Definito dal campo name

3. Endpoints: Indicati dal campo con lo stesso nome, nel nostro caso alcuni Endpoints sono 10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080, essi indicano gli indirizzi interni dei vari pods in cui è eseguita l'applicazione Hello-World

NOTA: Gli Endpoints hanno sempre come riferimento la porta del cluster, nel nostro caso la 8080

- Per verificare gli indirizzi interni dei pods basta eseguire:

Codice:
kubectl get pods --output=wide

Cosi da ottenere un output simile a:

Codice:
NAME                         ...  IP         NODE
hello-world-2895499144-1jaz9 ...  10.0.1.6   gke-cluster-1-default-pool-e0b8d269-1afc
hello-world-2895499144-2e5uh ...  10.0.1.8   gke-cluster-1-default-pool-e0b8d269-1afc
hello-world-2895499144-9m4h1 ...  10.0.0.6   gke-cluster-1-default-pool-e0b8d269-5v7a
hello-world-2895499144-o4z13 ...  10.0.1.7   gke-cluster-1-default-pool-e0b8d269-1afc
hello-world-2895499144-segjf ...  10.0.2.5   gke-cluster-1-default-pool-e0b8d269-cpuc

Per accedere alle applicazioni stateless ci avvaliamo di un comando shell molto noto: curl
Se non avete scaricato curl, basta farlo da apt:

Codice:
sudo apt install curl

- Eseguiamo ora l'invocazione verso l'IP esterno del cluster sulla porta esposta per accedere all'applicazione

Codice:
curl http://<external-ip>:<port>

In cui <external-ip> è l'IP esterno definito dal campo LoadBalancer Ingress e il campo <port> è uguale alla porta definita dalla voce Port nel file di configurazione

- Nel nostro caso avremo (tratto dal file di configurazione riportato sopra):

Codice:
curl http://104.198.205.71:8080

- L'output di questo comando sarà quello del programma in runtime sul pods:

Codice:
Hello Kubernetes!

NOTA: Ovviamente è possibile accederci anche tramite web browser con lo stesso indirizzo IP associato alla medesima porta.

3. Pulire l'applicazione di prova

Dato che questa è un'applicazione di prova, si può benissimo ripulire il contenuto dei pods e del sistema in generale, ossia andremo a cancellare il deployment e il servizio creati precedentemente andando ad eseguire:

Codice:
kubectl delete services my-service && kubectl delete deployment hello-world

Nella documentazione ufficiale ci sta un esempio carino su come creare un guestbook mantenuto su kubernetes. Per accedere al tutorial basta andare al seguente link


Fonti:
Documentazione Ufficiale di Kubernetes:
https://kubernetes.io/docs/home/