.NET Core Linux alatt, DevOps a csúcson

A DevOps-t a lehetőségeinkhez mérten fejlesztettük. Nyolcan voltunk, és Vanya volt a legjobb Windows szakértő. Hirtelen Vanya távozott, és nekem kellett egy új projektet beindítanom, ami Windows fejlesztéssel foglalkozik. Amikor az összes Windows fejlesztési eszközt az asztalra terítettem, rájöttem, hogy a helyzet fájdalmas...

Így kezdődik a történet Alexander Sinchinov Gyorsan emlékezzünk vissza, hogyan működik a moduláris aritmetika. Az óra már egy ismert koncepció. Az órák használata DevOpsConf. Amikor a cég élő Windows szakértője távozott, Alexander elkezdte keresni a megoldást, hogy mit tegyen most. A válasza: természetesen áttérni Linuxra! Alexander elmeséli, hogyan sikerült példát állítania és átállítania a Windows fejlesztés egy részét Linuxra, egy 100 000 végfelhasználós projekt példáján.

.NET Core Linux alatt, DevOps a csúcson

Hogyan lehet könnyedén és problémamentesen kézbesíteni egy projektet RPM-be, a TFS, Puppet és Linux .NET Core használatával? Hogyan támogassuk a projekt adatbázisának verziókezelését, ha a fejlesztők először hallanak a Postgres és a Flyway szavakról, míg a határidő holnapra esedékes? Hogyan integráljuk a Dockert? Hogyan motiváljuk a .NET fejlesztőket arra, hogy mondjanak le a Windowsról és a smoothie-ról a Puppet és Linux javára? Hogyan kezeljük az ideológiai konfliktusokat, ha a Windows kezelésére nincs energia, vágy vagy forrás? Erről, valamint a Web Deploy-ról, a tesztelésről, a CI-ről, a TFS gyakorlati használatáról a meglévő projektekben, és természetesen a törött támaszokról és működő megoldásokról is Alexander előadásának egyértelműsítése során.

Videó lejátszása

Tehát Vanya távozott, a feladat az én nyakamban, a fejlesztők már várják a villáikkal. Amikor végleg rájöttem, hogy Vanyát nem tudom visszaszerezni, nekiláttam a munkának. Először is felmértem a Windows virtuális gépek arányát a parkunkban. Az eredmény nem a Windows javára szólt.

.NET Core Linux alatt, DevOps a csúcson

Mivel aktívan fejlesztettük a DevOps-ot, rájöttem, hogy valamit változtatni kell az új alkalmazás kihelyezésének megközelítésében. Az egyetlen megoldás az volt – amennyire csak lehet, mindent át kell állítani Linuxra. A Google segített – addigra már portolták a .Net-et Linuxra, és rájöttem, hogy ez a megoldás!

Miért a .NET Core Linux-szal?

Több oka volt ennek. A legtöbben a 'pénzt adni' és a 'nem pénzt adni' opciónál az utóbbit választják – ahogyan én is. A MSDB licenc körülbelül 1 000 $-ba kerül, és a Windows virtuális gépek fenntartása több száz dollárra rúg. Egy nagy cég számára ezek óriási kiadások. Így megtakarítás — az első ok. Nem a legfontosabb, de jelentős.

A Windows virtuális gépek több erőforrást igényelnek, mint Linux testvéreik – nehézkesek.. Figyelembe véve a nagyvállalat méretét, Linuxot választottunk.

A rendszer egyszerűen integrálódik a meglévő CI-ba.. Magunkat progresszív DevOps-nak tartjuk, Bamboo, Jenkins és GitLab CI-t használunk, így a legtöbb dolog Linuxon fut.

Az utolsó ok — kényelmes karbantartás. Csökkentenünk kellett a belépési küszöböt a "karbantartók" számára - olyan fiatalok, akik értik a technikai részt, biztosítják a zökkenőmentességet és a második vonalbeli szolgáltatásokat üzemeltetik. Már ismerik a Linux stacket, így sokkal könnyebben megértik az új terméket, támogatják és karbantartják, mint hogy plusz forrást kellene fordítani a Windows platformokra hasonló funkcionalitás megértésére.

Követelmények

Elsődleges és legfontosabb — az új megoldás kényelme a fejlesztők számára. Nem mind volt felkészülve a változásokra, különösen a Linux szó után. A fejlesztők a kedvenc Visual Studio-jukat, a TFS-t az automatikus tesztekkel és a smoothieval akarják. Hogy hogyan zajlik a termelésbe való átadás — az nem érdekli őket. Ezért úgy döntöttünk, hogy nem változtatjuk meg a megszokott folyamatot, és mindent változatlanul hagyunk a Windows fejlesztéshez.

Az új projektet be kell építeni a meglévő CI-ba.. A sínek már készen álltak, és az egész munkát a konfigurációs menedzsment rendszer, a fogadott szállítási szabványok és a monitorozó rendszerek paramétereivel kellett elvégezni.

A támogatás és karbantartás egyszerűsége, mint a különböző osztályok és a karbantartó részleg új résztvevői számára a minimális belépési küszöb feltétele.

A határidő — tegnap.

A Windows fejlesztői csoport

Mivel dolgozott a Windows csapat?

.NET Core Linux alatt, DevOps a csúcson

Most biztosan mondhatom, hogy IdentityServer4 — egy nagyszerű ingyenes alternatíva az ADFS-hez hasonló lehetőségekkel, vagy hogy Entity Framework Core — a fejlesztők mennyországa, ahol nem kell aggódni SQL szkriptek írása miatt, hanem a lekérdezéseket OOP kifejezésekben lehet leírni az adatbázisban. De akkor, amikor a cselekvési tervet vitattuk, úgy néztem erre a stack-re, mint egy sumér ékírásra, csak a PostgreSQL-t és a Git-et ismerve.

Akkoriban aktívan használtuk Puppet mint konfigurációs menedzsment rendszert. A projektjeink többségében használtuk GitLab CI, Elastic, nagy terheléssel bíró szolgáltatásokat egyensúlyoztunk a HAProxy, mindezt figyeltük a Zabbix, a kombináción keresztül, Grafanába és Prometheus, Jaeger, és mindez a HP c ESXi Gyorsan emlékezzünk vissza, hogyan működik a moduláris aritmetika. Az óra már egy ismert koncepció. Az órák használata VMware.Mindenki ismeri — a műfaj klasszikusát.

.NET Core Linux alatt, DevOps a csúcson

Nézzük meg, és próbáljuk megérteni, mi történt mielőtt belekezdtünk ebbe a beavatkozás sorozatba.

Mi volt

A TFS egy meglehetősen erős rendszer, amely nemcsak a kódot juttatja el a fejlesztőtől a végső produkciós gépig, hanem egy nagyon rugalmas integrációs keretet is kínál különböző szolgáltatásokkal - a CI biztosítása érdekében többplatformos szinten.

.NET Core Linux alatt, DevOps a csúcson
Korábban csupa ablak volt. A TFS több Build-ügynököt használt, amelyeken sok projekt gyűlt össze. Minden ügynökben 3-4 munkás, hogy párhuzamosítsa a feladatokat és optimalizálja a folyamatot. Ezután a kiadási tervek szerint a TFS frissen készült Buildet szállított egy Windows alkalmazásszerverre.

Hova akartunk eljutni

A TFS-t használjuk a szállításhoz és fejlesztéshez, az alkalmazást pedig Linux alkalmazásszerveren indítjuk el, közöttük meg valami varázslat. Ez a varázsdoboz és ez a munka kulcsa. Mielőtt megfejtenénk, egy lépést hátralépek, és mondok pár szót az alkalmazásról.

Projekt

Az alkalmazás funkciót biztosít előre fizetett kártyák kezelésére.

.NET Core Linux alatt, DevOps a csúcson

Ügyfél

Kétféle felhasználó létezett. Az első hozzáférést kapott, SSL SHA-2 tanúsítványon keresztül hitelesítve. A második felhasználónévvel és jelszóval lépett be.

HAProxy

Ezután az ügyfélkérés a HAProxy-ba került, amely az alábbi feladatokat oldotta meg:

  • elsődleges hitelesítés;
  • SSL lezárás;
  • HTTP kérések optimalizálása;
  • kérések továbbítása.

A kliens tanúsítványának ellenőrzése láncon keresztül zajlott. Mi vagyunk a hatóság és ezt megengedhetjük magunknak, mivel magunk adjuk ki a tanúsítványokat a szolgáltatás ügyfeleinek.

Figyeljen a harmadik pontra, kicsit később visszatérünk rá.

Backend

A backend Linuxra volt tervezve. A backend interakcióba lép az adatbázissal, betölti a szükséges jogosultságlisztát, majd attól függően, hogy milyen jogosultságokkal rendelkezik a hitelesített felhasználó, hozzáférést biztosít pénzügyi dokumentumok aláírásához és azok végrehajtásra küldéséhez, vagy valamilyen jelentés generálásához.

Megtakarítás a HAProxy-val

A két kontextus mellett, amelyeken minden ügyfél végighaladt, volt még egy identity kontextus. IdentityServer4 amely lehetővé teszi a hitelesítést, ez egy ingyenes és erős alternatíva a ADFS — Active Directory Federation Services.

Az identity-re küldött kérés több lépésben lett feldolgozva. Az első lépés - az ügyfél a backendbe került., amely adatokat cserélt ezzel a szerverrel és ellenőrizte az ügyfél tokenjének meglétét. Ha nem találta, a kérés visszatért arra a kontextusra, ahonnan érkezett, de már átirányítással, és az átirányítás az identity-re ment.

A második lépés - a kérés eljutott az IdentityServer bejelentkezési oldalára, ahol az ügyfél regisztrált, és az IdentityServer adatbázisában megjelent az a régóta várt token.

A harmadik lépés - az ügyfél visszairányítódott arra a kontextusra, ahonnan érkezett.

.NET Core Linux alatt, DevOps a csúcson

Az IdentityServer4-nek van egy sajátossága: a visszairányított kérésre HTTP-n keresztül válaszol,. Akárhogy is próbálkoztunk a szerver beállításaival, akárhány dokumentációt elolvastunk, de minden alkalommal az ügyfél kezdeti kérését kaptuk meg URL-lel, amely HTTPS-en érkezett, míg az IdentityServer ugyanazon kontextust visszajuttatta HTTP-val. Megdöbbentünk! És mindezt az identity kontextuson keresztül átirányítottuk a HAProxy-ra, a fejekben pedig a HTTP protokollt HTTPS-re kellett módosítanunk.

Mi az előny, és hol spóroltunk?

Pénzt spóroltunk azáltal, hogy ingyenes megoldást használtunk a felhasználói csoportok hitelesítésére, forrásokat, mivel az IdentityServer4-et egy külön nodként külön szegmensben nem futtattuk, hanem együtt használtuk az alkalmazás backendjével ugyanazon a szerveren, ahol a backend működik.

Hogyan kell működnie

Tehát, ahogy ígértem - Magic Box. Már értjük, hogy garantáltan a Linux irányába haladunk. Formáljunk meg konkrét feladatokat, amelyek megoldásra vártak.

.NET Core Linux alatt, DevOps a csúcson

Puppet manifesztumok. A szolgáltatás és az alkalmazás konfigurációs kezeléséhez klassz recepteket kellett írni. A ceruza és a tekercs beszédesen mutatja, hogy mennyire gyorsan és minőségben készült el ez.

A szállítás módja. A standard az RPM. Mindenki tudja, hogy Linuxon nélküle nem lehet, de maga a projekt fordítás után egy futtatható DLL-fájlok halmazaként jelent meg. Körülbelül 150 volt belőle, a projekt elég nehéz. Az egyetlen harmonikus megoldás, hogy ezt a bináris anyagot RPM-be csomagoljuk, és már abból telepítsük az alkalmazást.

Verziókezelés. Sűrűn kellett kiadnunk, és meg kellett határoznunk, hogyan alakítsuk ki a csomag nevét. Ez a TFS integrációs szintjének kérdése. A Build-ügynökünk Linuxon futott. Amikor a TFS felad egy feladatot az ügynöknek - worker - a Build-ügynökön, átkonvertálja számára a szükséges változókat, amelyeket a folyamat környezeti változóihoz ad. Ezek között a környezeti változók között átadható a Build neve, a verzió neve és egyéb változók. További részletek a 'RPM-csomag építése' részben találhatóak.

TFS beállítása a Pipeline beállítására összpontosult. Korábban a Windows-ügynökökön gyűjtöttük az összes Windows-projektet, most viszont megjelenik a Linux-ügynök - Build-ügynök, amelyet be kell iktatni az építési csoportba, bizonyos artefaktumokkal gazdagítani, megmondani, milyen típusú projekteket fognak ezen a Build-ügynökön összeállítani, és valamilyen módon módosítani a Pipeline-t.

IdentityServer. Az ADFS nem a mi utunk, az Open Source mellett állunk ki.

Nézzük át a komponenseket.

varázsdoboz

Négy részből áll.

.NET Core Linux alatt, DevOps a csúcson

Linux Build-ügynök. Linux, mert erre állítjuk össze - logikus. Ezt a részt három lépésben végeztük el.

  • Ügynökök beállítása és nem egyet, mert elvártuk a projekt elosztott munkáját.
  • A .NET Core 1.x telepítése. Miért éppen 1.x, amikor már elérhető a 2.0 a standard tárolóban? Mert amikor elkezdtük a fejlesztést, az 1.09 stabil verzió volt, így ezt a verziót választottuk a projekthez.
  • Git 2.x.

RPM-tároló. Az RPM-csomagokat valahol tárolni kellett. Azt terveztük, hogy ugyanazt a vállalati RPM-tárolót használjuk, amely minden Linux hoszt számára elérhető. Így is tettünk. A tároló szerveren beállítottuk webhook amely letöltötte a megadott helyről a szükséges RPM-csomagot. A webhook verzióját a Build-ügynök közölte.

GitLab. Figyelem! A GitLab itt nem a fejlesztők által, hanem a üzemeltetési osztály által van használva az alkalmazás verzióinak, a csomagok verzióinak, minden Linux-gép állapotának ellenőrzésére, és az összes recept - minden Puppet-manifeszt itt található.

Puppet megoldja a vitás kérdéseket, és pontosan azt a konfigurációt szolgáltatja, amit szeretnénk, a Gitlab-ból.

Kezdjük el mélyebben belemerülni. Hogyan történik a DLL szállítása az RPM-be?

DLL szállítása az RPM-be

Tegyük fel, hogy van egy rockcsillagunk a .NET fejlesztésében. Ő a Visual Studio-t használja, és létrehoz egy kiadási ágat. Ezután feltölti azt a Git-be, és a Git itt - TFS entitás, tehát ez az alkalmazás tárolója, amellyel a fejlesztő dolgozik.

.NET Core Linux alatt, DevOps a csúcson

Ezután a TFS észleli, hogy új elkötelezés érkezett. Melyik alkalmazásról van szó? A TFS beállításaiban van egy címke, amely megmutatja, hogy milyen erőforrásokkal rendelkezik az egyes Build-ügynökök. Ebben az esetben látja, hogy .NET Core projektet építünk, ezért a Linux Build-ügynököt választja a poolból.

A Build-ügynök megkapja a forrást, letölti a szükséges függőségeket a .NET, npm stb. tárolóból, majd az alkalmazás építése és a csomagolás után elküldi az RPM-csomagot az RPM-tárolóba.

Másrészt a következő történik. Az üzemeltetési részleg mérnöke közvetlenül a projekt kiadásával foglalkozik: változtatja a csomagok verzióit a Hiera a tárolóban, ahol az alkalmazás receptje található, majd a Puppet aktiválja a Yum-ot,amely letölti az új csomagot a tárolóból, és az új verzió az alkalmazás készen áll a használatra.

.NET Core Linux alatt, DevOps a csúcson

Szóban minden egyszerű, de mi történik belül a Build-ügynökön?

DLL RPM csomagolása

Megkaptuk a projekt forrásait és a TFS-től érkező építési feladatot. A Build-ügynök elindítja a project építését a forrásokból.A megépített projekt több DLL fájl formájában érhető el,amelyeket zip-archívumba csomagolnak a fájlrendszer terhelésének csökkentése érdekében.

A ZIP-archívum a RPM csomagépítési könyvtárba kerül. Ezután a Bash-skriptek inicializálják a környezeti változókat, megkeresik a Build verzióját, a projekt verzióját, a build könyvtár elérési útját, és elindítják az RPM-build folyamatot. Az építés befejezése után a csomag publikálásra kerül a helyi tárolóba,amely a Build-ügynökön található.

Ezután a Build-ügynökről a szerverre az RPM-tárolóba JSON-kérést küldenek, amelyben megadják a verzió- és buildnevet. Az általam korábban említett Webhook letölti ezt a csomagot a Build-ügynök helyi tárolójából, és új építést tesz elérhetővé telepítésre.

.NET Core Linux alatt, DevOps a csúcson

Miért ilyen a csomagok tárolóba juttatásának terve? Miért nem lehet az összes csomagot közvetlenül a tárolóba küldeni? Az ok az, hogy ez a biztonság biztosítására szolgáló feltétel. Ez a forgatókönyv korlátozza a külső személyek általi jogosulatlan RPM-csomagok feltöltésének lehetőségét a minden Linux-gép számára elérhető szerverre.

DB verziózás

A fejlesztéssel folytatott konzíliumban kiderült, hogy a srácoknak közelebb áll a MS SQL, de a legtöbb nem Windows projektünkben már bőven használtuk a PostgreSQL-t. Mivel már eldöntöttük, hogy lemondunk minden fizetős megoldásról, így itt is a PostgreSQL-t kezdtük el használni.

.NET Core Linux alatt, DevOps a csúcson

Ebben a részben szeretném elmondani, hogyan végeztük a DB verzionálását, és hogyan választottunk a Flyway és az Entity Framework Core között. Nézzük meg az előnyeiket és hátrányaikat.

Hátrányok

A Flyway csak egy irányba működik, mi nem tudunk visszaváltani — ez jelentős hátrány. Az Entity Framework Core-ral más paraméterek szerint lehet összehasonlítani — a fejlesztők kényelme szempontjából. Biztosan emlékszik, hogy ezt állítottuk a középpontba, és alapvető kritérium volt, hogy semmit ne változtassunk meg a Windows fejlesztésben.

A Flyway-hoz szükségünk volt valamilyen burkolóra, hogy a srácok ne írjanak SQL-lekérdezéseket. Számukra sokkal kényelmesebb az OOP fogalmaival dolgozni. Írtunk utasításokat az DB objektumokkal való munkához, létrejött az SQL-lekérdezés és végrehajtásra került. Az új DB verzió kész, teszteltük — minden rendben van, minden működik.

Az Entity Framework Core-nak van egy hátránya — nagy terhelés esetén nem optimalizált SQL-lekérdezéseket épít, és a DB teljesítménye jelentős lehet. De mivel nem egy nagy terhelésű szolgáltatással dolgozunk, nem számítunk milliós RPS terhelésre, vállaltuk ezt a kockázatot és a jövőbeli problémát átdelegáltuk magunknak.

Előnyök

Entity Framework Core dobozból működik és kényelmes a fejlesztéshez, míg a Flyway könnyen integrálható a meglévő CI-be. De mi is a fejlesztők kényelmére összpontosítunk :)

A folyamatautomatizálás

A Puppet észleli, hogy változás történt a csomagok verziójában, beleértve azt is, amely a migrációért felelős. Először telepíti azt a csomagot, amely a migrációs szkripteket és az DB-vel kapcsolatos funkciót tartalmazza. Ezután újraindítja az alkalmazást, amely az DB-vel dolgozik. Ezután következik a többi komponens telepítése. A csomagok telepítési sorrendje és az alkalmazások indítása a Puppet manifesztjében van leírva.

Az alkalmazások érzékeny adatokat használnak, például tokeneket, DB jelszavakat, mindezek a konfigurációban a Puppet masterből töltődnek be, ahol titkosított formában tárolják őket.

TFS problémák

Miután eldöntöttük, és megértettük, hogy nálunk tényleg minden jól működik, úgy döntöttem, megnézem, mi történik a TFS buildjeivel az Win-fejlesztési részlegen más projekteknél — gyorsan vagyunk-e a buildel és a kiadáson, és jelentős sebességi problémákat fedeztem fel.

Az egyik fő projekt 12-15 percet vesz igénybe — ez hosszú, így nem lehet élni. Gyors elemzés mutatta, hogy borzalmasan gyenge az I/O, és ez az array-eken.

Megnézve komponensenként három gócpontot azonosítottam. Az első — „Kaspersky antivirus”, amely minden Windows Build-ügynökön beolvassa a forrásokat. A második - Windows Indexer. Nem volt letiltva, és a Build-ügynökök valós időben indexelték az összes folyamatban lévőt a telepítés során.

A harmadik - Npm install. Kiderült, hogy a legtöbb Pipeline-ban éppen ezt a szkriptet használtuk. Mi a hátránya? Az Npm install eljárás a függőségek fájltérképének létrehozásakor fut le. package-lock.json, ahol rögzítik a projektehez felhasznált csomagok verzióit. A hátránya, hogy az Npm install minden alkalommal a legfrissebb verziókat húzza le az internetről, ami jelentős időt vehet igénybe egy nagy projekt esetén.

A fejlesztők néha a helyi gépen kísérleteznek, hogy ellenőrizzék egy-egy rész vagy az egész projekt működését. Néha az történt, hogy helyben minden jól működött, de amikor összeállítottuk és telepítettük, semmi nem működött. Kezdünk utánajárni, mi a probléma - aha, különböző verziók a függőségekből.

Megoldás

  • A források az AV kivételekben.
  • Az indexálás letiltása.
  • Átállás a npm ci.

Az npm ci előnye, hogy a függőségek fájltérképét egyszer állítjuk össze, és lehetőséget ad arra, hogy a fejlesztő számára aktuális csomaglistát, amellyel szabadon kísérletezhet helyben. Ez időt takarít meg a kódot író fejlesztők számára.

Konfiguráció

Most egy kicsit a repozitórium konfigurációjáról. Történelmileg a Nexus-t használjuk a repozitóriumok kezelésére, beleértve az Internal REPO-t.Ebben a belső repozitóriumban találhatóak mindazon komponensek, amelyeket belső célokra használunk, például a saját készítésű monitorozások.

.NET Core Linux alatt, DevOps a csúcson

Emellett használjuk a NuGet-et,, mivel jobban cache-eli, mint a többi csomagkezelő.

Eredmény

Miután optimalizáltuk a Build-ügynököket, az átlagos összeállítási idő 12 percről 7 percre csökkent.

Ha számításba vesszük az összes gépet, amelyet használhattunk volna Windows alatt, de ebben a projektben Linuxra váltottunk, körülbelül 10 000 dollárt spóroltunk meg. És ez csak a licenceken, ha figyelembe vesszük a fenntartási költségeket - még többet.

Tervek

A következő negyedévre a kód szállításának optimalizálására terveztük a munkát.

Átállás a prebuildezett Docker-képre. A TFS nagyszerű dolog sok pluginnal, amelyek lehetővé teszik az integrációt a Pipeline-ba, beleértve a trigger szerinti összeállítást, például a Docker-képet. Ezt a triggert akarjuk megvalósítani arra a célra. package-lock.json. Ha valamilyen módon megváltozik a projekt összeállításához használt összetevők összetétele – új Docker-képet készítünk. Ezt követően ezt használjuk a konténer telepítéséhez a létrehozott alkalmazással. Jelenleg ez nincs, de tervezzük, hogy áttérünk a Kubernetes mikroszolgáltatás-architektúrára, amely aktívan fejlődik cégünknél és már régóta támogatja a produkciós megoldásokat.

Összefoglaló

Arra kérek mindenkit, hogy dobnak ki a Windows-t, de nem azért, mert nem tudom elkészíteni. Az oka az, hogy a legtöbb nyílt forráskódú megoldás – ez Linux-stack. Nagyon jól megtakarít pénzt az erőforrásokon. Véleményem szerint a jövő a Linuxon alapuló nyílt forráskódú megoldásoké, erős közösséggel.

A speaker profilja: Alexander Sinchinov GitHub-on.

DevOps Conf – egy konferencia a fejlesztési, tesztelési és üzemeltetési folyamatok integrálásáról szakemberek számára szakemberektől. Éppen ezért a projekt, amelyről Alexander beszélt, megvalósult és működik, míg a beszéd napján két sikeres kiadás is zajlott. A DevOps Conf a RIT++-n május 27-én és 28-án még több hasonló eset lesz a gyakorlóktól. Még lehet ugrani az utolsó vonatra és benyújtani egy előadást vagy nyugodtan lefoglalni a jegyet. Találkozunk Skolkovo-ban!

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster