Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Innanzitutto, una piccola teoria. Che è successo L'app dei dodici fattori?

In parole semplici, questo documento è pensato per semplificare lo sviluppo di applicazioni SaaS, aiutando a informare gli sviluppatori e gli ingegneri DevOps sui problemi e sulle pratiche che più spesso si incontrano nello sviluppo delle applicazioni moderne.

Il documento è stato creato dagli sviluppatori della piattaforma Heroku.

L'App Twelve-Factor può essere applicata ad applicazioni scritte in qualsiasi linguaggio di programmazione e utilizzando qualsiasi combinazione di servizi di supporto (database, code di messaggi, cache, ecc.).

Brevemente sui fattori su cui si basa questa metodologia:

  1. Base di codice – Una codebase monitorata nel controllo della versione – più distribuzioni
  2. Dipendenze – Dichiarare e isolare esplicitamente le dipendenze
  3. Configurazione – Salva la configurazione in runtime
  4. Servizi di supporto – Considerare i servizi di supporto come risorse plug-in
  5. Costruisci, rilascia, corri – Separare rigorosamente le fasi di montaggio e di esecuzione
  6. processi – Eseguire l'applicazione come uno o più processi senza stato
  7. Vincolo di porta – Servizi di esportazione tramite collegamento portuale
  8. parallelismo – Scala la tua applicazione utilizzando i processi
  9. Disponibilità – Massimizzare l'affidabilità con avvio rapido e spegnimento pulito
  10. Parità di sviluppo/operatività dell'applicazione – Mantieni i tuoi ambienti di sviluppo, gestione temporanea e produzione il più simili possibile
  11. Registrazione – Visualizza il registro come un flusso di eventi
  12. Compiti amministrativi – Eseguire attività di amministrazione/gestione utilizzando processi ad hoc

Puoi ottenere maggiori informazioni sui 12 fattori dalle seguenti risorse:

Che cos'è la distribuzione Blu-Verde?

La distribuzione blu-verde è un metodo per distribuire un'applicazione a produzione in modo tale che il cliente finale non veda alcun cambiamento da parte sua. In altre parole, distribuire un'applicazione con zero i tempi di inattività.

Il classico schema BG Deploy è simile a quello mostrato nell'immagine qui sotto.

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

  • All'inizio ci sono 2 server fisici con assolutamente lo stesso codice, applicazione, progetto e c'è un router (bilanciatore).
  • Il router inizialmente indirizza tutte le richieste a uno dei server (verde).
  • Nel momento in cui è necessario rilasciare nuovamente, l'intero progetto viene aggiornato su un altro server (blu), che al momento non sta elaborando alcuna richiesta.
  • Dopo che il codice è attivo blu il server è completamente aggiornato, al router viene dato un comando da cui passare verde su blu server.
  • Ora tutti i client vedono il risultato del codice in esecuzione con blu server.
  • Per un po 'di tempo, verde il server funge da copia di backup in caso di implementazione non riuscita blu server e in caso di guasti e bug, il router ripristina il flusso dell'utente verde server con la vecchia versione stabile e il nuovo codice viene inviato per revisione e test.
  • E alla fine del processo, viene aggiornato allo stesso modo verde server. E dopo averlo aggiornato, il router ripristina il flusso di richieste verde server.

Sembra tutto molto bello e a prima vista non dovrebbero esserci problemi.
Ma poiché viviamo nel mondo moderno, l'opzione con commutazione fisica come indicato nello schema classico non è adatta a noi. Per ora registriamo le informazioni, ci ritorneremo più tardi.

Cattivi e buoni consigli

Negazione di responsabilità: Gli esempi seguenti mostrano le utilità/metodologie che utilizzo, puoi utilizzare assolutamente qualsiasi alternativa con funzioni simili.

La maggior parte degli esempi si intersecherà in un modo o nell'altro con lo sviluppo web (questa è una sorpresa), con PHP e Docker.

I paragrafi seguenti forniscono una semplice descrizione pratica dell'uso dei fattori utilizzando esempi specifici; se desideri ottenere più teoria su questo argomento, segui i collegamenti sopra alla fonte originale.

1. Base di codici

Utilizza FTP e FileZilla per caricare i file sui server uno alla volta, non archiviare il codice altrove se non sul server di produzione.

Il progetto dovrebbe sempre avere un'unica base di codice, ovvero tutto il codice proviene da una Idiota deposito. I server (produzione, staging, test1, test2...) utilizzano il codice proveniente dai rami di un repository comune. In questo modo otteniamo la coerenza del codice.

2. Dipendenze

Scarica tutte le librerie nelle cartelle direttamente nella radice del progetto. Effettua gli aggiornamenti semplicemente trasferendo il nuovo codice nella cartella con la versione corrente della libreria. Installa tutte le utilità necessarie direttamente sul server host dove sono in esecuzione altri 20 servizi.

Un progetto dovrebbe sempre avere un elenco di dipendenze chiaramente comprensibile (per dipendenze intendo anche l'ambiente). Tutte le dipendenze devono essere definite e isolate in modo esplicito.
Prendiamo come esempio Compositore и docker.

Compositore — un gestore di pacchetti che ti consente di installare librerie in PHP. Composer ti consente di specificare le versioni in modo rigoroso o approssimativo e di definirle esplicitamente. Possono esserci 20 progetti diversi sul server e ognuno avrà un elenco personale di pacchetti e librerie indipendenti dall'altro.

docker — un'utilità che consente di definire e isolare l'ambiente in cui verrà eseguita l'applicazione. Di conseguenza, proprio come con Composer, ma in modo più approfondito, possiamo determinare con cosa funziona l'applicazione. Seleziona una versione specifica di PHP, installa solo i pacchetti necessari al funzionamento del progetto, senza aggiungere nulla in più. E, soprattutto, senza interferire con i pacchetti e l'ambiente della macchina host e con altri progetti. Cioè, tutti i progetti sul server in esecuzione tramite Docker possono utilizzare assolutamente qualsiasi set di pacchetti e un ambiente completamente diverso.

3. Configurazione

Memorizza le configurazioni come costanti direttamente nel codice. Costanti separate per il server di test, separate per la produzione. Lega il funzionamento dell'applicazione in base all'ambiente direttamente nella logica aziendale del progetto utilizzando i costrutti if else.

configurazioni - questo è l'unico modo in cui le implementazioni dei progetti dovrebbero differire. Idealmente, le configurazioni dovrebbero essere passate attraverso variabili di ambiente (env vars).

Cioè, anche se memorizzi diversi file di configurazione .config.prod .config.local e li rinomini al momento della distribuzione in .config (la configurazione principale da cui l'applicazione legge i dati), questo non sarà l'approccio giusto, poiché in questo caso le informazioni delle configurazioni saranno pubblicamente disponibili a tutti gli sviluppatori dell'applicazione e i dati del server di produzione verranno compromessi. Tutte le configurazioni devono essere archiviate direttamente nel sistema di distribuzione (CI/CD) e generate per ambienti diversi con valori diversi necessari per un ambiente specifico al momento della distribuzione.

4. Servizi di terze parti

Essere strettamente legati all'ambiente, utilizzare connessioni diverse per gli stessi servizi in determinati ambienti.

In effetti, questo punto si sovrappone fortemente al punto relativo alle configurazioni, poiché senza questo punto non è possibile creare i normali dati di configurazione e, in generale, la capacità di configurazione diminuirà a nulla.

Tutte le connessioni ai servizi esterni, quali server di coda, database, servizi di caching, devono essere le stesse sia per l'ambiente locale che per l'ambiente di terze parti/produzione. In altre parole, in qualsiasi momento, modificando la stringa di connessione, posso sostituire le chiamate alla base #1 con la base #2 senza modificare il codice dell'applicazione. Oppure, guardando al futuro, ad esempio, quando si ridimensiona il servizio, non sarà necessario specificare la connessione in alcun modo speciale per un server di cache aggiuntivo.

5. Costruisci, rilascia, esegui

Avere solo la versione finale del codice sul server, senza possibilità di ripristinare la versione. Non è necessario riempire lo spazio su disco. Chiunque pensi di poter rilasciare il codice in produzione con un errore è un cattivo programmatore!

Tutte le fasi della distribuzione devono essere separate le une dalle altre.

Avere la possibilità di tornare indietro. Effettua rilasci con vecchie copie dell'applicazione (già assemblate e pronte per la battaglia) salvate in accesso rapido, in modo che in caso di errori sia possibile ripristinare la vecchia versione. Cioè, condizionatamente c'è una cartella Comunicati e cartella correntee dopo aver distribuito e assemblato correttamente la cartella corrente collegati da un collegamento simbolico alla nuova versione che si trova all'interno Comunicati con il nome convenzionale del numero di release.

È qui che ricordiamo la distribuzione Blue-Green, che consente non solo di passare da un codice all'altro, ma anche di passare da una risorsa all'altra e persino da un ambiente all'altro con la possibilità di ripristinare tutto.

6. Processi

Archivia i dati sullo stato dell'applicazione direttamente all'interno dell'applicazione stessa. Utilizza le sessioni nella RAM dell'applicazione stessa. Utilizza quanta più condivisione possibile tra servizi di terze parti. Fare affidamento sul fatto che l'applicazione può avere un solo processo e non consentire il ridimensionamento.

Per quanto riguarda le sessioni, memorizza i dati solo in una cache controllata da servizi di terze parti (memcached, redis), quindi anche se hai 20 processi applicativi in ​​esecuzione, ognuno di essi, dopo aver effettuato l'accesso alla cache, sarà in grado di continuare a lavorare con il client in lo stesso stato in cui l'utente stava lavorando con l'applicazione in un altro processo. Con questo approccio, risulta che non importa quante copie di servizi di terze parti utilizzi, tutto funzionerà normalmente e senza problemi con l'accesso ai dati.

7. Porta vincolante

Solo il server web dovrebbe sapere come lavorare con i servizi di terze parti. O meglio ancora, installa servizi di terze parti direttamente all'interno del server web. Ad esempio, come modulo PHP in Apache.
Tutti i tuoi servizi devono essere accessibili tra loro tramite l'accesso a qualche indirizzo e porta (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), cioè da nginx posso accedere sia a php-fpm che a postgres, e da php-fpm a postgres e nginx e in realtà da ciascun servizio posso accedere a un altro servizio. In questo modo, la vitalità di un servizio non è legata alla vitalità di un altro servizio.

8. Parallelismo

Lavora con un processo, altrimenti diversi processi non saranno in grado di andare d'accordo tra loro!

Lasciare spazio per il ridimensionamento. Lo sciame Docker è ottimo per questo.
Docker Swarm è uno strumento per creare e gestire cluster di contenitori sia tra macchine diverse che tra un gruppo di contenitori sulla stessa macchina.

Usando swarm, posso determinare quante risorse assegnerò a ciascun processo e quanti processi dello stesso servizio lancerò, e il bilanciatore interno, ricevendo i dati su una determinata porta, li proxyrà automaticamente ai processi. Pertanto, visto che il carico sul server è aumentato, posso aggiungere più processi, riducendo così il carico su alcuni processi.

9. Usa e getta

Non utilizzare le code per lavorare con processi e dati. L'eliminazione di un processo dovrebbe influire sull'intera applicazione. Se un servizio va giù, tutto va giù.

Ogni processo e servizio può essere disattivato in qualsiasi momento e ciò non dovrebbe influire sugli altri servizi (ovviamente ciò non significa che il servizio non sarà disponibile per un altro servizio, ma che un altro servizio non verrà disattivato dopo questo). Tutti i processi devono essere terminati con garbo, in modo che quando vengono terminati, nessun dato verrà danneggiato e il sistema funzionerà correttamente la prossima volta che lo si accenderà. Cioè, anche in caso di chiusura di emergenza, i dati non dovrebbero essere danneggiati (il meccanismo della transazione è adatto qui, le query nel database funzionano solo in gruppi e se almeno una query del gruppo fallisce o viene eseguita con un errore, nessun'altra query del gruppo alla fine fallirà).

10. Parità di sviluppo/operatività delle applicazioni

La produzione, lo staging e la versione locale dell'applicazione devono essere diverse. In produzione utilizziamo il framework Yii Lite, e localmente Yii, in modo che funzioni più velocemente in produzione!

In realtà, tutte le distribuzioni e il lavoro con il codice dovrebbero avvenire in un ambiente quasi identico (non stiamo parlando di hardware fisico). Inoltre, qualsiasi addetto allo sviluppo dovrebbe essere in grado di distribuire il codice in produzione, se necessario, e non qualche reparto devops appositamente formato, che solo grazie a una forza speciale può portare l'applicazione in produzione.

Docker ci aiuta anche in questo. Se vengono rispettati tutti i punti precedenti, l'utilizzo di docker porterà il processo di distribuzione dell'ambiente sia sulla produzione che sulla macchina locale all'immissione di uno o due comandi.

11. Registri

Scriviamo log su file e database! Non puliamo file e database dai log. Compriamo semplicemente un disco rigido con 9000 Peta byte e va bene.

Tutti i registri dovrebbero essere considerati come un flusso di eventi. L'applicazione stessa non deve essere coinvolta nell'elaborazione dei log. I log dovrebbero essere emessi su stdout o inviati tramite un protocollo come udp, in modo che lavorare con i log non crei problemi per l'applicazione. Graylog va bene per questo. Graylog che riceve tutti i log tramite udp (questo protocollo non richiede l'attesa di una risposta sulla corretta ricezione del pacchetto) non interferisce in alcun modo con l'applicazione e si occupa solo della strutturazione e dell'elaborazione dei log. La logica dell'applicazione non cambia per funzionare con tali approcci.

12. Compiti amministrativi

Per aggiornare dati, database, ecc., utilizzare un endpoint creato separatamente nell'API, eseguirlo 2 volte di seguito comporterà la duplicazione di tutto. Ma non sei stupido, non cliccherai due volte e non abbiamo bisogno della migrazione.

Tutte le attività di amministrazione dovrebbero essere eseguite nello stesso ambiente di tutto il codice, a livello di rilascio. Cioè, se dobbiamo modificare la struttura del database, non lo faremo manualmente modificando i nomi delle colonne e aggiungendone di nuove tramite alcuni strumenti visivi di gestione del database. Per queste cose creiamo script separati: migrazioni, che vengono eseguite ovunque e in tutti gli ambienti allo stesso modo con un risultato comune e comprensibile. Per tutte le altre attività, come riempire il progetto di dati, dovrebbero essere utilizzate metodologie simili.

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

PS Tutti gli esempi sono stati realizzati su MacOS. La maggior parte di essi sono adatti anche per Linux. Utenti Windows, perdonatemi, ma non lavoro con Windows da molto tempo.

Immaginiamo una situazione in cui sul nostro PC non è installata alcuna versione di PHP e niente.
Installa le versioni più recenti di docker e docker-compose. (questo può essere trovato su Internet)

docker -v && 
docker-compose -v

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

1. Metti Laradock

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

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Per quanto riguarda Laradock, dirò che è una cosa molto interessante, che contiene molti contenitori e cose ausiliarie. Ma non consiglierei di utilizzare Laradock come tale senza modifiche nella produzione a causa della sua ridondanza. È meglio creare i propri contenitori sulla base di esempi in Laradock, questo sarà molto più ottimizzato, perché nessuno ha bisogno di tutto ciò che è lì allo stesso tempo.

2. Configura Laradock per eseguire la nostra applicazione.

cd laradock && 
cp env-example .env

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

2.1. Apri la directory habr (la cartella principale in cui viene clonato laradock) in qualche editor. (Nel mio caso PHPStorm)

In questa fase diamo solo un nome al progetto.

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

2.2. Avvia l'immagine dell'area di lavoro. (Nel tuo caso, la creazione delle immagini richiederà del tempo)
L'area di lavoro è un'immagine appositamente preparata per lavorare con il framework per conto dello sviluppatore.

Entriamo nel contenitore usando

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

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

2.3. Installazione di Laravel

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

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

2.4. Dopo l'installazione controlliamo se la directory con il progetto è stata creata e uccidiamo compose.

ls
exit
docker-compose down

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

2.5. Torniamo a PHPStorm e impostiamo il percorso corretto della nostra applicazione laravel nel file .env.

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

3. Aggiungi tutto il codice a Git.

Per fare ciò, creeremo un repository su Github (o altrove). Andiamo alla directory habr nel terminale ed eseguiamo il seguente codice.

echo "# habr-12factor" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin [email protected]:nzulfigarov/habr-12factor.git # здесь будет ссылка на ваш репо
git push -u origin master
git status

Controlliamo se è tutto in ordine.

Sviluppo di applicazioni e distribuzione Blue-Green, basato 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 lo è GitKraken. (ecco un link di riferimento)

4. Lanciamoci!

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

docker-compose up -d nginx php-fpm

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Pertanto, il nostro progetto è composto da 3 servizi separati:

  • nginx: server web
  • php-fpm - php per ricevere richieste da un server web
  • area di lavoro - PHP per sviluppatori

Al momento, siamo riusciti a creare un'applicazione che soddisfa 4 punti su 12, vale a dire:

1. Base di codice — tutto il codice è in un repository (piccola nota: potrebbe essere corretto aggiungere docker all'interno del progetto laravel, ma questo non è importante).

2. Dipendenze - Tutte le nostre dipendenze sono scritte esplicitamente in application/composer.json e in ciascun Dockerfile di ciascun contenitore.

3. Servizi di supporto — Ciascuno dei servizi (php-fom, nignx, workspace) vive la propria vita ed è connesso dall'esterno e quando si lavora con un servizio, l'altro non sarà influenzato.

4. processi — ogni servizio è un processo. Ciascuno dei servizi non mantiene lo stato interno.

5. Vincolo di porta

docker ps

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Come possiamo vedere, ogni servizio funziona sulla propria porta ed è accessibile a tutti gli altri servizi.

6. parallelismo

Docker ci consente di generare più processi degli stessi servizi con bilanciamento automatico del carico tra di loro.

Fermiamo i contenitori e facciamoli passare attraverso la bandiera --scala

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

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Come possiamo vedere, sono state create delle copie del contenitore php-fpm. Non abbiamo bisogno di cambiare nulla nel lavorare con questo contenitore. Continuiamo ad accedervi anche sulla porta 9000 e Docker regola per noi il carico tra i container.

7. Disponibilità - ogni contenitore può essere ucciso senza danneggiare l'altro. L'arresto o il riavvio del contenitore non influirà sul funzionamento dell'applicazione durante i lanci successivi. Ogni contenitore può inoltre essere sollevato in qualsiasi momento.

8. Parità di sviluppo/operatività dell'applicazione - tutti i nostri ambienti sono uguali. Eseguendo il sistema su un server in produzione, non dovrai modificare nulla nei tuoi comandi. Tutto sarà basato su Docker allo stesso modo.

9. Registrazione — tutti i log in questi contenitori vengono trasmessi in streaming e sono visibili nella console Docker. (in questo caso infatti, con altri contenitori fatti in casa, potrebbe non essere così se non ne hai cura)

 docker-compose logs -f

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Ma c’è un problema nel fatto che anche i valori predefiniti in PHP e Nginx scrivono i log in un file. Per soddisfare i 12 fattori, è necessario spegnere scrivere i log in un file nelle configurazioni di ciascun contenitore separatamente.

Docker offre anche la possibilità di inviare log non solo a stdout, ma anche a cose 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à in alcun modo.

10 Compiti amministrativi — tutti i compiti amministrativi vengono risolti da laravel grazie allo strumento artigianale esattamente come vorrebbero i creatori dell'applicazione a 12 fattori.

Ad esempio, mostrerò come vengono eseguiti alcuni comandi.
Entriamo nel contenitore.

 
docker-compose exec workspace bash
php artisan list

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

Ora possiamo usare qualsiasi comando. (nota che non abbiamo configurato il database e la cache, quindi metà dei comandi non verranno eseguiti correttamente, perché sono progettati per funzionare con la cache e il database).

Sviluppo di applicazioni e distribuzione Blue-Green, basato sulla metodologia The Twelve-Factor App con esempi in php e docker

11 configurazioni e 12. Costruisci, rilascia, corri

Avrei voluto dedicare questa parte al Blue-Green Deployment, ma si è rivelata troppo estesa per questo articolo. Scriverò un articolo separato su questo.

In poche parole, il concetto si basa su sistemi CI/CD come Jenkins и CI Gitlab. In entrambi, è possibile impostare variabili di ambiente associate a un ambiente specifico. Pertanto, in questa situazione, il punto c sarà soddisfatto Configurazioni.

E il punto su Costruisci, rilascia, corri è risolto dalle funzioni integrate con il nome Conduttura.

Conduttura consente di suddividere il processo di distribuzione in più fasi, evidenziando le fasi di assemblaggio, rilascio ed esecuzione. Anche in Pipeline puoi creare backup e in effetti qualsiasi cosa. Questo è uno strumento dal potenziale illimitato.

Il codice dell'applicazione è a Github.
Non dimenticare di inizializzare il sottomodulo quando cloni questo repository.

PS: tutti questi approcci possono essere utilizzati con qualsiasi altra utilità e linguaggio di programmazione. La cosa principale è che l'essenza non differisce.

Fonte: habr.com

Aggiungi un commento