ProHoster > Blog > Adminisztráció > Alkalmazásfejlesztés és kék-zöld üzembe helyezés, a The Twelve-Factor App módszertan alapján, php és docker példákkal
Alkalmazásfejlesztés és kék-zöld üzembe helyezés, a The Twelve-Factor App módszertan alapján, php és docker példákkal
Egyszerűen fogalmazva, ez a dokumentum a SaaS-alkalmazások fejlesztésének leegyszerűsítését szolgálja, segítve a fejlesztők és a DevOps mérnökök tájékoztatását a modern alkalmazások fejlesztése során leggyakrabban előforduló problémákról és gyakorlatokról.
A dokumentumot a Heroku platform fejlesztői készítették.
A Twelve-Factor App bármilyen programozási nyelven írt és a háttérszolgáltatások (adatbázisok, üzenetsorok, gyorsítótárak stb.) kombinációját használó alkalmazásokhoz alkalmazható.
Röviden azokról a tényezőkről, amelyeken ez a módszertan alapul:
Kódbázis – Egy kódbázis nyomon követhető a verzióvezérlésben – több telepítés
Függőségek – A függőségek kifejezett deklarálása és elkülönítése
Configuration – Mentse el a konfigurációt futás közben
Kisegítő szolgáltatások – Tekintse a háttérszolgáltatásokat beépülő erőforrásként
Építs, engedj el, fuss – Szigorúan válassza el az összeszerelési és kivitelezési szakaszt
A folyamatok – Futtassa az alkalmazást egy vagy több állapot nélküli folyamatként
Portkötés – Szolgáltatások exportálása portkötésen keresztül
Párhuzamosság – Méretezze az alkalmazást folyamatok segítségével
Eldobhatóság – Maximalizálja a megbízhatóságot a gyors indítással és a tiszta leállítással
Alkalmazásfejlesztési/működési paritás – Tartsa a lehető leghasonlóbban a fejlesztési, színpadi és gyártási környezetet
Fakitermelés – A napló megtekintése eseményfolyamként
Adminisztrációs feladatok – Ad hoc folyamatok segítségével adminisztrációs/menedzselési feladatok ellátása
A 12 tényezőről további információkat kaphat a következő forrásokból:
A kék-zöld telepítés az alkalmazás kézbesítésének módja Termelés oly módon, hogy a végfelhasználó ne lásson változást a maga részéről. Más szóval, egy alkalmazás üzembe helyezése nullával állásidő.
A klasszikus BG Deploy séma úgy néz ki, mint az alábbi képen.
Kezdetben van 2 fizikai szerver, teljesen azonos kóddal, alkalmazással, projekttel, és van egy router (balancer).
A router kezdetben minden kérést az egyik szerverre (zöld).
Abban a pillanatban, amikor újra ki kell adnia, a teljes projekt egy másik szerveren frissül (kék), amely jelenleg nem dolgoz fel kérelmeket.
A kód bekapcsolása után kék A szerver teljesen frissül, az útválasztó parancsot kap a váltáshoz zöld on kék szerver.
Most minden kliens látja a futott kód eredményét kék szerver.
Egy ideig, zöld a szerver biztonsági másolatként szolgál sikertelen telepítés esetén kék szerver és hiba és hibák esetén a router visszakapcsolja a felhasználói folyamatot zöld szervert a régi stabil verzióval, és az új kódot elküldi felülvizsgálatra és tesztelésre.
A folyamat végén pedig ugyanúgy frissül zöld szerver. És a frissítés után a router visszakapcsolja a kérésfolyamatot zöld szerver.
Minden nagyon jól néz ki, és első pillantásra nem lehet vele probléma.
De mivel a modern világban élünk, a klasszikus séma szerinti fizikai kapcsolási lehetőség nem felel meg nekünk. Egyelőre rögzítse az információkat, később visszatérünk rá.
Rossz és jó tanács
A felelősség megtagadása: Az alábbi példák az általam használt segédprogramokat/módszereket mutatják be, teljesen bármilyen hasonló funkciójú alternatívát használhatsz.
A legtöbb példa így vagy úgy keresztezi a webfejlesztést (ez meglepetés), a PHP-vel és a Dockerrel.
Az alábbi bekezdések egyszerű gyakorlati leírást adnak a faktorok használatáról konkrét példák segítségével; ha további elméleteket szeretne szerezni a témában, kövesse a fenti hivatkozásokat az eredeti forráshoz.
1. Kódbázis
FTP-vel és FileZillával egyenként töltsd fel a fájlokat a szerverekre, ne tárold a kódot máshol, csak az éles szerveren.
A projektnek mindig egyetlen kódbázissal kell rendelkeznie, vagyis minden kód egyből származik megy adattár. A szerverek (gyártás, állomásozás, teszt1, teszt2...) egyetlen közös adattár ágaiból származó kódot használnak. Ezzel a kódkonzisztenciát érjük el.
2. Függőségek
Töltse le az összes mappában lévő könyvtárat közvetlenül a projekt gyökérkönyvtárába. Frissítse egyszerűen az új kódot a könyvtár aktuális verziójával rendelkező mappába. Telepítse az összes szükséges segédprogramot közvetlenül a gazdagépen, ahol további 20 szolgáltatás fut.
Egy projektnek mindig tartalmaznia kell egy jól érthető függőségi listát (a függőségek alatt a környezetet is értem). Minden függőséget kifejezetten meg kell határozni és el kell különíteni.
Vegyünk példának Összeállít и Dokkmunkás.
Összeállít - csomagkezelő, amely lehetővé teszi könyvtárak telepítését PHP-ben. A Composer lehetővé teszi a verziók szigorú vagy laza megadását, és azok explicit meghatározását. 20 különböző projekt lehet a szerveren, és mindegyiknek van egy személyes listája a csomagokról és a könyvtárakról, amelyek egymástól függetlenek.
Dokkmunkás — egy segédprogram, amely lehetővé teszi annak a környezetnek a meghatározását és elkülönítését, amelyben az alkalmazás futni fog. Ennek megfelelően a zeneszerzőhöz hasonlóan, de alaposabban meg tudjuk határozni, hogy az alkalmazás mivel működik. Válasszon ki egy adott PHP-verziót, csak a projekt működéséhez szükséges csomagokat telepítse, anélkül, hogy bármit is hozzáadna. És ami a legfontosabb, anélkül, hogy beleavatkozna a gazdagép és más projektek csomagjaiba és környezetébe. Vagyis a Dockeren keresztül futó kiszolgálón lévő összes projekt teljesen bármilyen csomagkészletet és teljesen más környezetet használhat.
3. Konfiguráció
Tárolja a konfigurációkat konstansként közvetlenül a kódban. Külön konstansok a tesztszerverhez, külön a termeléshez. Az alkalmazás környezettől függő működését közvetlenül kösse be a projekt üzleti logikájába if else konstrukciók használatával.
Konfigurációk - Ez az egyetlen módja annak, hogy a projektek telepítése eltérő legyen. Ideális esetben a konfigurációkat környezeti változókon (env vars) keresztül kell átadni.
Vagyis még akkor sem, ha több konfigurációs fájlt tárol .config.prod .config.local néven, és a telepítéskor átnevezi őket .config-ra (a fő konfiguráció, amelyből az alkalmazás adatokat olvas ki) - ez nem lesz a helyes megközelítés, mivel ebben az esetben a konfigurációkból származó információk nyilvánosan elérhetők lesznek az összes alkalmazásfejlesztő számára, és az éles szerverről származó adatok veszélybe kerülnek. Az összes konfigurációt közvetlenül a telepítési rendszerben (CI/CD) kell tárolni, és különböző környezetekhez kell előállítani, különböző értékekkel, amelyek egy adott környezethez a telepítéskor szükségesek.
4. Harmadik fél szolgáltatásai
Legyen szigorúan a környezethez kötve, bizonyos környezetekben ugyanazon szolgáltatásokhoz különböző kapcsolatokat használjon.
Valójában ez a pont erősen átfedésben van a konfigurációkkal kapcsolatos ponttal, mivel e pont nélkül nem lehet normál konfigurációs adatokat készíteni, és általában a konfigurálási képesség is semmivé válik.
A külső szolgáltatásokhoz, például a sorkiszolgálókhoz, adatbázisokhoz, gyorsítótárazási szolgáltatásokhoz való minden kapcsolatnak azonosnak kell lennie mind a helyi környezetben, mind a harmadik féltől származó/éles környezetben. Más szóval, a kapcsolati karakterlánc megváltoztatásával bármikor lecserélhetem az 1-es bázis hívását a 2-es bázisra anélkül, hogy az alkalmazás kódját megváltoztatnám. Vagy előre tekintve, például a szolgáltatás méretezésekor nem kell speciális módon megadnia a kapcsolatot egy további gyorsítótár-kiszolgálóhoz.
5. Építsd meg, engedd el, hajtsd végre
Csak a kód végleges verziója legyen a szerveren, a kiadás visszaállításának esélye nélkül. Nem kell lemezterületet feltölteni. Rossz programozó, aki azt hiszi, hogy hibával ki tudja adni a kódot a termelésbe!
A telepítés minden szakaszát el kell választani egymástól.
Lehetőséged van visszafordulni. Készítsen kiadásokat az alkalmazás régi (már összeszerelt és harcra kész) másolataival, amelyeket gyors hozzáférésben mentettek el, hogy hiba esetén visszaállíthassa a régi verziót. Vagyis feltételesen van egy mappa kibocsátások és mappa jelenlegi, majd a sikeres telepítés és összeállítás után a mappát jelenlegi szimbolikus hivatkozással kapcsolódik a benne található új kiadáshoz kibocsátások a kiadási szám hagyományos nevével.
Itt emlékszünk a Blue-Green telepítésre, amely nem csak a kódok közötti váltást teszi lehetővé, hanem az összes erőforrás és akár környezet közötti váltást is, és mindent visszaállíthat.
6. Folyamatok
Az alkalmazás állapotának adatait közvetlenül az alkalmazásban tárolhatja. Használjon munkameneteket magának az alkalmazásnak a RAM-jában. Használjon minél több megosztást harmadik felek szolgáltatásai között. Bízzon abban, hogy az alkalmazásnak csak egy folyamata lehet, és nem teszi lehetővé a méretezést.
A munkameneteket illetően csak a külső szolgáltatások által vezérelt gyorsítótárban tároljon adatokat (memcached, redis), így még ha 20 alkalmazási folyamat fut is, bármelyik a gyorsítótár elérése után folytathatja a munkát a klienssel ugyanabban az állapotban, amelyben a felhasználó az alkalmazással dolgozott egy másik folyamatban. Ezzel a megközelítéssel kiderül, hogy függetlenül attól, hogy hány példányt használ a harmadik féltől származó szolgáltatásokból, minden normálisan és az adatokhoz való hozzáféréssel kapcsolatos problémák nélkül fog működni.
7. Portkötés
Csak a webszervernek kell tudnia, hogyan kell dolgozni harmadik féltől származó szolgáltatásokkal. Vagy ami még jobb, telepítse a harmadik féltől származó szolgáltatásokat közvetlenül a webszerveren belül. Például PHP-modulként az Apache-ban.
Minden szolgáltatásnak elérhetőnek kell lennie egymás számára valamilyen címhez és porthoz való hozzáférésen keresztül (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), vagyis az nginx-ről elérhetem a php- fpm-et és a postgres, és php-fpm-től postgres-ig és nginx-ig, és tulajdonképpen mindegyik szolgáltatásból hozzáférhetek egy másik szolgáltatáshoz. Így egy szolgáltatás életképessége nem kötődik egy másik szolgáltatás életképességéhez.
8. Párhuzamosság
Dolgozz egy folyamattal, különben több folyamat nem tud kijönni egymással!
Hagyjon teret a méretezésnek. A Docker raj kiválóan alkalmas erre.
A Docker Swarm egy eszköz konténerfürtök létrehozására és kezelésére mind a különböző gépek, mind pedig egy csomó konténer között ugyanazon a gépen.
A swarm segítségével meg tudom határozni, hogy az egyes folyamatokhoz mennyi erőforrást rendelek, és ugyanannak a szolgáltatásnak hány folyamatát indítom el, és a belső kiegyenlítő egy adott porton adatokat fogadva automatikusan proxyt küld a folyamatokhoz. Így, látva, hogy a szerver terhelése megnőtt, további folyamatokat tudok hozzáadni, ezzel csökkentve bizonyos folyamatok terhelését.
9. Eldobhatóság
Ne használjon sorokat a folyamatok és adatok kezeléséhez. Egy folyamat leállítása az egész alkalmazást érinti. Ha egy szolgáltatás leáll, minden leáll.
Minden folyamat és szolgáltatás bármikor kikapcsolható, és ez nem érintheti a többi szolgáltatást (természetesen ez nem azt jelenti, hogy a szolgáltatás nem lesz elérhető egy másik szolgáltatáshoz, hanem azt, hogy egy másik szolgáltatás nem kapcsol ki ezután). Minden folyamatot kecsesen kell leállítani, hogy a leállításukkor ne sérüljenek meg az adatok, és a rendszer a következő bekapcsoláskor megfelelően működjön. Vagyis sürgősségi felmondás esetén sem sérülhetnek meg az adatok (itt megfelelő a tranzakciós mechanizmus, az adatbázisban a lekérdezések csak csoportosan működnek, és ha a csoportból legalább egy lekérdezés meghiúsul, vagy egy hiba, akkor a csoportból egyetlen más lekérdezés sem sikerül).
10. Alkalmazásfejlesztési/működési paritás
Az alkalmazás gyártási, színpadi és helyi verziójának eltérőnek kell lennie. Gyártásban a Yii Lite keretrendszert használjuk, helyben pedig a Yii-t, hogy gyorsabban működjön a termelésben!
A valóságban minden telepítésnek és a kóddal végzett munkának szinte azonos környezetben kell történnie (nem fizikai hardverről beszélünk). Valamint bármely fejlesztő munkatársnak képesnek kell lennie arra, hogy szükség esetén élesre telepítse a kódot, és ne egy speciálisan képzett devops részlegnek, amely csak a speciális erőnek köszönhetően tudja az alkalmazást a termelésbe emelni.
Ebben a Docker is segít nekünk. Ha az összes előző pontot betartja, a docker használatával a környezet üzembe helyezésének folyamata mind az éles, mind a helyi gépen egy vagy két parancs beviteléhez vezet.
11. Rönkök
Fájlokba, adatbázisokba naplókat írunk! Fájlokat és adatbázisokat nem tisztítunk meg a naplókból. Csak vegyünk egy merevlemezt 9000 Peta bájttal, és rendben van.
Minden naplót eseményfolyamnak kell tekinteni. Maga az alkalmazás nem vehet részt a naplók feldolgozásában. A naplókat vagy az stdout-ba kell kiadni, vagy egy protokollon, például az udp-n keresztül kell elküldeni, hogy a naplókkal végzett munka ne okozzon problémát az alkalmazásnak. erre jó a graylog. Az összes naplót udp-n keresztül fogadó Graylog (ez a protokoll nem követeli meg a csomag sikeres fogadásáról szóló válasz megvárását) semmilyen módon nem zavarja az alkalmazást, csak a naplók strukturálásával és feldolgozásával foglalkozik. Az alkalmazás logikája nem változik az ilyen megközelítések használatához.
12. Adminisztrációs feladatok
Adatok, adatbázisok stb. frissítéséhez használjon külön létrehozott végpontot az API-ban, 2-szer egymás után végrehajtva minden megkettőződik. De te nem vagy hülye, nem fogsz kétszer kattintani, és nincs szükségünk a migrációra.
Minden adminisztrációs feladatot ugyanabban a környezetben kell végrehajtani, mint az összes kódot, kiadási szinten. Azaz, ha módosítanunk kell az adatbázis szerkezetét, akkor azt nem kézzel fogjuk megtenni az oszlopok nevének megváltoztatásával és újak hozzáadásával néhány vizuális adatbázis-kezelő eszközön keresztül. Az ilyen dolgokhoz külön szkripteket - migrációkat - készítünk, amelyek mindenhol és minden környezetben azonos módon hajtódnak végre, közös és érthető eredménnyel. Minden más feladatnál, mint például a projekt adatokkal való feltöltése, hasonló módszertant kell alkalmazni.
Példa megvalósításra PHP, Laravel, Laradock, Docker-Compose nyelven
PS Minden példa MacOS rendszeren készült. Legtöbbjük Linuxra is alkalmas. Windows-felhasználók, bocsáss meg, de régóta nem dolgozom Windows-szal.
Képzeljünk el egy olyan helyzetet, amikor a PHP egyetlen verziója sincs telepítve a számítógépünkre, és egyáltalán semmi.
Telepítse a docker és a docker-compose legújabb verzióit. (ez megtalálható az interneten)
git clone https://github.com/Laradock/laradock.git &&
ls
A Laradockról elmondom, hogy nagyon klassz dolog, amiben rengeteg konténer és segédanyag van. De nem javaslom a Laradock használatát a gyártásban változtatások nélkül, redundanciája miatt. Jobb, ha Laradockban példák alapján készíted el a saját konténereidet, ez sokkal optimalizáltabb lesz, mert senkinek sem kell minden, ami ott van egyszerre.
2. Állítsa be a Laradockot az alkalmazásunk futtatásához.
cd laradock &&
cp env-example .env
2.1. Nyissa meg a habr könyvtárat (a szülőmappát, amelybe a laradock klónozott) valamilyen szerkesztőben. (Az én PHPStorm esetemben)
Ebben a szakaszban csak nevet adunk a projektnek.
2.2. Indítsa el a munkaterület képét. (Az Ön esetében a képek elkészítése eltart egy ideig)
A Workspace egy speciálisan előkészített kép a keretrendszerrel való együttműködéshez a fejlesztő nevében.
Használatával bemegyünk a tartályba
docker-compose up -d workspace &&
docker-compose exec workspace bash
2.4. Telepítés után ellenőrizzük, hogy létrejött-e a projekttel rendelkező könyvtár, és megöljük a compose-t.
ls
exit
docker-compose down
2.5. Térjünk vissza a PHPStormhoz, és állítsuk be a laravel alkalmazásunk helyes elérési útját az .env fájlban.
3. Adja hozzá az összes kódot a Githez.
Ehhez létrehozunk egy adattárat a Githubon (vagy bárhol máshol). Menjünk a terminál habr könyvtárába, és hajtsuk végre a következő kódot.
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
Nézzük meg, hogy minden rendben van-e.
A kényelem kedvéért javaslom valamilyen vizuális felület használatát a Githez, az én esetemben az GitKraken. (itt egy ajánló link)
4. Indítsuk el!
Indítás előtt győződjön meg arról, hogy semmi nem lóg a 80-as és 443-as porton.
docker-compose up -d nginx php-fpm
Így projektünk 3 külön szolgáltatásból áll:
nginx - webszerver
php-fpm - php kérések fogadására webszervertől
munkaterület - php fejlesztőknek
Jelen pillanatban elértük, hogy elkészítettünk egy olyan alkalmazást, amely megfelel a 4 pontból 12 pontnak, nevezetesen:
1. Kódbázis — az összes kód egy tárolóban van (kis megjegyzés: lehet, hogy helyes lenne a docker hozzáadása a laravel projekthez, de ez nem fontos).
2. Függőségek - Minden függőségünk kifejezetten meg van írva az application/composer.json fájlban és az egyes tárolók minden Docker-fájljában.
3. Kisegítő szolgáltatások — Mindegyik szolgáltatás (php-fom, nignx, munkaterület) a saját életét éli és kívülről csatlakozik, és ha az egyik szolgáltatással dolgozik, a másikat nem érinti.
4. A folyamatok — minden szolgáltatás egy folyamat. A szolgáltatások egyike sem tart fenn belső állapotot.
5. Portkötés
docker ps
Amint látjuk, minden szolgáltatás a saját portján fut, és az összes többi szolgáltatás számára elérhető.
6. Párhuzamosság
A Docker lehetővé teszi számunkra, hogy ugyanazon szolgáltatások több folyamatát is elindítsuk a köztük lévő automatikus terheléselosztással.
Állítsuk meg a konténereket, és fussuk át őket a zászlón --skála
docker-compose down &&
docker-compose up -d --scale php-fpm=3 nginx php-fpm
Amint látjuk, a php-fpm tárolóról másolatok készültek. Semmit sem kell változtatnunk, ha ezzel a tárolóval dolgozunk. Továbbra is a 9000-es porton érjük el, és a Docker szabályozza helyettünk a konténerek közötti terhelést.
7. Eldobhatóság - minden tartály megölhető anélkül, hogy károsítaná a másikat. A tároló leállítása vagy újraindítása nem befolyásolja az alkalmazás működését a későbbi indítások során. Minden konténer bármikor felemelhető.
8. Alkalmazásfejlesztési/működési paritás - minden környezetünk egyforma. Ha a rendszert éles kiszolgálón futtatja, akkor semmit sem kell módosítania a parancsokon. Ugyanúgy minden a Dockerre épül majd.
9. Fakitermelés — ezekben a tárolókban lévő összes napló adatfolyamba kerül, és látható a Docker-konzolon. (jelen esetben más házi készítésű edényeknél ez nem biztos, hogy így van, ha nem vigyázol rá)
docker-compose logs -f
De van egy bökkenő, hogy a PHP és az Nginx alapértelmezett értékei naplókat is írnak egy fájlba. A 12 tényező teljesítéséhez szükséges kikapcsol naplók írása egy fájlba az egyes tárolók konfigurációiban külön-külön.
A Docker azt is lehetővé teszi, hogy naplókat küldjön nem csak az stdout-ra, hanem olyan dolgokra is, mint a graylog, amit fent említettem. A graylogon belül pedig tetszés szerint kezelhetjük a naplókat, és ezt az alkalmazásunk semmilyen módon nem veszi észre.
10. Adminisztrációs feladatok — minden adminisztrációs feladatot a laravel a kézműves eszköznek köszönhetően pontosan úgy old meg, ahogy a 12 faktoros alkalmazás készítői szeretnék.
Példaként bemutatom néhány parancs végrehajtásának módját.
Bemegyünk a konténerbe.
docker-compose exec workspace bash
php artisan list
Most bármilyen parancsot használhatunk. (kérjük, vegye figyelembe, hogy nem konfiguráltuk az adatbázist és a gyorsítótárat, így a parancsok fele nem fog megfelelően végrehajtódni, mert úgy vannak kialakítva, hogy a gyorsítótárral és az adatbázissal működjenek).
11. Konfigurációk és 12. Építs, engedj el, fuss
Ezt a részt a kék-zöld telepítésnek akartam szentelni, de túl terjedelmesnek bizonyult ehhez a cikkhez. Erről külön cikket írok.
Dióhéjban a koncepció olyan CI/CD rendszereken alapul, mint pl Jenkins и Gitlab CI. Mindkettőben beállíthat egy adott környezethez társított környezeti változókat. Ennek megfelelően ebben a helyzetben a c) pont teljesül Konfigurációk.
És a lényeg kb Építs, engedj el, fuss nevű beépített függvényekkel oldják meg Csővezeték.
Csővezeték lehetővé teszi a telepítési folyamat több szakaszra bontását, kiemelve az összeszerelés, kiadás és végrehajtás szakaszait. A Pipeline-ban is készíthet biztonsági másolatokat, sőt bármit. Ez egy korlátlan potenciállal rendelkező eszköz.
Az alkalmazás kódja a címen található GitHub.
Ne felejtse el inicializálni az almodult a tár klónozásakor.
PS: Mindezek a megközelítések bármely más segédprogrammal és programozási nyelvvel használhatók. A lényeg az, hogy a lényeg nem különbözik.