Università degli Studi di Padova - SIAGAS

Pagina creata da Giuseppe Franchi
 
CONTINUA A LEGGERE
Università degli Studi di Padova - SIAGAS
Università degli Studi di Padova
 Dipartimento di Matematica "Tullio Levi-Civita"
                Corso di Laurea in Informatica

  Sviluppo di una Proof of Concept per la
gestione di microservizi tramite API Gateway
                         Tesi di laurea triennale

Relatore
Prof.Luigi De Giovanni

                                                            Laureando
                                                    Damiano Cavazzana

                    Anno Accademico 2018-2019
Università degli Studi di Padova - SIAGAS
Damiano Cavazzana: Sviluppo di una Proof of Concept per la gestione di microservizi
tramite API Gateway, Tesi di laurea triennale, c Dicembre 2019.
Università degli Studi di Padova - SIAGAS
Sommario

Il presente documento descrive il lavoro svolto durante il periodo di stage, della durata
di trecentoventi ore, dal laureando Damiano Cavazzana presso l’azienda THRON S.p.A.

L’obiettivo principale era quello di sviluppare una POC che utilizzasse un software che
permettesse di gestire le richieste destinate a dei microservizi applicando rate limiting.

L’elaborato illustra:

   ∗ Il contesto aziendale nel quale si è svolto lo stage (Capitolo 1);
   ∗ La descrizione dello stage (Capitolo 2);
   ∗ Il contesto delle tecnologie utilizzate (Capitolo 3);

   ∗ La ricerca del software adatto (Capitolo 4);
   ∗ La soluzione sviluppata (Capitolo 5);
   ∗ La valutazione finale sull’esperienza e le competenze acquisite (Capitolo 6).

Organizzazione del testo
Riguardo la stesura del testo, relativamente al documento sono state adottate le
seguenti convenzioni tipografiche:

   ∗ gli acronimi, le abbreviazioni e i termini ambigui o di uso non comune menzionati
     vengono definiti nel glossario e nella lista degli acronimi, situati alla fine del
     presente documento;
   ∗ per la prima occorrenza dei termini riportati nel glossario viene utilizzata la
     colorazione azzurra;

   ∗ i termini in lingua straniera o facenti parti del gergo tecnico sono evidenziati con
     il carattere corsivo;
   ∗ i riferimenti alla bibliografia sono numerati ed evidenziati tra parentesi quadre.

                                           iii
Università degli Studi di Padova - SIAGAS
Ringraziamenti

Innanzitutto, vorrei esprimere la mia gratitudine al Prof. De Giovanni, relatore della
mia tesi, per l’aiuto e il sostegno fornitomi durante la stesura del lavoro.

Desidero ringraziare con affetto i miei genitori per il sostegno, il grande aiuto e per
essermi stati vicini in ogni momento durante gli anni di studio.

Ho desiderio di ringraziare poi i miei compagni studi Alberto, Davide, Fiorenza,
Tommaso e tutti i miei amici per tutti i bellissimi anni passati insieme e le mille
avventure vissute.

Padova, Dicembre 2019                                             Damiano Cavazzana

                                           v
Indice

1 L’azienda e il prodotto                                                                                                                    1

2 Descrizione dello stage                                                                                                                   3
  2.1 Introduzione al progetto      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   3
  2.2 Obiettivi . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   3
  2.3 Vincoli temporali . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   4
  2.4 Ripartizione oraria . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   4
  2.5 Vincoli del software . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   4
  2.6 Aspettative personali . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   5

3 Introduzione alle tecnologie                                                                                                              7
  3.1 Containerizzazione e Scaling del software . . . . . . . . . . . . . . . . .                                                           7
  3.2 Architettura a microservizi . . . . . . . . . . . . . . . . . . . . . . . .                                                           8

4 Scouting del Software                                                                                                                     11
  4.1 Requisiti del Software . . . . . . . . . . . .                            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   11
      4.1.1 Rate Limiting condiviso nel Cluster                                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   11
      4.1.2 Routing basato su Host . . . . . . .                                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   12
      4.1.3 Service Discovery . . . . . . . . . . .                             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   13
      4.1.4 Load Balancing . . . . . . . . . . . .                              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   14
      4.1.5 Caching . . . . . . . . . . . . . . . .                             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   14
      4.1.6 API di amministrazione . . . . . . .                                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
      4.1.7 Autenticazione e Autorizzazione . .                                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   16
  4.2 Soluzione individuata . . . . . . . . . . . . .                           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   16

5 Sviluppo della Proof of Concept                                                                                                           19
  5.1 Software e Tecnologie utilizzati              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
       5.1.1 Docker . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
       5.1.2 Portainer . . . . . . . .              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20
       5.1.3 Amazon Web Services .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   21
       5.1.4 Kong . . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   22
       5.1.5 Konga . . . . . . . . . .              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
       5.1.6 Locust . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
       5.1.7 Python . . . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
       5.1.8 Consul . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
       5.1.9 Registrator . . . . . . .              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
       5.1.10 PostgreSQL . . . . . . .              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
       5.1.11 Redis . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   27
  5.2 Proof of Concept . . . . . . . .              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28

                                                    vii
viii                                                                                                                            INDICE

             5.2.1 Proof of Concept locale tramite Docker                           .   .   .   .   .   .   .   .   .   .   .   .   .   28
             5.2.2 Proof of Concept tramite AWS . . . . .                           .   .   .   .   .   .   .   .   .   .   .   .   .   29
       5.3   Requisiti Soddisfatti . . . . . . . . . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   30
             5.3.1 Rate Limiting condiviso nel Cluster . .                          .   .   .   .   .   .   .   .   .   .   .   .   .   30
             5.3.2 Routing basato su Host . . . . . . . . .                         .   .   .   .   .   .   .   .   .   .   .   .   .   31
             5.3.3 Service Discovery . . . . . . . . . . . . .                      .   .   .   .   .   .   .   .   .   .   .   .   .   31
             5.3.4 Load Balancing . . . . . . . . . . . . . .                       .   .   .   .   .   .   .   .   .   .   .   .   .   31
             5.3.5 Caching . . . . . . . . . . . . . . . . . .                      .   .   .   .   .   .   .   .   .   .   .   .   .   32
             5.3.6 API di amministrazione . . . . . . . . .                         .   .   .   .   .   .   .   .   .   .   .   .   .   32
             5.3.7 Autenticazione e Autorizzazione . . . .                          .   .   .   .   .   .   .   .   .   .   .   .   .   32
       5.4   Test di Carico . . . . . . . . . . . . . . . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   32

6 Conclusioni                                                                                                                           35
  6.1 Raggiungimento degli obiettivi            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
  6.2 Consuntivo Finale . . . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
  6.3 Conoscenze acquisite . . . . . .          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   36
  6.4 Valutazione personale . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37

Glossario                                                                                                                               39

Acronimi                                                                                                                                43

Riferimenti bibliografici                                                                                                               45
Elenco delle figure

 1.1    Logo THRON S.p.A. . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                   1

 5.1    Logo Docker . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
 5.2    Logo Portainer . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20
 5.3    Interfaccia di Portainer . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20
 5.4    Logo Amazon Web Services . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   21
 5.5    Logo Kong . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   22
 5.6    Dashboard di Konga . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
 5.7    Logo Locust . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
 5.8    Interfaccia di Locust . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
 5.9    Logo Python . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
 5.10   Logo Consul . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
 5.11   Logo PostgreSQL . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
 5.12   Logo Redis . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   27
 5.13   POC in locale con Docker . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28
 5.14   POC tramite servizio ECS . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   30
 5.15   Risultati test di carico distribuiti   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   34

Elenco delle tabelle

 2.1    Tabella ripartizione oraria . . . . . . . . . . . . . . . . . . . . . . . . .                                               4

 4.1    Tabella reverse proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                              17

 5.1    Tabella dei test di carico sui plugin . . . . . . . . . . . . . . . . . . . .                                              33

 6.1    Tabella del raggiungimento degli obiettivi . . . . . . . . . . . . . . . .                                                 35

                                           ix
x                                                           ELENCO DELLE TABELLE

    6.2   Tabella Consuntivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   36
Capitolo 1

L’azienda e il prodotto

Questo capitolo introduce l’azienda nella quale è stato svolto il progetto di stage.

THRON S.p.A. (vedi Figura 1.1) è un’azienda italiana nata dalla startup "New Vision"
che opera nell’ambito dello sviluppo software.
La sede principale è situata a Piazzola sul Brenta, davanti alla famosa villa Contarini,
le altre sedi si trovano a Londra, Milano e Shanghai. La fondazione dell’azienda risale
al 2000 da parte di Nicola Meneghello, l’attuale CEO, e Dario De Agostini, l’attuale
CTO.

                            Figura 1.1: Logo THRON S.p.A.

THRON S.p.A. sviluppa e offre un unico prodotto cloud secondo il modello Software as
a Service (SAAS) chiamato a sua volta THRON, che è un Digital Asset Management
(DAM), ovvero un software che ha lo scopo di archiviare e rendere facilmente accessibili
i contenuti digitali, come ad esempio immagini, video, audio e documenti.
Tra i competitor appaiono nomi del calibro di Adobe, Aprimo e Bynder, questo non ha
però impedito a THRON di ottenere la fiducia di aziende di rilievo come Valentino,
Whirlpool e Maserati.

THRON nasce dal desiderio delle aziende di raggruppare in un unico strumento
tutti i propri contenuti digitali, evitando ad esempio la duplicazione e favorendo il
ritrovamento, il versionamento, l’analisi, l’arricchimento dei dati e molto altro ancora.

I file vengono raggruppati in un’unica piattaforma che si occupa di analizzare il
contenuto ed arricchirlo con tag e metadati attraverso un sistema di analisi chiamato
content intelligence, il quale aggiunge e aggiorna automaticamente le informazioni nel
tempo. Rimane comunque possibile anche inserire manualmente i tag.

                                             1
2                                     CAPITOLO 1. L’AZIENDA E IL PRODOTTO

È possibile inoltre vedere lo storico dei contenuti, versionarli e impostare permessi sulla
loro fruizione.

THRON si occupa anche di analizzare gli interessi degli utenti in base ai contenuti
consumati sui vari canali e di suggerirne automaticamente altri che seguano quelle
preferenze attraverso algoritmi di machine learning.
Capitolo 2

Descrizione dello stage

In questo capitolo è descritto il progetto, i suoi vincoli e i suoi obiettivi.

2.1      Introduzione al progetto
L’obiettivo principale di questo stage è l’individuazione di un software centralizzato
e scalabile adatto alla gestione dei microservizi e che, tra le varie funzioni, applichi
rate limiting alle richieste ad essi indirizzate; una volta trovato tale software è richiesta
la realizzazione di una Proof of Concept (POC) che faccia uso di esso, in modo da
valutare la sua eventuale applicabilità all’interno dell’infrastruttura di THRON.

Il rate limiting è richiesto esplicitamente per via del fatto che THRON è un prodotto
cloud con architettura multi-tenant, ovvero più "clienti" operano contemporaneamente
sulla stessa infrastruttura, e c’è quindi interesse nell’evitare che un cliente che operi in
modo imprevisto possa creare disservizi agli altri clienti.

2.2      Obiettivi
Durante la stesura del piano di lavoro avvenuta prima dell’inizio dello stage, con la
collaborazione del tutor aziendale, sono stati individuati degli obiettivi che sono stati
suddivisi in obbligatori, desiderabili e facoltativi.

Obbligatori
   ∗ O01: Identificazione di una soluzione per la gestione centralizzata di un rate
     limiter;

   ∗ O02: Rendere la soluzione identificata gestita tramite il sistema di containerizza-
     zione Docker;

   ∗ O03: Apprendimento della tecnologia Docker;

   ∗ O04: Apprendimento di architetture di erogazione di servizi nel web.

                                               3
4                                     CAPITOLO 2. DESCRIZIONE DELLO STAGE

Desiderabili
    ∗ D01: Apprendimento dei metodi di containerizzazione offerti da Amazon Web
      Services (AWS);
    ∗ D02: Integrazione della soluzione identificata nell’architettura di THRON.

Facoltativi
    ∗ F01: Apprendimento di metodologie per lo sviluppo di test di carico distribuiti.

2.3     Vincoli temporali
La durata dello stage, come previsto dai vincoli imposti dal corso di laurea, deve
essere compresa tra le 300 e le 320 ore. Per questo motivo, è stato concordato assieme
all’azienda un piano di lavoro della durata di 320 ore, le quali sono state distribuite in
8 settimane. In particolare, l’orario di lavoro prevedeva 8 ore al giorno dal lunedì al
venerdì, dalle 8:30 del mattino alle ore 18:00, con una pausa di un’ora e mezza dalle
12:30 alle 14:00.

2.4     Ripartizione oraria
Durante la stesura del piano di lavoro, sono state preventivate le ore di lavoro distribuite
come riportato in Tabella 2.1.

                         Tabella 2.1: Tabella ripartizione oraria

    Durata in ore                          Descrizione Attività
           8            Apprendimento architetture web implementate in THRON
           16                         Analisi dei requisiti funzionali
           24                       Analisi dei requisiti non funzionali
           24                                Studio di Docker
           32                       Scouting delle soluzioni disponibili
           40              Identificazione della POC da eseguire ed eventuale
                                    sviluppo delle parti propedeutiche
          104                  Sviluppo POC con le soluzioni identificate
          24             Esecuzione di test di carico e misura delle performance
                                          con e senza rate limiter
           32                            Stesura documentazione
           16               Sviluppo presentazione interna del lavoro svolto
          320                                   Totale Ore

2.5     Vincoli del software
I vincoli imposti dal contesto dello stage per il software da individuare sono:
2.6. ASPETTATIVE PERSONALI                                                              5

   ∗ Soddisfare autonomamente tutti i requisiti in modo da limitare la complessità;

   ∗ Essere adatto alla containerizzazione in immagini Docker;
   ∗ Poter funzionare correttamente in un cluster ;
   ∗ Essere open source o quantomeno avere una versione gratuita che permetta di
     testarlo nel corso dello stage senza costi aggiuntivi.

2.6     Aspettative personali
Per mettermi in contatto con le aziende e conoscere il panorama attuale del mondo
dell’IT ho scelto di partecipare all’evento StageIT organizzato dall’Università di Padova,
durante il quale ho avuto modo di conoscere varie aziende e le loro proposte di stage. Ho
successivamente scelto di effettuare il mio stage presso THRON S.p.A. per approfondire
degli argomenti che durante il corso di studi vengono toccati solo in ambito teorico: la
sicurezza delle reti e la containerizzazione di software.
Capitolo 3

Introduzione alle tecnologie

In questo capitolo sono illustrati brevemente concetti necessari alla comprensione del
contesto del progetto.

3.1     Containerizzazione e Scaling del software
Nello sviluppo di un sistema complesso che deve eseguire più software differenti con-
temporaneamente, può accadere che ci siano dei conflitti nelle dipendenze, come ad
esempio la necessità di avere allo stesso tempo a disposizione più versioni della stessa
libreria.

Per evitare questi problemi una soluzione potrebbe essere quella di eseguire ogni
software in una macchina differente, tuttavia è facile accorgersi che avere hardware
specifico per ogni software da eseguire non è realizzabile per via dei costi che comporta.
Si può quindi pensare di utilizzare una sola macchina e eseguire ogni software in un
contesto separato, in una virtual machine, all’interno della quale è eseguito un sistema
operativo adatto con installate le dipendenze necessarie, il quale esegue a sua volta il
software di nostro interesse; sfortunatamente anche così, per via del fatto che un intero
sistema operativo è eseguito a supporto di ogni singolo software, molte risorse sono
utilizzate per i processi dei sistemi invece che per lo scopo prefissato.

Nel tempo sono state cercate soluzioni che permettano di utilizzare un unico sistema
ed eseguire comunque ogni singolo programma in ambienti virtualmente separati, così
che il malfunzionamento di un software non comprometta il funzionamento degli altri:
questo è stato inizialmente effettuato con modifiche ai sistemi operativi fino all’avvento
di Docker nel 2013 [10].

Un’immagine di Docker è un modello che contiene le istruzioni e i file necessari
per la creazione di un container : all’interno di un’immagine sono presenti i software e
il relativo ambiente (ad esempio le sue dipendenze, le sue configurazioni) già pronti
per l’esecuzione, senza bisogno di installare nulla.
Ogni immagine viene eseguita costruendo un container secondo le istruzioni indicate,
eseguito direttamente dal sistema nativo della macchina in modo isolato dal resto,
senza ulteriori strati di complessità nel mezzo, permettendo di eseguire grandi quantità

                                            7
8                          CAPITOLO 3. INTRODUZIONE ALLE TECNOLOGIE

di container utilizzando una sola macchina [2].

La semplicità con cui è possibile avviare un nuovo container senza dover riconfi-
gurare l’ambiente ha semplificato di molto lo sviluppo di sistemi complessi e la gestione
di carichi di richieste molto ampi.

Se un software si trova nella situazione di dover soddisfare molte richieste contem-
poraneamente, potrebbe essere necessario allocargli più risorse come ad esempio più
memoria o processori più potenti, ovvero scalarlo verticalmente. Non è però detto che
questa soluzione funzioni, in quanto il software stesso potrebbe non essere in grado di
sfruttare al meglio le risorse che gli vengono aggiunte, ad esempio la memoria extra
che gli viene allocata potrebbe non venire mai utilizzata.

Vista la facilità con cui è possibile avviare nuovi container grazie a Docker, risul-
ta più comodo scalare orizzontalmente, ovvero avviare nuove istanze dello stesso
software e distribuire il lavoro su ognuna di esse, andando a generare un cluster.
Così facendo anche software inadatti a eseguire più operazioni in contemporanea di-
ventano virtualmente adatti a farlo.
Per rendere ancora più efficace lo scaling orizzontale, si può variare nel tempo la
quantità di container in esecuzione in base al carico di lavoro, così da avere sempre
la quantità più adatta, risparmiando risorse nei momenti nei quali è possibile farlo e
avendo sempre a disposizione la potenza di elaborazione necessaria quando richiesto.
Questa possibilità è fornita dai servizi Elastic Container Service e Fargate di Amazon
ed è chiamata solitamente auto-scaling [1].

3.2     Architettura a microservizi
Fino ad alcuni anni fa molte applicazioni erano caratterizzate da un’architettura monoli-
tica [9], ovvero ognuna era composta da un unico grande software con tante componenti
che svolgevano le funzioni delle quali si aveva bisogno.

Col tempo e gli aggiornamenti, questo portava a dei problemi:

    ∗ ad ogni nuova funzionalità da implementare, occorreva adattare le nuove tecnolo-
      gie al codice più datato già presente;

    ∗ il software diventava via via sempre più pesante, richiedendo risorse aggiuntive e
      tempi di compilazione più lunghi;

    ∗ la complessità che si raggiungeva faceva sì che prima di poter lavorare corret-
      tamente su un software, a un programmatore fosse richiesto diverso tempo per
      conoscerne la struttura;

    ∗ rimuovere o riscrivere parti del software diventava via via un lavoro sempre più
      lungo e costoso;

    ∗ a livello di affidabilità, un piccolo bug in una sola componente poteva causare il
      crash dell’intero programma;

    ∗ tutti i difetti precedenti rallentavano l’innovazione perché aumentavano tempi e
      costi dell’implementazione di nuove funzionalità;
3.2. ARCHITETTURA A MICROSERVIZI                                                           9

   ∗ se una sola componente era sovraccarica e richiedeva più risorse, occorreva scalare
     l’intero software per poterne avere un’altra verso la quale reindirizzare parte del
     traffico.

Per ovviare a questi problemi, con l’aumento del numero di utenti del web e della
velocità con la quale il software evolve, è stato necessario cambiare paradigma e passare
ad un’architettura a microservizi [5].

Con l’architettura a microservizi non si ha più un unico software molto grande (chiama-
to appunto monolite) che si occupa di tutto ma si hanno invece tanti piccoli software i
quali si occupano ciascuno di mettere a disposizione una sola o poche funzionalità.

Questi piccoli software, che da adesso chiameremo microservizi, non sono accoppiati
gli uni con gli altri ma comunicano invece tra loro solo tramite delle API (Application
Programming Interface) che ciascuno mette a disposizione, le quali permettono agli
altri software di comunicare senza bisogno di conoscere la struttura del microservizio
che le offre.

Questo disaccoppiamento genera vari vantaggi:

   ∗ ogni microservizio può essere facilmente scritto nel linguaggio più adatto a
     eseguire il compito desiderato;
   ∗ se un programmatore deve sviluppare una nuova funzionalità non ha bisogno di
     conoscere l’intera struttura del sistema ma gli basta solo conoscere il microservizio
     sul quale lavora e le API messe a disposizione dagli altri, ciò gli permette di
     dedicarsi di più all’ottimizzazione della funzionalità stessa piuttosto che a renderla
     compatibile col software più datato;
   ∗ tecnologie nuove e datate possono coesistere senza modificare nulla;
   ∗ se si vogliono riscrivere parti di software o un intero microservizio, è possibile
     farlo in modo invisibile al resto del sistema purché si continuino ad esporre le
     stesse API;
   ∗ se occorrono più risorse, possono scalare solo i microservizi che effettivamente le
     richiedono invece che tutto il monolite;
   ∗ se un microservizio ha dei problemi, il resto del sistema che non fa uso delle sue
     API continua a funzionare;

   ∗ i microservizi possono essere installati in macchine in luoghi geografici diversi e
     appartenere a proprietari diversi.

Questa "separazione dei software in più software" ha però creato la necessità di avere
ulteriori componenti della rete. In particolare è necessario avere un componente centrale
che rappresenti l’intera applicazione sulla rete esterna e che garantisca un accesso
sicuro alla rete interna ricevendo richieste e instradandole verso il microservizio corretto.
Questo componente è spesso rappresentato da un reverse proxy.
Un’altra funzionalità che diventa necessaria per via del fatto che i servizi sono separati
in più software e varia la quantità delle loro istanze è la possibilità di identificare quali
di questi sono disponibili in un determinato momento.
Capitolo 4

Scouting del Software

In questo capitolo sono descritti i software testati, i requisiti da soddisfare e le decisioni
prese di conseguenza.

THRON, negli anni, ha adottato l’architettura a microservizi descritta nel Capi-
tolo 3, pertanto si è presentata la necessità di individuare un software adatto a gestire
l’accesso e quindi proteggere tali microservizi.

Nonostante il tema principale dello stage fosse il rate limiting, con la collaborazione
del tutor aziendale sono stati individuati vari altri requisiti da soddisfare così che il
software sia adatto ad essere integrato nell’architettura esistente.

Nel corso della prima metà dello stage è stata quindi individuata la famiglia dei
reverse proxy come software adatti a svolgere il compito richiesto e sono state testa-
te le funzionalità di alcuni di essi in modo da metterle in relazione ai requisiti individuati.

In questo periodo dello stage è anche stato approfondito il funzionamento di Docker e
dei servizi di Amazon, software richiesti per lo sviluppo della POC.

4.1      Requisiti del Software
Di seguito vengono descritti i requisiti individuati per i quali occorre identificare una
soluzione.

4.1.1     Rate Limiting condiviso nel Cluster
Il rate limiting è il mantenimento di un contatore e la conseguente limitazione del
numero di richieste accettate dall’applicazione, e può essere applicato in base a varie
condizioni e attraverso diversi algoritmi.

Le condizioni possono essere ad esempio la limitazione del numero di richieste to-
tali o ricevute da parte della stessa macchina o utente indirizzate ad un certo servizio
in un determinato lasso di tempo.
Il riconoscimento dei mittenti, necessario per applicare le limitazioni per utente e per
macchina, può essere effettuato basandosi su informazioni provenienti dalle richieste, e
sono ad esempio l’indirizzo IP dal quale la richiesta proviene o valori ricavati dall’header,

                                              11
12                                      CAPITOLO 4. SCOUTING DEL SOFTWARE

come un identificativo quale può essere la chiave API.

Nel caso di THRON, le condizioni da cercare di prendere in considerazione sono
quelle provocabili da comportamenti scorretti di clienti o di macchine di loro proprietà.

Gli algoritmi di rate limiting variano da soluzione a soluzione, per riassumerne alcuni
presenti nei software testati:

     ∗ semplice rifiuto delle richieste in eccesso entro il lasso di tempo scelto;

     ∗ algoritmo Sliding Window [8]: le richieste oltre il limite vengono rifiutate ri-
       schiando di ripetersi nel tentativo di ottenere una risposta e di generare un burst
       (un picco di richieste) all’inizio del lasso di tempo successivo; le richieste ripetute
       andrebbero di conseguenza soddisfatte tutte contemporaneamente all’inizio del
       nuovo lasso esaurendo subito tutta la disponibilità. Questo burst del lasso successi-
       vo viene invece dosato mantenendo in considerazione una percentuale di chiamate
       del lasso precedente come se fossero arrivate in quello nuovo; questa percentuale
       decade poi nel tempo in modo da lasciare spazio alle nuove richieste, che vengono
       così accettate in momenti differenti invece che tutte contemporaneamente;

     ∗ algoritmo Token Bucket [27]: permette di dosare meglio il carico di richieste e
       di rifiutarne molte meno distribuendo il traffico nel tempo e accettando anche
       burst dopo momenti particolarmente "calmi". Questo è reso possibile generando
       un token ogni certo intervallo di tempo che viene consumato ad ogni richiesta
       accettata. Le richieste che arrivano in mancanza di token vengono messe in
       attesa fino alla generazione di un nuovo token. Se per molto tempo non arrivano
       richieste, i token cominciano ad accumularsi (fino ad un limite massimo) ed è
       quindi possibile accettare anche un piccolo burst che li consumi.

Il requisito specifica limiting "condiviso nel cluster " perché cercando una soluzione
scalabile è necessario che tutte le istanze nel cluster siano consapevoli delle richieste
ricevute dalle altre in modo da mantenere il contatore delle richieste al valore corretto.
Perché ciò sia possibile è necessario che le istanze comunichino tra loro o che si
appoggino ad una risorsa esterna centralizzata.

4.1.2      Routing basato su Host
Nel contesto dell’architettura a microservizi, il routing è il riconoscimento dello speci-
fico microservizio al quale una richiesta è destinata per effettuare un instradamento
corretto. Nei programmi testati, questo è solitamente effettuato basandosi sul path
della richiesta, sul campo host del suo header o sulla loro combinazione.

Nel caso di THRON però, per motivi dovuti all’infrastruttura esistente, è necessario
poter effettuare routing basandosi non solo sull’host nella sua interezza ma anche su
parte dei nomi di sottodominio dell’host indicato nelle richieste in modo da riconoscerne
interi gruppi con caratteristiche simili come se fossero lo stesso. Per poter soddisfare
questo requisito è necessario che il software da individuare sia in grado di identificare
gli host tramite espressioni regolari o sistemi simili, che permettono di riconoscere
interi gruppi di stringhe somiglianti invece che solamente stringhe specifiche.
4.1. REQUISITI DEL SOFTWARE                                                               13

4.1.3     Service Discovery
Il service discovery è il processo tramite il quale il reverse proxy viene a conoscenza delle
istanze dei microservizi disponibili nella rete. Questo processo può avvenire tramite
richieste al server DNS (Domain Name System) nel caso in cui la soluzione adottata sia
in grado di memorizzare i nomi DNS dei microservizi e di effettuare richieste di tipo
SRV (service), ovvero richieste la cui risposta fornisce non solo l’indirizzo IP effettivo
dei microservizi (memorizzato in un record DNS di tipo A, che sta per address) ma
anche i numeri delle porte che questi espongono (memorizzate in un record DNS di
tipo SRV).

La struttura tipica [13] di un record SRV è la seguente:

_service._proto.name. TTL class SRV priority weight port target.

   ∗ service: il nome simbolico del servizio desiderato.

   ∗ proto: il protocollo di trasporto adottato dal servizio desiderato; solitamente
     (TCP o UDP).

   ∗ name: il nome di dominio entro il quale il record è valido, seguito da un punto.

   ∗ TTL: rappresenta il time to live, ovvero il tempo in secondi per il quale
     l’informazione ottenuta è da considerarsi valida.

   ∗ class: classe standard DNS (corrisponde sempre a "IN").

   ∗ priority: la priorità dell’host indicato; valori minori rappresentano priorità più
     alta.

   ∗ weight: il peso relativo per i record della stessa priorità; un valore maggiore
     indica possibilità più alta di essere selezionato.

   ∗ port: la porta TCP o UDP attraverso la quale il servizio può essere contattato.

   ∗ target: l’hostname della macchina che mette a disposizione il servizio, seguito
     da un punto.

L’indirizzo IP, mancante nel Record SRV, è restituito da un record di tipo A.

Nel caso le richieste DNS per questo tipo di record non siano supportate, alcune
soluzioni individuate durante lo stage si appoggiano invece ad un software aggiuntivo
come ad esempio Consul, il quale, popolato a sua volta da software terzi, espone delle
API tramite le quali molti reverse proxy sono in grado di venire a conoscenza dei servizi
disponili.

Nel caso di THRON, un DNS con record di tipo SRV è già messo a disposizione
tramite i servizi di Amazon e sono quindi state cercate delle soluzioni che permettessero
di utilizzarlo.
14                                     CAPITOLO 4. SCOUTING DEL SOFTWARE

4.1.4      Load Balancing
Il Load Balancing è la distribuzione delle richieste tra più istanze dello stesso micro-
servizio, delle quali il software è venuto al corrente tramite il service discovery. Questa
operazione serve a evitare di affidare troppo lavoro a una singola istanza del cluster.
Per la scelta dell’istanza da contattare si utilizzano metodi che distribuiscono il carico,
in base al reverse proxy possono essere disponibili vari di questi:

     ∗ selezione casuale;

     ∗ Round Robin [14]: si seleziona via via ogni istanza dopo aver scelto una regola per
       cui sono ordinate, generalmente in base al valore dell’hash generato da qualche
       loro campo (come ad esempio l’indirizzo IP);

     ∗ Least Connections [7]: viene sempre selezionata una delle istanze che al momento
       sta servendo meno richieste.

Nel caso sia inoltre possibile ottenere un valore weight (cosa vera nel caso di supporto
dei DNS SRV, dato che il campo weight è presente nei valori restituiti dai record) è
possibile anche applicare le versioni "pesate" dei precedenti algoritmi. Il valore weight
è tanto più alto quanto più l’istanza del microservizio è in grado di servire più richieste,
così facendo se due o più microservizi che svolgono la stessa funzione dovessero avere
prestazioni diverse è possibile bilanciare le richieste correttamente.

4.1.5      Caching
Il caching è una pratica che sfrutta il fatto che, in certi contesti, determinate informa-
zioni non hanno necessità di essere aggiornate in tempo reale ma rimangono valide per
un certo lasso di tempo, o comunque il loro mancato aggiornamento non crea criticità
rilevanti.

Queste informazioni, una volta ottenute dal microservizio di riferimento e restituite
al primo richiedente (con una risposta di tipo cache miss, ovvero il non ritrovamento
della risposta in cache), possono venire mantenute temporaneamente in uno spazio di
memorizzazione più velocemente accessibile ed essere fornite come risposta a richieste
dello stesso tipo successive (con una risposta di tipo cache hit), senza bisogno di
ricontattare il microservizio che le ha generate, così da alleggerire il lavoro dello stesso
e rendere più soddisfatti gli utenti che ottengono risposte più velocemente.

Nel caso di THRON, questo si può facilmente riconoscere nell’ambito della distri-
buzione di contenuti, ad esempio le immagini all’interno dei siti web, le quali anche se
aggiornate un paio di minuti in ritardo non creano particolari problemi.

Le due principali configurazioni da definire quando si sceglie di adottare la cache
in un sistema sono quelle relative alle condizioni che distinguono le risposte attese e al
tempo di validità.

Le condizioni che distinguono le risposte attese possono essere ad esempio i valo-
ri dei campi contenuti nell’header della richiesta: se si riceve una richiesta che specifica
un particolare tipo di risposta attesa, come può essere il formato dei dati di risposta, è
importante assicurarsi che a questa richiesta non venga fornita una risposta di tipo
diverso solo perché presente in cache. Lo stesso esempio può essere fatto nel caso in
4.1. REQUISITI DEL SOFTWARE                                                                15

cui siano fornite credenziali di un utente, le quali implicano che la risposta conterrà
probabilmente dati riservati a quell’utente, che non si aspetta quindi di ricevere una
risposta che era destinata ad un utente differente.

Il tempo di validità della cache va scelto in base alla criticità dell’informazione restituita
dal servizio alla quale questa è destinata. Quando è possibile farlo, torna utile anche
diversificare questo tempo in base a condizioni come ad esempio il codice di stato della
risposta HTTP (HyperText Transfer Protocol).
Il codice di stato HTTP [4] è quello che indica come la richiesta è stata gestita; nella
maggior parte dei casi ci si aspetta di ottenere un codice di risposta compreso tra il
valore 200 e 299 (di tipo success), che indica che la richiesta è andata a buon fine, e
viene quindi naturale pensare di memorizzare in cache questo tipo di risposte.
Nel mondo reale però non sempre le cose vanno a buon fine, e capita quindi di ottenere
risposte HTTP con codice compreso tra 400 e 499 (client error ) o tra 500 e 599 (server
error ). Anche in questi casi, contrariamente a come si potrebbe credere, potrebbe
tornare utile mantenere in cache la risposta contenente l’errore per pochi secondi, così
da "concedere un attimo di pausa" al microservizio che ha generato quell’errore, il
quale potrebbe essere semplicemente sovraccarico e non essere in grado di tornare
operativo se venisse affollato di richieste in una situazione del genere.

Ovviamente in contesti vari potrebbe risultare utile avere la possibilità di configurare
la cache in base ad ancora differenti condizioni, e proprio questo è un problema per
i software che se ne occupano, i quali non sempre prevedono di poter sfruttare ogni
dettaglio per personalizzare la scelta.

Occorre inoltre ricordare che nonostante tutti i lati positivi di questa tecnologia,
non in tutti i casi risulta utile mantenere una cache. In contesti dove le richieste si
aspettano sempre risposte differenti o dove semplicemente non viene attesa una risposta
per utilizzarne le informazioni contenute ma solo per conferma dell’operazione andata a
buon fine, come nel caso delle richieste HTTP POST, la cache non porta alcun beneficio.

Alcuni software con cache più avanzate possono mettere inoltre a disposizione al-
tre funzioni interessanti, ad esempio la request coalescing (o grace mode [3]), che fa sì
che se più richieste dello stesso tipo che non trovano una risposta già pronta in cache
arrivano quasi contemporaneamente in un brevissimo lasso di tempo, solo una venga
inoltrata effettivamente al microservizio destinatario, mentre le altre vengono lasciate
in attesa che la risposta della prima sia memorizzata per essere riutilizzata.
Questa opzione aumenta ulteriormente la quantità di cache hit riducendo il carico di
lavoro dei microservizi.

4.1.6     API di amministrazione
Generalmente i reverse proxy ottengono le configurazioni tramite file che vanno riempiti
con quanto definito dall’utente secondo la struttura attesa dal proxy scelto. Questi
file, se possibile, vanno poi testati con i comandi forniti per evitare che contengano
errori e solo poi integrati nel proxy stesso. Questa operazione, eseguita in tal modo,
spesso richiede il riavvio del reverse proxy e la riapplicazione delle configurazioni su
ogni singola istanza del cluster.
Alcune soluzioni (ad esempio il servizio Elastic Container Service di Amazon [28])
semplificano questo processo permettendo di definire una nostra "nuova versione"
16                                     CAPITOLO 4. SCOUTING DEL SOFTWARE

(revisione) del proxy che contiene la nuova configurazione e occupandosi poi di termi-
nare autonomamente i proxy con la vecchia configurazione man mano che quelli nuovi
diventano operativi. Nonostante questa possibilità, l’operazione rimane scomoda, lenta
e pericolosa, provocando una situazione di inconsistenza durante la quale si hanno in
contemporanea alcune istanze con configurazione vecchia e altre con configurazione
nuova.

Per evitare questo, alcune soluzioni mettono a disposizione delle API da ammini-
stratore tramite le quali è possibile modificare rapidamente le configurazioni per
l’intero cluster senza downtime o inconsistenze, e prevengono così errori causati da
struttura del file scorretta.

4.1.7      Autenticazione e Autorizzazione
Ovviamente non tutti i microservizi sono sempre pensati per essere utilizzati da chiun-
que; alcuni, come nel caso di THRON, sono riservati ai clienti, che hanno permessi
e aspettative differenti. Da questo è facile intuire che è necessario avere modo di
riconoscere chi sta cercando di contattare un microservizio e di sapere se è autorizzato
a farlo.

Per l’autenticazione esistono vari sistemi, i quali coinvolgono tutti il passaggio di
un qualche identificativo tramite l’header delle richieste. I più famosi tra questi sono
l’uso di chiavi API, l’OAUTH [26] e il Json Web Token [6] (JWT).

4.2       Soluzione individuata
Come evidenziato nell’introduzione del Capitolo 4, nel corso dello stage i reverse proxy
sono stati identificati come i software che più si prestano a soddisfare questi requisiti.
Tra questi spicca la sottocategoria degli API Gateway [25], i quali generalmente offrono
funzioni aggiuntive specifiche per le API (come si può intuire dal nome) e configurazioni
molto meno complesse per l’utente perdendo però parte della personalizzazione.
In questo periodo sono state testate varie soluzioni, ad esempio gli API Gateway Kong,
KranenD e Gravitee e altri software che rientrano nella famiglia dei reverse proxy quali
Envoy, HAproxy e Traefik.

I problemi principali nell’individuare un software adatto sono apparsi proprio nel
soddisfare i requisiti principali:
     ∗ in tutti i casi è possibile applicare rate limiting, tuttavia solo alcuni software
       permettono di farlo in modo condiviso nel cluster;
     ∗ il routing basato su host non è quasi mai presente nei software dichiarati come
       API gateway; più in particolare questa funzione è apparsa mutualmente esclusiva
       nei confronti della funzione di caching, la quale è invece presente in tutti gli API
       gateway e mancante negli altri tipi di reverse proxy testati.
       Unica eccezione a questa regola è Kong, il quale possiede entrambe le funzioni, ma
       nel suo caso il routing basato su host non è abbastanza avanzato da riconoscere
       gli host come richiesto nel caso di THRON.
Altro requisito critico è quello delle API di amministrazione: spesso queste non sono
presenti, mancanza compensata in parte da interfacce grafiche dalle quali è possibile
4.2. SOLUZIONE INDIVIDUATA                                                                   17

vedere e solo in alcuni casi anche modificare le configurazioni.

Nel corso di questo periodo di scouting delle tecnologie sono stati anche identifi-
cati due software di supporto utili a completare o ad aggiungere le funzioni mancanti
necessarie per le soluzioni che non soddisfano autonomamente tutti i requisiti.
Il primo di questi è Consul, software che sarebbe servito a sostituire il service discovery
tramite DNS esponendo invece API che molti reverse proxy non in grado di effettuare
query di tipo SRV sono invece in grado di contattare nativamente; il secondo è Varnish
[24], un software per il caching HTTP veramente avanzato che possiede anche vari
moduli per funzioni aggiuntive, tra i tanti è particolarmente interessante il modulo
vsthrottle, che permette di applicare rate limiting.
L’adozione di Consul non avrebbe particolari problemi rispetto ai vincoli dello stage, in
quanto si sarebbe trattato solo di un componente aggiuntivo all’interno della rete che
avrebbe fatto le veci del DNS traducendone i record in API comprensibili. Varnish, al
contrario, si sarebbe dovuto posizionare frontalmente al reverse proxy scelto, violando
il vincolo di avere un unico software centralizzato e aggiungendo ulteriore complessità.

In Tabella 4.1 sono sintetizzati i risultati dello scouting per le soluzioni testate.

                            Tabella 4.1: Tabella reverse proxy

  Nome    e     Rate       Routing      Service      Load      Cache   Admin     Autorizza-
  Versione     Limiting    su Host    Discovery    Balancing             API     zione API

   Envoy       Software    Completo    Software       Si         No      No             Si
   1.12.0     Aggiuntivo              Aggiuntivo
 Gravitee     Condiviso      No         Consul        Si         Si      No             Si
  1.28.0
 HAproxy         Non       Completo      DNS          Si         No      No             Si
    2.1       Condiviso                  SRV
   Kong       Condiviso    Parziale      DNS          Si         Si       Si            Si
    1.3                                  SRV
 KrakenD        Non          No          DNS          Si         Si      No             Si
  0.9.0       Condiviso                  SRV
  Traefik       Non        Completo     Consul        Si         No      No         No
    1.7       Condiviso

A seguito dello scouting, durante una riunione in presenza del tutor aziendale e del
CTO di THRON è stato deciso di utilizzare per la POC l’API gateway Kong.
Kong è l’unico software fra quelli testati che offre almeno una soluzione basilare per
ogni requisito, pertanto è risultato una scelta quasi obbligatoria.
Oltre a questo hanno influito nella scelta le seguenti motivazioni:

   ∗ Kong è la soluzione individuata con documentazione qualitativamente migliore,
     più completa e ricca di esempi;

   ∗ Kong è un progetto maturo e ancora attivo, arrivato attualmente alla sua versione
     1.3: anche in fase di scouting é stato possibile apprezzare le novità implementate,
18                                     CAPITOLO 4. SCOUTING DEL SOFTWARE

      prima tra tutte l’integrazione della cache anche per la versione community
      (gratuita), che lo ha reso una scelta possibile;

     ∗ Kong è basato sul web server Nginx, tecnologia già utilizzata in THRON e nella
       quale è posta particolare fiducia da parte dell’azienda.
Il problema del routing basato su gruppi di host non è risolvibile da Kong singolarmente,
ed è quindi stato deciso che, in caso di sua effettiva applicazione, la riscrittura dell’host
in un formato gestibile sarà affidata ad un altro componente della rete di THRON, la
CDN (Content Delivery Network). Tra le alternative sono presenti software in grado
di risolvere questo problema, tuttavia questi peccano tutti in maniera più grave nel
soddisfare altri requisiti.
Capitolo 5

Sviluppo della Proof of Concept

In questo capitolo è descritto l’effettivo sviluppo della POC e i relativi software e le tecno-
logie impiegati.

5.1      Software e Tecnologie utilizzati
5.1.1     Docker
Docker [17] (vedi Figura 5.1) è un software open source che automatizza il deployment
di applicazioni all’interno di contenitori software, fornendo un’astrazione aggiuntiva
grazie alla virtualizzazione a livello di sistema operativo di Linux. Docker utilizza delle
funzionalità di isolamento delle risorse del kernel Linux per consentire a container
indipendenti di coesistere sulla stessa istanza di Linux, evitando l’installazione e la
manutenzione di un’intera macchina virtuale.

                                 Figura 5.1: Logo Docker

Tramite Docker è possibile costruire (o scaricare da repository online) delle immagini
dei software, le quali sono pacchetti che contengono il software stesso, un ambiente già
pronto alla sua esecuzione (completo delle dipendenze e delle configurazioni necessarie)
e i comandi da eseguire per la generazione di un container.
I container, una volta generati, entrano a far parte delle network di Docker, attraverso
le quali viene associato loro un indirizzo IP e possono quindi comunicare tra loro come
se fossero macchine differenti all’interno di una stessa rete.

Nel progetto di stage, Docker è stato il software principale, ampiamente utilizza-

                                              19
20                      CAPITOLO 5. SVILUPPO DELLA PROOF OF CONCEPT

to sia per testare le varie soluzioni in fase di scouting che per l’implementazione della
POC in locale.
Anche i servizi ECS e Fargate di AWS sono basati su Docker e utilizzano a loro volta
le stesse immagini.

5.1.2     Portainer
Portainer [20] (vedi Figura 5.2 e 5.3) è un set di strumenti che consente di creare,
gestire e mantenere facilmente ambienti Docker (ad esempio vedere quali container
sono in esecuzione e le loro informazioni, terminarli, riavviarli e accedere ad essi tramite
il terminale integrato nell’interfaccia).
È uno strumento che può essere a sua volta eseguito in un container Docker e fornisce
un’interfaccia grafica la quale permette di eseguire le principali operazioni in ambiente
Docker senza esecuzione di comandi da terminale.

                               Figura 5.2: Logo Portainer

Portainer non sostituisce interamente il classico controllo da terminale ma grazie alla
sua interfaccia rende lavorare con Docker molto più veloce e comprensibile, mantenendo
sempre tutto sotto controllo.

Nel progetto di stage è stato ampiamente utilizzato per monitorare la grande quantità
di container in esecuzione vista la centralità di Docker nello sviluppo della POC.

                           Figura 5.3: Interfaccia di Portainer
5.1. SOFTWARE E TECNOLOGIE UTILIZZATI                                                 21

5.1.3     Amazon Web Services
Amazon Web Services [15] (AWS, vedi Figura 5.4) è una piattaforma che fornisce
servizi di cloud computing on demand.

                         Figura 5.4: Logo Amazon Web Services

Nel contesto dello stage sono stati utilizzati i servizi seguenti.

Amazon Elastic Compute Cloud (EC2): è un servizio Web che fornisce capacità
   di elaborazione sicura e scalabile nel cloud.
   Nel progetto è stato utilizzato per avviare le macchine necessarie all’esecuzione
   del servizio ECS. Quelle utilizzate nel corso dello stage appartengono al gruppo
   delle macchine ad uso generale e sono quelle di tipo T2 ed M5.
   Le macchine T2 sono a prestazioni espandibili, ovvero forniscono delle prestazione
   di base garantite e la possibilità di superarle automaticamente per un certo periodo
   di tempo se richiesto dal carico di lavoro. Per farlo, sono accumulati dei "crediti"
   nei periodi di inattività o di attività ridotta che possono essere spesi per superare
   il limite nei momenti nei quali risulta necessario.
   La variazione di prestazioni delle macchine T2 renderebbe inconsistenti i test di
   carico e pertanto per questa attività ne è stata usata una di tipo M5, a prestazioni
   fisse.

Amazon Elastic Container Service (ECS): è un servizio di orchestrazione di con-
   tenitori altamente dimensionabile ad elevate prestazioni che supporta i contenitori
   Docker e consente di eseguire e ridimensionare facilmente le applicazioni suddivise
   in contenitori su AWS.
   Nel progetto ha consentito di eseguire container Docker sulle macchine fornite
   dal servizio EC2.

Amazon Elastic Container Registry (ECR): è un registro di contenitori Docker
   completamente gestito che semplifica agli sviluppatori la memorizzazione, la
   gestione e la distribuzione di immagini di contenitori Docker.
   Nel progetto è stato utilizzato per memorizzare e recuperare velocemente le
   immagini Docker da eseguire tramite i servizi ECS e Fargate.

Elastic Load Balancing (ELB): è un servizio che instrada automaticamente il traf-
     fico in entrata delle applicazioni tra molteplici destinazioni, quali istanze Amazon
     EC2, container, indirizzi IP e funzioni Lambda. Può gestire i mutevoli carichi di
     traffico di un’applicazione in una o più zone di disponibilità.
     Nel progetto è stato utilizzato per avviare l’Application Load Balancer della POC
     che si occupa di distribuire il carico di richieste tra le istanze dei reverse proxy
     testati.

AWS Fargate: è un motore di elaborazione per Amazon ECS che permette di eseguire
   contenitori senza dover gestire server o cluster.
22                       CAPITOLO 5. SVILUPPO DELLA PROOF OF CONCEPT

       Nel progetto è stato utilizzato per eseguire piccoli container Docker che non
       richiedono ingenti quantità di risorse per il loro funzionamento.
AWS Cloud Map: è un servizio di rilevamento delle risorse cloud. Con Cloud Map
   è possibile definire i nomi personalizzati per le risorse dell’applicazione e gestire
   la posizione aggiornata di queste risorse che cambiano in modo dinamico. Ciò
   aumenta la disponibilità dell’applicazione poiché il servizio Web rileva sempre le
   posizioni più aggiornate delle risorse.
   Nel progetto è stato utilizzato per assegnare nomi DNS alle componenti della
   POC.
Amazon Route 53: è un servizio Web di DNS (Domain Name System).
   Nel progetto è stato utilizzato per il service discovery e load balancing grazie ai
   record di tipo SRV messi a disposizione.

5.1.4      Kong
Kong [18] (vedi Figura 5.5) è un API Gateway Scalabile e open source sviluppato in
Lua ed eseguito sulla base del web server Nginx utilizzato come reverse proxy.
Ha nativamente poche funzioni basilari (routing, service discovery tramite DNS SRV,
load balancing) perché mette le altre a disposizione ufficialmente sottoforma di plugin.

                                  Figura 5.5: Logo Kong

Le configurazioni di Kong si basano su quattro entità:
     ∗ i Consumer, che rappresentano utenti o macchine che contattano le API dei
       microservizi;
     ∗ le Route, ovvero i metodi e le regole attraverso le quali i consumer possono
       contattare i microservizi ;
     ∗ i Service, ovvero le entità che rappresentano i microservizi all’interno di Kong;
     ∗ i Plugin, ovvero le funzioni aggiuntive, i quali possono essere applicati globalmente,
       per service e per route ed essere validi per tutti i consumer o specifici per uno
       solo di essi.
Kong espone le sue funzionalità attraverso le seguenti porte di default, che possono
essere variate di numerazione:
     ∗ la porta 8000 è quella dove ci si aspetta di ricevere le richieste degli utenti che
       vogliono contattare i microservizi ;
     ∗ la porta 8443 è per le richieste degli utenti attraverso il protocollo HTTPS;
5.1. SOFTWARE E TECNOLOGIE UTILIZZATI                                                   23

   ∗ la porta 8001 espone le API di amministrazione;

   ∗ la porta 8444 espone le API di amministrazione per il protocollo HTTPS.
Nel registrare un microservizio su Kong, si effettuano i seguenti step:
   ∗ si crea un service al quale viene associato il nome DNS del microservizio
     rappresentato;

   ∗ si creano una o più route associate al service creato precedentemente per ogni
     API che il microservizio corrispondente mette a disposizione, specificando quindi
     host e/o path corrispondenti;
   ∗ si aggiungono i plugin necessari (ad esempio il rate limiter e la cache) sul service
     stesso se si vuole che siano validi per tutte le API del microservizio, altrimenti
     sulle singole route. Si specifica inoltre se il plugin ha una configurazione generica
     per tutti o se è valido per un singolo consumer (distinto tramite un id ).
I plugin seguono le seguenti regole:
   ∗ non è possibile abilitare più di una volta lo stesso plugin per un’entità a meno
     che questo non sia rivolto ad utenti differenti;

   ∗ se più plugin dello stesso tipo sono applicati allo stesso servizio su livelli diversi
     (route, service e globale) e su più utenti (rispettando la regola precedente), per
     una richiesta viene applicato sempre e solo il plugin più specifico prima rispetto
     all’utente (quindi quello configurato per le credenziali del chiamante) e solo poi
     per livello.
     Se, ad esempio, è applicato un plugin di rate limiting su una route "X" che limita
     le richieste a 3 al secondo per tutti gli utenti, ma a livello globale l’utente "Y" in
     particolare ha un limite di 7 richieste al secondo, questo utente "Y", pur facendo
     richiesta alla route "X" può comunque eseguire 7 richieste al secondo, anche se
     la route è un livello più specifico rispetto al livello globale.
     Per limitare le richieste a 3 anche all’utente "Y" sulla route "X", se non si vuole
     modificare il limite globale, occorre quindi riapplicare rate limiting specifico per
     l’utente "Y" nella route "X".
24                      CAPITOLO 5. SVILUPPO DELLA PROOF OF CONCEPT

5.1.5     Konga
Konga [11] (vedi Figura 5.6) è un software open source che fornisce un’interfaccia
grafica pensata per visualizzare e modificare le configurazioni di Kong.

Nel contesto dello stage é stato utilizzato per modificare e monitorare le configurazioni
delle istanze di Kong presenti nella POC.

                            Figura 5.6: Dashboard di Konga

5.1.6     Locust
Locust [19] (vedi Figure 5.7 e 5.8) è uno strumento per l’esecuzione di test di carico
distribuiti il quale permette di simulare richieste da parte di utenti nel web.
È possibile programmare il comportamento dell’utente simulato in modo molto semplice
tramite uno script in Python che viene poi eseguito mentre si raccolgono dati sulle
prestazioni del servizio testato.

                                Figura 5.7: Logo Locust

Nel progetto di stage é stato utilizzato per soddisfare il requisito facoltativo dei test di
carico distribuiti.
5.1. SOFTWARE E TECNOLOGIE UTILIZZATI                                                   25

                            Figura 5.8: Interfaccia di Locust

5.1.7     Python
Python [22] (vedi Figura 5.9) è un linguaggio di programmazione ad alto livello,
orientato agli oggetti, adatto, tra gli altri usi, a sviluppare applicazioni distribuite,
scripting, computazione numerica e system testing.

                                Figura 5.9: Logo Python

Nel progetto di stage è stato utilizzato in modo marginale, in particolare per la scrittura
di piccoli servizi di test da containerizzare tramite Docker e per la configurazione di
Locust.

5.1.8     Consul
Consul [16] (vedi Figura 5.10) è una soluzione per implementare service discovery e
service mesh la quale offre tra le varie funzionalità quella di server DNS.
Con Consul è possibile creare una rete di istanze anche su macchine diverse che comu-
nicano tra loro, per essere sempre a conoscenza dei servizi scoperti da ogni istanza in
26                      CAPITOLO 5. SVILUPPO DELLA PROOF OF CONCEPT

ogni macchina.

                                Figura 5.10: Logo Consul

Nel contesto dello stage è stato utilizzato per fornire la funzionalità di service discovery
ai reverse proxy senza supporto a record SRV, e come DNS da utilizzare localmente su
Docker.

5.1.9     Registrator
Registrator [12] è un software che permette di registrare e deregistrare in tempo reale
su Consul i container in esecuzione su Docker e le relative porte esposte.

Nel progetto di stage è stato utilizzato in locale in accoppiata con Consul per fornire il
servizio DNS alla rete Docker.

5.1.10     PostgreSQL
Anche detto Postgres [21] (vedi Figura 5.11), è un RDBMS (Relational Database
Management System) open source che enfatizza l’estensibilità e la conformità agli
standard tecnici. È progettato per gestire una vasta gamma di carichi di lavoro.

                             Figura 5.11: Logo PostgreSQL

Nel contesto dello stage non ha avuto mai un ruolo principale, ma è stato utilizzato
soltanto containerizzato per conservare le configurazioni di Kong, in modo che queste
fossero unificate e condivise per l’intero cluster.
5.1. SOFTWARE E TECNOLOGIE UTILIZZATI                                                 27

5.1.11     Redis
Redis [23] (vedi Figura 5.12) è un archivio open source di strutture di dati in memoria,
utilizzato come database, cache e broker di messaggi.

                               Figura 5.12: Logo Redis

Nel contesto dello stage è stato utilizzato come cache per la sua velocità di accesso, in
particolare per conservare dati con accessi frequenti da condividere nei cluster, quali i
contatori richiesti per applicare rate limiting e le risposte dei servizi memorizzate in
cache.
28                      CAPITOLO 5. SVILUPPO DELLA PROOF OF CONCEPT

5.2      Proof of Concept
Sono state sviluppate due versioni della POC: la prima versione è eseguibile in locale con
il solo prerequisito di avere installato Docker; la seconda riprende la prima utilizzando
invece i servizi offerti da Amazon.

5.2.1      Proof of Concept locale tramite Docker
La struttura della POC locale è quella rappresentata in Figura 5.13.
Questa POC è composta da un gruppo di container Docker che riproducono un am-
biente con architettura a microservizi : sono presenti dei container necessari a fornire la
funzionalità DNS, dei container che fungono da microservizi di prova e le componenti
necessarie al funzionamento di Kong.

                         Figura 5.13: POC in locale con Docker

In particolare le componenti sono:

     ∗ il cluster di container che eseguono Kong, componente principale della POC;

     ∗ un container per l’interfaccia grafica di amministrazione Konga, utilizzata per
       configurare Kong;

     ∗ un container Postgres, database nel quale sono contenute le configurazioni
       condivise per l’intero cluster di istanze di Kong;

     ∗ un container Redis utilizzato per memorizzare i contatori delle richieste in modo
       da effettuare rate limiting condiviso mantenendo buone prestazioni grazie alla
       sua velocità di accesso;

     ∗ l’accoppiata di container Consul e Registrator:
Puoi anche leggere