Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Først en liten teori. Hva har skjedd Tolv-faktor-appen?

Med enkle ord er dette dokumentet designet for å forenkle utviklingen av SaaS-applikasjoner, ved å informere utviklere og DevOps-ingeniører om problemene og praksisene som oftest oppstår i utviklingen av moderne applikasjoner.

Dokumentet ble laget av utviklerne av Heroku-plattformen.

Twelve-Factor-appen kan brukes på applikasjoner skrevet på et hvilket som helst programmeringsspråk og ved hjelp av en hvilken som helst kombinasjon av støttetjenester (databaser, meldingskøer, cacher, etc.).

Kort om faktorene som denne metodikken er basert på:

  1. Kodebase – Én kodebase sporet i versjonskontroll – flere distribusjoner
  2. Avhengigheter – Eksplisitt erklære og isolere avhengigheter
  3. Konfigurasjon – Lagre konfigurasjon under kjøretid
  4. Støttetjenester – Vurder støttetjenester som plugin-ressurser
  5. Bygg, slipp, løp – Separer monterings- og utførelsesfasene strengt
  6. prosesser – Kjør applikasjonen som en eller flere statsløse prosesser
  7. Port binding – Eksporttjenester via havnebinding
  8. parallellitet – Skaler søknaden din ved hjelp av prosesser
  9. Disponibilitet – Maksimer påliteligheten med rask oppstart og ren avslutning
  10. Applikasjonsutvikling/driftsparitet – Hold utviklings-, iscenesettelses- og produksjonsmiljøene dine så like som mulig
  11. Hogst – Se loggen som en strøm av hendelser
  12. Administrasjonsoppgaver – Utføre administrasjons-/ledelsesoppgaver ved hjelp av ad hoc prosesser

Du kan få mer informasjon om de 12 faktorene fra følgende ressurser:

Hva er blågrønn utplassering?

Blue-Green distribusjon er en metode for å levere en applikasjon til produksjon på en slik måte at sluttkunden ikke ser noen endringer fra sin side. Med andre ord, distribuere en applikasjon med null nedetid.

Det klassiske BG Deploy-skjemaet ser ut som det som vises på bildet nedenfor.

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

  • I starten er det 2 fysiske servere med absolutt samme kode, applikasjon, prosjekt, og det er en ruter (balanserer).
  • Ruteren sender først alle forespørsler til en av serverne (grønn).
  • I det øyeblikket du trenger å gi ut igjen, oppdateres hele prosjektet på en annen server (blå), som for øyeblikket ikke behandler noen forespørsler.
  • Etter at koden er på blå serveren er fullstendig oppdatert, får ruteren en kommando å bytte fra grønnblå server.
  • Nå ser alle klienter resultatet av koden som kjører med blå server.
  • I noen tid, grønn serveren fungerer som en sikkerhetskopi i tilfelle mislykket distribusjon til blå server og i tilfelle feil og feil, bytter ruteren brukerflyten tilbake til grønn server med den gamle stabile versjonen, og den nye koden sendes for revisjon og testing.
  • Og på slutten av prosessen oppdateres den på samme måte grønn server. Og etter å ha oppdatert den, bytter ruteren forespørselsflyten tilbake til grønn server.

Det hele ser veldig bra ut, og ved første øyekast burde det ikke være noen problemer med det.
Men siden vi lever i den moderne verden, passer ikke alternativet med fysisk bytting som angitt i den klassiske ordningen oss. Registrer informasjonen foreløpig, vi kommer tilbake til den senere.

Dårlige og gode råd

Ansvarsfraskrivelse: Eksemplene nedenfor viser verktøyene/metodene jeg bruker, du kan bruke absolutt alle alternativer med lignende funksjoner.

De fleste eksemplene vil på en eller annen måte skjære sammen med webutvikling (dette er en overraskelse), med PHP og Docker.

Avsnittene nedenfor gir en enkel praktisk beskrivelse av bruken av faktorer ved hjelp av spesifikke eksempler; hvis du ønsker å få mer teori om dette emnet, følg lenkene ovenfor til originalkilden.

1. Kodebase

Bruk FTP og FileZilla for å laste opp filer til serverne en om gangen, ikke lagre koden andre steder enn på produksjonsserveren.

Prosjektet skal alltid ha en enkelt kodebase, det vil si at all kode kommer fra én oppbevaringssted. Servere (produksjon, staging, test1, test2...) bruker kode fra grener til ett felles depot. På denne måten oppnår vi kodekonsistens.

2. Avhengigheter

Last ned alle biblioteker i mapper direkte til roten av prosjektet. Gjør oppdateringer ganske enkelt ved å overføre den nye koden til mappen med gjeldende versjon av biblioteket. Installer alle nødvendige verktøy direkte på vertsserveren der 20 flere tjenester kjører.

Et prosjekt skal alltid ha en klart forståelig liste over avhengigheter (med avhengigheter mener jeg også miljøet). Alle avhengigheter må være eksplisitt definert og isolert.
La oss ta som et eksempel Komponer и Docker.

Komponer — en pakkebehandling som lar deg installere biblioteker i PHP. Composer lar deg spesifisere versjoner strengt eller løst, og eksplisitt definere dem. Det kan være 20 forskjellige prosjekter på serveren og hver vil ha en personlig liste over pakker og biblioteker uavhengig av hverandre.

Docker — et verktøy som lar deg definere og isolere miljøet der applikasjonen skal kjøres. Følgelig, akkurat som med komponist, men mer grundig, kan vi bestemme hva applikasjonen fungerer med. Velg en spesifikk versjon av PHP, installer bare pakkene som er nødvendige for at prosjektet skal fungere, uten å legge til noe ekstra. Og viktigst av alt, uten å forstyrre pakkene og miljøet til vertsmaskinen og andre prosjekter. Det vil si at alle prosjekter på serveren som kjører gjennom Docker kan bruke absolutt ethvert sett med pakker og et helt annet miljø.

3. Konfigurasjon

Lagre konfigurasjoner som konstanter direkte i koden. Separate konstanter for testserveren, separate for produksjon. Knyt driften av applikasjonen avhengig av miljøet direkte i forretningslogikken til prosjektet ved å bruke if else-konstruksjoner.

Konfigurasjoner - Dette er den eneste måten at prosjektdistribusjoner bør være forskjellige. Ideelt sett bør konfigurasjoner sendes gjennom miljøvariabler (env vars).

Det vil si at selv om du lagrer flere konfigurasjonsfiler .config.prod .config.local og gir dem nytt navn på distribusjonstidspunktet til .config (hovedkonfigurasjonen som applikasjonen leser data fra) - vil ikke dette være riktig tilnærming, siden i dette tilfellet vil informasjonen fra konfigurasjonene være offentlig tilgjengelig for alle applikasjonsutviklere, og data fra produksjonsserveren vil bli kompromittert. Alle konfigurasjoner må lagres direkte i distribusjonssystemet (CI/CD) og genereres for ulike miljøer med ulike verdier som er nødvendige for et spesifikt miljø på tidspunktet for utrulling.

4. Tredjepartstjenester

Vær strengt knyttet til miljøet, bruk forskjellige tilkoblinger for de samme tjenestene i visse miljøer.

Faktisk overlapper dette punktet sterkt med punktet om konfigurasjoner, siden uten dette punktet kan ikke vanlige konfigurasjonsdata lages, og generelt vil muligheten til å konfigurere falle til ingenting.

Alle koblinger til eksterne tjenester, som køservere, databaser, cachingtjenester, må være like for både lokalmiljøet og tredjeparts-/produksjonsmiljøet. Med andre ord, når som helst, ved å endre tilkoblingsstrengen, kan jeg erstatte anrop til base #1 med base #2 uten å endre applikasjonskoden. Eller, når du ser fremover, for eksempel når du skalerer tjenesten, trenger du ikke å spesifisere tilkoblingen på noen spesiell måte for en ekstra cache-server.

5. Bygg, slipp, utfør

Ha bare den endelige versjonen av koden på serveren, uten sjanse til å rulle tilbake utgivelsen. Du trenger ikke fylle opp diskplass. Alle som tror at de kan slippe kode i produksjon med en feil er en dårlig programmerer!

Alle trinn i utplasseringen må skilles fra hverandre.

Ha en sjanse til å rulle tilbake. Lag utgivelser med gamle kopier av applikasjonen (allerede satt sammen og klar for kamp) lagret i rask tilgang, slik at du i tilfelle feil kan gjenopprette den gamle versjonen. Det vil si at det er betinget en mappe utgivelser og mappe nåværende, og etter vellykket distribusjon og montering av mappen nåværende koblet med en symbolsk lenke til den nye utgivelsen som ligger inni utgivelser med det konvensjonelle navnet på utgivelsesnummeret.

Det er her vi husker Blue-Green distribusjon, som lar deg ikke bare bytte mellom kode, men også bytte mellom alle ressurser og til og med miljøer med muligheten til å rulle tilbake alt.

6. Prosesser

Lagre applikasjonsstatusdata direkte i selve applikasjonen. Bruk økter i RAM-en til selve applikasjonen. Bruk så mye deling mellom tredjepartstjenester som mulig. Hold deg til det faktum at applikasjonen bare kan ha én prosess og ikke tillater skalering.

Når det gjelder økter, lagre data kun i en hurtigbuffer kontrollert av tredjepartstjenester (memcached, redis), så selv om du har 20 applikasjonsprosesser i gang, vil enhver av dem, etter å ha tilgang til cachen, kunne fortsette å jobbe med klienten i samme tilstand som brukeren jobbet med applikasjonen i en annen prosess. Med denne tilnærmingen viser det seg at uansett hvor mange kopier av tredjepartstjenester du bruker, vil alt fungere normalt og uten problemer med tilgang til data.

7. Portbinding

Bare webserveren skal vite hvordan den skal jobbe med tredjepartstjenester. Eller enda bedre, installer tredjepartstjenester direkte på nettserveren. For eksempel som en PHP-modul i Apache.
Alle tjenestene dine må være tilgjengelige for hverandre gjennom tilgang til en eller annen adresse og port (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), det vil si at fra nginx kan jeg få tilgang til både php-fpm og til postgres, og fra php-fpm til postgres og nginx og faktisk fra hver tjeneste kan jeg få tilgang til en annen tjeneste. På denne måten er ikke levedyktigheten til en tjeneste knyttet til levedyktigheten til en annen tjeneste.

8. Parallellisme

Jobb med én prosess, ellers vil ikke flere prosesser klare å komme overens!

Gi rom for skalering. Docker sverm er flott for dette.
Docker Swarm er et verktøy for å lage og administrere klynger av containere både mellom forskjellige maskiner og en haug med containere på samme maskin.

Ved å bruke swarm kan jeg bestemme hvor mange ressurser jeg vil allokere til hver prosess og hvor mange prosesser av den samme tjenesten jeg vil starte, og den interne balanseren, som mottar data på en gitt port, vil automatisk proxyere den til prosessene. Når jeg ser at belastningen på serveren har økt, kan jeg legge til flere prosesser, og dermed redusere belastningen på visse prosesser.

9. Disponibilitet

Ikke bruk køer for å jobbe med prosesser og data. Å drepe én prosess bør påvirke hele applikasjonen. Hvis en tjeneste går ned, går alt ned.

Hver prosess og tjeneste kan slås av når som helst og dette skal ikke påvirke andre tjenester (selvfølgelig betyr dette ikke at tjenesten vil være utilgjengelig for en annen tjeneste, men at en annen tjeneste ikke vil slå seg av etter denne). Alle prosesser må avsluttes elegant, slik at når de avsluttes, vil ingen data bli skadet og systemet vil fungere korrekt neste gang du slår det på. Det vil si at selv i tilfelle en nødavslutning, skal dataene ikke skades (transaksjonsmekanismen er egnet her, spørringer i databasen fungerer kun i grupper, og hvis minst en spørring fra gruppen mislykkes eller utføres med en feil, så feiler ingen andre spørringer fra gruppen faktisk).

10. Applikasjonsutvikling/driftsparitet

Produksjon, iscenesettelse og lokal versjon av applikasjonen må være annerledes. I produksjonen bruker vi Yii Lite rammeverket, og lokalt Yii, slik at det fungerer raskere i produksjonen!

I virkeligheten bør all distribusjon og arbeid med kode være i nesten identiske omgivelser (vi snakker ikke om fysisk maskinvare). Dessuten bør enhver utviklingsmedarbeider kunne distribuere koden til produksjon om nødvendig, og ikke en spesialtrent devops-avdeling, som bare takket være spesiell styrke kan løfte applikasjonen i produksjon.

Docker hjelper oss også med dette. Hvis alle de foregående punktene er observert, vil bruk av docker bringe prosessen med å distribuere miljøet både på produksjon og på den lokale maskinen til å legge inn en eller to kommandoer.

11. Logger

Vi skriver logger til filer og databaser! Vi renser ikke filer og databaser fra logger. La oss bare kjøpe en harddisk med 9000 Peta byte og det er greit.

Alle logger bør betraktes som en strøm av hendelser. Selve søknaden skal ikke være involvert i behandling av logger. Logger bør sendes enten til stdout eller sendes via en protokoll som udp, slik at arbeid med logger ikke skaper noen problemer for applikasjonen. Graylog er bra for dette. Graylog som mottar alle logger via udp (denne protokollen krever ikke å vente på svar om vellykket mottak av pakken) forstyrrer ikke applikasjonen på noen måte og omhandler kun strukturering og behandling av logger. Applikasjonslogikken endres ikke til å fungere med slike tilnærminger.

12. Administrasjonsoppgaver

For å oppdatere data, databaser, etc., bruk et separat opprettet endepunkt i APIen, å utføre det 2 ganger på rad vil resultere i at alt dupliseres. Men du er ikke dum, du klikker ikke to ganger, og vi trenger ikke migrering.

Alle administrasjonsoppgaver skal utføres i samme miljø som all kode, på utgivelsesnivå. Det vil si at hvis vi trenger å endre strukturen til databasen, vil vi ikke gjøre det manuelt ved å endre navn på kolonner og legge til nye gjennom noen visuelle databaseadministrasjonsverktøy. For slike ting lager vi separate skript - migreringer, som utføres overalt og i alle miljøer på samme måte med et felles og forståelig resultat. For alle andre oppgaver, som å fylle prosjektet med data, bør lignende metoder brukes.

Eksempelimplementering i PHP, Laravel, Laradock, Docker-Compose

PS Alle eksemplene ble laget på MacOS. De fleste av dem er også egnet for Linux. Windows-brukere, tilgi meg, men jeg har ikke jobbet med Windows på lenge.

La oss forestille oss en situasjon der vi ikke har noen versjon av PHP installert på PC-en vår og ingenting i det hele tatt.
Installer de nyeste versjonene av docker og docker-compose. (dette finner du på Internett)

docker -v && 
docker-compose -v

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

1. Sett Laradock

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

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Angående Laradock vil jeg si at det er en veldig kul ting, som inneholder mange containere og hjelpeting. Men jeg vil ikke anbefale å bruke Laradock som sådan uten modifikasjoner i produksjonen på grunn av redundansen. Det er bedre å lage dine egne beholdere basert på eksempler i Laradock, dette vil være mye mer optimalisert, fordi ingen trenger alt som er der samtidig.

2. Konfigurer Laradock til å kjøre applikasjonen vår.

cd laradock && 
cp env-example .env

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

2.1. Åpne habr-katalogen (overordnet mappe som laradock er klonet inn i) i et redigeringsprogram. (I mitt PHPStorm-tilfelle)

På dette stadiet gir vi kun prosjektet et navn.

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

2.2. Start arbeidsområdebildet. (I ditt tilfelle vil bildene ta litt tid å bygge)
Workspace er et spesiallaget bilde for å jobbe med rammeverket på vegne av utvikleren.

Vi går inn i beholderen ved hjelp av

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

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

2.3. Installerer Laravel

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

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

2.4. Etter installasjonen sjekker vi om katalogen med prosjektet er opprettet og dreper compose.

ls
exit
docker-compose down

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

2.5. La oss gå tilbake til PHPStorm og angi riktig bane til laravel-applikasjonen vår i .env-filen.

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

3. Legg til all koden til Git.

For å gjøre dette vil vi opprette et depot på Github (eller andre steder). La oss gå til habr-katalogen i terminalen og kjøre følgende kode.

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

La oss sjekke om alt er i orden.

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

For enkelhets skyld anbefaler jeg å bruke et visuelt grensesnitt for Git, i mitt tilfelle er det det GitKraken. (her er en henvisningslenke)

4. La oss lansere!

Før du starter, sørg for at ingenting henger på portene 80 og 443.

docker-compose up -d nginx php-fpm

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Prosjektet vårt består derfor av 3 separate tjenester:

  • nginx - webserver
  • php-fpm - php for å motta forespørsler fra en webserver
  • arbeidsområde - php for utviklere

For øyeblikket har vi oppnådd at vi har laget en søknad som oppfyller 4 poeng av 12, nemlig:

1. Kodebase — all koden er i ett depot (liten merknad: det kan være riktig å legge til docker inne i laravel-prosjektet, men dette er ikke viktig).

2. Avhengigheter - Alle våre avhengigheter er eksplisitt skrevet i application/composer.json og i hver Dockerfile i hver container.

3. Støttetjenester — Hver av tjenestene (php-fom, nignx, workspace) lever sitt eget liv og er koblet utenfra og når man jobber med en tjeneste vil ikke den andre bli berørt.

4. prosesser — hver tjeneste er én prosess. Hver av tjenestene opprettholder ikke intern tilstand.

5. Port binding

docker ps

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Som vi kan se, kjører hver tjeneste på sin egen port og er tilgjengelig for alle andre tjenester.

6. parallellitet

Docker lar oss skape flere prosesser av de samme tjenestene med automatisk lastbalansering mellom dem.

La oss stoppe containerne og kjøre dem gjennom flagget --skala

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

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Som vi kan se, har det blitt laget kopier av php-fpm-beholderen. Vi trenger ikke å endre noe i arbeidet med denne beholderen. Vi fortsetter også å få tilgang til den på port 9000, og Docker regulerer lasten mellom containere for oss.

7. Disponibilitet - hver container kan drepes uten å skade den andre. Å stoppe eller starte beholderen på nytt vil ikke påvirke driften av applikasjonen under påfølgende lanseringer. Hver container kan også løftes når som helst.

8. Applikasjonsutvikling/driftsparitet – alle miljøene våre er like. Ved å kjøre systemet på en server i produksjon, trenger du ikke å endre noe i kommandoene dine. Alt vil være basert på Docker på samme måte.

9. Hogst — alle logger i disse beholderne går til stream og er synlige i Docker-konsollen. (i dette tilfellet, faktisk, med andre hjemmelagde beholdere, kan dette ikke være tilfelle hvis du ikke tar vare på det)

 docker-compose logs -f

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Men det er en hake ved at standardverdiene i PHP og Nginx også skriver logger til en fil. For å møte de 12 faktorene er det nødvendig stenges skrive logger til en fil i konfigurasjonene til hver beholder separat.

Docker gir også muligheten til å sende logger ikke bare til stdout, men også til slike ting som graylog, som jeg nevnte ovenfor. Og inne i graylog kan vi betjene loggene som vi vil, og applikasjonen vår vil ikke merke dette på noen måte.

10. Administrasjonsoppgaver — alle administrasjonsoppgaver løses av laravel takket være håndverksverktøyet akkurat slik skaperne av 12-faktor-applikasjonen ønsker.

Som et eksempel vil jeg vise hvordan noen kommandoer utføres.
Vi går inn i containeren.

 
docker-compose exec workspace bash
php artisan list

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

Nå kan vi bruke hvilken som helst kommando. (Vær oppmerksom på at vi ikke konfigurerte databasen og hurtigbufferen, så halvparten av kommandoene vil ikke bli utført riktig, fordi de er designet for å fungere med hurtigbufferen og databasen).

Applikasjonsutvikling og Blue-Green-distribusjon, basert på The Twelve-Factor App-metodikk med eksempler i php og docker

11. Konfigurasjoner og 12. Bygg, slipp, løp

Jeg ønsket å dedikere denne delen til Blue-Green Deployment, men den viste seg å være for omfattende for denne artikkelen. Jeg skal skrive en egen artikkel om dette.

I et nøtteskall er konseptet basert på CI/CD-systemer som Jenkins и Gitlab CI. I begge kan du angi miljøvariabler knyttet til et spesifikt miljø. Følgelig vil punkt c i denne situasjonen være oppfylt Konfigurasjoner.

Og poenget om Bygg, slipp, løp løses av innebygde funksjoner med navnet Rørledning.

Rørledning lar deg dele opp distribusjonsprosessen i mange stadier, og fremheve stadiene av montering, utgivelse og utførelse. Også i Pipeline kan du lage sikkerhetskopier, og faktisk hva som helst. Dette er et verktøy med ubegrenset potensial.

Søknadskoden er på Github.
Ikke glem å initialisere undermodulen når du kloner dette depotet.

PS: Alle disse tilnærmingene kan brukes med alle andre verktøy og programmeringsspråk. Det viktigste er at essensen ikke er forskjellig.

Kilde: www.habr.com

Legg til en kommentar