{"id":32217,"date":"2019-10-31T21:45:43","date_gmt":"2019-10-31T18:45:43","guid":{"rendered":"https:\/\/prohoster.info\/blog\/net-core-na-linux-devops-na-kone\/"},"modified":"2019-10-31T21:45:43","modified_gmt":"2019-10-31T18:45:43","slug":"net-core-na-linux-devops-na-kone","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","title":{"rendered":".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Vi utvecklade DevOps s\u00e5 gott vi kunde. Vi var \u00e5tta personer, och Vasja var den mest kompetenta n\u00e4r det kom till Windows. Pl\u00f6tsligt l\u00e4mnade Vasja, och jag fick i uppdrag att driva ett nytt projekt som levererar Windows-utveckling. N\u00e4r jag la ut hela Windows-utvecklingsstacken p\u00e5 bordet ins\u00e5g jag att situationen var problematisk...<\/p>\n<p>S\u00e5 h\u00e4r b\u00f6rjar historien <b>Alexandra Sinchinova<\/b> till <noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOpsConf<\/a><\/noindex>. N\u00e4r den ledande Windows-specialisten l\u00e4mnade f\u00f6retaget st\u00e4llde Alexandra sig fr\u00e5gan vad hon skulle g\u00f6ra nu. Sj\u00e4lvklart skulle hon byta till Linux! Alexandra kommer att ber\u00e4tta hur hon lyckades skapa ett prejudikat och flytta en del av Windows-utvecklingen till Linux med exemplet av ett genomf\u00f6rt projekt med 100 000 slutanv\u00e4ndare.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/3c944351864df95217e133236542c9b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHur kan man enkelt och smidigt leverera ett projekt i RPM med TFS, Puppet och Linux .NET core? Hur uppr\u00e4tth\u00e5ller man versionering av projektets databas om utvecklarna h\u00f6r f\u00f6r f\u00f6rsta g\u00e5ngen ord som Postgres och Flyway, och deadline \u00e4r om tv\u00e5 dagar? Hur integrerar man med Docker? Hur motiverar man .NET-utvecklare att avst\u00e5 fr\u00e5n Windows och smoothies till f\u00f6rm\u00e5n f\u00f6r Puppet och Linux? Hur l\u00f6ser man ideologiska konflikter n\u00e4r man inte har varken kraft, vilja eller resurser att st\u00f6dja Windows i produktion? Om detta, liksom Web Deploy, testning, CI, praktiker f\u00f6r att anv\u00e4nda TFS i befintliga projekt och sj\u00e4lvklart om brutna kryckor och fungerande l\u00f6sningar, i Alexandra's presentation.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<center><div class=\"youtube-placeholder\" data-id=\"tZH9Ro9j9KQ\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/tZH9Ro9j9KQ\/hqdefault.jpg\" alt=\"Spela video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nS\u00e5, Vasja hade l\u00e4mnat, uppgiften l\u00e5g p\u00e5 mig, utvecklarna v\u00e4ntade ot\u00e5ligt med gafflar. N\u00e4r jag till slut ins\u00e5g att jag inte kunde f\u00e5 tillbaka Vasja, satte jag ig\u00e5ng med arbetet. F\u00f6rst bed\u00f6mde jag andelen Win VM i v\u00e5r park. Resultatet var inte till Windows f\u00f6rdel.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/836e47372126b6ba369ac494b91c7d3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEftersom vi aktivt utvecklar DevOps ins\u00e5g jag att n\u00e5got m\u00e5ste f\u00f6r\u00e4ndras i tillv\u00e4gag\u00e5ngss\u00e4ttet f\u00f6r att flytta det nya programmet. L\u00f6sningen var att s\u00e5 mycket som m\u00f6jligt \u00f6verf\u00f6ra allt till Linux. Google hj\u00e4lpte mig \u2013 vid den tidpunkten fanns redan .Net porterat till Linux, och jag ins\u00e5g att det var l\u00f6sningen!<\/p>\n<h2>Varf\u00f6r .NET core i kombination med Linux?<\/h2>\n<p>\nDet fanns flera anledningar. Mellan \"att betala pengar\" och \"inte betala\" v\u00e4ljer de flesta det andra \u2013 precis som jag. Licensen f\u00f6r MSDB kostar cirka 1 000 $, och underh\u00e5llet av m\u00e4ngden Windows virtuella maskiner kostar hundratals dollar. F\u00f6r ett stort f\u00f6retag \u00e4r det stora utgifter. S\u00e5 d\u00e4rf\u00f6r <b>besparing\u00a0<\/b>\u2014<b> \u00e4r den f\u00f6rsta anledningen<\/b>. Det \u00e4r inte den viktigaste, men en av de betydande.<\/p>\n<p>Windows virtuell maskiner kr\u00e4ver mer resurser \u00e4n deras Linux-syskon \u2013 <b>de \u00e4r tunga<\/b>. Med tanke p\u00e5 storleken p\u00e5 ett stort f\u00f6retag valde vi Linux.<\/p>\n<p><b>Systemet integreras enkelt i den befintliga CI<\/b>. Vi ser oss sj\u00e4lva som progressiva DevOps:are, anv\u00e4nder Bamboo, Jenkins och GitLab CI, s\u00e5 d\u00e4rf\u00f6r k\u00f6rs det mesta av oss p\u00e5 Linux.<\/p>\n<p>Den sista anledningen \u00e4r <b>bekv\u00e4m support. <\/b>Vi beh\u00f6vde s\u00e4nka tr\u00f6skeln f\u00f6r \"supportarna\" - de som f\u00f6rst\u00e5r den tekniska delen, s\u00e4kerst\u00e4ller drift och underh\u00e5ller tj\u00e4nster med andra linjen. De var redan bekanta med Linux-stacken, s\u00e5 det var mycket l\u00e4ttare f\u00f6r dem att f\u00f6rst\u00e5 den nya produkten, st\u00f6dja och underh\u00e5lla den, \u00e4n att spendera extra resurser p\u00e5 att f\u00f6rst\u00e5 motsvarande funktionalitet av en programvara f\u00f6r Windows-plattformen.<\/p>\n<h2>Krav<\/h2>\n<p>\nF\u00f6rsta och fr\u00e4msta \u00e4r <b>bekv\u00e4mligheten med den nya l\u00f6sningen f\u00f6r utvecklarna<\/b>. Inte alla av dem var redo f\u00f6r f\u00f6r\u00e4ndringar, s\u00e4rskilt efter att ha h\u00f6rt ordet Linux. Utvecklare vill ha sin \u00e4lskade Visual Studio, TFS med automatiserade tester f\u00f6r byggen och smoothies. Hur leveransen g\u00e5r till produktion bryr de sig inte om. D\u00e4rf\u00f6r beslutade vi att inte \u00e4ndra den vanliga processen och beh\u00e5lla allt of\u00f6r\u00e4ndrat f\u00f6r Windows-utvecklingen. <\/p>\n<p>Nytt projekt m\u00e5ste <b>integreras i den befintliga CI<\/b>. Rails fanns redan och allt arbete m\u00e5ste genomf\u00f6ras med h\u00e4nsyn till konfigurationshanteringssystemets parametrar, antagna leveransstandarder och \u00f6vervakningssystem.<\/p>\n<p><b>Enkelhet i support och drift<\/b>, som ett villkor f\u00f6r en minimal ing\u00e5ngstr\u00f6skel f\u00f6r alla nya deltagare fr\u00e5n olika avdelningar och supportavdelningen.<\/p>\n<p><b>Deadline \u2013 ig\u00e5r<\/b>.<\/p>\n<h2>Windows-utvecklingsgruppen<\/h2>\n<p>\nVad arbetade d\u00e5 Windows-teamet med?<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/6e6e128ef3d49410c260d05114f819a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNu kan jag s\u00e4kert s\u00e4ga att <b>IdentityServer4<\/b>\u00a0\u2013 det \u00e4r ett fantastiskt gratis alternativ till ADFS med liknande m\u00f6jligheter, eller att <b>Entity Framework Core<\/b>\u00a0\u2013 \u00e4r en dr\u00f6m f\u00f6r utvecklare, d\u00e4r man kan slippa skriva SQL-skript och ist\u00e4llet beskriva fr\u00e5gor i databasen i termer av OOP. Men d\u00e5, under diskussionen om handlingsplanen, s\u00e5g jag p\u00e5 den h\u00e4r stacken som p\u00e5 sumerisk kilskrift och k\u00e4nde bara igen PostgreSQL och Git.<\/p>\n<p>Vid den tiden anv\u00e4nde vi aktivt <b>Puppet<\/b> som konfigurationshanteringssystem. I de flesta av v\u00e5ra projekt anv\u00e4nde vi <b>GitLab CI<\/b>, <b>Elastic<\/b>, balanserade h\u00f6gbelastade tj\u00e4nster med hj\u00e4lp av <b>HAProxy,<\/b> h\u00f6ll koll p\u00e5 allt med hj\u00e4lp av <b>Zabbix<\/b>, kombinationen <b>Grafana<\/b> och\u00a0<b>Prometheus<\/b>, <b>Jaeger<\/b>, och allt detta k\u00f6rdes p\u00e5 maskiner\u00a0<b>HP<\/b> c\u00a0<b>ESXi<\/b> till\u00a0<b>VMware<\/b>. Vem k\u00e4nner inte till \u2013 klassikern.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/f4ffcac7a7fbb4fa48d47f07bed52610.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nL\u00e5t oss titta p\u00e5 och f\u00f6rs\u00f6ka f\u00f6rst\u00e5 vad som h\u00e4nde innan vi p\u00e5b\u00f6rjade alla dessa ingrepp.<\/p>\n<h2>Vad h\u00e4nde<\/h2>\n<p>\nTFS \u00e4r ett ganska kraftfullt system som inte bara levererar kod fr\u00e5n utvecklaren till den slutliga produktionsmaskinen, utan \u00e4ven har en upps\u00e4ttning f\u00f6r mycket flexibel integration med olika tj\u00e4nster f\u00f6r att s\u00e4kerst\u00e4lla CI p\u00e5 plattforms\u00f6vergripande niv\u00e5.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/ea448b38e321a8350468d69f3e45e429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nTidigare var det bara f\u00f6nster. TFS anv\u00e4nde flera byggagenter d\u00e4r m\u00e5nga projekt samlades. I varje agent fanns det 3-4 arbetare f\u00f6r att parallellisera uppgifter och optimera processen. D\u00e4refter, enligt releaseplanerna, levererade TFS den nybakade bygget till Windows-applikationsservern.<\/p>\n<h2>Vad ville vi uppn\u00e5<\/h2>\n<p>\nF\u00f6r leverans och utveckling anv\u00e4nder vi TFS, och vi k\u00f6r applikationen p\u00e5 Linux-applikationsserver, och mellan dem finns n\u00e5gon slags magi. Den <b>Magic Box<\/b> \u00e4r sj\u00e4lva k\u00e4rnan i det kommande arbetet. Innan vi g\u00e5r in i detaljerna, l\u00e5t mig ta ett steg \u00e5t sidan och s\u00e4ga n\u00e5gra ord om applikationen.<\/p>\n<h2>Projektet<\/h2>\n<p>\nApplikationen tillhandah\u00e5ller funktionalitet f\u00f6r att hantera f\u00f6rbetalda kort. <\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/c93aa67b340c45ad279330466fc4f776.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Client<\/h3>\n<p>\nDet fanns tv\u00e5 typer av anv\u00e4ndare. <b>F\u00f6rsta<\/b> fick tillg\u00e5ng genom att autentisera med ett SSL-certifikat SHA-2. Han\u00a0<b>den andra<\/b> hade tillg\u00e5ng med inloggning och l\u00f6senord.<\/p>\n<h3>HAProxy<\/h3>\n<p>\nSedan skickades klientens beg\u00e4ran till HAProxy, som l\u00f6ste f\u00f6ljande uppgifter:<\/p>\n<ul>\n<li>prim\u00e4r autentisering;\n<\/li>\n<li>terminering av SSL;\n<\/li>\n<li>justering av HTTP-beg\u00e4rningar;\n<\/li>\n<li>\u00f6vers\u00e4ttning av beg\u00e4rningar.\n<\/li>\n<\/ul>\n<p>\nKontroll av klientens certifikat skedde genom en kedja. Vi \u00e4r <b>authority <\/b>och vi kan till\u00e5ta oss detta, eftersom vi sj\u00e4lva utf\u00e4rdar certifikat till tj\u00e4nsteanv\u00e4ndarna.<\/p>\n<p>Var uppm\u00e4rksam p\u00e5 den tredje punkten, vi \u00e5terkommer till den senare.<\/p>\n<h3>Backend<\/h3>\n<p>\nBackend var planerat att g\u00f6ras p\u00e5 Linux. Backend interagerar med databasen, laddar den n\u00f6dv\u00e4ndiga listan med beh\u00f6righeter och sedan, beroende p\u00e5 vilka beh\u00f6righeter den autentiserade anv\u00e4ndaren har, erbjuder tillg\u00e5ng f\u00f6r att signera finansiella dokument och skicka dem till utf\u00f6rande, eller f\u00f6r att generera n\u00e5gon form av rapport.<\/p>\n<h2>Besparingar med HAProxy<\/h2>\n<p>\nF\u00f6rutom de tv\u00e5 kontexter som varje klient passerade genom, fanns det ocks\u00e5 en kontext f\u00f6r identitet. <b>IdentityServer4<\/b> som just m\u00f6jligg\u00f6r autentisering, detta \u00e4r ett gratis och starkt alternativ till <b>ADFS\u00a0<\/b>\u2014<b> Active Directory Federation Services<\/b>.<\/p>\n<p>Beg\u00e4ran i identiteten bearbetades i flera steg. F\u00f6rsta steget - <b>klient<\/b> <b>hamnade i backend<\/b>, som utbytte data med denna server och kontrollerade f\u00f6rekomsten av en token f\u00f6r kunden. Om den inte hittades - f\u00f6rfr\u00e5gan skickades tillbaka till den kontext fr\u00e5n vilken den kom, men redan med en omdirigering, och med omdirigeringen gick till identity.<\/p>\n<p>Andra steget - f\u00f6rfr\u00e5gan kom <b>till inloggningssidan i IdentityServer,<\/b> d\u00e4r kunden registrerade sig, och i databasen f\u00f6r IdentityServer d\u00f6k den efterl\u00e4ngtade token upp. <\/p>\n<p>Tredje steget - <b>kunden omdirigerades tillbaka <\/b>till den kontext som han kom ifr\u00e5n.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/e052c408d67485ab9aa10d0fd25df57e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIdentityServer4 har en egenskap: <b>svaret p\u00e5 den omv\u00e4nda f\u00f6rfr\u00e5gan returneras via HTTP<\/b>. Oavsett hur vi k\u00e4mpade med serverinst\u00e4llningen, oavsett hur mycket vi l\u00e4ste dokumentationen, s\u00e5 fick vi varje g\u00e5ng den ursprungliga f\u00f6rfr\u00e5gan fr\u00e5n kunden med en URL som kom via HTTPS, medan IdentityServer returnerade samma kontext, men med HTTP. Vi var i chock! Och vi \u00f6versatte allt detta genom identity-kontexten p\u00e5 HAProxy, och i headers m\u00e5ste vi modifiera protokollet fr\u00e5n HTTP till HTTPS. <\/p>\n<p>Vad \u00e4r f\u00f6rb\u00e4ttringen och var sparade vi?<\/p>\n<blockquote><p>Vi sparade pengar genom att anv\u00e4nda en gratis l\u00f6sning f\u00f6r autentisering av gruppanv\u00e4ndare, resurser, eftersom vi inte flyttade IdentityServer4 som en separat nod till ett separat segment, utan anv\u00e4nde det tillsammans med backend p\u00e5 samma server d\u00e4r applikationens backend k\u00f6rs.<\/p><\/blockquote>\n<p><\/p>\n<h2>Hur det borde fungera<\/h2>\n<p>\nS\u00e5, som jag lovade - Magic Box. Vi f\u00f6rst\u00e5r redan att vi garanterat r\u00f6r oss mot Linux. L\u00e5t oss formulera specifika uppgifter som kr\u00e4vde l\u00f6sning.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/cc59632aa0e5c65fe0efc754311ecf5e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Puppet-manifest. <\/b>F\u00f6r att leverera och hantera konfigurationen av tj\u00e4nsten och applikationen beh\u00f6vde vi skriva fantastiska recept. En rullande med en penna visar tydligt hur snabbt och kvalitativt detta gjordes.<\/p>\n<p><b>Leveransmetod. <\/b>Standarden \u00e4r RPM. Alla f\u00f6rst\u00e5r att utan den kan man inte hantera Linux, men sj\u00e4lva projektet efter bygget bestod av ett antal k\u00f6rbara DLL-filer. Det var omkring 150, projektet \u00e4r ganska tungt. Den enda harmoniska l\u00f6sningen \u00e4r att paketera denna bin\u00e4rfil i RPM och redan fr\u00e5n den distribuera applikationen.<\/p>\n<p><b>Versionshantering. <\/b>Vi skulle g\u00f6ra utg\u00e5vor v\u00e4ldigt ofta, och vi beh\u00f6vde best\u00e4mma hur vi skulle skapa paketnamnet. Detta \u00e4r en fr\u00e5ga p\u00e5 integrationsniv\u00e5 med TFS. Byggagenten k\u00f6rdes p\u00e5 Linux. N\u00e4r TFS skickar en uppgift till behandlaren \u2014 worker \u2014 p\u00e5 byggagenten, vidarebefordrar den ocks\u00e5 en samling variabler som hamnar i processens milj\u00f6. I dessa milj\u00f6variabler skickas namn p\u00e5 bygget, versionsnamn och andra variabler. Mer om detta i avsnittet \"bygga RPM-paket\".<\/p>\n<p><b>TFS-inst\u00e4llning<\/b> bestod av att konfigurera Pipeline. Tidigare samlade vi alla Windows-projekt p\u00e5 Windows-agenter, men nu l\u00e4ggs en Linux-agent \u2014 byggagenten \u2014 till i bygggruppen, vilket m\u00e5ste berikas med vissa artefakter, s\u00e4ga vilken typ av projekt som ska byggas p\u00e5 denna byggagent och p\u00e5 n\u00e5got s\u00e4tt modifiera Pipeline.<\/p>\n<p><b>IdentityServer. <\/b>ADFS \u00e4r inte v\u00e5r v\u00e4g, vi satsar p\u00e5 Open Source.<\/p>\n<p>L\u00e5t oss titta p\u00e5 komponenterna.<\/p>\n<h2>Magic Box<\/h2>\n<p>\nDen best\u00e5r av fyra delar.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/22ea63bcf184046c15e034ec093352bb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Linux byggagent. <\/b>Linux, eftersom vi bygger f\u00f6r det \u2014 det \u00e4r logiskt. Denna del utf\u00f6rdes i tre steg.<\/p>\n<ul>\n<li><b>Konfigurera workers<\/b> och inte bara en, eftersom distribuerat arbete antogs f\u00f6r projektet.\n<\/li>\n<li><b>Installera .NET Core 1.x<\/b>. Varf\u00f6r just 1.x, n\u00e4r 2.0 redan \u00e4r tillg\u00e4nglig i standardrepositoryt? Eftersom n\u00e4r vi b\u00f6rjade utvecklingen var den stabila versionen 1.09, och projektet beslutades att g\u00f6ras f\u00f6r den.\n<\/li>\n<li><b>Git 2.x<\/b>.\n<\/li>\n<\/ul>\n<p>\n<b>RPM-repository. <\/b>RPM-paketen beh\u00f6vde lagras n\u00e5gonstans. Det antogs att vi skulle anv\u00e4nda samma f\u00f6retags RPM-repository som \u00e4r tillg\u00e4ngligt f\u00f6r alla Linux-v\u00e4rdar. S\u00e5 gjordes det. P\u00e5 servern f\u00f6r repositoryt \u00e4r det konfigurerat <b>webhook<\/b> som laddade ner det n\u00f6dv\u00e4ndiga RPM-paketet fr\u00e5n den angivna platsen. Byggagent meddelade versionen av paketet till webhook.<\/p>\n<p><b>GitLab. <\/b>Observera! GitLab anv\u00e4nds h\u00e4r inte av utvecklarna, utan av driftavdelningen f\u00f6r versionskontroll av applikationen, versionskontroll av paketen, \u00f6vervakning av alla Linux-maskinvaror och i den lagras receptet \u2014 alla Puppet-manifest. <\/p>\n<p><b>Puppet<\/b>\u00a0\u2014 l\u00f6ser alla tvistiga fr\u00e5gor och levererar just den konfiguration vi vill ha, fr\u00e5n Gitlab.<\/p>\n<p>Vi b\u00f6rjar dyka in. Hur sker leveransen av DLL till RPM?<\/p>\n<h3>Leveransen av DLL till RPM<\/h3>\n<p>\nAnta att vi har en rockstj\u00e4rna inom utveckling p\u00e5 .NET. Han anv\u00e4nder Visual Studio och skapar en release-gren. Efter det laddar han upp den till Git, och Git h\u00e4r \u00e4r en TFS-entitet, det vill s\u00e4ga detta \u00e4r applikationens repository som utvecklaren arbetar med.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/978240886981d41fc6d7b17d0a4fcb05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEfter vilket TFS ser att en ny commit har kommit. Vilket program? I TFS-inst\u00e4llningarna finns en m\u00e4rkning av vilka resurser varje Build-agent har. I det h\u00e4r fallet ser den att vi bygger ett .NET Core-projekt och v\u00e4ljer en Linux Build-agent fr\u00e5n poolen. <\/p>\n<p>Build-agenten h\u00e4mtar k\u00e4llkoden, laddar ner n\u00f6dv\u00e4ndiga <b>dependencies<\/b> fr\u00e5n .NET-repositoriet, npm, etc. och efter byggandet av sj\u00e4lva applikationen och den efterf\u00f6ljande paketeringen skickar den RPM-paketet till RPM-repositoriet.<\/p>\n<p>\u00c5 andra sidan h\u00e4nder f\u00f6ljande. Ingenj\u00f6ren p\u00e5 driftsavdelningen hanterar direkt distributionen av projektet: \u00e4ndrar versionsnummer p\u00e5 paketen i\u00a0<b>Hiera<\/b> i f\u00f6rr\u00e5det d\u00e4r receptet f\u00f6r applikationen f\u00f6rvaras, varefter Puppet triggar <b>Yum<\/b>, h\u00e4mtar det nya paketet fr\u00e5n f\u00f6rr\u00e5det, och den nya versionen av applikationen \u00e4r redo att anv\u00e4ndas.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/6c2db3ce4bd7d4268e88c6c3d3ecbeba.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDet l\u00e5ter enkelt, men vad h\u00e4nder inuti sj\u00e4lva Build-agenten?<\/p>\n<h3>Paketering av DLL RPM<\/h3>\n<p>\nK\u00e4llkoden f\u00f6r projektet har mottagits och en bygguppgift fr\u00e5n TFS. Build-agenten <b>startar byggandet av sj\u00e4lva projektet fr\u00e5n k\u00e4llkoden.<\/b>Det byggda projektet \u00e4r tillg\u00e4ngligt i form av ett antal <b>DLL-filer<\/b>, som paketeras i ett zip-arkiv f\u00f6r att minska belastningen p\u00e5 filsystemet.<\/p>\n<p>ZIP-arkivet l\u00e4ggs <b>i katalogen f\u00f6r byggandet av RPM-paketet.<\/b> D\u00e4refter initierar ett Bash-skript milj\u00f6variabler, hittar versionen av Build, versionen av projektet, s\u00f6kv\u00e4gen till byggkatalogen och startar RPM-build. N\u00e4r byggandet \u00e4r klart publiceras paketet i\u00a0<b>det lokala f\u00f6rr\u00e5det<\/b>, som finns p\u00e5 Build-agenten.<\/p>\n<p>D\u00e4refter skickas en JSON-f\u00f6rfr\u00e5gan fr\u00e5n Build-agenten till servern i RPM-repositoriet <b>med angivande av versionsnamn och build. Webhooken som jag n\u00e4mnde tidigare h\u00e4mtar detta paket fr\u00e5n det lokala f\u00f6rr\u00e5det p\u00e5 Build-agenten och g\u00f6r den nya byggnaden tillg\u00e4nglig f\u00f6r installation.<\/b> Varf\u00f6r \u00e4r just denna leveransmetod av paketet till RPM-repositoriet? Varf\u00f6r kan man inte skicka den byggda paketet direkt till f\u00f6rr\u00e5det? Anledningen \u00e4r att detta \u00e4r ett villkor f\u00f6r att s\u00e4kerst\u00e4lla s\u00e4kerheten. Detta scenarion begr\u00e4nsar m\u00f6jligheten till obeh\u00f6rig uppladdning av RPM-paket av utomst\u00e5ende p\u00e5 servern, som \u00e4r tillg\u00e4nglig f\u00f6r alla Linux-maskiner.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/b69cacdadd171f4cbc9913b2ff4b7a79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVersionering av databasen<\/p>\n<h2>Vid en konsil med utvecklarna framgick det att teamet f\u00f6redrog MS SQL, men i de flesta non-Windows-projekten hade vi redan anv\u00e4nt PostgreSQL. Eftersom vi redan hade beslutat att avst\u00e5 fr\u00e5n allt som \u00e4r betalt, b\u00f6rjade vi anv\u00e4nda PostgreSQL \u00e4ven h\u00e4r.<\/h2>\n<p>\nVid konsortiet med utvecklingen framkom det att grabbarna f\u00f6redrog MS SQL, men i de flesta icke-Windows-projekten hade vi redan anv\u00e4nt PostgreSQL. Eftersom vi redan hade beslutat att avst\u00e5 fr\u00e5n allt betalt, b\u00f6rjade vi anv\u00e4nda PostgreSQL \u00e4ven h\u00e4r.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/6b6c081344f2408c399248a70a63dccc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI denna del vill jag ber\u00e4tta hur vi genomf\u00f6rde versionering av databasen och hur vi valde mellan Flyway och Entity Framework Core. L\u00e5t oss titta p\u00e5 deras f\u00f6rdelar och nackdelar.<\/p>\n<h3>Nackdelar<\/h3>\n<p>\nFlyway g\u00e5r bara i en riktning, vi\u00a0<b>kan inte g\u00e5 tillbaka<\/b>\u00a0\u2014 det \u00e4r en betydande nackdel. Att j\u00e4mf\u00f6ra med Entity Framework Core kan g\u00f6ras utifr\u00e5n andra parametrar \u2014 ur utvecklarens bekv\u00e4mlighetssynpunkt. Ni minns v\u00e4l att vi satte detta i fokus, och det st\u00f6rsta kriteriet var att inte \u00e4ndra n\u00e5got f\u00f6r Windows-utvecklingen.<\/p>\n<p>F\u00f6r Flyway beh\u00f6vde vi <b>n\u00e5gon form av omslag<\/b>, s\u00e5 att killarna inte skrev <b>SQL-fr\u00e5gor<\/b>. Det \u00e4r mycket n\u00e4rmare f\u00f6r dem att arbeta i OOP-termer. Vi skrev instruktioner f\u00f6r att arbeta med databasobjekt, en SQL-fr\u00e5ga formades och k\u00f6rdes. Den nya databasen \u00e4r klar, den har testats \u2014 allt \u00e4r bra, allt fungerar.<\/p>\n<p>Entity Framework Core har en nackdel \u2014 vid h\u00f6g belastning\u00a0<b>skapar den icke-optimala SQL-fr\u00e5gor<\/b>, och belastningen p\u00e5 databasen kan bli betydande. Men eftersom v\u00e5r tj\u00e4nst inte \u00e4r h\u00f6gbelastad, r\u00e4knar vi inte belastningen i hundratals RPS, accepterade vi dessa risker och delegerade problemet till framtida oss.<\/p>\n<h3>F\u00f6rdelar<\/h3>\n<p>\nEntity Framework Core <b>fungerar ur l\u00e5dan och \u00e4r bekv\u00e4m f\u00f6r utveckling<\/b>, medan Flyway <b>l\u00e4tt integreras i befintlig CI.<\/b>Men vi vill ju g\u00f6ra det bekv\u00e4mt f\u00f6r utvecklarna :)<\/p>\n<h3>Proceduren f\u00f6r distribueringsuppdateringen<\/h3>\n<p>\nPuppet ser att det kommer en version\u00e4ndring i paketen, d\u00e4ribland det som ansvarar f\u00f6r migrering. F\u00f6rst installerar den paketet som inneh\u00e5ller migreringsskripten och funktionaliteten kopplad till databasen. Efter detta startar applikationen om som arbetar med databasen. D\u00e4refter installeras de \u00e5terst\u00e5ende komponenterna. Installationsordningen av paketen och k\u00f6rningen av applikationerna beskrivs i Puppet-manifestet.<\/p>\n<p>Applikationerna anv\u00e4nder k\u00e4nsliga uppgifter, s\u00e5som tokens, databaspassord, och allt detta dras in i konfigurationen fr\u00e5n Puppet master, d\u00e4r de lagras i krypterad form.<\/p>\n<h2>TFS-problem<\/h2>\n<p>\nEfter att vi hade klargjort och insett att allt verkligen fungerade, best\u00e4mde jag mig f\u00f6r att se vad som h\u00e4nder med byggena i TFS generellt f\u00f6r avdelningen f\u00f6r Windows-utveckling av andra projekt \u2014 om vi bygger\/releases snabbt eller inte, och uppt\u00e4ckte betydande problem med hastigheten.<\/p>\n<p>Ett av de viktigaste projekten tar 12-15 minuter att bygga \u2014 det \u00e4r l\u00e4nge, s\u00e5 kan vi inte leva. En snabb analys visade en fruktansv\u00e4rd nedg\u00e5ng i I\/O, och det p\u00e5 matriser.<\/p>\n<p>Genom att analysera komponent f\u00f6r komponent identifierade jag tre fokusomr\u00e5den. Det f\u00f6rsta \u2014 <b>\u00abKaspersky antivirus\u00bb<\/b>, som skannar k\u00e4llkoden p\u00e5 alla Windows Build-agenter. Den andra - <b>Windows<\/b> <b>Indexer.<\/b> Den var inte avst\u00e4ngd, och allt indexerades i realtid p\u00e5 Build-agenterna under distributionsprocessen. <\/p>\n<p>Den tredje - <b>Npm install. <\/b>Det visade sig att vi i de flesta Pipelines anv\u00e4nde just det h\u00e4r scenariot. Vad \u00e4r nackdelen? Proceduren Npm install k\u00f6rs n\u00e4r beroendetr\u00e4det skapas i\u00a0<b>package-lock.json<\/b>, d\u00e4r versionerna av paketen som ska anv\u00e4ndas f\u00f6r att bygga projektet registreras. Nackdelen \u00e4r att Npm install varje g\u00e5ng h\u00e4mtar aktuella versioner av paketen fr\u00e5n internet, vilket tar tid i fallet med ett stort projekt.<\/p>\n<blockquote><p>Utvecklare experimenterar ibland p\u00e5 den lokala maskinen f\u00f6r att kontrollera funktionen hos en specifik del eller hela projektet. Ibland visade det sig att allt fungerade bra lokalt, men vid sammanst\u00e4llning och distribution fungerade inget. Vi b\u00f6rjar unders\u00f6ka problemet - aha, olika versioner av beroendepaketen.<\/p><\/blockquote>\n<p><\/p>\n<h3>L\u00f6sning<\/h3>\n<p><\/p>\n<ul>\n<li>K\u00e4llorna i undantag AV.\n<\/li>\n<li>St\u00e4ng av indexeringen.\n<\/li>\n<li>\u00d6verg\u00e5ng till\u00a0<b>npm ci<\/b>.\n<\/li>\n<\/ul>\n<p>\nF\u00f6rdelarna med npm ci \u00e4r att vi\u00a0<b>skapar beroendetr\u00e4det en g\u00e5ng<\/b>, och f\u00e5r m\u00f6jlighet att ge utvecklaren <b>en aktuell lista \u00f6ver paket<\/b>, som han kan experimentera med lokalt utan begr\u00e4nsningar. Det <b>sparar tid<\/b> f\u00f6r utvecklarna som skriver kod.<\/p>\n<h3>Konfiguration<\/h3>\n<p>\nNu lite om konfigurationen av repositoriet. Historiskt har vi anv\u00e4nt <b>Nexus<\/b> f\u00f6r att hantera repositorier, inklusive <b>Internal REPO<\/b>. I detta interna repository levereras alla komponenter som vi anv\u00e4nder f\u00f6r interna \u00e4ndam\u00e5l, till exempel egna \u00f6vervakningar.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/147d7e80bf20e03a232f8b533be316eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVi anv\u00e4nder ocks\u00e5 <b>NuGet<\/b>, eftersom det cachelagrar b\u00e4ttre j\u00e4mf\u00f6rt med andra paketf\u00f6rvaltare.<\/p>\n<h3>Resultat<\/h3>\n<p>\nEfter att vi har optimerat Build-agenterna har den genomsnittliga byggtiden minskat fr\u00e5n 12 minuter till 7.<\/p>\n<blockquote><p>Om vi r\u00e4knar alla de maskiner som vi skulle ha kunnat anv\u00e4nda f\u00f6r Windows, men som vi ist\u00e4llet har \u00f6verf\u00f6rt till Linux i detta projekt, har vi sparat cirka $10 000. Och det h\u00e4r \u00e4r bara f\u00f6r licenser, och om man r\u00e4knar med driftkostnader - mer.<\/p><\/blockquote>\n<p><\/p>\n<h2>Planer<\/h2>\n<p>\nF\u00f6r n\u00e4sta kvartal har vi planerat arbete med att optimera kodleveransen.<\/p>\n<p><b>\u00d6verg\u00e5ng till en f\u00f6rbyggd Docker-image<\/b>. TFS \u00e4r en bra grej med m\u00e5nga plugins som m\u00f6jligg\u00f6r integration i Pipeline, inklusive byggen utl\u00f6sta av triggers, till exempel Docker-image. Denna trigger vill vi skapa p\u00e5 just det. <b>package-lock.json<\/b>. Om sammans\u00e4ttningen av komponenter som anv\u00e4nds f\u00f6r att bygga projektet p\u00e5 n\u00e5got s\u00e4tt \u00e4ndras, s\u00e5 skapas en ny Docker-image. Den anv\u00e4nds senare f\u00f6r att distribuera en container med den sammanst\u00e4llda applikationen. F\u00f6r n\u00e4rvarande har vi inte detta, men vi planerar att g\u00e5 \u00f6ver till mikrotj\u00e4nstarkitektur i Kubernetes, som aktivt utvecklas inom v\u00e5rt f\u00f6retag och l\u00e4nge har drivit produktionsl\u00f6sningar.<\/p>\n<h2>Sammanfattning<\/h2>\n<p>\nJag uppmanar alla att \u00f6verge Windows, men det beror inte p\u00e5 att jag inte kan hantera det. Anledningen \u00e4r att st\u00f6rsta delen av Open Source-l\u00f6sningar \u00e4r <b>Linux-stack<\/b>. Du kommer att <b>spara mycket p\u00e5 resurser<\/b>. Enligt min \u00e5sikt ligger framtiden hos Open Source-l\u00f6sningar p\u00e5 Linux med ett starkt community.<\/p>\n<p><i>Profilen f\u00f6r talare Alexander Sinchinov <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/alextuning\">p\u00e5 GitHub<\/a><\/noindex>.<\/i><\/p>\n<blockquote><p><noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOps Conf<\/a><\/noindex>\u00a0\u00e4r en konferens om integrationen av utvecklings-, test- och driftsprocesser f\u00f6r professionella av professionella. D\u00e4rf\u00f6r \u00e4r projektet som Alexander ber\u00e4ttade om genomf\u00f6rt och fungerar, och p\u00e5 dagen f\u00f6r presentationen genomf\u00f6rdes tv\u00e5 framg\u00e5ngsrika releaser. P\u00e5\u00a0<noindex><a rel=\"nofollow\" href=\"http:\/\/devopsconf.io\/moscow-rit\/2019\">DevOps Conf p\u00e5 RIT++<\/a><\/noindex> den 27 och 28 maj blir det \u00e4nnu fler s\u00e5dana fall fr\u00e5n praktiker. Man kan fortfarande hoppa p\u00e5 sista t\u00e5get och <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/lectures\/propose\/?conference=dc2019-rit\">skicka in en presentation<\/a><\/noindex> eller ta sin tid och <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/conference\/join\/rit2019.html?popup=3\">boka<\/a><\/noindex> ett biljett. Vi ses i Skolkovo!<\/p><\/blockquote>\n<p>K\u00e4lla: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/oleg-bunin\/blog\/448496\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u044b\u00a0\u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8\u00a0\u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438\u00a0\u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e\u00a0Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430\u00a0\u0443\u00a0\u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u041a\u043e\u0433\u0434\u0430 \u044f\u00a0\u0432\u044b\u0441\u044b\u043f\u0430\u043b \u043d\u0430\u00a0\u0441\u0442\u043e\u043b \u0432\u0435\u0441\u044c \u0441\u0442\u0435\u043a Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u043e\u00a0\u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u00a0\u2014 \u0431\u043e\u043b\u044c\u2026 \u0422\u0430\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u043d\u0447\u0438\u043d\u043e\u0432\u0430 \u043d\u0430 DevOpsConf. \u041a\u043e\u0433\u0434\u0430 \u0438\u0437\u00a0\u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0443\u0448\u0435\u043b \u0432\u0435\u0434\u0443\u0449\u0438\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442 \u043f\u043e\u00a0Windows, \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0437\u0430\u0434\u0430\u043b\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430\u00a0Linux, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24043,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32217","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438 \u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47.NET Core \u043d\u0430 Linux, DevOps \u043d\u0430 \u043a\u043e\u043d\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438 \u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:45:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:45:43+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47.NET Core p\u00e5 Linux, DevOps p\u00e5 topp | ProHoster","description":"Vi utvecklade DevOps s\u00e5 gott vi kunde. Vi var 8 personer, och Vasja var den b\u00e4sta p\u00e5 Windows. Pl\u00f6tsligt slutade Vasja, och jag fick uppdraget att lansera ett nytt projekt som levererar Windows-utveckling.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47.NET Core \u043d\u0430 Linux, DevOps \u043d\u0430 \u043a\u043e\u043d\u0435 | ProHoster","og:description":"\u041c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0438 DevOps \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u0438. \u041d\u0430\u0441 \u0431\u044b\u043b\u043e 8 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0438 \u0412\u0430\u0441\u044f \u0431\u044b\u043b \u0441\u0430\u043c\u044b\u043c \u043a\u0440\u0443\u0442\u044b\u043c \u043f\u043e Windows. \u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0412\u0430\u0441\u044f \u0443\u0448\u0435\u043b, \u0430 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Windows-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430.","og:url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:45:43+00:00","article:modified_time":"2019-10-31T18:45:43+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32217","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 09:49:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:02:47","updated":"2026-01-21 09:49:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/32217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=32217"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/32217\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/24043"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=32217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=32217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=32217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}