{"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\/ro\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","title":{"rendered":".NET Core pe Linux, DevOps \u00een armonie","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Am dezvoltat DevOps c\u00e2t am putut. Eram 8 oameni, iar Vasya era cel mai bun pe Windows. Dintr-o dat\u0103, Vasya a plecat, iar eu am avut de rezolvat sarcina de a lansa un nou proiect care s\u0103 furnizeze dezvoltare Windows. C\u00e2nd am r\u0103sturnat pe mas\u0103 \u00eentregul stack de dezvoltare Windows, am realizat c\u0103 situa\u021bia era dureroas\u0103\u2026<\/p>\n<p>A\u0219a \u00eencepe povestea <b>Alexandra Sinchinova<\/b> pe <noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOpsConf<\/a><\/noindex>. C\u00e2nd specialistul nostru principal pe Windows a p\u0103r\u0103sit compania, Alexandra s-a \u00eentrebat ce ar trebui s\u0103 facem acum. S\u0103 trecem pe Linux, desigur! Alexandra va vorbi despre cum a reu\u0219it s\u0103 creeze un precedent \u0219i s\u0103 transfere o parte a dezvolt\u0103rii Windows pe Linux, folosind ca exemplu un proiect realizat pentru 100.000 de utilizatori finali.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/3c944351864df95217e133236542c9b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCum s\u0103 livr\u0103m un proiect \u00een RPM, folosind TFS, Puppet, Linux .NET core, \u00eentr-un mod simplu \u0219i f\u0103r\u0103 stres? Cum s\u0103 gestion\u0103m versiunea bazei de date a proiectului, dac\u0103 dezvoltatorii auzit pentru prima dat\u0103 cuvintele Postgres \u0219i Flyway, iar termenul limit\u0103 este poim\u00e2ine? Cum s\u0103 integr\u0103m cu Docker? Cum s\u0103 motiv\u0103m dezvoltatorii .NET s\u0103 renun\u021be la Windows \u0219i sucuri \u00een favoarea Puppet \u0219i Linux? Cum s\u0103 rezolv\u0103m conflictele ideologice, dac\u0103 nu avem for\u021b\u0103, dorin\u021b\u0103 sau resurse pentru a men\u021bine Windows \u00een produc\u021bie? Despre asta, \u0219i despre Web Deploy, testare, CI, despre practicile de utilizare a TFS \u00een proiectele existente, \u0219i, desigur, despre solu\u021bii improvizate \u0219i func\u021bionale, ne va povesti Alexandra.<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=\"Reda\u021bi video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nDeci, Vasya a plecat, responsabilitatea este acum a mea, iar dezvoltatorii a\u0219teapt\u0103 cu ner\u0103bdare. C\u00e2nd am realizat \u00een cele din urm\u0103 c\u0103 nu-l voi putea aduce \u00eenapoi pe Vasya, m-am apucat de treab\u0103. Mai \u00eent\u00e2i, am evaluat procentul de Win VM din parcul nostru. Num\u0103rul nu era \u00een favoarea Windows.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/836e47372126b6ba369ac494b91c7d3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDeoarece dezvolt\u0103m activ DevOps, am realizat c\u0103 trebuie s\u0103 schimb\u0103m ceva \u00een abordarea lans\u0103rii noii aplica\u021bii. Decizia a fost clar\u0103 \u2014 s\u0103 transfer\u0103m totul pe Linux, pe c\u00e2t posibil. Google m-a ajutat \u2013 \u00een acel moment, .Net fusese deja portat pe Linux, iar eu am realizat c\u0103 aceasta era solu\u021bia!<\/p>\n<h2>De ce .NET core \u00een combina\u021bie cu Linux?<\/h2>\n<p>\nExistau c\u00e2teva motive. \u00centre \"a pl\u0103ti bani\" \u0219i \"a nu pl\u0103ti\", majoritatea aleg cea din urm\u0103 \u2014 la fel ca mine. Licen\u021ba pentru MSDB cost\u0103 aproximativ 1.000 $, iar \u00eentre\u021binerea parcului de ma\u0219ini virtuale Windows se ridic\u0103 la sute de dolari. Pentru o companie mare, acestea sunt cheltuieli semnificative. A\u0219adar, <b>economia\u00a0<\/b>\u2014<b> este primul motiv<\/b>. Nu este cel mai important, dar este unul dintre cele semnificative.<\/p>\n<p>Ma\u0219inile virtuale Windows consum\u0103 mai multe resurse dec\u00e2t fra\u021bii lor din Linux \u2014 <b>sunt greoaie<\/b>. Av\u00e2nd \u00een vedere dimensiunea unei companii mari, am ales Linux.<\/p>\n<p><b>Sistemul se integreaz\u0103 u\u0219or \u00een CI existent<\/b>. Ne consider\u0103m DevOps progresivi, folosim Bamboo, Jenkins \u0219i GitLab CI, a\u0219a c\u0103 cea mai mare parte a tot ce facem se desf\u0103\u0219oar\u0103 pe Linux.<\/p>\n<p>Ultimul motiv este <b>suportul convenabil. <\/b>A trebuit s\u0103 reducem pragul de intrare pentru \u201esus\u021bin\u0103tori\u201d - persoanele care \u00een\u021beleg partea tehnic\u0103, asigur\u0103 continuitatea \u0219i \u00eentre\u021bin serviciile de nivelul doi. Ace\u0219tia erau deja familiariza\u021bi cu stiva Linux, a\u0219a c\u0103 le este mult mai u\u0219or s\u0103 \u00een\u021beleag\u0103 noul produs, s\u0103-l sus\u021bin\u0103 \u0219i s\u0103-l \u00eentre\u021bin\u0103 dec\u00e2t s\u0103 investeasc\u0103 resurse suplimentare pentru a \u00eenv\u0103\u021ba un software similar pentru platforma Windows.<\/p>\n<h2>Cerin\u021be<\/h2>\n<p>\nPrimul \u0219i cel mai important <b>este comoditatea noii solu\u021bii pentru dezvoltatori<\/b>. Nu to\u021bi dintre ei au fost preg\u0103ti\u021bi pentru schimbare, mai ales dup\u0103 ce au auzit cuv\u00e2ntul Linux. Dezvoltatorii doresc s\u0103 foloseasc\u0103 Visual Studio preferat\u0103, TFS cu teste automate de build \u0219i smoothie-uri. Cum se desf\u0103\u0219oar\u0103 livrarea \u00een produc\u021bie \u2013 nu le pas\u0103. De aceea, am decis s\u0103 nu schimb\u0103m procesul familiar \u0219i s\u0103 l\u0103s\u0103m totul neschimbat pentru dezvoltarea pe Windows. <\/p>\n<p>Noul proiect trebuie <b>s\u0103 fie integrat \u00een CI existent<\/b>. Au existat deja c\u0103ile, iar \u00eentreaga munc\u0103 a trebuit s\u0103 fie realizat\u0103 \u00een conformitate cu parametrii sistemului de gestionare a configura\u021biei, standardele de livrare acceptate \u0219i sistemele de monitorizare.<\/p>\n<p><b>U\u0219urin\u021ba de suport \u0219i operare<\/b>, ca o condi\u021bie pentru un prag minim de intrare pentru to\u021bi noii participan\u021bi din diferite departamente \u0219i din departamentul de suport.<\/p>\n<p><b>Termenul limit\u0103 a fost ieri<\/b>.<\/p>\n<h2>Grupul de dezvoltare Win<\/h2>\n<p>\nCu ce lucra echipa Windows?<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/6e6e128ef3d49410c260d05114f819a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAcum pot spune cu \u00eencredere c\u0103 <b>IdentityServer4<\/b>\u00a0este o alternativ\u0103 gratuit\u0103 grozav\u0103 la ADFS cu capacit\u0103\u021bi similare, sau c\u0103 <b>Entity Framework Core<\/b>\u00a0este un paradis pentru dezvoltatori, unde pot evita scrierea scripturilor SQL, descriind interog\u0103rile \u00een BD \u00een termeni de OOP. Dar atunci, \u00een timpul discu\u021biei planului de ac\u021biune, am privit aceast\u0103 stiv\u0103 ca pe o scriere cuneiform\u0103 sumerean\u0103, recunosc\u00e2nd doar PostgreSQL \u0219i Git.<\/p>\n<p>\u00cen acel moment foloseam activ <b>Puppet<\/b> ca sistem de gestionare a configura\u021biei. \u00cen majoritatea proiectelor noastre am utilizat <b>GitLab CI<\/b>, <b>Elastic<\/b>, am echilibrat servicii cu sarcin\u0103 mare folosind <b>HAProxy,<\/b> am monitorizat totul cu ajutorul <b>Zabbix<\/b>, setul <b>Grafana<\/b> \u0219i\u00a0<b>Prometheus<\/b>, <b>Jaeger<\/b>, \u0219i totul rula pe echipamentele\u00a0<b>HP<\/b> c\u00a0<b>ESXi<\/b> pe\u00a0<b>VMware<\/b>. Toat\u0103 lumea cunoa\u0219te - clasic\u0103.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/f4ffcac7a7fbb4fa48d47f07bed52610.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS\u0103 vedem \u0219i s\u0103 \u00eencerc\u0103m s\u0103 \u00een\u021belegem ce se \u00eent\u00e2mpla \u00eenainte de a \u00eencepe toate aceste interven\u021bii.<\/p>\n<h2>Ce a fost<\/h2>\n<p>\nTFS este un sistem destul de puternic, care nu doar livreaz\u0103 codul de la dezvoltator la serverul de produc\u021bie final, ci are \u0219i un set de integrare foarte flexibil cu diferite servicii - pentru a asigura CI la un nivel multiplatform\u0103.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/ea448b38e321a8350468d69f3e45e429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n\u00cen trecut, erau doar feronerie la fereastra. TFS folosea mai mul\u021bi agen\u021bi de construire, pe care se adunau multe proiecte. \u00cen fiecare agent erau 3-4 lucr\u0103tori, pentru a paraleliza sarcinile \u0219i a optimiza procesul. Apoi, conform planurilor de lansare, TFS livra build-ul proasp\u0103t pe serverul de aplica\u021bii Windows.<\/p>\n<h2>La ce voiam s\u0103 ajungem<\/h2>\n<p>\nPentru livrare \u0219i dezvoltare folosim TFS, iar aplica\u021bia este rulat\u0103 pe un server de aplica\u021bii Linux, \u0219i \u00eentre ele exist\u0103 o anumit\u0103 magie. Acest <b>Magic Box<\/b> este sarea muncii viitoare. \u00cenainte de a-l descompune \u00een p\u0103r\u021bi, voi face un pas \u00een lateral \u0219i voi spune c\u00e2teva cuvinte despre aplica\u021bie.<\/p>\n<h2>Proiect<\/h2>\n<p>\nAplica\u021bia ofer\u0103 func\u021bionalitate pentru operarea cardurilor prepl\u0103tite. <\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/c93aa67b340c45ad279330466fc4f776.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Client<\/h3>\n<p>\nAu existat dou\u0103 tipuri de utilizatori. <b>Primul<\/b> a avut acces autentific\u00e2ndu-se printr-un certificat SSL SHA-2. Utilizatorul\u00a0<b>a doua<\/b> a avut acces prin login \u0219i parol\u0103.<\/p>\n<h3>HAProxy<\/h3>\n<p>\nApoi, cererea clientului ajungea \u00een HAProxy, care rezolva urm\u0103toarele sarcini:<\/p>\n<ul>\n<li>autentificarea ini\u021bial\u0103;\n<\/li>\n<li>terminarea SSL;\n<\/li>\n<li>optimizarea cererilor HTTP;\n<\/li>\n<li>translatarea cererilor.\n<\/li>\n<\/ul>\n<p>\nVerificarea certificatului clientului se realiza printr-un lan\u021b. Noi - <b>authority <\/b>\u0219i ne putem permite asta, deoarece emitem noi \u00een\u0219ine certificate clien\u021bilor serviciului.<\/p>\n<p>Re\u021bine\u021bi punctul trei, ne vom \u00eentoarce la el pu\u021bin mai t\u00e2rziu.<\/p>\n<h3>Backend<\/h3>\n<p>\nBackend-ul era planificat s\u0103 fie realizat pe Linux. Backend-ul interac\u021bioneaz\u0103 cu baza de date, \u00eencarc\u0103 lista necesar\u0103 de privilegii \u0219i apoi, \u00een func\u021bie de privilegii de\u021binute de utilizatorul autentificat, ofer\u0103 acces pentru semnarea documentelor financiare \u0219i trimiterea acestora pentru execu\u021bie sau generarea unui raport.<\/p>\n<h2>Economia cu HAProxy<\/h2>\n<p>\nPe l\u00e2ng\u0103 cele dou\u0103 contexte prin care au trecut fiecare dintre clien\u021bi, mai exista un context de identitate. <b>IdentityServer4<\/b> care permite autentificarea, acesta fiind un echivalent gratuit \u0219i puternic pentru <b>ADFS\u00a0<\/b>\u2014<b> Active Directory Federation Services<\/b>.<\/p>\n<p>Cererea \u00een identitate era procesat\u0103 \u00een c\u00e2teva etape. Prima etap\u0103 - <b>client<\/b> <b>ajungea \u00een backend<\/b>, care schimb\u0103 date cu acest server \u0219i verifica existen\u021ba unui token pentru client. Dac\u0103 nu \u00eel g\u0103sea \u2013 cererea era returnat\u0103 \u00eenapoi la contextul din care a venit, dar deja cu un redirect, \u0219i cu redirectul mergea la identity.<\/p>\n<p>Pasul doi \u2013 cererea ajungea <b>pe pagina de autentificare \u00een IdentityServer,<\/b> unde clientul se \u00eenregistra, iar \u00een baza de date a IdentityServer ap\u0103rea acel a\u0219teptat token. <\/p>\n<p>Pasul trei \u2013 <b>clientul era redirec\u021bionat \u00eenapoi <\/b>la contextul din care a venit.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/e052c408d67485ab9aa10d0fd25df57e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIdentityServer4 are o particularitate: <b>r\u0103spunsul la cererea invers\u0103 este returnat prin HTTP<\/b>. Indiferent c\u00e2t de mult ne-am chinuit cu configurarea serverului, c\u00e2t de mult ne-am informat din documenta\u021bie, de fiecare dat\u0103 primeam cererea ini\u021bial\u0103 a clientului cu URL-ul venit prin HTTPS, iar IdentityServer returna acela\u0219i context, dar cu HTTP. Eram \u0219oca\u021bi! \u0218i am trecut totul prin contextul identity pe HAProxy, iar \u00een headers a trebuit s\u0103 modific\u0103m protocolul HTTP \u00een HTTPS. <\/p>\n<p>Care este \u00eembun\u0103t\u0103\u021birea \u0219i unde am economisit?<\/p>\n<blockquote><p>Am economisit bani folosind o solu\u021bie gratuit\u0103 pentru autentificarea unui grup de utilizatori, resurse, deoarece nu am desf\u0103\u0219urat IdentityServer4 ca un nod separat \u00eentr-un segment separat, ci l-am folosit \u00eempreun\u0103 cu backend-ul pe acela\u0219i server pe care ruleaz\u0103 backend-ul aplica\u021biei.<\/p><\/blockquote>\n<p><\/p>\n<h2>Cum ar trebui s\u0103 func\u021bioneze<\/h2>\n<p>\nA\u0219adar, a\u0219a cum am promis \u2013 Magic Box. Deja \u00een\u021belegem c\u0103 ne \u00eendrept\u0103m garantat spre Linux. S\u0103 formul\u0103m sarcinile concrete care necesitau solu\u021bionare.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/cc59632aa0e5c65fe0efc754311ecf5e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Manifestele Puppet. <\/b>Pentru a livra \u0219i gestiona configura\u021bia serviciului \u0219i aplica\u021biei, a fost necesar s\u0103 scriem re\u021bete excelente. Un mic rola cu un creion arat\u0103 c\u00e2t de repede \u0219i calitativ a fost realizat acest lucru.<\/p>\n<p><b>Metoda de livrare. <\/b>Standardul este RPM. Toat\u0103 lumea \u00een\u021belege c\u0103 \u00een Linux nu po\u021bi f\u0103r\u0103 el, dar proiectul \u00een sine, dup\u0103 compilare, consta dintr-un set de fi\u0219iere DLL executabile. Au fost aproximativ 150, proiectul destul de greu. Solu\u021bia harmonic\u0103 unic\u0103 este s\u0103 \u00eempachet\u0103m aceast\u0103 binaritate \u00een RPM \u0219i din ea s\u0103 desf\u0103\u0219ur\u0103m aplica\u021bia.<\/p>\n<p><b>Versionare. <\/b>A trebuit s\u0103 lans\u0103m foarte des \u0219i a fost necesar s\u0103 decid\u0103 cum s\u0103 form\u0103m numele pachetului. Aceasta este o problem\u0103 la nivelul integr\u0103rii cu TFS. Agentul de build l-am avut pe Linux. C\u00e2nd TFS trimite o sarcin\u0103 c\u0103tre procesor - worker - pe agentul de build, el \u00eei transmite \u0219i un set de variabile, care ajung \u00een mediul procesului procesorului. \u00cen aceste variabile de mediu se transmite numele Build, numele versiunii \u0219i alte variabile. Mai multe detalii despre aceasta \u00een sec\u021biunea \u201econstruirea pachetului RPM\u201d.<\/p>\n<p><b>Configurarea TFS<\/b> se concentra pe configurarea Pipeline-ului. \u00cen trecut, am construit toate proiectele Windows pe agen\u021bi Windows, iar acum apare agentul Linux - agentul de build, care trebuie inclus \u00een grupul de construc\u021bie, \u00eembog\u0103\u021bit cu anumite artefacte, s\u0103 i se spun\u0103 ce tip de proiecte vor fi create pe acest agent de build \u0219i s\u0103 modifice Pipeline-ul.<\/p>\n<p><b>IdentityServer. <\/b>ADFS nu este calea noastr\u0103, sus\u021binem Open Source.<\/p>\n<p>Haide\u021bi s\u0103 trecem prin componente.<\/p>\n<h2>Magic Box<\/h2>\n<p>\nSe compune din patru p\u0103r\u021bi.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/22ea63bcf184046c15e034ec093352bb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Agent de build Linux. <\/b>Linux, pentru c\u0103 construim pentru el - este logic. Aceast\u0103 parte a fost realizat\u0103 \u00een trei pa\u0219i.<\/p>\n<ul>\n<li><b>Configureaz\u0103 worker-ii<\/b> \u0219i nu unul, deoarece era planificat\u0103 o munc\u0103 distribuit\u0103 asupra proiectului.\n<\/li>\n<li><b>Instaleaz\u0103 .NET Core 1.x<\/b>. De ce exact 1.x, c\u00e2nd 2.0 este deja disponibil \u00een depozitul standard? Pentru c\u0103, atunci c\u00e2nd am \u00eenceput dezvoltarea, versiunea stabil\u0103 era 1.09, iar proiectul a fost decis s\u0103 fie realizat pentru aceasta.\n<\/li>\n<li><b>Git 2.x<\/b>.\n<\/li>\n<\/ul>\n<p>\n<b>Repository RPM. <\/b>Pachetele RPM trebuiau stocate undeva. Se presupunea c\u0103 vom folosi acela\u0219i repository RPM corporativ, care este disponibil pentru toate gazdele Linux. A\u0219a am procedat. Pe serverul repository-ului a fost configurat <b>webhook<\/b> care desc\u0103rca pachetul RPM necesar din locul specificat. Versiunea pachetului era comun\u0103 webhook-ului de c\u0103tre agentul de build.<\/p>\n<p><b>GitLab. <\/b>Aten\u021bie! GitLab aici este folosit nu de dezvoltatori, ci de departamentul de exploatare pentru a controla versiunile aplica\u021biei, versiunile pachetelor, starea tuturor ma\u0219inilor Linux \u0219i aici se p\u0103streaz\u0103 re\u021beta - toate manifestele Puppet. <\/p>\n<p><b>Puppet<\/b>\u00a0- rezolv\u0103 toate problemele disputate \u0219i livreaz\u0103 exact configura\u021bia pe care o dorim, din GitLab.<\/p>\n<p>\u00cencepem s\u0103 ne aprofund\u0103m. Cum se desf\u0103\u0219oar\u0103 livrarea DLL \u00een RPM?<\/p>\n<h3>Livrarea DLL \u00een RPM<\/h3>\n<p>\nS\u0103 presupunem c\u0103 avem o stea a dezvolt\u0103rii \u00een .NET. El folose\u0219te Visual Studio \u0219i creeaz\u0103 o ramur\u0103 de lansare. Dup\u0103 aceea, o \u00eencarc\u0103 \u00een Git, iar Git aici este o entitate TFS, adic\u0103 acesta este repository-ul aplica\u021biei cu care lucreaz\u0103 dezvoltatorul.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/978240886981d41fc6d7b17d0a4fcb05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDup\u0103 care TFS vede c\u0103 a sosit un nou commit. Ce aplica\u021bie? \u00cen set\u0103rile TFS exist\u0103 o etichet\u0103 care indic\u0103 resursele de care dispune fiecare Build-agent. \u00cen acest caz, el vede c\u0103 adun\u0103m un proiect .NET Core \u0219i alege Build-agent-ul Linux din pool. <\/p>\n<p>Build-agentul prime\u0219te sursele, descarc\u0103 necesarul <b>dependencies<\/b> din repositoriu .NET, npm etc. \u0219i, dup\u0103 construirea aplica\u021biei propriu-zise \u0219i pachetului ulterioare, trimite pachetul RPM \u00een repositoriu RPM.<\/p>\n<p>Pe de alt\u0103 parte, se \u00eent\u00e2mpl\u0103 urm\u0103toarele. Inginerul din departamentul de exploatare se ocup\u0103 direct cu release-ul proiectului: modific\u0103 versiunile pachetelor \u00een\u00a0<b>Hiera<\/b> din repositoriu, unde se afl\u0103 re\u021beta aplica\u021biei, dup\u0103 care Puppet declan\u0219eaz\u0103 <b>Yum<\/b>, preia noul pachet din repositoriu, iar noua versiune a aplica\u021biei este gata de utilizare.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/6c2db3ce4bd7d4268e88c6c3d3ecbeba.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPe h\u00e2rtie totul este simplu, dar ce se \u00eent\u00e2mpl\u0103 \u00een interior, pe Build-agent?<\/p>\n<h3>Pachetizarea DLL RPM<\/h3>\n<p>\nS-au primit sursele proiectului \u0219i sarcina de construire de la TFS. Build-agentul <b>ini\u021biaz\u0103 construc\u021bia proiectului din surse<\/b>. Proiectul construit este disponibil sub form\u0103 de multe <b>fi\u0219iere DLL<\/b>, care sunt pachetate \u00eentr-un arhiv\u0103 zip pentru a reduce sarcina pe sistemul de fi\u0219iere.<\/p>\n<p>Arhiva ZIP este aruncat\u0103 <b>\u00een directorul de construc\u021bie al pachetului RPM.<\/b> Apoi, un script Bash ini\u021biaz\u0103 variabilele de mediu, afl\u0103 versiunea Build, versiunea proiectului, calea c\u0103tre directorul de construc\u021bie \u0219i ini\u021biaz\u0103 RPM-build. La finalizarea construc\u021biei, pachetul este publicat \u00een\u00a0<b>repositorio local<\/b>, care se afl\u0103 pe Build-agent.<\/p>\n<p>Apoi, de pe Build-agent, pe serverul din repositoriile RPM <b>se trimite o solicitare JSON<\/b> cu indica\u021bia numelui versiunii \u0219i a build-ului. Webhook-ul despre care am vorbit mai devreme descarc\u0103 acest pachet din repositoriul local de pe Build-agent \u0219i face noua construc\u021bie disponibil\u0103 pentru instalare.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/b69cacdadd171f4cbc9913b2ff4b7a79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe ce tocmai acest sistem de livrare a pachetului \u00een repositoriul RPM? De ce nu se poate trimite direct pachetul construit \u00een repositoriu? Problema const\u0103 \u00een faptul c\u0103 aceasta este o condi\u021bie pentru asigurarea securit\u0103\u021bii. Un astfel de scenariu limiteaz\u0103 posibilitatea \u00eenc\u0103rc\u0103rii neautorizate a pachetelor RPM de c\u0103tre persoane str\u0103ine pe serverul accesibil tuturor ma\u0219inilor Linux.<\/p>\n<h2>Versionarea Bazei de Date<\/h2>\n<p>\n\u00cen cadrul unei consilieri cu dezvoltarea, s-a aflat c\u0103 echipei \u00eei place mai mult MS SQL, dar \u00een majoritatea proiectelor non-Windows foloseam deja PostgreSQL. Deoarece am decis s\u0103 renun\u021b\u0103m la tot ce este pl\u0103tit, am \u00eenceput s\u0103 folosim PostgreSQL \u0219i aici.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/6b6c081344f2408c399248a70a63dccc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen aceast\u0103 sec\u021biune vreau s\u0103 explic cum am realizat versiunea bazei de date \u0219i cum am ales \u00eentre Flyway \u0219i Entity Framework Core. Haide\u021bi s\u0103 examin\u0103m avantajele \u0219i dezavantajele lor.<\/p>\n<h3>Dezavantaje<\/h3>\n<p>\nFlyway func\u021bioneaz\u0103 \u00eentr-o singur\u0103 direc\u021bie, noi\u00a0<b>nu putem reveni \u00eenapoi<\/b>\u00a0\u2014 aceasta este o dezavantajare semnificativ\u0103. Compararea cu Entity Framework Core se poate face \u00een func\u021bie de alte criterii \u2014 din perspectiva confortului dezvoltatorului. \u00ce\u021bi aminte\u0219ti c\u0103 acesta a fost pus \u00een prim-plan, iar criteriul principal a fost s\u0103 nu modific\u0103m nimic pentru dezvoltarea pe Windows.<\/p>\n<p>Pentru Flyway, aveam nevoie de un fel de wrapper <b>, astfel \u00eenc\u00e2t colegii s\u0103 nu scrie<\/b>interog\u0103ri SQL <b>. Le este mult mai aproape s\u0103 opereze \u00een termeni de OOP. Am redactat instruc\u021biuni despre cum s\u0103 lucr\u0103m cu obiectele bazei de date, s-a format interogarea SQL \u0219i a fost executat\u0103. Noua versiune a bazei de date este gata, a fost testat\u0103 \u2014 totul este bine, totul func\u021bioneaz\u0103.<\/b>Entity Framework Core are un dezavantaj \u2014 la sarcini mari, acesta<\/p>\n<p>construie\u0219te interog\u0103ri SQL suboptimale\u00a0<b>, iar impactul asupra bazei de date poate fi semnificativ. Dar, deoarece serviciul nostru nu este foarte solicitat, nu calcul\u0103m sarcina \u00een sute de RPS, am acceptat aceste riscuri \u0219i am delegat problema viitorului nostru.<\/b>func\u021bioneaz\u0103 din cutie \u0219i este convenabil pentru dezvoltare<\/p>\n<h3>Advantages<\/h3>\n<p>\nEntity Framework Core <b>, iar Flyway<\/b>se integreaz\u0103 u\u0219or \u00een CI existent <b>. Dar noi ne str\u0103duim s\u0103 facem via\u021ba dezvoltatorilor mai u\u0219oar\u0103 :)<\/b>Procedura de executare<\/p>\n<h3>Puppet observ\u0103 c\u0103 a avut loc o modificare a versiunii pachetelor, inclusiv pachetul responsabil pentru migrare. \u00cen primul r\u00e2nd, instaleaz\u0103 pachetul care con\u021bine scripturile de migrare \u0219i func\u021bionalitatea legat\u0103 de baza de date. Dup\u0103 aceea, aplica\u021bia care lucreaz\u0103 cu baza de date este repornit\u0103. Apoi urmeaz\u0103 instalarea celorlalte componente. Ordinea instal\u0103rii pachetelor \u0219i a lans\u0103rii aplica\u021biilor este descris\u0103 \u00een manifestul Puppet.<\/h3>\n<p>\nAplica\u021biile utilizeaz\u0103 date sensibile, cum ar fi token-uri, parole pentru baza de date, toate acestea fiind extrase din configura\u021bia de la Puppet master, unde sunt stocate \u00een form\u0103 criptat\u0103.<\/p>\n<p>Problemele TFS<\/p>\n<h2>Dup\u0103 ce ne-am hot\u0103r\u00e2t \u0219i am realizat c\u0103 totul func\u021bioneaz\u0103, am decis s\u0103 verific ce se \u00eent\u00e2mpl\u0103 cu construc\u021biile \u00een TFS, \u00een general pentru departamentul de dezvoltare Windows \u00een cadrul altor proiecte \u2014 dac\u0103 ne compil\u0103m\/lans\u0103m rapid sau nu, \u0219i am descoperit probleme semnificative cu viteza.<\/h2>\n<p>\nUnul dintre proiectele principale se compileaz\u0103 \u00een 12-15 minute \u2014 acest lucru este prea mult, nu se poate tr\u0103i a\u0219a. O analiz\u0103 rapid\u0103 a ar\u0103tat o sc\u0103dere drastic\u0103 a I\/O, \u0219i aceasta pe arii de stocare.<\/p>\n<p>Dup\u0103 o analiz\u0103 detaliat\u0103, am identificat trei focare. Primul \u2014<\/p>\n<p>\u201eKaspersky antivirus\u201d <b>\u201eKaspersky antivirus\u201d<\/b>, care scaneaz\u0103 sursele pe toate agen\u021bii de build Windows. Al doilea - <b>Windows<\/b> <b>Indexer.<\/b> Nu a fost dezactivat \u0219i pe agen\u021bii de build, totul a fost indexat \u00een timp real \u00een procesul de deploy. <\/p>\n<p>Al treilea - <b>Npm install. <\/b>S-a dovedit c\u0103 \u00een majoritatea pipeline-urilor am folosit exact acest script. Ce este gre\u0219it? Procedura Npm install se lanseaz\u0103 la formarea arborilor de dependen\u021be \u00een\u00a0<b>package-lock.json<\/b>, unde sunt fixate versiunile pachetelor care vor fi folosite pentru construirea proiectului. Un dezavantaj este c\u0103 Npm install trage de fiecare dat\u0103 versiunile actualizate ale pachetelor din internet, iar aceasta ia un timp considerabil \u00een cazul unui proiect mare.<\/p>\n<blockquote><p>Dezvoltatorii uneori experimenteaz\u0103 pe ma\u0219ina local\u0103 pentru a verifica func\u021bionarea unei p\u0103r\u021bi individuale sau a \u00eentregului proiect. Uneori se \u00eent\u00e2mpla ca local totul s\u0103 fie grozav, dar la construirea \u0219i implementarea - nimic nu func\u021biona. \u00cencepem s\u0103 investig\u0103m problema - aha, versiuni diferite ale pachetelor cu dependen\u021be.<\/p><\/blockquote>\n<p><\/p>\n<h3>Solu\u021bie<\/h3>\n<p><\/p>\n<ul>\n<li>Sursele \u00een excep\u021bii AV.\n<\/li>\n<li>Dezactivarea index\u0103rii.\n<\/li>\n<li>Trecerea la\u00a0<b>npm ci<\/b>.\n<\/li>\n<\/ul>\n<p>\nAvantajele npm ci sunt c\u0103\u00a0<b>construim o dat\u0103 arborele de dependen\u021be<\/b>, \u0219i ob\u021binem oportunitatea de a oferi dezvoltatorului <b>o list\u0103 actualizat\u0103 de pachete<\/b>, cu care poate experimenta local c\u00e2t dore\u0219te. Aceasta <b>economise\u0219te timp<\/b> dezvoltatorilor care scriu cod.<\/p>\n<h3>Configura\u021bie<\/h3>\n<p>\nAcum pu\u021bin despre configura\u021bia depozitului. Istoric, folosim <b>Nexus<\/b> pentru gestionarea depozitelor, inclusiv <b>Internal REPO<\/b>. \u00cen acest depozit intern sunt livrate toate componentele pe care le folosim pentru scopuri interne, de exemplu, monitoriz\u0103rile scrise de noi.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core pe Linux, DevOps \u00een armonie\" src=\"\/wp-content\/uploads\/2019\/04\/147d7e80bf20e03a232f8b533be316eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFolosim de asemenea <b>NuGet<\/b>, deoarece acesta cache-uie\u0219te mai bine \u00een compara\u021bie cu al\u021bi gestionari de pachete.<\/p>\n<h3>Rezultatul<\/h3>\n<p>\nDup\u0103 ce am optimizat agen\u021bii de build, timpul mediu de construire a fost redus de la 12 minute la 7.<\/p>\n<blockquote><p>Dac\u0103 am calcula toate ma\u0219inile pe care le-am putea folosi pentru Windows, dar le-am mutat la Linux \u00een acest proiect, am economisit \u00een jur de 10.000 $. \u0218i aceasta este doar pe licen\u021be; dac\u0103 includem costurile de \u00eentre\u021binere - mai mult.<\/p><\/blockquote>\n<p><\/p>\n<h2>Planuri<\/h2>\n<p>\nPentru urm\u0103torul trimestru am planificat optimizarea livr\u0103rii codului.<\/p>\n<p><b>Trecerea la o imagine Docker preconstruit\u0103<\/b>. TFS este o unealt\u0103 grozav\u0103 cu o mul\u021bime de plugin-uri care permit integrarea \u00een Pipeline, inclusiv construirea pe un trigger, de exemplu, al unei imagini Docker. Acest trigger vrem s\u0103-l facem pe acela. <b>package-lock.json<\/b>. Dac\u0103 somehow se schimb\u0103 compozi\u021bia componentelor folosite pentru a construi proiectul - ne construim o nou\u0103 imagine Docker. Ulterior, aceasta este folosit\u0103 pentru desf\u0103\u0219urarea unui container cu aplica\u021bia construit\u0103. Acum nu avem aceasta, dar pl\u0103nuim s\u0103 trecem la o arhitectur\u0103 microservicii \u00een Kubernetes, care se dezvolt\u0103 activ \u00een compania noastr\u0103 \u0219i deja sus\u021bine solu\u021bii de produc\u021bie.<\/p>\n<h2>Rezumat<\/h2>\n<p>\n\u00cendemn pe to\u021bi s\u0103 renun\u021be la Windows, dar nu pentru c\u0103 nu \u0219tiu cum s\u0103 o preg\u0103tesc. Motivul este c\u0103 cea mai mare parte a solu\u021biilor Opensource este <b>stiva Linux<\/b>. Ve\u021bi <b>economisi bine resurse<\/b>. \u00cen opinia mea, viitorul apar\u021bine solu\u021biilor Open Source pe Linux cu o comunitate puternic\u0103.<\/p>\n<p><i>Profilul vorbitorului Alexandru Sinchinov <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/alextuning\">pe GitHub<\/a><\/noindex>.<\/i><\/p>\n<blockquote><p><noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOps Conf<\/a><\/noindex>\u00a0este o conferin\u021b\u0103 dedicat\u0103 integr\u0103rii proceselor de dezvoltare, testare \u0219i operare pentru profesioni\u0219ti de la profesioni\u0219ti. De aceea, proiectul despre care a vorbit Alexandru? este realizat \u0219i func\u021bioneaz\u0103, iar \u00een ziua prezent\u0103rii au avut loc dou\u0103 lans\u0103ri de succes. La\u00a0<noindex><a rel=\"nofollow\" href=\"http:\/\/devopsconf.io\/moscow-rit\/2019\">DevOps Conf la RIT++<\/a><\/noindex> pe 27 \u0219i 28 mai vor fi \u0219i mai multe cazuri similare de la practicieni. \u00cenc\u0103 mai po\u021bi s\u0103 te urci \u00een ultimul vagon \u0219i <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/lectures\/propose\/?conference=dc2019-rit\">trimite un raport<\/a><\/noindex> sau f\u0103r\u0103 grab\u0103 <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/conference\/join\/rit2019.html?popup=3\">rezerva<\/a><\/noindex> bilet. Ne vedem la Skolkovo!<\/p><\/blockquote>\n<p>Sursa: <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.2.1 - 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\/ro\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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 pe Linux, DevOps pe cai mari | ProHoster","description":"Am dezvoltat DevOps c\u00e2t am putut. Eram 8 oameni, iar Vasya era cel mai bun la Windows. Deodat\u0103, Vasya a plecat, iar eu am avut sarcina de a lansa un nou proiect care furnizeaz\u0103 dezvoltare Windows.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/32217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=32217"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/32217\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/24043"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=32217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=32217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=32217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}