.NET Core na Linuxu, DevOps na koni

Vyvinuli jsme DevOps, jak nejlépe jsme mohli. Bylo nás 8 a Vasya byl nejlepší ve Windows. Najednou Vasja odešel a já měl za úkol spustit nový projekt, který dodal vývoj Windows. Když jsem na stůl vysypal celý zásobník vývoje Windows, uvědomil jsem si, že situace je bolestná...

Takhle příběh začíná Alexandra Sinchinová na DevOpsConf. Když přední specialista na Windows opustil společnost, Alexander přemýšlel, co dělat teď. Přejít na Linux, samozřejmě! Alexander vám na příkladu dokončeného projektu pro 100 000 koncových uživatelů prozradí, jak se mu podařilo vytvořit precedens a přenést část vývoje Windows do Linuxu.

.NET Core na Linuxu, DevOps na koni

Jak snadno a bez námahy dodat projekt do RPM pomocí TFS, Puppet, Linux .NET core? Jak podpořit verzování databáze projektů, když vývojový tým slyší slova Postgres a Flyway poprvé a uzávěrka je pozítří? Jak se integrovat s Dockerem? Jak motivovat vývojáře .NET, aby opustili Windows a smoothies ve prospěch Puppet a Linuxu? Jak vyřešit ideologické konflikty, když není ani síla, ani touha, ani prostředky na udržení Windows ve výrobě? O tom, stejně jako o Web Deploy, testování, CI, o postupech používání TFS ve stávajících projektech a samozřejmě o nefunkčních berlích a fungujících řešeních, v přepisu Alexandrovy zprávy.


Vasja tedy odešel, úkol je na mně, vývojáři netrpělivě čekají s vidlemi. Když jsem si konečně uvědomil, že Vasju nelze vrátit, pustil jsem se do práce. Nejprve jsem zhodnotil procento Win VM v naší flotile. Skóre nebylo ve prospěch Windows.

.NET Core na Linuxu, DevOps na koni

Vzhledem k tomu, že aktivně vyvíjíme DevOps, uvědomil jsem si, že je potřeba něco změnit v přístupu k doručování nové aplikace. Existovalo jediné řešení – pokud možno přenést vše na Linux. Pomohl mi Google – v té době už byl .Net portován na Linux a já si uvědomil, že toto je řešení!

Proč jádro .NET ve spojení s Linuxem?

Důvodů k tomu bylo několik. Mezi „zaplatit peníze“ a „nezaplatit“ si většina vybere to druhé – jako já. Licence pro MSDB stojí asi 1 000 USD, údržba flotily virtuálních strojů Windows stojí stovky dolarů. Pro velkou společnost je to velký náklad. Proto úspory - první důvod. Ne nejdůležitější, ale jeden z nejvýznamnějších.

Virtuální stroje Windows zabírají více zdrojů než jejich linuxoví bratři - jsou těžké. Vzhledem k rozsahu velké společnosti jsme zvolili Linux.

Systém je jednoduše integrován do stávající CI. Považujeme se za progresivní DevOps, používáme Bamboo, Jenkins a GitLab CI, takže většina naší práce běží na Linuxu.

Poslední důvod je pohodlný doprovod. Potřebovali jsme snížit bariéru vstupu pro „eskorty“ – lidi, kteří rozumí technické části, zajišťují nepřetržitou službu a udržují služby z druhé linie. Byli již obeznámeni s linuxovým stackem, takže je pro ně mnohem snazší porozumět, podporovat a udržovat nový produkt, než utrácet další prostředky na pochopení stejné funkce softwaru pro platformu Windows.

Požadavky

V první řadě - pohodlí nového řešení pro vývojáře. Ne všichni byli připraveni na změnu, zvláště poté, co bylo vysloveno slovo Linux. Vývojáři chtějí své oblíbené Visual Studio, TFS s automatickými testy pro sestavení a smoothies. Není pro ně důležité, jak probíhá dodávka do výroby. Proto jsme se rozhodli neměnit běžný postup a nechat vše beze změny pro vývoj Windows.

Je potřeba nový projekt integrovat do stávající CI. Kolejnice tam již byly a veškerá práce musela být provedena s ohledem na parametry systému řízení konfigurace, přijaté standardy dodávek a monitorovací systémy.

Snadná obsluha a podpora, jako podmínka pro minimální vstupní práh pro všechny nové účastníky z různých divizí a oddělení podpory.

Termín - včera.

Win Development Group

S čím tým Windows tehdy pracoval?

.NET Core na Linuxu, DevOps na koni

Nyní to mohu s jistotou říci IdentityServer4 je skvělá bezplatná alternativa k ADFS s podobnými schopnostmi nebo co Jádro Entity Framework - ráj pro vývojáře, kde se nemusíte obtěžovat psaním SQL skriptů, ale popisovat dotazy v databázi v termínech OOP. Ale pak, během diskuse o akčním plánu, jsem se na tento zásobník podíval, jako by to bylo sumerské klínové písmo, rozpoznával jsem pouze PostgreSQL a Git.

V té době jsme aktivně využívali Loutka jako systém pro správu konfigurace. Ve většině našich projektů jsme použili GitLab CI, Elastický, vyvážené služby s vysokou zátěží pomocí HAProxy vše sledoval Zabbix, vazy grafana и Prometheus, Mořský ptáka to vše se točilo na kusech železa HPESXi na VMware. Každý to zná - klasika žánru.

.NET Core na Linuxu, DevOps na koni

Podívejme se a pokusme se porozumět tomu, co se stalo, než jsme začali se všemi těmito zásahy.

Co se stalo

TFS je poměrně výkonný systém, který nejen dodává kód od vývojáře do finálního produkčního stroje, ale má také sadu pro velmi flexibilní integraci s různými službami – pro poskytování CI na multiplatformní úrovni.

.NET Core na Linuxu, DevOps na koni
Dříve to byla pevná okna. TFS používal několik Build agentů, které byly použity k sestavení mnoha projektů. Každý agent má 3–4 pracovníky pro paralelizaci úkolů a optimalizaci procesu. Poté, podle plánů vydání, TFS dodal čerstvě upečený Build na aplikační server Windows.

Čeho jsme chtěli dosáhnout?

K doručování a vývoji používáme TFS a spouštíme aplikaci na aplikačním serveru Linux a mezi nimi je nějaké kouzlo. Tento Magic Box a před námi je sůl práce. Než to rozeberu, udělám krok stranou a řeknu pár slov o aplikaci.

projekt

Aplikace poskytuje funkce pro manipulaci s předplacenými kartami.

.NET Core na Linuxu, DevOps na koni

Klient

Existovaly dva typy uživatelů. První získal přístup přihlášením pomocí certifikátu SSL SHA-2. U druhý byl přístup pomocí přihlašovacího jména a hesla.

HAProxy

Poté požadavek klienta šel do HAProxy, který vyřešil následující problémy:

  • primární oprávnění;
  • ukončení SSL;
  • ladění požadavků HTTP;
  • požadavky na vysílání.

Klientský certifikát byl ověřen v řetězci. My - autorita a můžeme si to dovolit, protože sami vydáváme certifikáty servisním klientům.

Věnujte pozornost třetímu bodu, vrátíme se k němu o něco později.

backend

Plánovali vytvořit backend na Linuxu. Backend interaguje s databází, načte potřebný seznam oprávnění a poté podle toho, jaká oprávnění má oprávněný uživatel, poskytne přístup k podepisování finančních dokumentů a jejich odeslání k provedení nebo vygeneruje nějaký druh zprávy.

Úspory s HAProxy

Kromě dvou kontextů, kterými se každý klient pohyboval, existoval také kontext identity. IdentityServer4 jen vám umožní přihlásit se, toto je bezplatný a výkonný analog pro ADFS - Federační služby Active Directory.

Žádost o identitu byla zpracována v několika krocích. První krok - zákazník se dostal do backendu, který komunikoval s tímto serverem a kontroloval přítomnost tokenu pro klienta. Pokud nebyl nalezen, byl požadavek vrácen zpět do kontextu, ze kterého přišel, ale s přesměrováním a s přesměrováním přešel na identitu.

Druhý krok – žádost byla přijata na autorizační stránku na IdentityServer, kde se klient zaregistroval a tento dlouho očekávaný token se objevil v databázi IdentityServer.

Třetí krok - klient byl přesměrován zpět do kontextu, ze kterého pochází.

.NET Core na Linuxu, DevOps na koni

IdentityServer4 má funkci: vrátí odpověď na požadavek na návrat přes HTTP. Bez ohledu na to, jak moc jsme se potýkali s nastavením serveru, bez ohledu na to, jak moc jsme se osvětlili v dokumentaci, pokaždé, když jsme obdrželi počáteční požadavek klienta s URL, která přišla přes HTTPS, a IdentityServer vrátil stejný kontext, ale s HTTP. Byli jsme v šoku! A to vše jsme přenesli přes identitní kontext do HAProxy a v hlavičkách jsme museli upravit HTTP protokol na HTTPS.

Jaké je zlepšení a kde jste ušetřili?

Ušetřili jsme peníze použitím bezplatného řešení pro autorizaci skupiny uživatelů, zdrojů, protože jsme IdentityServer4 neumístili jako samostatný uzel do samostatného segmentu, ale použili jsme jej společně s backendem na stejném serveru, kde běží backend aplikace. .

Jak by to mělo fungovat

Takže, jak jsem slíbil - Magic Box. Už chápeme, že se zaručeně posuneme k Linuxu. Formulujme konkrétní úkoly, které vyžadovaly řešení.

.NET Core na Linuxu, DevOps na koni

Loutka manifestuje. Aby bylo možné dodávat a spravovat konfiguraci služeb a aplikací, musely být napsány skvělé recepty. Svitek tužky výmluvně ukazuje, jak rychle a efektivně to bylo provedeno.

Způsob doručení. Standardem jsou otáčky za minutu. Každý chápe, že v Linuxu se bez něj neobejdete, ale samotný projekt byl po sestavení souborem spustitelných souborů DLL. Bylo jich asi 150, projekt byl dost náročný. Jediným harmonickým řešením je zabalit tento binární soubor do RPM a nasadit aplikaci z něj.

Verzování. Museli jsme vydávat velmi často a museli jsme se rozhodnout, jak vytvořit název balíčku. To je otázka úrovně integrace s TFS. Měli jsme build agenta na Linuxu. Když TFS odešle úkol na handler – worker – agentovi Build, předá mu také spoustu proměnných, které skončí v prostředí procesu handleru. Tyto proměnné prostředí obsahují název sestavení, název verze a další proměnné. Přečtěte si o tom více v části „Vytvoření balíčku RPM“.

Nastavení TFS přistoupil k nastavení Pipeline. Dříve jsme shromažďovali všechny projekty Windows na agentech Windows, ale nyní se objevuje agent Linux - agent Build, kterého je třeba zahrnout do skupiny sestavení, obohatit o některé artefakty a sdělit, jaký typ projektů bude postaven na tomto agentovi Build. a nějak upravit Pipeline.

IdentityServer. ADFS není naše cesta, jdeme na Open Source.

Pojďme si projít komponenty.

Magic Box

Skládá se ze čtyř částí.

.NET Core na Linuxu, DevOps na koni

Linux Build agent. Linux, protože pro něj stavíme – je to logické. Tato část byla provedena ve třech krocích.

  • Nakonfigurujte pracovníky a ne sám, protože se očekávala distribuovaná práce na projektu.
  • Nainstalujte .NET Core 1.x. Proč 1.x, když 2.0 je již k dispozici ve standardním úložišti? Protože když jsme začali s vývojem, stabilní verze byla 1.09 a bylo rozhodnuto vytvořit projekt na jejím základě.
  • Git 2.x.

RPM-úložiště. RPM balíčky bylo potřeba někde uložit. Předpokládalo se, že budeme používat stejné podnikové úložiště RPM, které je dostupné všem hostitelům Linuxu. Tak to udělali. Server úložiště je nakonfigurován webový háček který stáhl požadovaný RPM balíček ze zadaného umístění. Verzi balíčku nahlásil webhooku agent Build.

GitLab. Pozornost! GitLab zde nepoužívají vývojáři, ale provozní oddělení ke kontrole verzí aplikací, verzí balíčků, sledování stavu všech linuxových strojů a ukládá recept - všechny manifesty Puppet.

Loutka — řeší všechny kontroverzní problémy a poskytuje přesně takovou konfiguraci, jakou od Gitlabu požadujeme.

Začínáme se potápět. Jak funguje doručení DLL do RPM?

Doručení DDL do RPM

Řekněme, že máme vývojářskou rockovou hvězdu .NET. Používá Visual Studio a vytváří větev vydání. Poté to nahraje do Gitu a Git je zde entita TFS, to znamená, že je to úložiště aplikací, se kterým vývojář pracuje.

.NET Core na Linuxu, DevOps na koni

Poté TFS vidí, že přišel nový commit. Která aplikace? V nastavení TFS je štítek udávající, jaké prostředky má konkrétní agent sestavování. V tomto případě vidí, že budujeme projekt .NET Core, a vybere z fondu agenta Linux Build.

Agent sestavení obdrží zdroje a stáhne potřebné Závislostí z úložiště .NET, npm atd. a po sestavení samotné aplikace a následném zabalení odešle RPM balíček do RPM úložiště.

Na druhou stranu se stane následující. Inženýr provozního oddělení je přímo zapojen do zavádění projektu: mění verze balíčků Hiera v úložišti, kde je uložen recept aplikace, po kterém se spustí Puppet Yum, načte nový balíček z úložiště a nová verze aplikace je připravena k použití.

.NET Core na Linuxu, DevOps na koni

Všechno je jednoduché slovy, ale co se děje uvnitř samotného agenta Build?

Packaging DLL RPM

Přijaté zdroje projektu a úkol sestavení z TFS. Sestavit agenta začíná budovat samotný projekt ze zdrojů. Sestavený projekt je k dispozici jako sada DLL soubory, které jsou zabaleny v archivu zip, aby se snížilo zatížení systému souborů.

ZIP archiv se vyhodí do adresáře sestavení balíčku RPM. Dále skript Bash inicializuje proměnné prostředí, najde verzi sestavení, verzi projektu, cestu k adresáři sestavení a spustí RPM-build. Po dokončení sestavení je balíček publikován na místní úložiště, který se nachází na agentu Build.

Dále z agenta Build na server v úložišti RPM Požadavek JSON je odeslán s uvedením názvu verze a sestavení. Webhook, o kterém jsem mluvil dříve, stáhne právě tento balíček z místního úložiště na agentovi Build a zpřístupní nové sestavení k instalaci.

.NET Core na Linuxu, DevOps na koni

Proč toto konkrétní schéma doručování balíčků do úložiště RPM? Proč nemohu okamžitě odeslat sestavený balíček do úložiště? Faktem je, že je to podmínka pro zajištění bezpečnosti. Tento scénář omezuje možnost neoprávněných osob nahrávat balíčky RPM na server, který je přístupný všem počítačům se systémem Linux.

Verze databáze

Na konzultaci s vývojářským týmem se ukázalo, že kluci mají blíž k MS SQL, ale ve většině projektů mimo Windows jsme už s vypětím všech sil používali PostgreSQL. Protože jsme se již rozhodli opustit vše placené, začali jsme používat PostgreSQL i zde.

.NET Core na Linuxu, DevOps na koni

V této části vám chci říci, jak jsme verzovali databázi a jak jsme se rozhodovali mezi Flyway a Entity Framework Core. Pojďme se podívat na jejich klady a zápory.

Zápory

Flyway jede jen jedním směrem, my nemůžeme se vrátit zpět - to je značná nevýhoda. S Entity Framework Core to můžete porovnat i jinak – pokud jde o pohodlí pro vývojáře. Pamatujete si, že jsme to postavili do popředí a hlavním kritériem bylo neměnit nic pro vývoj Windows.

Pro nás Flyway byl potřeba nějaký obalaby kluci nepsali SQL dotazy. Jsou mnohem blíže fungování v podmínkách OOP. Sepsali jsme instrukce pro práci s databázovými objekty, vygenerovali SQL dotaz a provedli jej. Nová verze databáze je připravena, otestována - vše v pořádku, vše funguje.

Entity Framework Core má mínus - při velkém zatížení vytváří suboptimální SQL dotazya čerpání v databázi může být značné. Protože ale nemáme službu s vysokou zátěží, nepočítáme zátěž ve stovkách RPS, přijali jsme tato rizika a delegovali problém na nás budoucí.

Pros

Jádro Entity Framework funguje po vybalení z krabice a snadno se vyvíjía Flyway Snadno se integruje do stávající CI. Ale děláme to pohodlné pro vývojáře :)

Postup srolování

Puppet vidí, že se blíží změna verze balíčku, včetně té, která je zodpovědná za migraci. Nejprve nainstaluje balíček, který obsahuje migrační skripty a funkce související s databází. Poté se aplikace, která pracuje s databází, restartuje. Následuje instalace zbývajících komponent. Pořadí, ve kterém jsou balíčky instalovány a aplikace spouštěny, je popsáno v manifestu Puppet.

Aplikace používají citlivá data, jako jsou tokeny, hesla k databázím, to vše se stahuje do konfigurace z Puppet master, kde jsou uloženy v zašifrované podobě.

Problémy s TFS

Poté, co jsme se rozhodli a uvědomili si, že nám všechno opravdu funguje, rozhodl jsem se podívat na to, co se děje se sestavami v TFS jako celku pro vývojové oddělení Win na jiných projektech – ať už jsme stavěli/uvolňovali rychle nebo ne, a objevil značné problémy s rychlostí.

Sestavení jednoho z hlavních projektů trvá 12–15 minut – to je dlouhá doba, takhle se žít nedá. Rychlá analýza ukázala hrozné snížení I/O, a to na polích.

Po analýze komponent po komponentě jsem identifikoval tři ohniska. První - "Kaspersky antivirus", který kontroluje zdroje na všech agentech Windows Build. Druhý - Windows Indexer. Nebylo deaktivováno a vše bylo indexováno v reálném čase na agentech Build během procesu nasazení.

Třetí - Instalace Npm. Ukázalo se, že ve většině Pipeline jsme použili přesně tento scénář. Proč je špatný? Instalační procedura Npm se spustí, když se vytvoří strom závislostí balíček-lock.json, kde jsou zaznamenány verze balíčků, které budou použity k sestavení projektu. Nevýhodou je, že Npm install pokaždé stáhne nejnovější verze balíčků z internetu, což v případě velkého projektu zabere spoustu času.

Vývojáři někdy experimentují na místním počítači, aby otestovali, jak konkrétní část nebo celý projekt funguje. Někdy se ukázalo, že lokálně je vše v pohodě, ale oni to smontovali, vyváleli a nic nefungovalo. Začínáme zjišťovat, v čem je problém - ano, různé verze balíčků se závislostmi.

rozhodnutí

  • Zdroje ve výjimkách AV.
  • Zakázat indexování.
  • Jít do npm ci.

Výhody npm ci jsou v tom, že my Shromažďujeme strom závislostí jednou, a dostaneme příležitost poskytnout developerovi aktuální seznam balíčků, se kterou může lokálně experimentovat, jak se mu zlíbí. Tento šetří čas vývojáři, kteří píší kód.

Konfigurace

Nyní něco málo o konfiguraci úložiště. Historicky používáme Nexus pro správu úložišť, včetně Interní REPO. Toto interní úložiště obsahuje všechny komponenty, které používáme pro interní účely, např. vlastní monitorování.

.NET Core na Linuxu, DevOps na koni

Také používáme NuGet, protože má lepší ukládání do mezipaměti ve srovnání s jinými správci balíčků.

Výsledek

Poté, co jsme optimalizovali sestavovací agenty, se průměrná doba sestavování zkrátila z 12 minut na 7.

Pokud spočítáme všechny stroje, které jsme mohli použít pro Windows, ale v tomto projektu jsme přešli na Linux, ušetřili jsme asi $ 10 000. A to jen na licencích a více, pokud vezmeme v úvahu obsah.

Plány

Na další čtvrtletí jsme plánovali pracovat na optimalizaci doručování kódu.

Přepnutí na předem sestavený obraz Dockeru. TFS je skvělá věc s mnoha zásuvnými moduly, které vám umožňují integraci do Pipeline, včetně sestavení, řekněme, obrazu Dockeru na základě triggeru. Chceme vytvořit tento spouštěč pro stejný balíček-lock.json. Pokud se složení komponent použitých k sestavení projektu nějak změní, vytvoříme nový obraz Dockeru. Později se použije k nasazení kontejneru se sestavenou aplikací. Nyní tomu tak není, ale plánujeme přechod na mikroservisní architekturu v Kubernetes, která se v naší společnosti aktivně rozvíjí a dlouhodobě slouží produkčním řešením.

Shrnutí

Doporučuji všem, aby Windows zahodili, ale není to proto, že bych je neuměl vařit. Důvodem je většina Opensource řešení Linuxový zásobník. jsi v pořádku ušetřit na zdrojích. Podle mého názoru patří budoucnost Open Source řešením na Linuxu se silnou komunitou.

Profil řečníka Alexandra Sinčinova na GitHubu.

DevOps Conf je konference o integraci vývojových, testovacích a provozních procesů pro profesionály profesionály. Proto ten projekt, o kterém Alexander mluvil? implementován a funkční a v den představení došlo ke dvěma úspěšným vydáním. Na DevOps Conf ve společnosti RIT++ 27. a 28. května bude podobných případů od praktiků ještě více. Ještě můžete naskočit do posledního kočáru a podat zprávu nebo si dejte na čas zarezervovat lístek. Seznamte se s námi ve Skolkovo!

Zdroj: www.habr.com

Přidat komentář