.NET Core na Linuxu, DevOps na konju

DevOps smo razvili po najboljših močeh. Bilo nas je 8 in Vasya je bil najbolj kul v Windowsih. Nenadoma je Vasya odšel, jaz pa sem imel nalogo zagnati nov projekt, ki ga je zagotovil razvoj Windows. Ko sem na mizo odvrgel celoten razvojni sklad za Windows, sem ugotovil, da je situacija boleča ...

Tako se zgodba začne Aleksandra Sinčinova o DevOpsConf. Ko je vodilni strokovnjak za Windows zapustil podjetje, se je Alexander spraševal, kaj storiti zdaj. Preklopite na Linux, seveda! Alexander vam bo povedal, kako mu je uspelo ustvariti precedens in del razvoja sistema Windows prenesti na Linux na primeru dokončanega projekta za 100 končnih uporabnikov.

.NET Core na Linuxu, DevOps na konju

Kako enostavno in brez truda dostaviti projekt v RPM z uporabo TFS, Puppet, Linux .NET core? Kako podpreti verzioniranje projektne baze, če razvojna ekipa prvič sliši besedi Postgres in Flyway, rok pa je pojutrišnjem? Kako se integrirati z Dockerjem? Kako motivirati razvijalce .NET, da opustijo Windows in smoothije v korist Puppet in Linuxa? Kako rešiti ideološke konflikte, če ni niti moči, niti želje, niti sredstev za vzdrževanje sistema Windows v proizvodnji? O tem, pa tudi o Web Deploy, testiranju, CI, o praksah uporabe TFS v obstoječih projektih in seveda o pokvarjenih berglah in delujočih rešitvah v prepisu Aleksandrovega poročila.


Torej, Vasya je odšel, naloga je na meni, razvijalci nestrpno čakajo z vilami. Ko sem končno ugotovil, da Vasje ni mogoče vrniti, sem se lotil posla. Za začetek sem ocenil odstotek Win VM v naši floti. Rezultat ni bil v prid sistemu Windows.

.NET Core na Linuxu, DevOps na konju

Ker aktivno razvijamo DevOps, sem ugotovil, da je treba nekaj spremeniti v pristopu k dostavi nove aplikacije. Rešitev je bila le ena - če je možno, vse prenesti na Linux. Google mi je pomagal - takrat je bil .Net že prenesen na Linux, in ugotovil sem, da je to rešitev!

Zakaj .NET core v povezavi z Linuxom?

Razlogov za to je bilo več. Med "plačati denar" in "ne plačati" bo večina izbrala drugo - tako kot jaz. Licenca za MSDB stane približno 1 $; vzdrževanje flote virtualnih strojev Windows stane na stotine dolarjev. Za veliko podjetje je to velik strošek. Zato prihranki  - prvi razlog. Ne najpomembnejši, a eden izmed pomembnih.

Virtualni stroji Windows zavzamejo več virov kot njihovi bratje Linux - težki so. Glede na obseg velikega podjetja smo izbrali Linux.

Sistem se preprosto integrira v obstoječi CI. Menimo, da smo progresivni DevOps, uporabljamo Bamboo, Jenkins in GitLab CI, tako da večina našega dela poteka v Linuxu.

Zadnji razlog je priročno spremljavo. Morali smo znižati vstopno oviro za "spremljevalce" - fante, ki razumejo tehnični del, zagotavljajo nemoteno storitev in vzdržujejo storitve iz druge linije. Sklad Linuxa so že poznali, zato jim je veliko lažje razumeti, podpirati in vzdrževati nov izdelek, kot pa porabiti dodatna sredstva za razumevanje iste funkcionalnosti programske opreme za platformo Windows.

Zahteve

Najprej in predvsem - priročnost nove rešitve za razvijalce. Niso bili vsi pripravljeni na spremembe, še posebej po besedi Linux. Razvijalci želijo svoj najljubši Visual Studio, TFS s samodejnimi testi za sestave in gladke. Kako poteka dostava v proizvodnjo, jim ni pomembno. Zato smo se odločili, da ne bomo spreminjali običajnega postopka in pustili vse nespremenjeno za razvoj sistema Windows.

Potreben nov projekt integrirati v obstoječe KI. Tirnice so že bile tam in vse delo je bilo treba opraviti ob upoštevanju parametrov sistema za upravljanje konfiguracije, sprejetih standardov dobave in sistemov za spremljanje.

Enostavnost podpore in delovanja, kot pogoj za minimalni vstopni prag za vse nove udeležence iz različnih divizij in podpornega oddelka.

Rok - včeraj.

Win Development Group

S čim je takrat delala ekipa Windows?

.NET Core na Linuxu, DevOps na konju

Zdaj lahko to z gotovostjo trdim IdentityServer4 je kul brezplačna alternativa ADFS s podobnimi zmogljivostmi, ali kaj Jedro Entity Framework - raj za razvijalce, kjer se vam ni treba truditi s pisanjem SQL skriptov, ampak poizvedbe v bazi podatkov opisujete v izrazih OOP. Potem pa sem med razpravo o akcijskem načrtu pogledal na ta sklad, kot da bi bil sumerski klinopis, pri čemer sem prepoznal samo PostgreSQL in Git.

Takrat smo aktivno uporabljali Lutkovno kot sistem za upravljanje konfiguracije. V večini naših projektov smo uporabili GitLab CI, Elastic, uporabo uravnoteženih visoko obremenjenih storitev HAProxy vse spremljal s Zabbix, vezi grafana и Prometej, Jaeger, in vse to se je vrtelo na kosih železa HPESXiVMware. Vsi ga poznajo - klasika žanra.

.NET Core na Linuxu, DevOps na konju

Poglejmo in poskusimo razumeti, kaj se je zgodilo, preden smo začeli z vsemi temi posegi.

Kaj se je zgodilo

TFS je dokaj zmogljiv sistem, ki ne le dostavlja kodo od razvijalca do končnega produkcijskega stroja, ampak ima tudi nabor za zelo prilagodljivo integracijo z različnimi storitvami – za zagotavljanje CI na medplatformski ravni.

.NET Core na Linuxu, DevOps na konju
Prej so bila to masivna okna. TFS je uporabil več agentov Build, ki so bili uporabljeni za sestavljanje številnih projektov. Vsak agent ima 3-4 delavce za paralelizacijo nalog in optimizacijo procesa. Nato je TFS v skladu z načrti izdaje sveže pečeno gradnjo dostavil aplikacijskemu strežniku Windows.

Kaj smo želeli doseči?

Za dostavo in razvoj uporabljamo TFS in izvajamo aplikacijo na aplikacijskem strežniku Linux, med njima pa je nekakšna čarovnija. to Čarobna škatla in pred nami je sol dela. Preden ga razstavim, bom naredil korak stran in spregovoril nekaj besed o aplikaciji.

Projekt

Aplikacija nudi funkcionalnost za delo s predplačniškimi karticami.

.NET Core na Linuxu, DevOps na konju

Pomoč

Obstajali sta dve vrsti uporabnikov. Prvič pridobili dostop s prijavo s potrdilom SSL SHA-2. U drugi je bil dostop z uporabo prijave in gesla.

HAProxy

Nato je zahteva odjemalca šla na HAProxy, ki je rešil naslednje težave:

  • primarno dovoljenje;
  • prekinitev SSL;
  • prilagajanje zahtev HTTP;
  • zahteve za oddajanje.

Certifikat stranke je bil preverjen vzdolž verige. mi - organ in to si lahko privoščimo, saj sami izdajamo certifikate naročnikom storitev.

Bodite pozorni na tretjo točko, k njej se bomo vrnili malo kasneje.

Backend

Zaledje so nameravali narediti na Linuxu. Zaledje komunicira z bazo podatkov, naloži potreben seznam privilegijev in nato, odvisno od tega, kakšne privilegije ima pooblaščeni uporabnik, omogoči dostop za podpisovanje finančnih dokumentov in njihovo pošiljanje v izvedbo ali ustvarjanje neke vrste poročila.

Prihranki s HAProxy

Poleg dveh kontekstov, po katerih je krmaril vsak odjemalec, je obstajal tudi kontekst identitete. IdentityServer4 samo omogoča prijavo, to je brezplačen in zmogljiv analog za ADFS  - Storitve zveze Active Directory.

Zahteva po identiteti je bila obdelana v več korakih. Prvi korak - stranka prišel v zaledje, ki je komuniciral s tem strežnikom in preverjal prisotnost žetona za odjemalca. Če ni bila najdena, se je zahteva vrnila nazaj v kontekst, iz katerega je prišla, vendar s preusmeritvijo, s preusmeritvijo pa je šla na identiteto.

Drugi korak – zahteva je bila prejeta na avtorizacijsko stran v IdentityServer, kjer se je odjemalec registriral, in ta dolgo pričakovani žeton se je pojavil v bazi podatkov IdentityServer.

Tretji korak - stranka je bila preusmerjena nazaj na kontekst, iz katerega prihaja.

.NET Core na Linuxu, DevOps na konju

IdentityServer4 ima funkcijo: vrne odgovor na povratno zahtevo prek HTTP. Ne glede na to, kako zelo smo se mučili z nastavitvijo strežnika, ne glede na to, koliko smo se razsvetljevali z dokumentacijo, vsakič, ko smo prejeli začetno zahtevo odjemalca z URL-jem, ki je prišel prek HTTPS, je IdentityServer vrnil isti kontekst, vendar s HTTP. Bili smo šokirani! In vse to smo prenesli skozi identitetni kontekst v HAProxy, v glavah pa smo morali spremeniti protokol HTTP v HTTPS.

Kakšna je izboljšava in kje ste prihranili?

Prihranili smo z uporabo brezplačne rešitve za avtorizacijo skupine uporabnikov, virov, saj IdentityServer4 nismo postavili kot ločeno vozlišče v ločen segment, ampak smo ga uporabljali skupaj z zaledjem na istem strežniku, kjer teče zaledje aplikacije. .

Kako bi moralo delovati

Torej, kot sem obljubil - Magic Box. Že razumemo, da se bomo zagotovo pomaknili proti Linuxu. Oblikujmo konkretne naloge, ki so zahtevale rešitve.

.NET Core na Linuxu, DevOps na konju

Lutkovni manifesti. Za zagotavljanje in upravljanje konfiguracije storitev in aplikacij je bilo treba napisati kul recepte. Zvitek svinčnika zgovorno pove, kako hitro in učinkovito je bilo opravljeno.

Način dostave. Standard je RPM. Vsi razumejo, da v Linuxu ne morete brez njega, vendar je bil sam projekt po sestavljanju nabor izvedljivih datotek DLL. Bilo jih je okoli 150, projekt je bil kar težak. Edina harmonična rešitev je zapakirati to dvojiško datoteko v RPM in iz nje razmestiti aplikacijo.

Versioning. Izdajati smo morali zelo pogosto in morali smo se odločiti, kako oblikovati ime paketa. To je vprašanje stopnje integracije s TFS. Imeli smo gradbenega agenta za Linux. Ko TFS pošlje nalogo obdelovalcu - delavcu - agentu Build, mu posreduje tudi kup spremenljivk, ki končajo v okolju procesa obdelovalca. Te spremenljivke okolja vsebujejo ime graditve, ime različice in druge spremenljivke. Preberite več o tem v razdelku »Izdelava paketa RPM«.

Nastavitev TFS prišel do postavitve Pipelinea. Prej smo zbrali vse projekte Windows v agentih Windows, zdaj pa se pojavi agent za Linux - agent Build, ki ga je treba vključiti v skupino gradnje, obogatiti z nekaterimi artefakti in povedati, kakšne vrste projektov bodo zgrajeni na tem agentu Build , in nekako spremeniti cevovod.

IdentityServer. ADFS ni naša pot, gremo za odprto kodo.

Pojdimo skozi komponente.

Čarobna škatla

Sestavljen je iz štirih delov.

.NET Core na Linuxu, DevOps na konju

Agent za gradnjo Linuxa. Linux, ker gradimo zanj - to je logično. Ta del je bil izveden v treh korakih.

  • Konfigurirajte delavce in ne sam, saj je bilo pričakovano porazdeljeno delo na projektu.
  • Namestite .NET Core 1.x. Zakaj 1.x, ko je 2.0 že na voljo v standardnem repozitoriju? Ker ko smo začeli z razvojem, je bila stabilna različica 1.09 in je bilo odločeno, da projekt naredimo na njeni osnovi.
  • Git 2.x.

RPM-repozitorij. Pakete RPM je bilo treba nekje shraniti. Predpostavljeno je bilo, da bomo uporabili isto korporativno skladišče RPM, ki je na voljo vsem gostiteljem Linuxa. To so storili. Repozitorijski strežnik je konfiguriran spletni kavelj ki je zahtevani paket RPM prenesel z navedene lokacije. Različico paketa je webhooku prijavil agent Build.

GitLab. Pozor! GitLab tukaj ne uporabljajo razvijalci, ampak operativni oddelek za nadzor različic aplikacij, različic paketov, spremljanje stanja vseh strojev Linux in shranjuje recepte – vse manifeste Puppet.

Lutkovno — rešuje vsa sporna vprašanja in zagotavlja točno tisto konfiguracijo, ki jo želimo od Gitlaba.

Začnemo se potapljati. Kako deluje dostava DLL v RPM?

Dostava DDL v RPM

Recimo, da imamo rock zvezdo razvoja .NET. Uporablja Visual Studio in ustvari izdajno vejo. Po tem ga naloži v Git, Git pa je tukaj entiteta TFS, to je repozitorij aplikacij, s katerim dela razvijalec.

.NET Core na Linuxu, DevOps na konju

Po tem TFS vidi, da je prispela nova potrditev. Katera aplikacija? V nastavitvah TFS je oznaka, ki označuje, katere vire ima določen gradbeni agent. V tem primeru vidi, da gradimo projekt .NET Core, in iz skupine izbere agenta Linux Build.

Agent za gradnjo prejme vire in prenese potrebne odvisnosti iz repozitorija .NET, npm itd. in po izdelavi same aplikacije in kasnejšem pakiranju pošlje paket RPM v repozitorij RPM.

Po drugi strani pa se zgodi naslednje. Inženir operativnega oddelka je neposredno vključen v uvedbo projekta: spreminja različice paketov Hiera v repozitorij, kjer je shranjen recept aplikacije, nakar se sproži Puppet yum, pridobi nov paket iz repozitorija in nova različica aplikacije je pripravljena za uporabo.

.NET Core na Linuxu, DevOps na konju

Z besedami je vse preprosto, toda kaj se zgodi znotraj samega agenta Build?

Pakiranje DLL RPM

Prejeti viri projekta in naloga gradnje iz TFS. Gradbeni agent sam začne graditi projekt iz virov. Sestavljen projekt je na voljo kot komplet datoteke DLL, ki so zapakirani v zip arhiv za zmanjšanje obremenitve datotečnega sistema.

ZIP arhiv zavržemo v imenik za gradnjo paketa RPM. Nato skript Bash inicializira spremenljivke okolja, poišče različico gradnje, različico projekta, pot do imenika gradnje in zažene RPM-build. Ko je gradnja končana, je paket objavljen v lokalni repozitorij, ki se nahaja na Build agentu.

Nato od Build agenta do strežnika v repozitoriju RPM Zahteva JSON je poslana ki označuje ime različice in zgradbe. Webhook, o katerem sem govoril prej, prenese ta isti paket iz lokalnega repozitorija na agentu Build in naredi nov sklop na voljo za namestitev.

.NET Core na Linuxu, DevOps na konju

Zakaj ravno ta shema dostave paketov v repozitorij RPM? Zakaj ne morem takoj poslati sestavljenega paketa v repozitorij? Dejstvo je, da je to pogoj za zagotavljanje varnosti. Ta scenarij omejuje možnost, da bi nepooblaščene osebe naložile pakete RPM na strežnik, ki je dostopen vsem napravam Linux.

Različice baze podatkov

Na posvetu z razvojno ekipo se je izkazalo, da je fantom bližje MS SQL, vendar smo v večini ne-Windows projektov že na vso moč uporabljali PostgreSQL. Ker smo se že odločili, da opustimo vse plačljivo, smo tudi tukaj začeli uporabljati PostgreSQL.

.NET Core na Linuxu, DevOps na konju

V tem delu vam želim povedati, kako smo različico baze podatkov in kako smo izbirali med Flyway in Entity Framework Core. Poglejmo njihove prednosti in slabosti.

Proti

Flyway gre samo v eno smer, mi ne moremo vrniti nazaj - to je pomembna pomanjkljivost. Lahko ga primerjate z Entity Framework Core na druge načine – v smislu priročnosti za razvijalce. Saj se spomnite, da smo to postavili v ospredje in glavno merilo je bilo, da ne spremenimo ničesar za razvoj Windows.

Za Flyway nas je bil potreben nekakšen ovojda fantje ne pišejo SQL poizvedbe. So veliko bližje delovanju v smislu OOP. Napisali smo navodila za delo z objekti baze podatkov, generirali SQL poizvedbo in jo izvedli. Nova različica baze je pripravljena, testirana - vse je v redu, vse deluje.

Entity Framework Core ima minus - pri velikih obremenitvah ga gradi neoptimalne poizvedbe SQL, padec v bazi podatkov je lahko precejšen. Ker pa nimamo storitve z visoko obremenitvijo, obremenitve ne izračunavamo v stotinah RPS, smo sprejeli ta tveganja in težavo prenesli na prihodnost.

Pros

Jedro Entity Framework deluje brezhibno in je enostaven za razvojin Flyway Enostavno se integrira v obstoječi CI. Ampak to naredimo priročno za razvijalce :)

Postopek roll-up

Puppet vidi, da prihaja sprememba v različici paketa, vključno s tisto, ki je odgovorna za selitev. Najprej namesti paket, ki vsebuje selitvene skripte in funkcionalnost, povezano z bazo podatkov. Po tem se znova zažene aplikacija, ki deluje z bazo podatkov. Sledi namestitev preostalih komponent. Vrstni red, v katerem se namestijo paketi in zaženejo aplikacije, je opisan v manifestu Puppet.

Aplikacije uporabljajo občutljive podatke, kot so žetoni, gesla baze podatkov, vse to se potegne v konfiguracijo iz Puppet master, kjer so shranjeni v šifrirani obliki.

Težave s TFS

Ko smo se odločili in ugotovili, da nam res vse deluje, sem se odločil pogledati, kaj se dogaja s sklopi v TFS kot celoti za razvojni oddelek Win na drugih projektih - ne glede na to, ali gradimo/sproščamo hitro ali ne, in odkril velike težave s hitrostjo.

Eden od glavnih projektov traja 12-15 minut, da se sestavi - to je dolgo, tako se ne da živeti. Hitra analiza je pokazala strašno zmanjšanje V/I, in to na nizih.

Po analizi posamezne komponente sem identificiral tri žarišča. prvi - "Protivirusni program Kaspersky", ki skenira vire na vseh agentih Windows Build. drugi - Windows Indeksator. Ni bil onemogočen in vse je bilo v realnem času indeksirano na agentih Build med postopkom uvajanja.

tretji - Namestitev Npm. Izkazalo se je, da smo v večini cevovodov uporabili točno ta scenarij. Zakaj je slab? Postopek namestitve Npm se zažene, ko je oblikovano drevo odvisnosti package-lock.json, kjer so zabeležene različice paketov, ki bodo uporabljeni za izdelavo projekta. Slaba stran je, da Npm install vsakič potegne najnovejše različice paketov iz interneta, kar v primeru velikega projekta vzame veliko časa.

Razvijalci včasih eksperimentirajo na lokalnem računalniku, da preizkusijo, kako deluje določen del ali celoten projekt. Včasih se je izkazalo, da je lokalno vse kul, pa so sestavili, razvaljali in nič ni delovalo. Začnemo ugotavljati, v čem je težava - ja, različne različice paketov z odvisnostmi.

odločitev

  • Viri v izjemah AV.
  • Onemogoči indeksiranje.
  • Pojdi do npm ci.

Prednosti npm ci so, da mi Drevo odvisnosti zberemo enkrat, in dobimo priložnost, da zagotovimo razvijalca trenutni seznam paketov, s katerim lahko lokalno eksperimentira, kolikor hoče. to prihrani čas razvijalci, ki pišejo kodo.

Konfiguracija

Zdaj pa nekaj o konfiguraciji repozitorija. Zgodovinsko uporabljamo Nexus za upravljanje repozitorijev, vključno z Notranji REPO. To interno skladišče vsebuje vse komponente, ki jih uporabljamo za interne namene, na primer samonapisano spremljanje.

.NET Core na Linuxu, DevOps na konju

Uporabljamo tudi NuGet, saj ima boljše predpomnjenje v primerjavi z drugimi upravitelji paketov.

Rezultat

Potem ko smo optimizirali gradbene agente, se je povprečni čas gradnje zmanjšal z 12 minut na 7.

Če preštejemo vse stroje, ki bi jih lahko uporabljali za Windows, pa smo v tem projektu prešli na Linux, smo privarčevali okoli 10 $.In to samo pri licencah, če upoštevamo vsebino, pa še več.

Načrti

Za naslednje četrtletje smo načrtovali delo na optimizaciji dostave kode.

Preklop na predhodno izdelano sliko Dockerja. TFS je kul stvar s številnimi vtičniki, ki vam omogočajo integracijo v Pipeline, vključno s sestavljanjem, na primer slike Docker, na podlagi sprožilcev. Ta sprožilec želimo narediti za istega package-lock.json. Če se sestava komponent, uporabljenih za gradnjo projekta, nekako spremeni, zgradimo novo sliko Dockerja. Kasneje se uporabi za razmestitev vsebnika s sestavljeno aplikacijo. Zdaj temu ni tako, načrtujemo pa prehod na mikrostoritveno arhitekturo v Kubernetesu, ki se v našem podjetju aktivno razvija in že dolgo časa služi produkcijskim rešitvam.

Povzetek

Spodbujam vse, da zavržejo Windows, vendar ne zato, ker ne znam kuhati. Razlog je v tem, da je večina odprtokodnih rešitev Linux sklad. ali si v redu prihranite pri virih. Po mojem mnenju prihodnost pripada odprtokodnim rešitvam na Linuxu z močno skupnostjo.

Profil govorca Aleksandra Sinčinova na GitHubu.

DevOps Conf je konferenca o integraciji procesov razvoja, testiranja in delovanja za profesionalce s strani profesionalcev. Zato projekt, o katerem je govoril Alexander? izvedena in delujoča, na dan izvedbe pa dve uspešni izdaji. Vklopljeno DevOps Conf na RIT++ 27. in 28. maja bo podobnih primerov s strani praktikov še več. Še vedno lahko skočite v zadnji vagon in Pošlji poročilo ali si vzemite čas rezervirati vstopnica. Spoznajte nas v Skolkovu!

Vir: www.habr.com

Dodaj komentar