CI/CD a mikroszolgáltatási architektúrákhoz

Azure

A gyorsabb kiadási ciklusok a mikroszolgáltatási architektúrák egyik fő előnye. Jó CI/CD-folyamat nélkül azonban nem éri el a mikroszolgáltatások által ígért rugalmasságot. Ez a cikk ismerteti a kihívásokat, és a probléma néhány megközelítését javasolja.

Mi az a CI/CD?

Amikor a CI/CD-ről beszélünk, valójában több kapcsolódó folyamatról beszélünk: folyamatos integrációról, folyamatos teljesítésről és folyamatos üzembe helyezésről.

  • Folyamatos integráció. A kódmódosítások gyakran egyesülnek a főágban. Az automatizált buildelési és tesztelési folyamatok biztosítják, hogy a főágban lévő kód mindig éles minőségű legyen.

  • Folyamatos teljesítés. A CI-folyamatot átadó kódmódosítások automatikusan közzé lesznek téve egy éles környezetbe. Az éles éles környezetben történő üzembe helyezés manuális jóváhagyást igényelhet, de máskülönben automatizált. A cél az, hogy a kódnak mindig készen kell állnia az éles környezetben való üzembe helyezésre.

  • Folyamatos üzembe helyezés. Az előző két lépésen átmenő kódmódosítások automatikusan üzembe lesznek helyezve az éles környezetben.

A mikroszolgáltatási architektúra robusztus CI/CD-folyamatának néhány célja:

  • Minden csapat önállóan hozhatja létre és helyezheti üzembe a tulajdonában lévő szolgáltatásokat anélkül, hogy ez hatással lenne a többi csapatra.

  • Mielőtt üzembe helyeznénk egy szolgáltatás új verzióját az éles környezetben, a rendszer üzembe helyezi azt fejlesztési/tesztelési/minőségbiztosítási környezetekben ellenőrzés céljából. A minőségi kapukat minden fázisban érvényesítjük.

  • A szolgáltatás új verziója az előző verzió mellett helyezhető üzembe.

  • Megfelelő hozzáférés-vezérlési szabályzatok vannak érvényben.

  • Tárolóalapú számítási feladatok esetén megbízhat az éles környezetben üzembe helyezett tárolórendszerképekben.

Miért fontos egy robusztus CI/CD-folyamat?

Egy hagyományos monolitikus alkalmazásban egyetlen buildfolyamat létezik, amelynek kimenete az alkalmazás végrehajtható. Minden fejlesztési munka ebbe a folyamatba kerül. Magas prioritású hiba esetén a javítást integrálva, tesztelve és közzétéve kell tenni, ami késleltetheti az új funkciók kiadását. Ezeket a problémákat úgy csökkentheti, ha megfelelően faktorált modulokat használ, és funkcióágakkal minimalizálja a kódmódosítások hatását. De ahogy az alkalmazás egyre összetettebbé válik, és egyre több funkciót adnak hozzá, a monolit kiadási folyamata általában törékenyebbé válik, és valószínűleg megszakad.

A mikroszolgáltatások filozófiáját követve soha nem lehet hosszú kiadású vonat, ahol minden csapatnak sorba kellállnia. Az "A" szolgáltatást összeállító csapat bármikor kiadhat egy frissítést anélkül, hogy várnia kellene a "B" szolgáltatás módosításainak egyesítése, tesztelése és üzembe helyezése nélkül.

CI/CD-monolit diagramja

A nagy kiadási sebesség eléréséhez a kiadási folyamatnak automatizáltnak és megbízhatónak kell lennie a kockázat minimalizálása érdekében. Ha naponta egy vagy több alkalommal bocsát ki éles üzemet, a regresszióknak vagy a szolgáltatáskimaradásoknak ritkanak kell lenniük. Ugyanakkor, ha egy rossz frissítés üzembe helyezése nem történik meg, megbízható módon kell gyorsan visszagörgetnie vagy visszalépnie egy szolgáltatás korábbi verziójára.

Problémák

  • Sok kis, független kódbázis. Minden csapat felelős azért, hogy saját szolgáltatást építsen saját buildelési folyamattal. Egyes szervezetekben a csapatok külön kódtárakat használhatnak. A különálló adattárak olyan helyzethez vezethetnek, amikor a rendszer felépítésének ismerete elosztva van a csapatok között, és a szervezeten belül senki sem tudja, hogyan kell üzembe helyezni a teljes alkalmazást. Mi történik például egy vészhelyreállítási forgatókönyvben, ha gyorsan üzembe kell helyeznie egy új fürtöt?

    Kockázatcsökkentés: Legyen egy egységes és automatizált folyamat a szolgáltatások létrehozásához és üzembe helyezéséhez, hogy ez a tudás ne legyen "rejtve" az egyes csapatokban.

  • Több nyelv és keretrendszer. Mivel minden csapat saját technológiákat használ, nehéz lehet egyetlen, a szervezet egészében működő buildelési folyamatot létrehozni. A buildelési folyamatnak elég rugalmasnak kell lennie ahhoz, hogy minden csapat alkalmazkodni tudjon a választott nyelvhez vagy keretrendszerhez.

    Kockázatcsökkentés: Az egyes szolgáltatások buildelési folyamatának tárolóba helyezése. Így a buildrendszernek képesnek kell lennie a tárolók futtatására.

  • Integrációs és terheléstesztelés. Mivel a csapatok a saját tempójukban bocsátanak ki frissítéseket, nehéz lehet robusztus, végpontok közötti tesztelést tervezni, különösen akkor, ha a szolgáltatások más szolgáltatásoktól függnek. Emellett a teljes éles fürt futtatása költséges lehet, ezért nem valószínű, hogy minden csapat éles méretekben futtatja a saját teljes fürtjét, csak tesztelés céljából.

  • Kiadáskezelés. Minden csapatnak képesnek kell lennie egy frissítés éles környezetben való üzembe helyezésére. Ez nem jelenti azt, hogy minden csapattag rendelkezik erre vonatkozó engedélyekkel. A központi Kiadáskezelő szerepkör azonban csökkentheti az üzembe helyezés sebességét.

    Kockázatcsökkentés: Minél inkább automatizált és megbízható a CI/CD-folyamat, annál kevésbé kell központi hatóságot igényelnie. Ez azt is jelentheti, hogy különböző szabályzatokkal rendelkezhet a főbb funkciófrissítések és az apró hibajavítások kiadásához. A decentralizáltság nem jelenti a zéró irányítást.

  • Szolgáltatásfrissítések. Amikor egy szolgáltatást új verzióra frissít, az nem szakíthatja meg az attól függő egyéb szolgáltatásokat.

    Kockázatcsökkentés: Használjon olyan üzembehelyezési technikákat, mint a kék-zöld vagy a kanári-kiadás a nem kompatibilitástörő változásokhoz. Az API kompatibilitástörő változásaihoz helyezze üzembe az új verziót az előző verzió mellett. Így az előző API-t használó szolgáltatások frissíthetők és tesztelhetők az új API-hoz. Lásd alább a Szolgáltatások frissítése című szakaszt.

Monorepo vs. multi-repo

A CI/CD-munkafolyamat létrehozása előtt tudnia kell, hogyan lesz strukturálva és felügyelve a kódbázis.

  • A csapatok külön adattárakban vagy monorepóban (egyetlen adattárban) dolgoznak?
  • Mi az elágaztatási stratégia?
  • Ki küldhet le kódot az éles környezetbe? Van kiadáskezelői szerepkör?

A monorepo megközelítés egyre inkább kedvez, de vannak előnyei és hátrányai mindkettőnek.

  Monorepo Több adattár
Előnyök Kódmegosztás
A kód és az eszközök egyszerűbb szabványosítása
A kód egyszerűbb újrabontása
Felderíthetőség – a kód egyetlen nézete
Csoportonkénti tulajdonjog törlése
Potenciálisan kevesebb egyesítési ütközés
Segít kikényszeríteni a mikroszolgáltatások leválasztását
Problémák A megosztott kód módosításai több mikroszolgáltatást is érinthetnek
Nagyobb egyesítési ütközések
Az eszközöknek nagy kódbázisra kell skálázniuk
Hozzáférés-vezérlés
Összetettebb üzembehelyezési folyamat
Nehezebb megosztani a kódot
Nehezebb kikényszeríteni a kódolási szabványokat
Függőségkezelés
Diffúz kódbázis, gyenge felderíthetőség
A megosztott infrastruktúra hiánya

Szolgáltatások frissítése

A már éles környezetben lévő szolgáltatások frissítésére különböző stratégiák állnak rendelkezésre. Itt három gyakori lehetőséget ismertetünk: a működés közbeni frissítést, a kék-zöld üzembe helyezést és a kanári-kiadást.

Működés közbeni frissítések

Egy működés közbeni frissítés során új szolgáltatáspéldányokat helyez üzembe, és az új példányok azonnal megkezdik a kérések fogadását. Ahogy az új példányok megjelennek, a rendszer eltávolítja az előző példányokat.

Példa: A Kubernetesben a működés közbeni frissítések az alapértelmezett viselkedések, amikor frissíti az üzembe helyezés podspecifikációját. Az üzembehelyezési vezérlő létrehoz egy új ReplicaSetet a frissített podokhoz. Ezután vertikálisan felskálázza az új ReplicaSetet, miközben a régit skálázza le a kívánt replikaszám fenntartása érdekében. Nem törli a régi podokat, amíg az újak nem állnak készen. A Kubernetes megőrzi a frissítés előzményeit, így szükség esetén visszaállíthatja a frissítést.

Példa: Az Azure Service Fabric alapértelmezés szerint a működés közbeni frissítési stratégiát használja. Ez a stratégia a legjobb megoldás egy új funkciókkal rendelkező szolgáltatásverzió üzembe helyezésére a meglévő API-k módosítása nélkül. A Service Fabric úgy indítja el a frissítés központi telepítését, hogy frissíti az alkalmazástípust a csomópontok egy részhalmazára vagy egy frissítési tartományra. Ezután a következő frissítési tartományra lép, amíg az összes tartományt nem frissíti. Ha egy frissítési tartomány frissítése nem sikerül, az alkalmazás típusa az összes tartomány előző verziójára visszagörget. Vegye figyelembe, hogy egy több szolgáltatást tartalmazó alkalmazástípus (és ha az összes szolgáltatás egy frissítési telepítés részeként frissül) hajlamos a hibára. Ha az egyik szolgáltatás nem frissül, a teljes alkalmazás vissza lesz állítva az előző verzióra, a többi szolgáltatás pedig nem frissül.

A működés közbeni frissítések egyik kihívása, hogy a frissítési folyamat során a régi és az új verziók vegyesen futnak és fogadják a forgalmat. Ebben az időszakban a kérések a két verzió valamelyikére irányíthatók.

Az API kompatibilitástörő változásai esetén ajánlott mindkét verziót egymás mellett támogatni, amíg az előző verzió összes ügyfelet nem frissítik. Lásd: API-verziószámozás.

Kék-zöld üzembe helyezés

Kék-zöld környezetben az új verziót az előző verzió mellett helyezi üzembe. Az új verzió ellenőrzése után az összes forgalmat egyszerre váltja át az előző verzióról az új verzióra. A kapcsoló után az alkalmazás figyeli az esetleges problémákat. Ha valami probléma merül fel, visszacserélheti a régi verzióra. Feltéve, hogy nincsenek problémák, törölheti a régi verziót.

A hagyományos monolitikus vagy N szintű alkalmazások esetében a kék-zöld üzembe helyezés általában két azonos környezet kiépítését jelentette. Az új verziót átmeneti környezetben helyezné üzembe, majd átirányítaná az ügyfélforgalmat az átmeneti környezetbe – például a VIP-címek felcserélésével. A mikroszolgáltatási architektúrákban a frissítések a mikroszolgáltatás szintjén történnek, ezért általában ugyanabban a környezetben helyezné üzembe a frissítést, és egy szolgáltatásfelderítési mechanizmust használna a felcseréléshez.

Példa. A Kubernetesben nem kell külön fürtöt kiépítenie a kék-zöld üzembe helyezéshez. Ehelyett kihasználhatja a választók előnyeit. Hozzon létre egy új üzembehelyezési erőforrást egy új podspecifikációval és egy másik címkekészlettel. Hozza létre ezt az üzemelő példányt anélkül, hogy törli az előző üzemelő példányt, vagy módosítaná a rá hivatkozó szolgáltatást. Miután az új podok futnak, frissítheti a szolgáltatás választóját, hogy megfeleljen az új üzembe helyezésnek.

A kék-zöld üzembe helyezés egyik hátránya, hogy a frissítés során kétszer annyi podot futtat a szolgáltatáshoz (aktuális és következő). Ha a podok sok cpu- vagy memória-erőforrást igényelnek, előfordulhat, hogy ideiglenesen horizontálisan fel kell skáláznia a fürtöt az erőforrás-felhasználás kezeléséhez.

Kanári-kiadás

Egy kanári-kiadásban egy frissített verziót fog kibocsátani néhány ügyfél számára. Ezután monitorozza az új szolgáltatás viselkedését, mielőtt az összes ügyfél számára elérhetővé teszi. Ez lehetővé teszi a lassú bevezetést szabályozott módon, valós adatok megfigyelésével és a problémák észlelésével, mielőtt az összes ügyfelet érintené.

A kanári kiadások kezelése összetettebb, mint a kék-zöld vagy a működés közbeni frissítés, mivel a kéréseket dinamikusan kell átirányítani a szolgáltatás különböző verzióihoz.

Példa. A Kubernetesben konfigurálhat egy szolgáltatást úgy, hogy két replikakészletre terjedjen ki (minden verzióhoz egyet), és manuálisan módosítsa a replikák számát. Ez a megközelítés azonban meglehetősen durva szemcsés, mivel a Kubernetes terheléselosztása a podok között történik. Ha például összesen 10 replikával rendelkezik, a forgalmat csak 10%-os növekményekben helyezheti át. Ha szolgáltatáshálót használ, a szolgáltatásháló útválasztási szabályaival kifinomultabb kanári kiadási stratégiát valósíthat meg.

Következő lépések