.NET Core på Linux, DevOps til hest

Vi udviklede DevOps så godt vi kunne. Vi var 8, og Vasya var den sejeste i Windows. Pludselig gik Vasya, og jeg havde til opgave at lancere et nyt projekt, som blev leveret af Windows-udvikling. Da jeg dumpede hele Windows-udviklingsstakken på bordet, indså jeg, at situationen var en smertefuld...

Sådan begynder historien Alexandra SinchinovaDevOpsConf. Da den førende Windows-specialist forlod virksomheden, spekulerede Alexander på, hvad han skulle gøre nu. Skift til Linux, selvfølgelig! Alexander vil fortælle dig, hvordan han formåede at skabe en præcedens og overføre en del af Windows-udviklingen til Linux ved at bruge eksemplet på et afsluttet projekt for 100 slutbrugere.

.NET Core på Linux, DevOps til hest

Hvordan leverer man nemt og ubesværet et projekt til RPM ved hjælp af TFS, Puppet, Linux .NET core? Hvordan understøtter man versionering af en projektdatabase, hvis udviklingsteamet hører ordene Postgres og Flyway for første gang, og deadline er i overmorgen? Hvordan integreres med Docker? Hvordan motiverer man .NET-udviklere til at opgive Windows og smoothies til fordel for Puppet og Linux? Hvordan løser man ideologiske konflikter, hvis der hverken er styrken, lysten eller ressourcerne til at opretholde Windows i produktionen? Om dette, såvel som om Web Deploy, test, CI, om praksisser for at bruge TFS i eksisterende projekter, og selvfølgelig om knækkede krykker og arbejdsløsninger, i udskriften af ​​Alexanders rapport.


Så Vasya forlod, opgaven er på mig, udviklerne venter utålmodigt med højgafler. Da jeg endelig indså, at Vasya ikke kunne returneres, gik jeg i gang. Til at begynde med vurderede jeg procentdelen af ​​Win VM'er i vores flåde. Scoren var ikke til fordel for Windows.

.NET Core på Linux, DevOps til hest

Da vi aktivt udvikler DevOps, indså jeg, at noget skal ændres i tilgangen til at levere en ny applikation. Der var kun én løsning - hvis det er muligt, overfør alt til Linux. Google hjalp mig - på det tidspunkt var .Net allerede blevet overført til Linux, og jeg indså, at dette var løsningen!

Hvorfor .NET core i forbindelse med Linux?

Det var der flere grunde til. Mellem "betale penge" og "ikke betale", vil flertallet vælge den anden - ligesom mig. En licens til MSDB koster omkring $1; vedligeholdelse af en flåde af virtuelle Windows-maskiner koster hundredvis af dollars. For en stor virksomhed er dette en stor udgift. Derfor besparelser  første grund. Ikke den vigtigste, men en af ​​de væsentlige.

Virtuelle Windows-maskiner optager flere ressourcer end deres Linux-brødre - de er tunge. I betragtning af omfanget af den store virksomhed, valgte vi Linux.

Systemet er simpelthen integreret i eksisterende CI. Vi betragter os selv som progressive DevOps, vi bruger Bamboo, Jenkins og GitLab CI, så det meste af vores arbejde kører på Linux.

Den sidste grund er praktisk akkompagnement. Vi var nødt til at sænke adgangsbarrieren for "eskorte" - de fyre, der forstår den tekniske del, sikrer uafbrudt service og vedligeholder tjenester fra anden linje. De var allerede bekendt med Linux-stakken, så det er meget nemmere for dem at forstå, understøtte og vedligeholde et nyt produkt end at bruge yderligere ressourcer på at forstå den samme funktionalitet af software til Windows-platformen.

Krav

Først og fremmest - den nye løsnings bekvemmelighed for udviklere. Ikke alle af dem var klar til forandring, især efter at ordet Linux blev talt. Udviklere vil have deres foretrukne Visual Studio, TFS med autotest til samlinger og smoothies. Hvordan levering til produktion foregår, er ikke vigtigt for dem. Derfor besluttede vi ikke at ændre den sædvanlige proces og lade alt være uændret til Windows-udvikling.

Nyt projekt påkrævet integreres i eksisterende CI. Skinnerne var der allerede, og alt arbejdet skulle udføres under hensyntagen til parametrene for konfigurationsstyringssystemet, accepterede leveringsstandarder og overvågningssystemer.

Nem support og betjening, som betingelse for mindste adgangstærsklen for alle nye deltagere fra forskellige afdelinger og supportafdelingen.

Deadline - i går.

Vind udviklingsgruppe

Hvad arbejdede Windows-teamet med dengang?

.NET Core på Linux, DevOps til hest

Nu kan jeg trygt sige det Identitetsserver 4 er et sejt gratis alternativ til ADFS med lignende muligheder, eller hvad Entity Framework Core - et paradis for en udvikler, hvor du ikke skal besvære at skrive SQL-scripts, men beskrive forespørgsler i databasen i OOP-termer. Men så, under diskussionen af ​​handlingsplanen, så jeg på denne stak, som om den var sumerisk kileskrift, og genkendte kun PostgreSQL og Git.

På det tidspunkt brugte vi aktivt Marionet som et konfigurationsstyringssystem. I de fleste af vores projekter brugte vi GitLab CI, Elastik, afbalanceret høj belastning tjenester ved hjælp af HAProxy overvåget alt med Zabbix, ledbånd grafana и Prometheus, Jaeger, og alt dette snurrede på jernstykker HPESXi på VMware. Alle kender den – en klassiker i genren.

.NET Core på Linux, DevOps til hest

Lad os se og prøve at forstå, hvad der skete, før vi startede alle disse indgreb.

Hvad skete der

TFS er et ret kraftfuldt system, der ikke kun leverer kode fra udvikleren til den endelige produktionsmaskine, men som også har et sæt til meget fleksibel integration med forskellige tjenester – for at levere CI på tværplatformsniveau.

.NET Core på Linux, DevOps til hest
Tidligere var der tale om solide vinduer. TFS brugte flere Build-agenter, som blev brugt til at samle mange projekter. Hver agent har 3-4 medarbejdere til at parallelisere opgaver og optimere processen. Derefter, ifølge udgivelsesplanerne, leverede TFS den friskbagte Build til Windows-applikationsserveren.

Hvad ønskede vi at opnå?

Vi bruger TFS til levering og udvikling og kører applikationen på en Linux applikationsserver, og der er en form for magi mellem dem. Det her Magic Box og der er saltet af arbejdet forude. Inden jeg skiller det ad, vil jeg tage et skridt til side og sige et par ord om applikationen.

Projekt

Applikationen giver funktionalitet til håndtering af forudbetalte kort.

.NET Core på Linux, DevOps til hest

Klient

Der var to typer brugere. Første fået adgang ved at logge ind med et SSL SHA-2 certifikat. U den anden der var adgang ved hjælp af login og adgangskode.

HAProxy

Derefter gik klientanmodningen til HAProxy, som løste følgende problemer:

  • primær autorisation;
  • SSL opsigelse;
  • tuning af HTTP-anmodninger;
  • udsendelsesanmodninger.

Klientcertifikatet blev verificeret langs kæden. Vi - myndighed og det har vi råd til, da vi selv udsteder certifikater til servicekunder.

Vær opmærksom på det tredje punkt, vi vender tilbage til det lidt senere.

Bagende

De planlagde at lave backend på Linux. Backend'en interagerer med databasen, indlæser den nødvendige liste over privilegier og giver derefter, afhængigt af hvilke privilegier den autoriserede bruger har, adgang til at underskrive finansielle dokumenter og sende dem til udførelse eller generere en form for rapport.

Besparelser med HAProxy

Ud over de to kontekster, som hver klient navigerede efter, var der også en identitetskontekst. Identitetsserver 4 giver dig bare mulighed for at logge ind, dette er en gratis og kraftfuld analog til ADFS  Active Directory Federation Services.

Identitetsanmodningen blev behandlet i flere trin. Første skridt - kunde kom ind i backend, som kommunikerede med denne server og kontrollerede tilstedeværelsen af ​​et token til klienten. Hvis den ikke blev fundet, blev anmodningen returneret til den kontekst, den kom fra, men med en omdirigering, og med omdirigeringen gik den til identitet.

Andet trin - anmodningen blev modtaget til autorisationssiden i IdentityServer, hvor klienten registrerede sig, og det længe ventede token dukkede op i IdentityServer-databasen.

Tredje trin - klienten blev omdirigeret tilbage til den kontekst, den kom fra.

.NET Core på Linux, DevOps til hest

IdentityServer4 har en funktion: det returnerer svaret på returanmodningen via HTTP. Uanset hvor meget vi kæmpede med at sætte serveren op, uanset hvor meget vi oplyste os med dokumentationen, modtog vi hver gang en indledende klientanmodning med en URL, der kom via HTTPS, og IdentityServer returnerede den samme kontekst, men med HTTP. Vi var chokerede! Og vi overførte alt dette gennem identitetskonteksten til HAProxy, og i headerne skulle vi ændre HTTP-protokollen til HTTPS.

Hvad er forbedringen, og hvor har du sparet?

Vi sparede penge ved at bruge en gratis løsning til at godkende en gruppe brugere, ressourcer, da vi ikke placerede IdentityServer4 som en separat node i et separat segment, men brugte den sammen med backend på den samme server, hvor backend af applikationen kører .

Hvordan det skal fungere

Så, som jeg lovede - Magic Box. Vi forstår allerede, at vi med garanti vil bevæge os mod Linux. Lad os formulere konkrete opgaver, der krævede løsninger.

.NET Core på Linux, DevOps til hest

Dukke manifesterer sig. For at levere og administrere service og applikationskonfiguration skulle der skrives fede opskrifter. En blyantrulle viser veltalende, hvor hurtigt og effektivt det blev gjort.

Leveringsmetode. Standarden er RPM. Alle forstår, at i Linux kan du ikke undvære det, men selve projektet, efter montering, var et sæt eksekverbare DLL-filer. Der var omkring 150 af dem, projektet var ret svært. Den eneste harmoniske løsning er at pakke denne binære til RPM og implementere applikationen fra den.

Versionering. Vi skulle frigive meget ofte, og vi skulle beslutte, hvordan vi skulle danne pakkenavnet. Dette er et spørgsmål om integrationsniveauet med TFS. Vi havde en build-agent på Linux. Når TFS sender en opgave til en handler - arbejder - til Build-agenten, sender den også en masse variabler til den, der ender i behandlerprocessens miljø. Disse miljøvariabler indeholder Build-navnet, versionsnavnet og andre variabler. Læs mere om dette i afsnittet "Opbygning af en RPM-pakke".

Opsætning af TFS kom ned til at opsætte Pipeline. Tidligere har vi samlet alle Windows-projekter på Windows-agenter, men nu dukker der en Linux-agent op - en Build-agent, som skal inkluderes i build-gruppen, beriget med nogle artefakter og fortalt, hvilken type projekter der vil blive bygget på denne Build-agent , og på en eller anden måde ændre Pipeline.

Identitetsserver. ADFS er ikke vores måde, vi går efter Open Source.

Lad os gennemgå komponenterne.

Magic Box

Består af fire dele.

.NET Core på Linux, DevOps til hest

Linux Build agent. Linux, fordi vi bygger til det - det er logisk. Denne del blev udført i tre trin.

  • Konfigurer arbejdere og ikke alene, da der var forventet fordelt arbejde på projektet.
  • Installer .NET Core 1.x. Hvorfor 1.x, når 2.0 allerede er tilgængelig i standardlageret? For da vi startede udviklingen, var den stabile version 1.09, og det blev besluttet at lave projektet ud fra den.
  • Git 2.x.

RPM-lager. RPM-pakker skulle opbevares et sted. Det blev antaget, at vi ville bruge det samme virksomheds RPM-lager, som er tilgængeligt for alle Linux-værter. Det var, hvad de gjorde. Lagerserveren er konfigureret webkrog som downloadede den nødvendige RPM-pakke fra den angivne placering. Pakkeversionen blev rapporteret til webhook af Build-agenten.

GitLab. Opmærksomhed! GitLab her bruges ikke af udviklere, men af ​​driftsafdelingen til at kontrollere applikationsversioner, pakkeversioner, overvåge status på alle Linux-maskiner, og det gemmer opskriften - alle Puppet-manifester.

Marionet — løser alle kontroversielle problemer og leverer præcis den konfiguration, vi ønsker fra Gitlab.

Vi begynder at dykke. Hvordan virker DLL-levering til RPM?

Levering DDL til RPM

Lad os sige, at vi har en .NET udviklingsrockstar. Det bruger Visual Studio og opretter en udgivelsesgren. Derefter uploader den det til Git, og Git her er en TFS-entitet, det vil sige, det er applikationsarkivet, som udvikleren arbejder med.

.NET Core på Linux, DevOps til hest

Hvorefter TFS ser, at der er kommet en ny commit. Hvilken app? I TFS-indstillingerne er der en etiket, der angiver, hvilke ressourcer en bestemt Build-agent har. I dette tilfælde ser han, at vi er ved at bygge et .NET Core-projekt og vælger en Linux Build-agent fra puljen.

Build-agenten modtager kilderne og downloader de nødvendige afhængigheder fra .NET-lageret, npm osv. og efter at have bygget selve applikationen og efterfølgende pakning, sender RPM-pakken til RPM-lageret.

På den anden side sker der følgende. Driftsafdelingens ingeniør er direkte involveret i udrulningen af ​​projektet: han ændrer versionerne af pakker i Hiera i depotet, hvor applikationsopskriften er gemt, hvorefter Puppet trigger Yum, henter den nye pakke fra lageret, og den nye version af applikationen er klar til brug.

.NET Core på Linux, DevOps til hest

Alt er enkelt i ord, men hvad sker der inde i selve Build-agenten?

Emballage DLL RPM

Modtaget projektkilder og byggeopgave fra TFS. Byg agent begynder at bygge selve projektet fra kilder. Det samlede projekt fås som et sæt DLL-filer, som er pakket i et zip-arkiv for at reducere belastningen på filsystemet.

ZIP-arkivet er smidt væk til RPM-pakkebyggebiblioteket. Dernæst initialiserer Bash-scriptet miljøvariablerne, finder Build-versionen, projektversionen, stien til build-mappen og kører RPM-build. Når opbygningen er færdig, udgives pakken til lokalt depot, som er placeret på Build-agenten.

Dernæst fra Build-agenten til serveren i RPM-lageret JSON-anmodning er sendt med angivelse af navnet på versionen og build. Webhook, som jeg talte om tidligere, downloader netop denne pakke fra det lokale lager på Build-agenten og gør den nye samling tilgængelig til installation.

.NET Core på Linux, DevOps til hest

Hvorfor netop denne pakkeleveringsordning til RPM-lageret? Hvorfor kan jeg ikke straks sende den samlede pakke til depotet? Faktum er, at dette er en betingelse for at sikre sikkerheden. Dette scenarie begrænser muligheden for, at uautoriserede personer uploader RPM-pakker til en server, der er tilgængelig for alle Linux-maskiner.

Databaseversionering

Ved en konsultation med udviklingsteamet viste det sig, at fyrene var tættere på MS SQL, men i de fleste ikke-Windows-projekter brugte vi allerede PostgreSQL med al deres magt. Da vi allerede havde besluttet at opgive alt betalt, begyndte vi også at bruge PostgreSQL her.

.NET Core på Linux, DevOps til hest

I denne del vil jeg fortælle dig, hvordan vi versionerede databasen, og hvordan vi valgte mellem Flyway og Entity Framework Core. Lad os se på deres fordele og ulemper.

Cons

Flyway går kun én vej, vi vi kan ikke rulle tilbage - det er en væsentlig ulempe. Du kan sammenligne det med Entity Framework Core på andre måder - med hensyn til udviklerkomfort. Du husker, at vi satte dette på spidsen, og hovedkriteriet var ikke at ændre noget for Windows-udvikling.

Til Flyway os en slags indpakning var nødvendigså fyrene ikke skriver SQL-forespørgsler. De er meget tættere på at fungere i OOP-termer. Vi skrev instruktioner til at arbejde med databaseobjekter, genererede en SQL-forespørgsel og udførte den. Den nye version af databasen er klar, testet - alt er fint, alt fungerer.

Entity Framework Core har et minus - under tunge belastninger bygger suboptimale SQL-forespørgsler, og nedskæringen i databasen kan være betydelig. Men da vi ikke har en højbelastningstjeneste, beregner vi ikke belastningen i hundredvis af RPS, vi accepterede disse risici og uddelegerede problemet til fremtidige os.

Pros

Entity Framework Core fungerer ud af boksen og er nem at udvikle, og Flyway Integreres nemt i eksisterende CI. Men vi gør det praktisk for udviklere :)

Roll-up procedure

Puppet ser, at der kommer en ændring i pakkeversionen, inklusive den, der er ansvarlig for migreringen. Først installerer den en pakke, der indeholder migreringsscripts og databaserelateret funktionalitet. Herefter genstartes programmet, der fungerer med databasen. Dernæst kommer installationen af ​​de resterende komponenter. Rækkefølgen, hvori pakker installeres og applikationer startes, er beskrevet i Puppet-manifestet.

Applikationer bruger følsomme data, såsom tokens, databaseadgangskoder, alt dette trækkes ind i konfigurationen fra Puppet master, hvor de gemmes i krypteret form.

TFS problemer

Efter vi besluttede og indså, at alt virkelig fungerede for os, besluttede jeg at se på, hvad der foregik med samlingerne i TFS som helhed for Win udviklingsafdelingen på andre projekter - uanset om vi byggede/frigav hurtigt eller ej, og opdagede betydelige problemer med hastigheden.

Et af hovedprojekterne tager 12-15 minutter at samle - det er lang tid, sådan kan man ikke leve. En hurtig analyse viste en frygtelig nedtrækning i I/O, og dette var på arrays.

Efter at have analyseret det komponent for komponent, identificerede jeg tre foci. Først - "Kaspersky antivirus", som scanner kilder på alle Windows Build-agenter. Anden - Windows Indekser. Det var ikke deaktiveret, og alt blev indekseret i realtid på Build-agenterne under implementeringsprocessen.

Tredje - Npm installation. Det viste sig, at vi i de fleste rørledninger brugte netop dette scenarie. Hvorfor er han dårlig? Npm-installationsproceduren køres, når afhængighedstræet dannes i package-lock.json, hvor de versioner af pakker, der vil blive brugt til at bygge projektet, registreres. Ulempen er, at Npm install trækker de nyeste versioner af pakker op fra internettet hver gang, og det tager meget tid i tilfælde af et stort projekt.

Udviklere eksperimenterer nogle gange på en lokal maskine for at teste, hvordan en bestemt del eller hele projektet fungerer. Nogle gange viste det sig, at alt var fedt lokalt, men de samlede det, rullede det ud, og intet virkede. Vi begynder at finde ud af, hvad problemet er - ja, forskellige versioner af pakker med afhængigheder.

beslutning

  • Kilder i AV-undtagelser.
  • Deaktiver indeksering.
  • Gå til npm ci.

Fordelene ved npm ci er, at vi Vi samler afhængighedstræet én gang, og vi får mulighed for at give udvikleren aktuelle liste over pakker, som han kan eksperimentere lokalt med, så meget han vil. Det her sparer tid udviklere, der skriver kode.

Konfiguration

Nu lidt om lagerkonfigurationen. Historisk bruger vi Nexus til håndtering af depoter, herunder Intern REPO. Dette interne lager indeholder alle de komponenter, som vi bruger til interne formål, for eksempel selvskrevet overvågning.

.NET Core på Linux, DevOps til hest

Vi bruger også nuget, da den har bedre caching sammenlignet med andre pakkeadministratorer.

Outcome

Efter at vi har optimeret byggeagenterne, blev den gennemsnitlige byggetid reduceret fra 12 minutter til 7.

Hvis vi tæller alle de maskiner med, som vi kunne have brugt til Windows, men som skiftede til Linux i dette projekt, sparede vi omkring 10 kr. Og det er kun på licenser, og mere, hvis vi tager indholdet i betragtning.

Planer

I det næste kvartal planlagde vi at arbejde på at optimere kodeleveringen.

Skift til et forudbygget Docker-billede. TFS er en cool ting med mange plugins, der giver dig mulighed for at integrere i Pipeline, inklusive trigger-baseret samling af for eksempel et Docker-billede. Vi ønsker at gøre denne trigger for den samme package-lock.json. Hvis sammensætningen af ​​komponenterne, der bruges til at bygge projektet, på en eller anden måde ændrer sig, bygger vi et nyt Docker-billede. Det bruges senere til at installere beholderen med den samlede applikation. Det er ikke tilfældet nu, men vi planlægger at skifte til en mikroservicearkitektur i Kubernetes, som er aktivt i udvikling i vores virksomhed og har betjent produktionsløsninger i lang tid.

Resumé

Jeg opfordrer alle til at smide Windows, men det er ikke fordi, jeg ikke ved, hvordan man tilbereder det. Årsagen er, at de fleste Opensource-løsninger er det Linux stak. er du okay spare på ressourcerne. Efter min mening tilhører fremtiden Open Source-løsninger på Linux med et stærkt fællesskab.

Talerprofil af Alexander Sinchinov på GitHub.

DevOps Conf er en konference om integration af udviklings-, test- og driftsprocesser for professionelle af professionelle. Det var derfor projektet, som Alexander talte om? implementeret og fungerer, og på forestillingsdagen var der to succesfulde udgivelser. På DevOps Conf på RIT++ Den 27. og 28. maj kommer der endnu flere lignende sager fra praktiserende læger. Du kan stadig hoppe ind i den sidste vogn og Indsend en rapport eller tag dig god tid Bestil billet. Mød os i Skolkovo!

Kilde: www.habr.com

Tilføj en kommentar