Me arendasime DevOps nii hästi, kui suudame. Meid oli 8 inimest ja Vassil oli Windowsi alal kõige rohkem kogemusi. Äkki lahkus Vassil ja mul tuli ülesanne käivitada uus projekt, mis pakub Windowsi arendust. Kui ma laotasin lauale kogu Windowsi arenduse tehnoloogiapaki, siis sain aru, et olukord on valus…
Nii algab lugu Aleksandr Sinčinov järgnevaga . Kui ettevõttest lahkus peamine Windowsi spetsialist, küsis Aleksandr endalt, mida nüüd teha. Loomulikult tuli minna Linuxile! Aleksandr räägib, kuidas tal õnnestus luua eelkäija ja viia osa Windowsi arendusest Linuxile, kasutades 100 000 lõppkasutajaga elluviidud projekti näidet.

Kuidas on lihtne ja muretu projekti RPM-i toimetamine, kasutades TFS-i, Puppetit, Linux .NET core'i? Kuidas hallata projekti andmebaasi versioonimist, kui arendajad kuulevad esmakordselt Postgresi ja Flyway sõnu, ja tähtaeg on ülehomme? Kuidas integreerida Dockeriga? Kuidas motiveerida .NET arendajaid loobuma Windowsist ja smuutidest Puppetile ja Linuxile üle minnes? Kuidas lahendada ideoloogilisi konfliktide, kui Windowsi teenindamine tootmises pole enam jõud, tahtmine ega ressursid? Sellest ja veel Web Deploy'ist, testimisest, CI-st, TFS-i kasutamise praktikatest olemasolevates projektides ning muidugi purunenud karkudest ja töötavatest lahendustest rääkis Alexander oma ettekandes.

Nii et Vasja lahkus, ülesanne on minu, arendajad ootavad talgute ja kannatamatusega. Kui ma lõpuks mõistsin, et Vasjat ei saa tagasi, asusin tööle. Esiteks hindasin Windows VM-i protsent meie pargis. Arvud ei olnud Windowsi kasuks.

Kuna me arendame aktiivselt DevOps-i, sain aru, et pean midagi muutma uue rakenduse välja toomise lähenemises. Lahendus oli üks - võimaluse korral viia kõik Linuxile üle. Google aitas mind - tol hetkel oli .Net juba Linuxile portitud ja mõistsin, et see on lahendus!
Miks .NET core koos Linuxiga?
Sellel oli mitu põhjust. Enamiku jaoks, kes peab valima raha maksmise ja mitte maksmise vahel, valib enamus teise — nagu ka mina. MSDB litsents maksab umbes 1000 €, Windowsi virtuaalmasinate hooldus ulatub sadadesse eurodesse. Suure ettevõtte jaoks on need suured kulud. Seetõttu sääst — esimene põhjus. See ei ole kõige olulisem, aga üks tähtsatest.
Windowsi virtuaalmasinad tarbivad rohkem ressursse kui nende Linuxi vennad — need on rasked. Arvestades suure ettevõtte mastaapi, valisime Linuxi.
Süsteem integreerub lihtsalt olemasolevasse CI. Peame end progressiivseteks DevOps'iks, kasutame Bamboo, Jenkins ja GitLab CI, seetõttu on enamik meie töödest Linuxis.
Viimane põhjus on mugav jälgimine. Meil oli vaja vähendada „jälgijate” sisenemisbarjääri — poistele, kes mõistavad tehnilist osa, tagavad töökindluse ja hooldavad teenuseid teise taseme kaudu. Nad olid juba tuttavad Linuxi tehnoloogiaga, seega on neil palju lihtsam uue toote mõistmine, toetamine ja hooldamine kui investeerida täiendavaid ressursse Windowsi platvormi sarnase funktsionaalsuse mõistmiseks.
Nõuded
Esiteks ja kõige tähtsam — uue lahenduse mugavus arendajatele. Mitte kõik neist ei olnud muutusteks valmis, eriti pärast sõna Linux esitamist. Arendajad soovivad oma lemmik Visual Studio't, TFS-i koos testide automaatika ja smuutidega. Kuidas toimub tootmise toimetamine — see ei huvita neid. Seetõttu otsustasime jätta harjumuspärase protsessi muutmata ja hoida Windowsi arenduses kõik endisena.
Uus projekt tuleb integreerida olemasolevasse CI. Raudteed olid juba olemas ja kogu töö pidi toimuma arvestusega süsteemihalduse parameetrite, vastuvõetud kohaletoimetamise standardite ja jälgimissüsteemide järgi.
Lihtsus hoolduses ja kasutuses, nagu tingimus, et kõik uued osalejad erinevate osakondade ja tugiosakonna poolt saaksid minimaalselt sisse elada.
Tähtaeg — eile.
Windowsi arendusmeeskond
Millega töötas Windowsi meeskond siis?

Praegu võin kindlalt öelda, et IdentityServer4 — see on suurepärane tasuta ADFS alternatiiv sarnaste võimalustega, või et Entity Framework Core — arendaja paradiis, kus ei pea muretsema SQL skriptide kirjutamise pärast, vaid saab kirjeldada andmebaasi päringuid OOP mõistetega. Kuid siis, tegevuskava arutelus, vaatasin sellele stackile kui šumeeria kliendikirja, tunnustades vaid PostgreSQL ja Git.
Sel ajal kasutasime aktiivselt Puppet konfiguratsioonihalduse süsteemina. Enamikus meie projektides kasutasime GitLab CI, Elastic, koormatud teenuseid tasakaalustades HAProxy, jälgisime kõike Zabbix, komplekti Grafana ja Prometheus, Jaeger, ja kõik see töötas raua peal HP c ESXi järgnevaga VMware. Ikka tuntud — žanri klassika.

Vaatame ja püüame mõista, mis toimus enne, kui me kõik need sekkumised ette võtsime.
Mis oli
TFS on üsna võimas süsteem, mis mitte ainult ei edasta koodi arendajalt lõppkasutaja masinasse, vaid omab ka komplekti väga paindlikuks integreerimiseks erinevate teenustega – CI tagamiseks ristplatvormi tasandil.

Раньше это были сплошные форточки. TFS использовал несколько Build-агентов, на которых собиралось множество проектов. В каждом агенте по 3-4 worker-a, чтобы распараллелить задачи и оптимизировать процесс. Дальше, согласно релизным планам, TFS доставлял свежеиспеченный Build на Windows-сервер приложений.
К чему мы хотели прийти
Для доставки и разработки используем TFS, а запускаем приложение на Linux Application server, и между ними какая-то магия. Этот Magic Box и есть соль предстоящей работы. Перед тем, как разобрать его по частям, сделаю шаг в сторону и скажу два слова о приложении.
Projekt
Приложение предоставляет функциональность для оперирования предоплаченными картами.

Kliendi
Существовало два типа пользователей. Esimene получал доступ, авторизуясь по сертификату SSL SHA-2. У teine был доступ по логину и паролю.
HAProxy
Дальше клиентский запрос попадал в HAProxy, который решал следующие задачи:
- первичная авторизация;
- терминирование SSL;
- тюнинг HTTP запросов;
- трансляция запросов.
Проверка сертификата клиента шла по цепочке. Мы — authority и можем себе такое позволить, так как сами выдаем сертификаты клиентам сервиса.
Pöörake tähelepanu kolmandale punktile, toome selle teemani tagasi veidi hiljem.
Backend
Tahtsime taustsüsteemi teha Linuxil. Taustsüsteem suhtleb andmebaasiga, laadib vajalikud õiguste loendid ja seejärel, sõltuvalt sellest, milliste õigustega autentitud kasutaja on, annab juurde pääsuga finantsdokumentide allkirjastamiseks ja nende täitmiseks saatmiseks või mingi aruande genereerimiseks.
Säästmine c HAProxy
Lisaks kahele kontekstile, millega iga klient toimis, oli veel üks kontekst identity. IdentityServer4 see võimaldab sisse logida, see on tasuta ja võimas analoog ADFS — Active Directory Federation Services.
Identiteedi päringut töödeldi mitmes etapis. Esimene etapp, kliendi sattus taustsüsteemi, mis vahetas andmeid selle serveriga ja kontrollis kliendi tokeni olemasolu. Kui see ei leitud - päring tagastati tagasi konteksti, kust see tuli, kuid juba suunamisega, ja koos suunamisega läks see identiteedile.
Teine etapp - päring sattus autentimise lehele IdentityServeris, kus klient registreerus ja IdentityServeri andmebaasis ilmus see kauaoodatud token.
Kolmas etapp - klient suunati tagasi kontekstist, millest ta tuli.

IdentityServer4-l on üks omadus: vastus tagasiside päringule tuleb läbi HTTP. Ükski meie serveri seadistamise katsest või dokumentatsioonist ei aidanud, me saime iga kord algse kliendi päringu, mille URL tuli HTTPS kaudu, aga IdentityServer tagastas sama konteksti HTTP kaudu. Olime šokis! Ja suunasime selle kõik läbi identity konteksti HAProxy kaudu, kuid peame protokolli HTTP modifitseerima HTTPS-iks päistes.
Mis on parendused ja kus kokkuhoid?
Oleme raha kokku hoidnud, kasutades tasuta lahendust kasutajagruppide autoriseerimiseks, ressursse, kuna me ei tõstnud IdentityServer4 eraldi sõlmena eraldi segmenti, vaid kasutasime seda koos rakenduse tagarindega samal serveril, kus rakenduse tagariba töötab.
Kuidas see peaks töötama
Nii et, nagu ma lubasin - Magic Box. Me mõistame nüüd, et suundume kindlasti Linuxi poole. Vaatame konkreetsed ülesanded, mis vajasid lahendamist.

Puppet manifestid. Teenuste ja rakenduste konfiguratsiooni edastamiseks ja haldamiseks tuli kirjutada suurepärased retseptid. Karp pliiatsiga näitab selgelt, kui kiiresti ja kvaliteetselt see tehtud sai.
Tarnimisviis. Standard on RPM. Kõik mõistavad, et Linuxis ei saa ilma selleta, kuid ise projekt pärast kompileerimist oli komplekt täidetud DLL-failidest. Neid oli umbes 150, projekt oli piisavalt mahukas. Ainus harmooniline lahendus oli pakkida see binaar RPM-i ja seejärel sealt rakendus üles tõsta.
Versioonimine. Me pidime vabastama väga sageli ja tuli otsustada, kuidas paketi nime kujundada. See on tasemeküsimus TFS-iga integreerimisel. Meie Build-agendiks oli Linux. Kui TFS saadab ülesande töötlejale — worker — Build-agentile, edastab ta talle ka muutuja massiivi, mis tuleb töötleja protsessi keskkonda. Nendes keskkonnamuutujates edastatakse Buildi nimi, versiooni nimi ja teised muutujad. Täiendavat teavet leiate allpool jaotises „RPM-paketi koostamine“.
TFS-i seadistamine äärmus kulmineerub Pipeline'i seadistusse. Varem kogusime Windows-agentides kõik Windows-projektid, kuid nüüd lisandub Linux-agent — Build-agent, mille tuleb lisada kogumisse, rikastada mingite artefaktidega, märkida, millise tüübi projekte sellele Build-agentile kogutakse, ja muuta Pipeline'i.
IdentityServer. ADFS ei ole meie tee, toetame Open Source'i.
Vaadakem komponente.
Magic Box
Koosneb neljast osast.

Linux Build-agent. Linux, sest me kogume selle alla — loogiline. See osa viidi ellu kolme sammuga.
- Seadistada worker'id ja mitte ainult üks, kuna eeldati projekti jaotatud töötamist.
- Installeerida .NET Core 1.x. Miks just 1.x, kui 2.0 on juba tavarepositooriumis saadaval? Sest kui me arendamisega alustasime, oli stabiilne versioon 1.09 ja projekti otsustati teha selle alla.
- Git 2.x.
RPM-repositoorium. RPM-pakette tuli kuskil hoida. Eeldati, et kasutame sama ettevõtte RPM-repositooriumi, mis on kõigile Linuxi hostidele saadaval. Nii ka tegime. Serveris on repositoorium seadistatud webhook , mis laadis vajalikud RPM-paketid määratud kohast alla. Paketiversiooni teatas Build-agent webhook'ule.
GitLab. Tähtis! GitLab'i kasutatakse siin mitte arendajate, vaid halduskeskuse poolt rakenduse, paketiversioonide ning kõikide Linux-masinate oleku jälgimiseks, samuti hoitakse seal retsepte – kõiki Puppet'i manifeste.
Puppet — lahendab kõik vaidlusalused küsimused ja toob meile just selle konfigureeringu, mida soovime, GitLab'ist.
Alustame süvenemist. Kuidas toimub DLL'i tarnimine RPM'i?
DDL'i tarnimine RPM'i
Oletame, et meil on .NET-i arenduse rokktäht. Ta kasutab Visual Studio't ja loob versiooniharu. Pärast seda laadib ta selle Git'i, kus Git on TFS-üksus, see tähendab rakenduse hoidla, millega arendaja töötab.

Pärast seda näeb TFS, et uus kinnitus on saabunud. Milline rakendus? TFS-i seadetes on märge, milliste ressurssidega on erinevad Build-agendid varustatud. Antud juhul näeb ta, et ehitame .NET Core projekti ja valib Linuxi Build-agendi basseinist.
Build-agent saab lähtekoodid, tõmbab vajalikud sõltuvused .NET hoidlast, npm-ist jne, ja pärast rakenduse enda koostamist ja järgmist pakkimist saadab RPM-paketi RPM-hoidlasse.
Teiselt poolt toimub järgmist. Käitamise osakonna insener tegeleb projekti käivitamisega: muudab pakettide versioone Hiera hoidlas, kus hoitakse rakenduse retseptuuri, pärast mida Puppet käivitab Yum, tõmbab uue paketi hoidlast ja uus rakenduse versioon on kasutamiseks valmis.

Käesolev osa on lihtne, kuid mis toimub tegelikult Build-agentis?
DLL RPM pakkimine
Projektin allikad on saadud ja koostamise ülesanne TFS-ilt. Build-agent käivitab projekti koostamise allikatest.Koostatud projekt on saadaval hulgaliselt DLL faile, mis on pakitud zip-arhiivi, et vähendada koormust failisüsteemile.
ZIP-arhiiv visatakse RPM pakendi koostamise katalooge. Järgmisena Bash-skript initsialiseerib keskkonnamuutujad, leiab Build versiooni, projekti versiooni, tee koostamise kataloogi ja käivitab RPM-buildi. Pärast koostamise lõpetamist avaldatakse paketid kohalikku hoidlasse, mis asub Build-agentis.
Seejärel saadetakse Build-agentist serverisse RPM-hoidlatesse JSON-päring versiooni ja build'i nime määramisega. Webhook, millest ma varem rääkisin, tõmbab selle paketi kohalikust hoidlast Build-ainel ja teeb uue ehituse installimiseks kergesti kättesaadavaks.

Miks just selline paketi kohaletoimetamise skeem RPM hoidlast? Miks ei saa kohe kokku pandud paketti hoidlast saata? Asi on selles, et see on turvalisuse tagamise tingimus. Selline stsenaarium piirab kõrvaliste isikute võimalust mitteautoriseeritud RPM-pakettide üleslaadimiseks serverisse, mis on kõigile Linuxi masinatele ligipääsetav.
Andmebaasi versioonimine
Arenduskonsiiliumil selgus, et arendajatele meeldib rohkem MS SQL, kuid enamikus non-Windows projektides oleme juba aktiivselt kasutanud PostgreSQL-i. Kuna otsustasime loobuda kõigest tasulisest, hakkasime ka siin PostgreSQL-i kasutama.

Selles osas tahan rääkida, kuidas me andmebaasi versioonimist teostasime ja kuidas valisime Flyway ja Entity Framework Core vahel. Vaatame nende plusse ja miinuseid.
Miinused
Flyway töötab ainult ühes suunas, me ei saa tagasi tagasi minna — see oluline puudus. Entity Framework Core'i saab võrrelda teiste kriteeriumitega — arendaja mugavuse seisukohalt. Teate ju, et oleme sellele esmatähtsuse andnud, ja peamine kriteerium oli, et mitte muuta midagi Windowsi arenduse jaoks.
Flyway jaoks meil oli vajalik mingi ümbris, et mehed ei kirjutaks SQL-päringuteks. Neil on palju mugavam töötada OOP-tasandil. Kirjutasime juhised andmebaasi objektide kasutamiseks, SQL-i päring moodustus ja täideti. Uus andmebaasi versioon on valmis, testitud — kõik on hästi, kõik töötab.
Entity Framework Core'il on puudus — suurte koormustega teeb ta mitteoptimaalseid SQL-päringuid, ja andmebaasi koormus võib olla märkimisväärne. Kuid kuna meil ei ole kõrge koormuse teenust, me ei mõõda koormust sadade RPS-idega, siis võtsime need riskid endale ja delegasime probleemi tulevikus meile.
Plussid
Entity Framework Core töötab kohe ja on arendajatele mugav, kuid Flyway integreerub kergesti olemasolevasse CI. Aga me ju teeme arendajatele mugavamaks :)
Käivitamisprotseduur
Puppet näeb, et pakettide versioonide muutus toimub, sealhulgas see, mis vastutab migration'i eest. Esmalt installitakse pakett, kus sisaldub migration'i skriptid ja andmebaasi funktsionaalsus. Pärast seda taaskäivitub rakendus, mis töötab andmebaasiga. Järgneb ülejäänud komponentide installimine. Pakettide installimise järjekord ja rakenduste käivitamine on kirjeldatud Puppet'i manifestis.
Rakendused kasutavad tundlikke andmeid, nagu token'id ja andmebaasi paroolid; kõik need tõmmatakse konfiguraatorist Puppet master, kus nad on salastatud.
TFS probleemid
Pärast seda, kui olime kindlad ja mõistsime, et meil tõepoolest kõik töötab, otsustasin vaadata, mis toimub TFS-i kogumite osas üldiselt Win-arendusosakonna muude projektide puhul – kas kokkupanekud/ülekanded on kiired või mitte – ja tuvastasin märkimisväärseid probleeme kiirusest.
Üks olulisi projekte koostatakse 12-15 minuti jooksul – see on liiga pikk, nii ei saa elada. Kiire analüüs näitas kohutavat I/O langust ja see toimub massiivide peal.
Pärast komponendi analüüsi eristasin kolm keskpunkti. Esimene – «Kaspersky antivirus», mis skannib lähtekoodide kõigil Windows Build-agentidel. Teine — Windows Indexer. See ei olnud välja lülitatud ja Build-agentidel indekseeriti reaalses ajas kõik deploy'imise protsessi jooksul.
Kolmas — Npm install. Selgus, et enamikus Pipelines kasutasime just seda skripti. Mis on selle probleem? Npm install protseduur käivitatakse sõltuvuste puu loomisel package-lock.json, kus fikseeritakse pakettide versioonid, mida projekti kokkupanekuks kasutatakse. Miinus seisneb selles, et Npm install toob iga kord uusimad paketiversioonid internetist, mis kulutab märkimisväärselt aega suurte projektide korral.
Arendajad katsetavad mõnikord kohalikul masinal, et kontrollida, kuidas töötavad üksikud osad või terve projekt. Mõnikord selgus, et kohapeal kõik toimib hästi, aga kokkupanekul — mitte midagi ei töötanud. Alustame probleemi lahendamist — ah, erinevad paketiversioonid sõltuvustega.
Lahendus
- Lähtekoodid AV välja jätta.
- Indekseerimise keelamine.
- Üleminekule npm ci.
Npm ci plussideks on see, et me koostame sõltuvuste puu ühe korra, ja saame võimaluse esitada arendajale aktuaalne paketilisti, millega saab katsetada lokaalselt nii palju kui soovib. See säästab aega arendajatele, kes kirjutavad koodi.
Konfiguratsioon
Natuke nüüd repositooriumi konfiguratsioonist. Ajalooliselt oleme kasutanud Nexus repositooriumide haldamiseks, sealhulgas Internaalse REPO. Selles sisemises repositooriumis on kõik komponendid, mida kasutame sisetöödeks, näiteks kohandatud monitooringud.

Kasutame ka NuGet, kuna see on paremini puhverdatud võrreldes teiste pakihalduritega.
Tulemus
Pärast Build-agentide optimeerimist vähenes keskmine ehitusaeg 12 minutilt 7 minutile.
Kui arvestada kõiki masiname, mida oleksime saanud Windowsile, aga muutsime Linuxiks selle projekti raames, siis säästsime umbes 10 000 dollarit. Ja see on ainult litsentside pealt, kui arvestada sisu - veel rohkem.
Tunniplaanid
Järgmisse kvartalisse oleme plaaninud koodi kohaletoimetamise optimeerimise.
Üleminek eelkoostatud Docker-pildi. TFS on äge asi koos paljude pluginatega, mis võimaldavad integreerida Pipeline'i, sealhulgas ehituse käivitamise näiteks Docker-pildi puhul. Soovime teha selle käivitaja sellele. package-lock.json. Kui mingil viisil muutub projektis kasutatavate komponentide koosseis, kogume uue Docker-pildi. Edasi kasutatakse seda konteineri juurutamiseks koos kogutud rakendusega. Praegu seda ei ole, kuid plaanime üle minna mikroteenuste arhitektuurile Kuberneteses, mis meie ettevõttes aktiivselt areneb ja juba pikka aega toetab tootmislahendusi.
Kokkuvõte
Kutsub kõiki Windowsist loobuma, kuid see pole seetõttu, et ma ei oska seda seadistada. Põhjus on selles, et suur osa avatud lähtekoodiga lahendustest on Linuxi stack. Te säästate hästi ressursse. Minu arvates on tulevik avatud lähtekoodiga lahendustes Linuxis, millel on tugev kogukond.
Läbiviija profiil Aleksandr Sinčinov .
— see on konverents arendamise, testimise ja opereerimise protsesside integreerimiseks professionaalidelt professionaalidele. Just seetõttu on projekt, millest Aleksandr rääkis, ellu viidud ja töötab, ning esinemispäeva jooksul toimusid kaks edukat versiooni. 27. ja 28. mail on veel rohkem selliseid juhtumeid praktikutelt. Veel on võimalik viimasele rongile hüpata ja või rahulikult. pilet. Kohtume Skolkovo's!
Allikas: habr.com
