Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Per iniziare, un po' di teoria. Cos'è The Twelve-Factor App?

In parole semplici, si tratta di un documento concepito per semplificare lo sviluppo di applicazioni SaaS, indirizzando gli sviluppatori e gli ingegneri DevOps verso le problematiche e le pratiche più comuni riscontrate nello sviluppo delle moderne applicazioni.

Il documento è stato creato dagli sviluppatori della piattaforma Heroku.

La metodologia delle dodici pratiche (The Twelve-Factor App) può essere applicata a applicazioni scritte in qualsiasi linguaggio di programmazione e che utilizzano combinazioni di servizi esterni (backing services) (database, code di messaggi, cache, ecc.).

Un breve riepilogo dei fattori su cui si basa questa metodologia:

  1. Codice sorgente – Una base di codice, tracciata in un sistema di controllo versioni, – molteplici distribuzioni
  2. Dipendenze – Dichiarare esplicitamente e isolare le dipendenze
  3. Configurazione – Conservare la configurazione nell'ambiente di esecuzione
  4. Servizi di terze parti (Backing Services) – Considerare i servizi esterni (backing services) come risorse connesse
  5. Costruzione, rilascio, esecuzione – Separare rigorosamente le fasi di costruzione ed esecuzione
  6. Processi – Esegui l'applicazione come uno o più processi stateless
  7. Binding delle porte (Port binding) – Esporta i servizi tramite binding delle porte
  8. Parallelsimo – Scala l'applicazione utilizzando processi
  9. Disposabilità (Disposability) – Massimizza l'affidabilità con avvii rapidi e corrette chiusure
  10. Parità sviluppo/produzione dell'applicazione – Mantieni gli ambienti di sviluppo, staging e produzione il più simili possibile
  11. Logging (Logs) – Considera il log come un flusso di eventi
  12. Task di amministrazione – Esegui i compiti di amministrazione/gestione tramite processi one-off

Per ulteriori informazioni sui 12 fattori, puoi consultare le seguenti risorse:

Cos'è il Blue-Green deployment?

Il Blue-Green deployment è un metodo per consegnare applicazioni su produzione in modo che il cliente finale non noti alcun cambiamento da parte sua. In altre parole, il deployment dell'applicazione avviene senza downtime.

Lo schema classico di BG Deploy appare come indicato nell'immagine seguente.

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

  • All'inizio ci sono 2 server fisici con codice, applicazione e progetto identici, e c'è un router (bilanciatore di carico).
  • Il router inizialmente indirizza tutte le richieste a uno dei server (verde).
  • ). Quando è necessario effettuare nuovamente un rilascio, l'intero progetto viene aggiornato sull'altro server (blu), che in quel momento non gestisce alcuna richiesta.
  • Dopo che il codice sul server blu è stato completamente aggiornato, al router viene dato il comando di passare da verde con blu server.
  • Ora tutti i clienti vedono il risultato del codice dal server blu. Per un certo periodo,
  • Un po' di tempo, verde il server funge da backup nel caso di un deployment fallito su blu server e, in caso di errori e bug, il router reindirizza il flusso degli utenti di nuovo al verde server con la vecchia versione stabile, mentre il nuovo codice viene inviato per ulteriori sviluppi e testing.
  • E alla fine del processo, viene aggiornato allo stesso modo verde server. E dopo il suo aggiornamento, il router reindirizza il flusso delle richieste di nuovo a verde server.

Tutto ciò sembra molto buono e a prima vista non dovrebbero esserci problemi.
Ma poiché viviamo in un mondo moderno, l'opzione di commutazione fisica come indicato nello schema classico non è adatta. Per ora, memorizza queste informazioni, ci torneremo sopra più tardi.

Consigli cattivi e buoni

Avvertenza: Negli esempi sotto sono indicate le utilità / metodologie che utilizzo io, puoi usare qualsiasi alternativa con funzionalità simili.

La maggior parte degli esempi sarà in qualche modo collegata allo sviluppo web (che sorpresa!), con PHP e Docker.

Nei punti seguenti è presente una semplice descrizione pratica dell'utilizzo dei fattori in esempi specifici; se desideri avere più teoria su questo argomento, fai riferimento ai link sopra per la fonte originale.

1. Base di codice

Utilizza FTP e FileZilla per caricare i file sui server uno alla volta, non memorizzare il codice in nessun luogo tranne che sul server di produzione.

Nel progetto deve sempre esserci una base di codice unitaria, cioè, tutto il codice proviene da un unico Git repository. I server (production, staging, test1, test2…) utilizzano codice da rami di un unico repository condiviso. In questo modo raggiungiamo la coerenza del codice.

2. Dipendenze

Scarica tutte le librerie in cartelle direttamente nella radice del progetto. Aggiornamenti possono essere effettuati semplicemente trasferendo il nuovo codice nella cartella con la versione attuale della libreria. Installa tutte le utility necessarie direttamente sul server di hosting dove operano altre 20 service.

Il progetto deve sempre avere un elenco di dipendenze chiaramente definito (con dipendenze intendo anche l'ambiente). Tutte le dipendenze devono essere esplicitamente definite e isolate.
Come esempio prendiamo Composer e Docker.

Composer – un gestore di pacchetti che consente di installare librerie PHP. Composer permette di specificare versioni in modo rigoroso o non rigoroso e di definirle esplicitamente. Sul server possono esserci 20 progetti diversi e ciascuno avrà la propria lista di pacchetti e librerie indipendente dagli altri.

Docker — uno strumento che consente di determinare e isolare l'ambiente in cui funzionerà l'applicazione. Pertanto, in modo simile a composer, ma con una solidità maggiore, possiamo definire gli elementi con cui lavora l'applicazione. Scegliere una versione specifica di PHP, installare solo i pacchetti necessari per il funzionamento del progetto, senza aggiungere nulla di superfluo. E, cosa più importante, senza sovrapporci ai pacchetti e all'ambiente della macchina host e degli altri progetti. Questo significa che tutti i progetti sul server che operano tramite Docker possono utilizzare qualsiasi combinazione di pacchetti e un ambiente completamente diverso.

3. Configurazione

Conserva le configurazioni come costanti direttamente nel codice. Costanti separate per il server di test e costanti separate per la produzione. Collega il funzionamento dell'applicazione alle condizioni ambientali direttamente nella logica aziendale del progetto utilizzando le strutture if else.

Configurazioni — sono l'unica cosa che dovrebbe differenziare i deployment del progetto. Idealmente, le configurazioni dovrebbero essere passate tramite variabili d'ambiente (env vars).

Questo significa che anche se memorizzi più file di configurazione .config.prod .config.local e li rinomini al momento del deployment in .config (il file di configurazione principale da cui l'applicazione legge i dati) — questo non è un approccio corretto, in quanto in tal caso le informazioni delle configurazioni sarebbero accessibili a tutti gli sviluppatori dell'applicazione e i dati del server di produzione sarebbero compromessi. Tutte le configurazioni devono essere memorizzate direttamente nel sistema di deployment (CI/CD) e generate per diversi ambienti con valori differenti necessari per ciascun ambiente al momento del deployment.

4. Servizi di terze parti (Backing Services)

Fissati rigidamente all'ambiente, utilizza connessioni diverse per gli stessi servizi in ambienti specifici.

In realtà, questo punto si sovrappone fortemente con il punto sulle configurazioni, poiché senza la presenza di questo punto non è possibile ottenere dati di configurazione adeguati e in generale la possibilità di configurare verrebbe meno.

Tutte le connessioni ai servizi esterni, come server di coda, database e servizi di cache, devono essere uniformi sia per l'ambiente locale che per l'ambiente di produzione. In altre parole, posso cambiare la stringa di connessione per passare da un database #1 a un database #2 in qualsiasi momento, senza modificare il codice dell'applicazione. Oppure, per esempio, durante la scalabilità del servizio, non sarà necessario indicare una connessione speciale per un server di cache aggiuntivo.

5. Costruzione, rilascio, esecuzione

Avere sul server solo la versione finale del codice, senza possibilità di tornare indietro nel rilascio. Non bisogna occupare spazio su disco. Chi pensa di poter lanciare il codice in produzione con errori è un cattivo programmatore!

Tutte le fasi del deployment devono essere separate tra loro.

Avere la possibilità di tornare indietro. Effettua i rilasci mantenendo copie precedenti dell'applicazione (già compilate e pronte all'uso) che possono essere ripristinate in caso di errori. Cioè, esiste, condizionatamente, una cartella releases e una cartella current, e dopo un deployment e una costruzione riusciti, la cartella current collegato tramite un collegamento simbolico alla nuova versione presente all'interno releases con un nome di rilascio provvisorio.

Qui ricordiamo il Blue-Green deployment, che non solo consente di eseguire il cambio tra il codice, ma anche di passare tra tutte le risorse e persino gli ambienti, con la possibilità di ripristinare tutto indietro.

6. Processi

Conserva i dati di stato dell'applicazione direttamente all'interno dell'app stessa. Utilizza sessioni nella memoria operativa dell'app. Condividi il più possibile tra i servizi esterni. Presupponi che l'applicazione possa avere solo un processo e non consentire scaling.

Per quanto riguarda le sessioni, memorizza i dati solo nella cache gestita da servizi esterni (memcached, redis). In questo modo, anche se hai 20 processi dell'applicazione in esecuzione, ognuno di essi può accedere alla cache e continuare a lavorare con il cliente nello stesso stato in cui l'utente era durante l'interazione con l'applicazione in un altro processo. Con questo approccio, indipendentemente da quante copie di servizi esterni utilizzi, tutto funzionerà normalmente e senza problemi di accesso ai dati.

7. Binding delle porte (Port binding)

Soltanto il server web dovrebbe sapere come lavorare con servizi esterni. È preferibile avviare i servizi esterni direttamente all'interno del server web, ad esempio come modulo PHP in Apache.
Tutti i tuoi servizi devono essere accessibili l'uno dall'altro tramite un indirizzo e una porta specifici (localhost:5432, localhost:3000, nginx:80, php-fpm:9000). Ad esempio, da nginx posso accedere sia a php-fpm che a postgres, e da php-fpm posso accedere a postgres e nginx. Quindi, da ciascun servizio, posso accedere ad un altro servizio. In questo modo, la funzionalità di un servizio non dipende dalla funzionalità di un altro servizio.

8. Parallelismo

Lavora con un solo processo, altrimenti potrebbero sorgere conflitti tra più processi!

Lascia spazio per la scalabilità. Docker Swarm è ideale per questo.
Docker Swarm è uno strumento per creare e gestire cluster di container, sia su macchine diverse che su un singolo server con molteplici container.

Utilizzando Swarm, posso definire la quantità di risorse da allocare per ciascun processo e il numero di processi della stessa servizio da avviare. L bilanciatore interno, ricevendo i dati su una porta specifica, li gestirà automaticamente verso i processi. Quindi, se vedo che il carico sul server aumenta, posso aggiungere più processi per ridurre così il carico su alcuni di essi.

9. Smaltibilità (Disposability)

Non utilizzare code per gestire processi e dati. La terminazione di un processo deve influenzare il funzionamento dell'intera applicazione. Se un servizio fallisce, falliscono tutti.

Ogni processo e servizio possono essere disattivati in qualsiasi momento senza influenzare gli altri servizi (non si parla del fatto che il servizio non sarà disponibile per un altro servizio, ma che un altro servizio non si spegnerà in seguito a questo). Tutti i processi devono essere terminati in modo controllato, in modo tale che al momento della loro chiusura non vengano compromessi i dati e al successivo avvio il sistema funzioni correttamente. Quindi, anche in caso di arresto anomalo, i dati non devono andare persi (in questo caso un meccanismo di transazioni è utile: le richieste al database vengono eseguite solo in gruppi, e se anche una sola richiesta del gruppo non è andata a buon fine o ha restituito un errore, nessun'altra richiesta del gruppo viene effettivamente eseguita).

10. Parità dello sviluppo/funzionamento dell'applicazione

La versione di produzione, di staging e locale dell'applicazione devono essere diverse. In produzione utilizziamo il framework Yii Lite, mentre localmente Yii, per garantire prestazioni migliori in produzione!

In realtà, tutte le implementazioni e il lavoro con il codice devono avvenire in un ambiente quasi identico (non si parla di hardware fisico). Inoltre, il codice deve poter essere implementato in produzione da qualsiasi membro del team di sviluppo, non solo da un apposito reparto devops addestrato, che potrebbe sollevare un'applicazione in produzione solo grazie a capacità particolari.

Anche in questo ci aiuta Docker. Seguendo tutti i punti precedenti, l'uso di Docker ridurrà il processo di implementazione dell'ambiente sia in produzione che sulla macchina locale a una o due semplici comandi.

11. Registrazione (Logs)

Scriviamo i log in file e database! Non puliamo i file e i database dai log. Compreremo semplicemente un disco rigido da 9000 petabyte e va bene così.

Tutti i log devono essere considerati come un flusso di eventi. L'applicazione stessa non dovrebbe occuparsi del trattamento dei log. I log devono essere inviati o a stdout, o tramite un protocollo come UDP, in modo che l'elaborazione dei log non crei problemi all'applicazione. A questo scopo, graylog è un'ottima soluzione. Graylog, ricevendo tutti i log tramite UDP (con questo protocollo non è necessario attendere una conferma di ricezione del pacchetto), non interferisce in alcun modo con l'applicazione e si occupa solo della strutturazione e del trattamento dei log. La logica dell'applicazione non cambia quando si utilizzano approcci simili.

12. Compiti di amministrazione

Per aggiornare i dati, il database, ecc., utilizza un endpoint API appositamente creato; l'esecuzione di questo due volte di seguito potrebbe portare a una duplicazione. Ma non siete persone stupide, non cliccherete due volte, e le migrazioni non ci servono.

Tutte le operazioni di amministrazione devono essere eseguite nello stesso ambiente del codice, a livello di release. In altre parole, se dobbiamo modificare la struttura del database, non lo faremo manualmente cambiando i nomi delle colonne e aggiungendo nuove colonne tramite strumenti visivi di gestione del database. Per queste operazioni, creiamo script separati — le migrazioni, che vengono eseguite ovunque e in tutti gli ambienti con risultati chiari e coerenti. Per tutte le altre attività, come il riempimento del progetto con dati, devono essere applicate metodologie simili.

Esempio di implementazione in PHP, Laravel, Laradock, Docker-Compose

P.S. Tutti gli esempi sono stati realizzati su MacOS. La maggior parte è adatta anche per Linux. Gli utenti Windows, mi scuso, ma non lavoro con Windows da tempo.

Immaginiamo di trovarci in una situazione in cui non è installata alcuna versione di PHP sul nostro PC e non c'è nulla.
Installiamo le ultime versioni di Docker e Docker-Compose. (questo può essere trovato online)

docker -v && 
docker-compose -v

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

1. Installiamo Laradock

git clone https://github.com/Laradock/laradock.git && 
ls

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Riguardo a Laradock posso dire che è uno strumento eccellente, che raccoglie molti container e strumenti ausiliari. Tuttavia, utilizzare Laradock così com'è in produzione senza modifiche non lo consiglio per via della sua complessità. È meglio creare i propri container basandosi sugli esempi di Laradock, poiché questo consente un maggiore ottimizzamento, dato che non ha senso avere tutto ciò che lì è presente contemporaneamente.

2. Configuriamo Laradock per il funzionamento della nostra applicazione.

cd laradock && 
cp env-example .env

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

2.1. Apriamo la cartella habr (la cartella principale in cui è clonata laradock) in un qualsiasi editor. (Nel mio caso PHPStorm)

In questa fase inseriamo solo il nome del progetto.

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

2.2. Avviamo l'immagine del workspace. (Nel vostro caso le immagini verranno buildate per un certo periodo)
Il workspace è un'immagine appositamente preparata per lavorare con il framework a nome dello sviluppatore.

Accediamo all'interno del container utilizzando

docker-compose up -d workspace && 
docker-compose exec workspace bash

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

2.3. Installiamo Laravel

composer create-project --prefer-dist laravel/laravel application

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

2.4. Dopo l'installazione verifichiamo se è stata creata la directory del progetto e poi chiudiamo compose.

ls
exit
docker-compose down

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

2.5. Torniamo indietro in PHPStorm e impostiamo il percorso corretto per la nostra applicazione Laravel nel file .env.

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

3. Aggiungiamo tutto il codice su Git.

A tal fine, creiamo un repository su Github (o altrove). Passiamo nella directory habr nel terminale e eseguiamo il seguente codice.

echo "# habr-12factor" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:nzulfigarov/habr-12factor.git # qui ci sarà il link al tuo repo
git push -u origin master
git status

Controlliamo se tutto è a posto.

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Per comodità, consiglio di utilizzare un'interfaccia visiva per Git, nel mio caso è GitKraken. (qui il link di affiliazione)

4. Avviamo!

Prima di avviare, assicurati che non ci sia nulla in ascolto sulle porte 80 e 443.

docker-compose up -d nginx php-fpm

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

In questo modo, il nostro progetto è composto da 3 servizi distinti:

  • nginx — server web
  • php-fpm — php per ricevere richieste dal server web
  • workspace — php per lo sviluppatore

Finora abbiamo raggiunto l'obiettivo di creare un'applicazione conforme ai già 4 punti su 12, ovvero:

1. Codice sorgente — tutto il codice è in un unico repository (una piccola nota: potrebbe essere corretto inserire docker all'interno del progetto Laravel, ma non è fondamentale).

2. Dipendenze — Tutte le nostre dipendenze sono esplicitamente definite in application/composer.json e in ogni Dockerfile di ciascun container.

3. Servizi di terze parti (Backing Services) — Ogni servizio (php-fpm, nginx, workspace) vive la propria vita ed è accessibile dall'esterno; lavorando su un servizio, l'altro non verrà influenzato.

4. Processi — ogni servizio è un processo. Ogni servizio non conserva uno stato interno.

5. Binding delle porte (Port binding)

docker ps

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Come possiamo vedere, ogni servizio è in esecuzione sulla propria porta ed è accessibile da tutti gli altri servizi.

6. Parallelsimo

Docker ci consente di avviare più processi dello stesso servizio con bilanciamento del carico automatico tra di essi.

Arrestiamo i container e avviamoli tramite il flag —scale

docker-compose down && 
docker-compose up -d --scale php-fpm=3 nginx php-fpm

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Come possiamo vedere, sono state create copie per il container php-fpm. Non dobbiamo modificare nulla nel lavoro con questo container. Continuiamo a contattarlo sulla porta 9000, mentre Docker gestisce il carico tra i container.

7. Disposabilità (Disposability) — ogni container può essere arrestato senza compromettere gli altri. L'arresto o il riavvio di un container non influenzerà il funzionamento dell'applicazione nei successivi avvii. Ogni container può essere avviato in qualsiasi momento.

8. Parità sviluppo/produzione dell'applicazione — tutti i nostri ambienti sono identici. Avviando il sistema su un server di produzione, non dovrai modificare nulla nei tuoi comandi. Tutto sarà esattamente basato su Docker.

9. Logging (Logs) — tutti i log all'interno di questi container vengono inviati in streaming e sono visibili nella console di Docker. (in questo caso, in realtà, con altri container creati artigianalmente, potrebbe non essere così se non te ne prendi cura)

 docker-compose logs -f

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Ma c'è un problema, poiché i valori di Default in PHP e Nginx registrano anche i log in un file. Per essere conformi ai 12 fattori, è necessario disabilitare la registrazione dei log nei file nelle configurazioni di ogni container singolarmente.

Docker offre anche la possibilità di inviare i log non solo a stdout, ma anche a strumenti come graylog, di cui ho parlato sopra. E all'interno di graylog possiamo gestire i log come vogliamo e la nostra applicazione non se ne accorgerà.

10. Task di amministrazione — tutte le attività di amministrazione vengono gestite da Laravel grazie allo strumento artisan, proprio come desidererebbero i creatori di un'applicazione conforme ai 12 fattori.

Come esempio, ti mostrerò come vengono eseguite alcune comandi.
Entriamo nel container.

 
docker-compose exec workspace bash
php artisan list

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

Ora possiamo utilizzare qualsiasi comando. (si prega di notare che non abbiamo configurato il database e la cache, quindi metà dei comandi non verrà eseguita correttamente, poiché sono progettati per lavorare con la cache e il database).

Sviluppo di applicazioni e Blue-Green deployment, basandosi sulla metodologia The Twelve-Factor App con esempi in php e docker.

11. Configurazioni e 12. Costruzione, rilascio, esecuzione

Questa parte volevo dedicarla al Blue-Green Deployment, ma si è rivelata troppo complessa per questo articolo. Scriverò un articolo separato al riguardo.

In poche parole, il concetto si basa su sistemi CI/CD come Jenkins e Gitlab CI. In entrambi si possono impostare variabili d'ambiente correlate a un ambiente specifico. Pertanto, in questo scenario verrà eseguita la voce con Configurazioni.

E la voce su Costruzione, rilascio, esecuzione è gestita dalle funzioni integrate in entrambi gli strumenti chiamate Pipeline.

Pipeline che consente di suddividere il processo di deployment in più fasi, evidenziando le fasi di costruzione, rilascio e esecuzione. Inoltre, nel Pipeline, potrai creare backup e fare praticamente qualsiasi cosa. Questo strumento ha un potenziale illimitato.

Il codice dell'applicazione si trova su Github.
Non dimenticare di inizializzare il submodule quando cloni questo repository.

P.S.: Tutti questi approcci possono essere utilizzati con qualsiasi altro strumento e linguaggio di programmazione. L'importante è che il principio rimanga lo stesso.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster