Container from zero to hero: 1 - Orchestratori e k8s intro

Breve introduzione all’utilizzo degli orchestratori e k8s intro

Oltre i container

Questa è la seconda parte della serie Container from zero to hero.

Nella prima parte della serie < Container from zero to hero: 0 - FONDAMENTI > sono state introdotte le origini e le motivazioni della diffusione dei container.

Qui introduciamo gli orchestratori, i loro obiettivi e le funzionalità principali, fino alla descrizione dello standard attuale tra gli orchestratori: kubernetes.

Già nell’anno 2013, docker si era affermato come standard de-facto per la gestione dei container. Docker con i suoi componenti poteva essere sufficiente all’utilizzo in produzione su sistemi distribuiti con molti microservizi? No, mancavano alcuni elementi importanti.

Con la gestione di molti container si sviluppa anche la necessità di automatismi per:

  • il deploy

  • l’alta affidabilità

  • la scalabilità

  • …​

Kubernetes: le origini

Kubernetes nasce nel 2015 come risposta alla necessità di automazione e orchestrazione dei container. Nasce internamente a Google dall’esperienza del sistema Borg, il sistema di gestione del cluster su cui si basano le loro tecnologie di punta:

  • Gmail, YouTube, Google Search, …​

Google mantiene il tema Borg (di startrek) con il progetto Seven of Nine (poi Kubernetes).

Kubernetes: opensource community

Kubernetes è la piattaforma di orchestrazione dei container più utilizzata al mondo, spesso è descritta come “Linux of the cloud”. Fonte

Il primo commit del progetto Kubernetes risale al 6 giugno 2014. Da allora la diffusione di Kubernetes è sempre cresciuta e ha attratto molti contributori e finanziatori.

k8s numbers
Commits

CNCF

Il 10 marzo 2016 il progetto Kubernetes entra a far parte della CNCF, la Cloud Native Computing Fondation.

La Cloud Native Container Foundation nasce nel 2015 e si occupa di mantenere molti progetti e standard aperti intorno al tema del cloud native e dell’orchestrazione dei servizi, per esempio:

La CNCF conta attualmente oltre 450 membri, tra i quali si annoverano grandi fornitori di cloud pubblici, le più grandi aziende di sviluppo software, oltre a centinaia di startup innovative.

L’immagine seguente mostra solo alcuni dei molti membri della CNCF.

cncf members

Che cos’è fornito col k8s?

Kubernetes (abbreviato spesso come k8s) fornisce queste funzionalità fondamentali per un sistema di orchestrazione:

  • Service discovery e load balancing

  • Storage orchestration

  • Automated rollouts e rollbacks

  • Automatic bin packing - distribuzione nel cluster del workload

  • Self-healing - gestione automatica dei fault

  • Secret e configuration management

I perché di Kubernetes

Gli sviluppatori della community del k8s hanno definito gli obiettivi principali del kubernetes:

  1. velocità del deploy

  2. permettere scalabilità del software e dei team

  3. fornire un’astrazione sull’infrastruttura

  4. migliorare l’efficienza

Velocità del deploy

Con molti (micro)servizi da aggiornare in breve tempo risulta molto importante avere una elevata velocità dei deploy.

Inoltre, con l’utilizzo di una progettazione del software Agile, è prevista una cadenza di rilascio molto frequente. In questo modo si riescono ad avere feedback immediati da parte degli utilizzatori senza le complicazioni dovute alla sovrapposizione di modifiche successive. Quindi l’utilizzo di una più elevata frequenza di rilascio si riducono le sovrapposizione di problematiche, visto che tipicamente le modifiche comprenderanno ben pochi cambiamenti.

La modalità tradizionale per l’aggiornamento dei componenti prevede tre fasi distinte:

  1. stop del servizio

  2. aggiornamento del servizio

  3. riavvio del servizio.

Visto che i microservizi sono tendenzialmente molto collegati tra di loro, l’utilizzo di questa modalità per effettuare gli aggiornamenti porterebbe ad un disservizio dopo l’altro.

Quindi è necessario individuare un meccanismo diverso per effettuare queste operazioni a livello di cluster.

Uno degli obiettivi principali del k8s è quello di offrire la possibilità di aggiornare il servizio senza interruzioni dell’operatività.

Come è ottenuta una maggiore velocità nel deploy?

  1. immutability: i componenti creati non possono essere modificati e possono quindi essere re-instanziati altrove in caso di problemi, proprio perché non è mantenuto alcuno stato al proprio interno

  2. declarative configuration: k8s si occupa di assicurare lo stato dichiarato come indicato, instanziando e ri-configurando i componenti ove necessario

  3. self-healing system: k8s tenta di mantenere lo stato desiderato anche se qualche condizione cambiasse

Scalabilità del software

La scalabilità del software è uno degli altri obiettivi fondamentali del k8s ed è ottenuta:

  • incoraggiando il disaccoppiamento nelle applicazioni

    • componenti separati che comunicano tramite APIben definite per mezzo di servizi load-balanced

  • esecuzione in ambiente astratti condivisi e senza interferenze

  • utilizzo del formato standard dei container per poterlo avviare su qualsiasi macchina.

Scalabilità del team

Un altro aspetto della scalabilità è legato ai team di lavoro. È necessario separare gli aspetti critici legati alla consistenza delle applicazioni ed alla scalabilità della piattaforma su cui eseguirle. Questa suddivisione risulta particolarmente di aiuto specialmente per chi gestisce una grossa quantità di servizi o di server.

Perché?

  • gli application ops si affidano agli SLA forniti dalla piattaforma

  • gli orchestrator ops si occupano dello SLA

Le due tipologie di team, così suddivise, possono cambiare in numero in modo completamente indipendente. E anche se l’architettura a microservizi richiede molti container e molte interazioni tra questi, il numero delle persone incaricate del buon funzionamento del sistema sono potenzialmente più basse. In particolare l’orchestratore fornirà l’astrazione utile ad incalanare le evoluzioni del software.

Astrazione dell’architettura

L’astrazione della modalità di deploy delle applicazioni dall’hardware sottostante è particolarmente utile per poter ottenere l’elasticità nell’esecuzione delle nostre applicazioni. In particolare uno degli obiettivi è quello di poter aggiungere nuovi nodi al cluster senza la necessità che l’hardware sia uguale o simile a quello già presente.

L’astrazione dell’architettura è ottenuta disaccoppiando le immagini dei container dai server che li ospitano. Questa astrazione fornisce:

  • la possibilità di comporre i cluster con nodi eterogenei - con una potenziale riduzione dei costi.

  • la portabilità, avendo dei container che possono essere utilizzati su un altro cluster senza essere modificati.

Migliorare l’efficienza

Migliorando l’efficienza si possono ridurre notevolmente i costi di gestione dei server su cui far girare la nostre applicazioni.

L’ottimizzazione dell’utilizzo delle risorse dei server (worker node) è possibile grazie all’avvio di molti container sullo stesso server. I container utilizzando namespace separati possono lavorare senza alcuna interferenza reciproca.

Si ma quante risorse è possibile risparmiare?

Going from one service per VM to containers had saved the
company 40% in AWS costs, and moving the containers to
Kubernetes saved an additional 35%.
                             Financial Times, KubeCon 2018

Architettura k8s

Effettuando il deploy di Kubernetes si ottiene un cluster. Il cluster è un insieme di server, chiamati nodi, che eseguono le applicazioni containerized gestite da Kubernetes. Un cluster ha inoltre almeno un nodo worker ed almeno un nodo master. In verità occorrono almeno tre nodi master per ragioni di failover ed alta affidabilità.

  • i nodi worker ospitano i pod che corrispondono ai componenti dell’applicazione.

  • i nodi master gestiscono i nodi worker ed i pod del cluster.

I componenti contenuti nei nodi master forniscono la control plane del cluster, alla quale sono assegnate le decisioni principali del cluster, come ad esempio lo scheduling: rilevando e rispondendo agli eventi del cluster, come per esempio l’avvio di un nuovo pod, se il campo deployment.replicas non è soddisfatto.

I componenti dei nodi master potrebbero essere eseguiti su uno qualsiasi dei nodi del cluster. Per semplicità vengono separati i compiti dei nodi worker da quelli dei master, evitando di avviare i container delle applicazioni sui nodi master.

I componenti dei nodi worker ospitano i pod avviati, fornendo l’ambiente di container runtime del cluster.

È possibile far comunicare i vari pod tramite una overlay network ottenuta tramite uno dei network provider disponibili per il k8s. È possibile ma non ci sono vincoli in merito.

L’immagine seguente mostra l’architettura generale di un cluster kubernetes.

Architettura cluster kubernetes

Container image format e avvio dei container

Le immagini docker ci fornisco il filesystem di base per l’esecuzione dei container.

Le immagini si basano su un layered format che permette di ereditare i contenuti dai livelli più bassi e modificarli aggiungendo, cambiando o rimuovendo file. Può essere molto utile lavorare con delle immagini di container molto piccole, quindi senza dipendenze o layer inutili. In questo modo possono essere costruite, gestite e avviate più velocemente.

Oltre all’immagine già indicata, sono necessarie alcune altre informazioni per poter eseguire correttamente i container:

  • variabili d’ambiente, requisiti di CPU/RAM, indicazioni sul processo da eseguire e la sua command-line, le porte da esporre,…​

Quindi è possibile fare il deploy di un container in Kubernetes? No, o almeno non direttamente.

Perchè no? Perché l’unità più piccola di calcolo di cui si può fare il deploy non è il container ma…​

Pod

I pod sono la più piccole unità di computing in k8s. Permettono la co-locazione di molte app (container) in una singola unità atomica, schedulata su una singola macchina, e staticamente allocata su un certo nodo.

Ogni Pod viene eseguito nel proprio namespace e condivide:

  • file system, indirizzo IP e porta, lo stesso hostname, canali IPC per la comunicazione

Per esempio i container dentro un pod possono comunicare tra loro tramite localhost.

Perché Pod e non container direttamente

I Pod permettono un approccio di tipo “tutto o niente” per i container simbiotici (da mantenere sempre uniti), infatti un pod viene considerato avviato se tutti i suoi container sono running.

Si può effettuare il deploy di un container in k8s? Si, dentro un pod!

Quando sono presenti più container all’interno di un singolo Pod?

Ci sono alcuni casi dove è normale avere più container all’interno di un Pod:

  1. quanto è impossibile per loro lavorare su macchine differenti (per esempio condivisione del filesystem o utilizzo di IPC)

  2. quando uno di loro facilità la comunicazione con l’altro senza modificarlo (adapter)

  3. quando uno di loro offre un supporto per l’altro (logging/monitoring)

  4. quando uno di loro configura l’altro

Pod scheduling

Il pod scheduler è il componente presente nei nodi master che si occupa di garantire l’affidabilità dei servizi del cluster, distribuendo le repliche su più nodi.

Le repliche dei vari pod sono associate al nodo di avvio, quindi non sono mai spostate (immutability) e in caso in cui il nodo fisico non sia più disponibile i pod a lui associati, sono autmaticamente cancellati e rischedulati per l’avvio su uno degli altri nodi disponibili.

Il pod scheduler verifica lo stato dei pod e prende le proprie decisioni di scheduling attraverso due tipi di controlli:

liveness probe

verifica che l’applicazione stia comportandosi come atteso, altrimenti lo riavvia

readiness_probe

verifica che l’applicazione sia pronta per ricevere traffico - per esempio al primo avvio

Kubernetes Objects

I Kubernetes Objects sono entità persistenti all’interno del sistema k8s. Sono utilizzate per rappresentare lo stato del cluster ed in particolare possono descrivere:

  • quali applicazioni sono in esecuzione e su quali nodi

  • le risorse disponibili per queste applicazioni

  • le policy relative al comportamento delle applicazioni, come le restart policy, gli upgrade, la fault-tolerance

Gli oggetti rappresentano lo stato desiderato del cluster, quello che viene chiamato record of intent. Una volta creato un oggetto il k8s eseguirà costantemente le operazioni necessarie per assicurare che l’oggetto sia presente nel cluster e funzioni come specificato.

Gli oggetti possono essere creati/modificati/cancellati attraverso l’API k8s.

kubectl è la CLI che effettua le chiamate alla Kubernetes API.

Esempio Deployment

Nell’esempio sottostante viene utilizzato il kubectl in combinazione con un file yaml per definire e creare un oggetto di tipo deployment che indica al k8s di avviare due pod ognuno dei quali con all’interno un container _ nginx:1.17.5_ in ascolto sulla porta 80.

$ kubectl apply -f application.yaml
application.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # indica di eseguire 2 pod che corrispondono al template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.5
        ports:
        - containerPort: 80

Pubblicato il
    Be Smart Be Open

    Business Software Solutions

    Ultimi articoli

    Rilasciata in produzione applicazione Wasteful basata su Flutter

    11 Marzo 2022

    I nostri contatti

    Email: besmart@besmartbeopen.it
    Pec: besmartbeopen@pec.it
    P.IVA e C.F.: 02137570509
    Top
    Noi ed alcuni partner utilizziamo cookie o tecnologie simili come specificato nella cookie policy Per maggiori informazioni consulta la nostra Cookie Policy Cookie Policy