Serverless Computing e Docker container: due tecnologie molto discusse nell’ambito del cloud computing. Alcuni sostengono che il modello FaaS andrà completamente a sostituire l’utilizzo dei container. Altri pensano che ne diminuiranno i casi d’uso. Ma sono davvero due paradigmi a mutua esclusione, o semplicemente possono essere utilizzati in contesti differenti?

In uno dei precedenti articoli abbiamo parlato di  serverless computing, uno dei paradigmi in rapida evoluzione nel mondo del cloud. Del serverless computing abbiamo evidenziando vantaggi e svantaggi. Di seguito metteremo a confronto tale modello con un altro trend del mondo del cloud computing, ormai consolidato: i container.

Come abbiamo visto, il serverless computing è un paradigma di elaborazione cloud che permette di eseguire applicazioni senza preoccuparsi dei problemi legati all’infrastruttura sottostante: il provisioning, la scalabilità e la gestione dei server su cui le applicazioni vengono eseguite sono amministrati in automatico, in maniera completamente trasparente allo sviluppatore.

Costui (o costei!) deve solo preoccuparsi di scrivere in una function  il codice che deve essere eseguito in risposta a determinati eventi, specificandone i requisiti in termini di risorse. Da cui l’espressione Function as a Service. Tutto il resto, compreso il dimensionamento delle risorse stesse, è gestito in modo automatico dal provider, in base al carico di lavoro richiesto.

 

Cosa si intende per container?

I container non sono altro che ambienti di virtualizzazione. Essi includono tutto ciò di cui il software che inglobano ha bisogno, ovvero librerie, dipendenze, filesystem, interfacce di rete ecc. Al contrario delle classiche macchine virtuali, dei container tutti i suddetti elementi condividono il kernel con la macchina su cui sono in esecuzione. In questo modo si riduce molto l’impatto sull’utilizzo delle risorse del nodo ospitante. Ciò rende quella dei container una tecnologia alquanto appetibile in termini di scalabilità, performance e isolamento.

I container non sono una tecnologia giovane. Tuttavia hanno visto il proprio successo con il lancio di Docker nel 2013. A partire da allora, hanno rivoluzionato totalmente gli standard utilizzati per lo sviluppo e la gestione delle applicazioni. Docker è una piattaforma basata sull’implementazione dei LinuX Containers (LXC), che estende le funzionalità di tale tecnologia con la possibilità di gestire i container come immagini self-contained e vi aggiunge ulteriori tool per la coordinazione del loro ciclo di vita e il salvataggio del loro stato.

 

Perché tanto successo?

Grazie ai container, nessuno sviluppatore può più permettersi di dire “Ma sulla mia macchina funzionava!”. L’idea della containerizzazione è proprio quella di permettere a una data applicazione di essere eseguita su qualsiasi tipo di sistema, dato che tutte le sue dipendenze sono già incluse nel container stesso.

In questo modo l’applicazione diventa altamente portabile, e può essere facilmente testata e deployata su qualsiasi tipologia di ambiente, sia on-premise sia cloud.

Perché le funzioni serverless dovrebbero prevaricare i container?

Rispetto ai container il paradigma serverless è caratterizzato da un passo in avanti: l’utilizzo dei container prevede infatti il setup dell’infrastruttura sottostante e il relativo mantenimento. Nel caso serverless, l’infrastruttura è totalmente gestita dal provider, per cui ci si limita al solo sviluppo e caricamento del codice sulla piattaforma.

Esistono casi in cui i container vincono rispetto al serverless computing?

Ci sono aree in cui le funzioni serverless non riescono a proporsi come valide sostitute dei container:

  • Un’applicazione basata su container non ha particolari limiti per quanto riguarda la grandezza e la complessità. Un’applicazione monolitica può essere scompattata in più microservizi container-based, adattando la nuova architettura alle esigenze del nuovo sistema ridisegnato. Creare la stessa applicazione utilizzando le funzioni serverless comporterebbe il frazionamento della stessa in diversi blocchi. Ognuno di essi sarebbe caratterizzato da un certo livello di incertezza per quanto riguarda la disponibilità e il ritardo di avvio.
  • L’utilizzo dei container permette di avere controllo completo sia sull’infrastruttura ospitante sia sui singoli container, e quindi di poter gestire al meglio le risorse e le questioni legate alla sicurezza.
  • Avendo un completo controllo dell’ambiente, è anche possibile utilizzare diverse risorse per debugging, testing e monitoraggio delle performance a livelli di granularità differenti, in modo da adattare facilmente l’infrastruttura alle esigenze dell’applicazione. Nel caso serverless, le attività di debugging e monitoraggio non sono facilmente estendibili al di fuori di quelle messe a disposizione dal provider.
  • I container sono portabili e vendor-agnostic. Le funzioni serverless, soprattutto se integrate con altri servizi messi a disposizione dallo stesso provider, non lo sono.
  • Sviluppare o ridisegnare un’applicazione legacy attraverso le funzioni serverless non è molto semplice.

D’altra parte, l’utilizzo dei container rispetto alle funzioni serverless comporta alcuni accorgimenti in più:

  • occorre innanzitutto fare attenzione ai costi di esecuzione: mentre le funzioni serverless sono attivate solo al momento del bisogno e l’infrastruttura necessaria è creata e scalata secondo necessità, nella maggior parte dei casi i container sono in continua esecuzione sui nodi ospitanti. Questo comporta che tali nodi debbano essere sempre attivi.
  • Il fatto di dover effettuare il provisioning dell’infrastruttura rende i container una soluzione piuttosto scomoda per gli sviluppatori che, se coinvolti nelle attività di progettazione, dovrebbero far fronte alle decisioni riguardanti la quantità di risorse (CPU, memoria, disco) da utilizzare.
  • Il ciclo di vita dei container non viene gestito dal provider (nel caso cloud), ma deve essere monitorato e manutenuto costantemente, cosi come l’utilizzo delle risorse.

 

Possiamo dunque parlare di un vincitore?

La risposta è no. La verità è che il serverless computing e i container possono dare il massimo se utilizzati insieme, lasciando a ognuna di tali tecnologie la possibilità di lavorare per quello per cui è designata.

Ad esempio un’applicazione legacy complessa potrebbe essere trasformata in una container-based. Se essa è poi costituita da task individuali, da eseguire per esempio in background o che devono essere acceduti da servizi esterni o dall’applicazione stessa, allora essi potranno essere trasformati in funzioni serverless, facilmente aggiornabili o modificabili senza impattare il resto dell’applicativo containerizzato.

Se si ha bisogno di una certa flessibilità e sono richieste specifiche versioni per i software da utilizzare (per esempio il tipo di sistema operativo), e si vuole avere il pieno controllo dell’ambiente, allora la scelta giusta ricade sui container.

Soluzioni serverless sono utili nel caso in cui si voglia svincolare lo sviluppatore dalla gestione dell’infrastruttura sottostante, dando maggiore priorità al codice. Eventuali modifiche al codice possono essere effettuate con più rapidità, dato che non c’è bisogno di effettuare il provisioning delle risorse.

Anche dal punto di vista dei costi non esiste un chiaro vincitore, ma tutto dipende dal caso d’uso e dal tipo di applicazione coinvolta: la convenienza del serverless computing viene meno nel caso ad esempio di una web-application, che deve essere costantemente pronta a ricevere traffico. Non è possibile pensare di attivare una funzione ad ogni richiesta di connessione, sia perché i costi salirebbero in modo sproporzionato, anche a fronte dello scaling delle risorse, sia perché il provisioning delle risorse non è immediato, per cui si peccherebbe in termini di performance.

Se invece occorre effettuare operazioni sporadiche o a intervalli regolari, allora optare per le funzioni serverless è la cosa migliore.