In questo articolo vedremo come installare e scalare un applicazione Laravel in AWS. Come esempio di applicazione userò Laravel poiché mi è più familiare ma è possibile utilizzare questo tutorial anche per altre tipologie di applicazione che utilizzino PHP, Mysql e Apache.
Creeremo più istanze EC2 bilanciate da un load balancer ELB e ci applicheremo delle regole di autoscaling. Queste istanze condivideranno uno stesso database RDS e gli stessi file dell’applicazione tramite EFS.
Inoltre vedremmo come configurare autoscaling, per ottimizzare prestazioni e costi, variando il numero di istanze EC2 attive a seconda delle necessita impostate.
Amazon EC2
Amazon Elastic Compute Cloud (Amazon EC2) fornisce capacità di elaborazione scalabile nel cloud di Amazon Web Services (AWS).
L’utilizzo Amazon EC2 elimina la necessità di investimenti anticipati in hardware e ti permette di sviluppare e distribuire più rapidamente le applicazioni. Puoi utilizzare Amazon EC2 per avviare il numero di server virtuali necessari, configurare la sicurezza e i servizi di rete, nonché gestire lo storage.
Amazon EC2 permette di aumentare o ridurre le risorse per gestire le variazioni a livello di requisiti o i picchi di popolarità, riducendo la necessità di elaborare previsioni relative al traffico.
Permette inoltre di registrare un account gratuito, che consente di acquisire familiarità, creare e gestire dei servizi base.
Una volta eseguito l’accesso, è necessario andare al pannello di gestione EC2.
Avviare un istanza
Innanzitutto creiamo e configuriamo un istanza, utilizzando la versione ufficiale Linux AMI (versione RHL customizzata da Amazon).
Quindi lanciamo l’istanza e selezioniamo la versione di Amazon Linux AMI che include Pyton, Ruby, Perl…
Selezioniamo il tipo di istanza t2.micro tipo compatibile con Free-Tier. Il t2.micro tipo è un tipo di istanza inclusa nel piano gratuito di valutazione di Amazon che offre 750 ore gratuite.
Lasciamo i punti 3, 4, 5 come proposti e configuriamo i gruppi di sicurezza. In questa sezione andiamo a configurare un nuovo gruppo di sicurezza, indicando quali porte la macchina è accessibile dall’esterno.
Aggiungiamo alla porta SSH di default, HTTP e HTTPS per l’accesso alla propria applicazione.
Una volta fatto, fai clic sul pulsante Rivedi e avvia.
La console ci chiederà di generare una chiave RSA (oppure utilizzare una chiave precedentemente creata) per l’accesso SSH alla macchina, e ci farà scaricare la chiave privata da utilizzare per accedere in ssh dalla nostra macchina locale.
A questo punto avremmo questo messaggio.
Ora ritorniamo nell’area riservata e vedremmo che la nostra macchina si sta inizializzando.
Una volta inizializzata, l’indicazione “inizializing” sparirà, colleghiamoci via SSH.
Connessione all’istanza EC2 tramite SSH
Ora che l’istanza è avviata, dobbiamo prendere l’indirizzo IP dns o ip pubblico dell’istanza per consentirci di stabilire una connessione ssh, utilizzando la chiave privata generata precedentemente. Attenzione che questo indirizzo è dinamico e potrebbe variare nel tempo.
L’indirizzo ip o dns pubblico lo si trova in basso a destra nel dettaglio dell’istanza, cliccando sul bottone connect, verrà illustrata la procedura dettagliata per connettersi alla macchina via ssh.
Se avete linux potete accedere tramite bash, invece con Windows è necessario utilizzare PuTTY o GitBash.
Ora non ci resta che collegarci via ssh.
Nel caso venisse generato questo errore:
Permissions 0644 for 'key.pem' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key "key.pem": bad permissions
E’ necessario i permessi come di seguito
chmod 400 key.pem
Installazione di Apache e PHP
Prima di tutto eseguiamo l’aggiornamento del sistema tramite utente root
sudo su yum update
Ora avviamo l’installazione dei pacchetti, in questa guida non ci preoccuperemo di configurare e parametrizzare al meglio i servizi, ma eseguiremo una configurazione base.
yum install httpd24 yum install php73 php73-mysqlnd php73-imap php73-pecl-memcache php73-pecl-apcu php73-gd php73-mbstring yum install mod24_ssl
Avviamo il servizio apache e facciamo in modo che venga avviato all’avvio della macchina.
service httpd start
sudo chkconfig httpd on
Ora navigando da browser tramite ip o dns pubblico dovremmo vedere la pagina di default di apache comparire.
Per far eseguire all’istanza l’avvio automatico del servizio Apache digiteremo
chkconfig —add httpd
Creazione e avvio database Amazon RDS
Amazon RDS è un servizio di database relazionale in AWS che consente di avviare database relazionali completamente gestiti come MySQL, Oracle, Amazon Aurora (MySQL ad alte prestazioni e disponibili), PostgreSQL, MariaDB e Microsoft SQL Server.
Creeremo un database MariDB in RDS prima di installare Laravel sulla nostra istanza EC2 . Questo ci fornirà gli endpoint del database necessari per configurare l’app Web Laravel su tutte le istanze EC2 che andremo a creare.
Accedere alla RDS pagina e fare clic sul tasto create database
Selezionare il motore MariaDB
Selezioniamo Free tier per utilizzare il piano gratuito di 12 mesi
Quindi impostiamo il nome database, utente e password che poi utilizzeremo per poi collegarci alle nostra istanze:
Ora cliccando Create database iniziarà la procedura di creazione del DB
L’ultima cosa che dobbiamo fare è creare un gruppo di sicurezza che consentirà il traffico attraverso la porta 3306
al nostro database MySQL
Passare a gruppi di protezione sotto rete e sicurezza sul cruscotto EC2 e fare clic sul Crea gruppo di protezione pulsante
In questo esempio lasceremo l’accesso da ogni ip, in caso è possibile limitarne l’accesso da Source.
Al termine ritorniamo nel pannello RDS, selezioniamo il database e andiamo in modifica.
Nel pannello che apparirà, nella configurazione di sicurezza inseriamo il nostro gruppo appena creato.
Per testare l’accesso al database, o avete necessità di accedere pubblicamente è necessario attivare l’ultima spunta.
L’operazione potrebbe durare del tempo.
In seguito potete testare l’accesso al db utilizzando i parametri che verranno mostrati all’interno dei dettaglio del db. Questi parametri, assieme alle credenziali impostate in fase di creazione del db, saranno necessarie per il collegamento da parte della nostra applicazione.
Ora abbiamo tutto quello che ci serve per configurare la nostra applicazione.
Elastic File System
Utilizzando più istanze EC2 avremmo bisogno che ogni singola istanza acceda e condivida agli stessi files dell’applicazione.
Per questo motivo utilizziamo il servizio EFS di AWS e monteremo il volume nella istanza EC2.
Alcuni dei vantaggi di EFS sono:
- Completamente gestito da AWS
- Basso costo, si paga per quello che usa
- Alta disponibilità e durata
- Autoscaling
Accediamo alla console di AWS, accedere ai servizi EFS e generare un file systems.
AWS assegnerà automaticamente un indirizzo IP nella zona di disponibilità. Se è necessario modificare, è possibile farlo nella schermata successiva.
Inoltre assegnamo il gruppo di sicurezza corretto ad ogni zona di disponibilità.
Nelle schermate successive sono presenti delle opzioni che in questo caso non andremmo a toccare, quindi procediamo alla creazione del file systems.
Nella schermata successiva vedremmo questo, quindi aspettiamo che la creazione sia ultimata
Una volta terminata dovremmo montare il volume nella nostra macchina EC2.
Nella stessa pagina sono presenti le istruzioni per il montaggio che riporto di seguito:
Prima di proseguire però dobbiamo assolutamente aggiungere la porta del servizio NFS nella policies della nostra istanza EC2 altrimenti non riusciremo a montare il volume.
L’opzione è accessibile dal menu EC2 in gruppi di sicurezza, e modificando la regola corrispondente
A questo punto colleghiamoci alla nostra Istanza EC2 via SSH e montiamo il volume appena creato.
Per fare ciò montero il volume EFS nella directory /var/www/html/laravel dove in seguito andrò ad inserire il mio applicativo.
Quindi eseguiamo questi comandi:
cd /var/www/html/ mkdir laravel sudo mount -t efs fs-ba06ca0b:/ laravel
come possiamo vedere abbiamo montato correttamente il volume EFS
Nota: utilizzando l’applicativo da un volume condiviso le prestazioni sono inferiori rispetto al volume locale della macchina EC2. Consiglio innanzitutto di ottimizzare la vostra applicazione utilizzando l’ultima versione di PHP e l’attivazione del modulo opcache. Nei test che ho effettuato l’incremento di prestazioni è molto evidente.
A questo punto facciamo mappare automaticamente il nostro volume all’avvio aggiungendo la seguente riga al file /etc/fstab
.
fs-12345678
:/ /mnt/efs
efs defaults,_netdev 0 0
dove fs-12345678
è l’ID del file system Amazon EFS e /mnt/efs
Il punto di montaggio del file system EFS sull’istanza EC2.
Ora riavviamo e possiamo verificare la il volume EFS verrà automaticamente mappato all’avvio.
A questo punto siamo pronti ed installare la nostra applicazione e a distribuire la nostra applicazione su più istanze EC2 tramite ELB.
Installazione di Laravel
Innanzi tutto prepariamo il nostro ambiente per ospitare la nostra applicazione. Per fare prima non creeremo un vhost dedicato ma configureremo la cosa in modo rapida in modo che di default ogni richiesta venga servita dall’applicazione senza particolari accorgimenti.
In questa guida utilizzeremo la versione 5.8, la versione 6.x differisce nella configurazione di autenticazione, che verrà spiegata in seguito.
Installiamo git
sulla nostra istanza.
yum install git
Installiamo composer tramite curl
sudo curl -sS https://getcomposer.org/installer | php
Rendiamo composer accessibile globalmente
mv composer.phar /usr/local/bin/composer
Ora avviamo composer nella command line per verificare che sia correttamente richiamabile
Ora ci spostiamo sulla directory /var/www/html e cloniamo la repo di laravel
composer create-project --prefer-dist laravel/laravel laravel "5.8.*"
Cambiamo il proprietario del contenuto della directory
chown -R apache.apache /var/www/html/laravel chmod -R 755 /var/www/html/laravel chmod -R 755 /var/www/html/laravel/storage
Ora che abbiamo clonato un nuovo progetto Laravel, dobbiamo riconfigurare il nostro server Apache per puntare alla directory Laravel. lo faremo copiando il codice qui sotto in fondo al /etc/httpd/conf/httpd.conf
file
nano /etc/httpd/conf/httpd.conf
Alias / /var/www/html/laravel/public/
<Directory "/var/www/html/laravel/public">
AllowOverride All
Order allow,deny
allow from all
</Directory>
Modifica il file .htaccess
nano /var/www/html/laravel/public/.htaccess
Quindi aggiungi RewriteBase /
appena sottoRewriteEngine On
Ora copiamo il file .env.example
cp .env.example .env
e andiamo a modificare il file appena creato impostando l’endpoint del database e modificando il driver di sessione in database
Eseguiamo l’aggiornamento delle dipendenze tramite composer
composer update
Genera chiave dell’applicazione:
php artisan key:generate
Crea scaffold di autenticazione:
php artisan make:auth
La sessione utente verrà memorizzata nel database anziché su file.
Questo perché se non utilizzeremo un volume condiviso EFS tra le istanze, quando andremmo a ridimensioneremo la nostra app Web Laravel, il Load Balancer bilancerà la richiesta di traffico in tutte le istanze che non condividono gli stessi file.
Quindi, se il mio file di sessione è stato archiviato istanza 1e la mia prossima richiesta è indirizzata istanza 5, istanza 5 non avrò accesso al mio file di sessione del istanza 1, quindi mi chiederà di eseguire l’autenticazione nuovamente.
Per evitare ciò, gestiremo le sessioni utente sul database, poiché tutte le istanze sono connesse e hanno accesso ad esso. In alternativa, possiamo utilizzare Amazon Elastic Cache che offre Redis e Memcache completamente gestiti.
Dalla versione 6 la configurazione è leggermente differente, qui sotto potete approfondire la nuova configurazione:
https://laravel-news.com/running-make-auth-in-laravel-6
Creare una migrazione della tabella delle sessioni:
php artisan session:table
Prima di lanciare la migrate che creerà le tabelle, è necessario creare il database:
Ora eseguiamo le migrazioni di Laravel:
php artisan migrate
A questo punto output dovrebbe restituire questo:
Ora collegandoci alla nostra istanza dovremmo vedere questo:
Ora Laravel è stato installato e configurato correttamente sulla nostra istanza Amazon Ec2. Abbiamo anche collegato l’istanza al nostro database MySQL.
È possibile effettuare tentativi di accesso per testare l’app.
Elastic Load Balancer
Nella prima parte dell’articolo abbiamo distribuito correttamente un’applicazione Web Laravel su un istanza Amazon Elastic Cloud Compute (EC2) residente in un istanza EFS e l’abbiamo connessa a un’istanza di database MySQL fornita da Amazon Relational Database System (RDS).
In questa parte conclusiva dell’articolo, distribuiremo la nostra applicazione Laravel su diverse istanze EC2 per garantire un’alta disponibilità. Configureremo un Load Balancer e un gruppo di ridimensionamento automatico Amazon EC2 per mantenere la disponibilità delle nostre istanze.
Innanzitutto, creiamo una Amazon Machine Image (AMI) della nostra istanza Ec2 che ha tutte le risorse necessarie installate e configurate correttamente. Questo AMI verrà utilizzato come origine per altre istanze che verranno create nel processo di ridimensionamento, garantendo una replica esatta e un comportamento comune di tutte le istanze fornite.
Crea un’immagine Amazon Machine Image (AMI)
Passare alla dashboard Ec2, selezionare l’istanza e fare clic su Action . Seleziona Image , quindi Create Image.
Potrebbero essere necessari alcuni minuti prima che sia pronto, ma è possibile passare alle AMI in Immagini per verificare l’avanzamento.
Ora che la nostra AMI è stata creata, dovremo:
- Crea un’applicazione Web Laravel resistente agli errori e altamente disponibile eseguendo il provisioning di diverse istanze dietro un bilanciamento del carico Amazon Elastic . Load Balancer distribuirà automaticamente il traffico in entrata su più istanze Ec2 su cui è in esecuzione la nostra Laravel Web App e condurrà periodicamente controlli di integrità su di esse, interrompendo la distribuzione del traffico a chiunque non superi il controllo.
- Crea un gruppo di ridimensionamento automatico per mantenere la disponibilità della nostra applicazione Laravel ridimensionando o riducendo le istanze, in base a eventi diversi come richiesta di traffico alto / basso, utilizzo elevato / basso della CPU, errore di una o più istanze fornite.
Creeremo un’altra istanza Ec2 utilizzando l’AMI creata sulla base della nostra istanza Ec2. Quindi clicchiamo su Launch Istance e a questo punto selezioniamo My AMIs per generare delle istanze partendo dall’immagine precendentemente creata.
Questa volta creiamo altre 3 istanze:
E infine assegnamo il gruppo corretto alle istanze:
Ora le nuove istanze sono in corso di creazione
Ora accedendo tramite dns pubblico vedrete che ogni istanza eseguirà correttamente lo stesso applicativo
Ora creeremo un bilanciamento del carico:
Individuate la voce Load Balancers sotto Load Balancing , sul cruscotto EC2.
Fare clic sul pulsante Crea bilanciamento del carico . Seleziona Bilanciamento carico applicazioni.
Selezioniamo l’opzione Application Load Balancer
Diamo un nome alla configurazione e aggiungiamo entrambi i protocollo http e https
E’ necessario quindi aggiungere minimo 2 Availability Zone
Create o selezionate un certificato esistente.
Selezionate un gruppo di sicurezza
Qui è possibile parametrizzare
Ora aggiungiamo le istanze da inserire sotto il load balancer
A questo punto ELB è finalizzato
Ora collegandosi al dns pubblico vedremmo che il load balancer distribuirà le chiamate tra le istanze. Possiamo verificare l’effettivo funzionamento facendo stampare ip address del server, inserendo nella pagina index la stampa del IP locale.
Facendo alcuni refresh della pagina la chiamata viene distribuita su tutte le istanze come visibile qui sotto:
Autoscaling
Attraverso Amazon AWS Auto Scaling è possibile programmare in modo automatico la scalabilità della soluzione EC2, variando il numero di Cloud Server sulla base delle metriche impostate, per mantenere le prestazioni durante i picchi, facendo avviare nuove istanze in automatico, e diminuire i costi di utilizzo durante i periodi di pausa in questo caso ridimensionando in automatico le istanze attive.
Per configurare l’autoscaling, per prima cosa creiamo la configurazione d’avvio.
Questa configurazione permette di definire le caratteristiche dell’istanza con cui autoscaling creerà le nuove istanze.
In questo caso andremmo a selezionare la nuova immagine già configurata in precedenza.
Configuriamo il nome della configurazione
e selezionato il gruppo che verrà assegnato alle nuove istanze.
Infine assegnamo la chiave per accesso SSH e concludiamo la configurazione
Ora configuriamo un gruppo Autoscaling:
Selezioniamo la configurazione d’avvio precedentemente creata
Ora impostiamo il nome del gruppo, la dimensione minima delle istanze da avviare inizialmente, la rete vpc e le sottoreti
Inoltre facciamo in modo che le nuove istanze create siano inserite nel nostro load balancer precedentemente creato
Quindi possiamo definire delle regole con cui autoscaling vada ad aggiungere o a fermare de istanze, il numero minimo di macchine che rimarranno sempre attive e il numero massimo di istanze avviabili che impostiamo a 3
Possiamo intervenire su vari parametri, in questo caso, per testare velocemente il funzionamento, facciamo in modo che la macchina si avvi quando il load della macchina superi il 10% e ridurre le istanze quando è al di sotto.
Appena salvata la regola il sistema andrà subito a creare e avviare una nuova istanza.
Ora secondo le regole che abbiamo impostato, aumentando il carico dell’istanza autoscaling dovrebbe aumentare le istanze automaticamente, quindi alziamo l’utilizzo della CPU sopra il 10%. Autoscaling andrà ad aggiungere automaticamente una nuova instanza.
Al contrario lasciando le macchine al di sotto il 10% del carico di CPU, autoscaling fermerà man mano una macchina.