{"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\/it\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","title":{"rendered":".NET Core su Linux, DevOps a cavallo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Abbiamo sviluppato DevOps come meglio potevamo. Eravamo in 8 persone, e Vasya era il migliore per Windows. Improvvisamente, Vasya se n'\u00e8 andato e mi \u00e8 stata affidata la responsabilit\u00e0 di lanciare un nuovo progetto per lo sviluppo su Windows. Quando ho riversato sul tavolo l'intero stack per lo sviluppo su Windows, ho capito che la situazione era critica...<\/p>\n<p>Cos\u00ec inizia la storia <b>Aleksandr Sinchinov<\/b> con <noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOpsConf<\/a><\/noindex>. Quando il nostro principale esperto di Windows ha lasciato l'azienda, Aleksandr si \u00e8 chiesto cosa fare ora. Passare a Linux, naturalmente! Aleksandr racconter\u00e0 come \u00e8 riuscito a creare un precedente e a trasferire parte dello sviluppo Windows su Linux con l'esempio di un progetto implementato per 100.000 utenti finali.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/3c944351864df95217e133236542c9b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCome \u00e8 facile e informale distribuire un progetto in RPM utilizzando TFS, Puppet, Linux .NET core? Come mantenere la versioning del database del progetto, se gli sviluppatori sentono per la prima volta le parole Postgres e Flyway, mentre la scadenza \u00e8 dopodomani? Come integrarsi con Docker? Come motivare gli sviluppatori .NET a rinunciare a Windows e smoothie a favore di Puppet e Linux? Come risolvere i conflitti ideologici se non ci sono n\u00e9 forze n\u00e9 voglia n\u00e9 risorse per gestire Windows in produzione? Di questo, cos\u00ec come di Web Deploy, testing, CI, delle pratiche di utilizzo di TFS in progetti esistenti, e naturalmente delle stampelle rotte e delle soluzioni funzionanti, ne parler\u00e0 la trascrizione della presentazione di Alexander.<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=\"Riproduci video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nQuindi, Vasya se n'\u00e8 andato, il compito \u00e8 su di me, gli sviluppatori aspettano con i forconi con impazienza. Quando ho finalmente realizzato che non potevo riportare Vasya, mi sono messo al lavoro. Per prima cosa, ho valutato la percentuale di VM Windows nel nostro parco. Il conteggio non era a favore di Windows.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/836e47372126b6ba369ac494b91c7d3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPoich\u00e9 stiamo attivamente sviluppando DevOps, ho capito che dovevo cambiare qualcosa nell'approccio alla distribuzione di una nuova applicazione. La soluzione era una sola: trasferire tutto su Linux, se possibile. Google mi ha aiutato: a quel tempo .Net era gi\u00e0 stato portato su Linux, e ho capito che questa era la soluzione!<\/p>\n<h2>Perch\u00e9 .NET core in combinazione con Linux?<\/h2>\n<p>\nCi sono diverse ragioni. Tra \"pagare\" e \"non pagare\", la maggior parte sceglier\u00e0 la seconda opzione, proprio come ho fatto io. Una licenza per MSDB costa circa 1.000 $, e la manutenzione di un parco di macchine virtuali Windows si traduce in centinaia di dollari. Per una grande azienda, sono costi significativi. Perci\u00f2 <b>risparmio\u00a0<\/b>\u2014<b> prima ragione<\/b>. Non \u00e8 la pi\u00f9 importante, ma \u00e8 una delle pi\u00f9 rilevanti.<\/p>\n<p>Le macchine virtuali Windows consumano pi\u00f9 risorse rispetto ai loro equivalenti Linux - <b>sono pesanti<\/b>. Considerando le dimensioni di una grande azienda, abbiamo scelto Linux.<\/p>\n<p><b>Il sistema si integra facilmente con il CI esistente<\/b>. Ci consideriamo DevOps all'avanguardia, utilizziamo Bamboo, Jenkins e GitLab CI, quindi gran parte delle nostre operazioni si svolgono su Linux.<\/p>\n<p>L'ultima ragione - <b>facile manutenzione. <\/b>Avevamo bisogno di abbassare la soglia d'ingresso per i \"manutentori\" - le persone che comprendono la parte tecnica, garantiscono la continuit\u00e0 e gestiscono i servizi di secondo livello. Loro conoscevano gi\u00e0 lo stack Linux, quindi per loro \u00e8 molto pi\u00f9 facile capire il nuovo prodotto, supportarlo e mantenerlo, piuttosto che spendere risorse aggiuntive per orientarsi in funzionalit\u00e0 analoghe di software per la piattaforma Windows.<\/p>\n<h2>Requisiti<\/h2>\n<p>\nPrima di tutto - <b>la comodit\u00e0 della nuova soluzione per gli sviluppatori<\/b>. Non tutti erano pronti per i cambiamenti, specialmente dopo aver sentito la parola Linux. Gli sviluppatori vogliono Visual Studio, TFS con autotest sui build e smoothie. Non importa come avviene la consegna in produzione. Pertanto, abbiamo deciso di non cambiare il processo abituale e di mantenere tutto invariato per lo sviluppo su Windows. <\/p>\n<p>Un nuovo progetto deve essere <b>integrato nel CI esistente<\/b>. I binari erano gi\u00e0 presenti e tutto il lavoro doveva essere svolto tenendo conto delle impostazioni del sistema di gestione della configurazione, degli standard di consegna adottati e dei sistemi di monitoraggio.<\/p>\n<p><b>Semplicit\u00e0 nella manutenzione e operativit\u00e0<\/b>, come condizione per una soglia minima di ingresso per tutti i nuovi partecipanti provenienti da diversi reparti e dal settore di supporto.<\/p>\n<p><b>La scadenza \u00e8 ieri<\/b>.<\/p>\n<h2>Gruppo di sviluppo Win<\/h2>\n<p>\nCon cosa ha lavorato quindi il team Windows?<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/6e6e128ef3d49410c260d05114f819a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOra posso dire con certezza che <b>IdentityServer4<\/b>\u00a0\u00e8 un'ottima alternativa gratuita a ADFS con funzionalit\u00e0 simili, o che <b>Entity Framework Core<\/b>\u00a0\u2014 un paradiso per gli sviluppatori, dove non bisogna preoccuparsi di scrivere script SQL, ma piuttosto di descrivere le query nel database in termini di OOP. Tuttavia, durante la discussione del piano d'azione, guardavo a questo stack come se fosse un cuneo sumero, riconoscendo solo PostgreSQL e Git.<\/p>\n<p>A quel tempo, usavamo attivamente <b>Puppet<\/b> come sistema di gestione della configurazione. In gran parte dei nostri progetti, utilizzavamo <b>GitLab CI<\/b>, <b>Elastic<\/b>, bilanciando i servizi ad alta richiesta con <b>HAProxy,<\/b> monitorando tutto con <b>Zabbix<\/b>, una combinazione di <b>Grafana<\/b> e\u00a0<b>Prometheus<\/b>, <b>Jaeger<\/b>, e tutto ci\u00f2 girava su hardware\u00a0<b>HP<\/b> c\u00a0<b>ESXi<\/b> con\u00a0<b>VMware<\/b>. \u00c8 noto a tutti \u2014 un classico del settore.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/f4ffcac7a7fbb4fa48d47f07bed52610.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDiamo un'occhiata e cerchiamo di capire cosa stesse succedendo prima che iniziassimo tutti questi interventi.<\/p>\n<h2>Cosa era<\/h2>\n<p>\nTFS \u00e8 un sistema piuttosto potente, che non solo consegna il codice dallo sviluppatore alla macchina di produzione finale, ma ha anche un insieme di strumenti per un'integrazione molto flessibile con diversi servizi \u2014 per garantire CI a livello di cross-platform.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/ea448b38e321a8350468d69f3e45e429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIn passato, si trattava di semplici finestre. TFS utilizzava diversi agenti di build su cui venivano raccolti numerosi progetti. Ogni agente aveva 3-4 worker per parallelizzare i compiti e ottimizzare il processo. Successivamente, secondo i piani di rilascio, TFS inviava il build freschissimo su un server Windows per applicazioni.<\/p>\n<h2>A cosa volevamo arrivare<\/h2>\n<p>\nPer la distribuzione e lo sviluppo utilizziamo TFS, mentre l'applicazione viene eseguita su un server Linux Application, e tra di loro c'\u00e8 una sorta di magia. Questa <b>Magic Box<\/b> \u00e8 il cuore del lavoro a venire. Prima di smontarlo pezzo per pezzo, far\u00f2 un passo indietro e dir\u00f2 due parole sull'applicazione.<\/p>\n<h2>Progetto<\/h2>\n<p>\nL'applicazione fornisce funzionalit\u00e0 per gestire carte prepagate. <\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/c93aa67b340c45ad279330466fc4f776.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Client<\/h3>\n<p>\nC'erano due tipi di utenti. <b>Primo<\/b> accedeva autenticandosi tramite certificato SSL SHA-2. Un\u00a0<b>secondo<\/b> aveva accesso tramite nome utente e password.<\/p>\n<h3>HAProxy<\/h3>\n<p>\nSuccessivamente, la richiesta del cliente arrivava a HAProxy, che gestiva le seguenti operazioni:<\/p>\n<ul>\n<li>autenticazione primaria;\n<\/li>\n<li>terminazione SSL;\n<\/li>\n<li>ottimizzazione delle richieste HTTP;\n<\/li>\n<li>traslazione delle richieste.\n<\/li>\n<\/ul>\n<p>\nLa verifica del certificato del cliente avveniva attraverso la catena. Noi siamo <b>authority <\/b>e possiamo permetterci di farlo, poich\u00e9 noi stessi rilasciamo certificati ai nostri clienti.<\/p>\n<p>Fai attenzione al terzo punto, ne riparleremo pi\u00f9 tardi.<\/p>\n<h3>Backend<\/h3>\n<p>\nIl backend era previsto su Linux. Il backend interagisce con il DB, carica l'elenco necessario delle autorizzazioni e poi, a seconda delle autorizzazioni del utente autenticato, fornisce l'accesso per la firma di documenti finanziari e il loro invio per l'esecuzione, oppure per la generazione di un rapporto.<\/p>\n<h2>Risparmi con HAProxy<\/h2>\n<p>\nOltre ai due contesti in cui ciascuno dei clienti era attivo, esisteva anche il contesto identity. <b>IdentityServer4<\/b> proprio permette l'autenticazione, \u00e8 un'alternativa gratuita e potente per <b>ADFS\u00a0<\/b>\u2014<b> Active Directory Federation Services<\/b>.<\/p>\n<p>La richiesta a identity veniva elaborata in diversi passaggi. Il primo passaggio \u00e8 <b>client<\/b> <b>andava al backend<\/b>, che scambiava dati con questo server e verificava la presenza di un token per il cliente. Se non lo trovava, la richiesta veniva restituita al contesto da cui era arrivata, ma con un redirect, e col redirect andava a identity.<\/p>\n<p>Il secondo passaggio \u00e8 che la richiesta arrivava <b>alla pagina di autenticazione in IdentityServer,<\/b> dove il cliente si registrava, e nel database di IdentityServer appariva il tanto atteso token. <\/p>\n<p>Il terzo passaggio \u00e8 che <b>il cliente veniva reindirizzato di nuovo. <\/b>nel contesto da cui \u00e8 arrivato.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/e052c408d67485ab9aa10d0fd25df57e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIdentityServer4 ha una peculiarit\u00e0: <b>la risposta alla richiesta di callback viene restituita tramite HTTP<\/b>. Non importa quanto ci siamo sforzati nel configurare il server, n\u00e9 quanto abbiamo studiato la documentazione, ogni volta ricevevamo la richiesta originale del client con un URL che arrivava tramite HTTPS, mentre IdentityServer restituiva lo stesso contesto, ma tramite HTTP. Siamo rimasti scioccati! E abbiamo reindirizzato tutto questo attraverso il contesto identity su HAProxy, e nelle intestazioni abbiamo dovuto modificare il protocollo da HTTP a HTTPS. <\/p>\n<p>Qual \u00e8 stato il miglioramento e dove abbiamo risparmiato?<\/p>\n<blockquote><p>Abbiamo risparmiato denaro utilizzando una soluzione gratuita per l'autorizzazione di un gruppo di utenti, risorse, poich\u00e9 non abbiamo separato IdentityServer4 come nodo autonomo in un segmento separato, ma lo abbiamo utilizzato insieme al backend sullo stesso server dove gira il backend dell'applicazione.<\/p><\/blockquote>\n<p><\/p>\n<h2>Come dovrebbe funzionare<\/h2>\n<p>\nQuindi, come promesso \u2014 Magic Box. Ora capiamo che ci stiamo muovendo in direzione di Linux. Formuliamo le specifiche esigenze che necessitavano di una soluzione.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/cc59632aa0e5c65fe0efc754311ecf5e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Manifesti Puppet. <\/b>Per fornire e gestire la configurazione del servizio e dell'applicazione, era necessario scrivere ricette eccellenti. Un rotolo con una matita mostra eloquentemente quanto rapidamente e qualitativamente sia stato fatto.<\/p>\n<p><b>Metodo di consegna. <\/b>Lo standard \u00e8 RPM. Tutti capiscono che in Linux non si pu\u00f2 fare a meno di lui, ma il progetto stesso, dopo la compilation, era un insieme di file DLL eseguibili. Ce n'erano circa 150, il progetto era piuttosto pesante. L'unica soluzione armoniosa era imballare questo insieme di binari in RPM e poi lanciare l'applicazione da l\u00ec.<\/p>\n<p><b>Versioning. <\/b>Avevamo in programma di rilasciare molto frequentemente e dovevamo decidere come generare il nome del pacchetto. Questa \u00e8 una questione di integrazione con TFS. Il nostro agent di build era su Linux. Quando TFS invia un compito a un worker sul Build-agent, gli passa anche un insieme di variabili che finiscono nell'ambiente del processo. In queste variabili d'ambiente vengono passati il nome della Build, il nome della versione e altre variabili. Maggiori dettagli su questo nella sezione \"Costruzione del pacchetto RPM.\"<\/p>\n<p><b>Configurazione TFS<\/b> si riassume nella configurazione di Pipeline. In precedenza, raccoglievamo tutti i progetti Windows sugli agenti Windows, mentre ora introduciamo un agente Linux \u2014 l'agente Build, che deve essere incluso nel gruppo di build, arricchito con alcuni artefatti, specificare che tipo di progetti verranno costruiti su questo agente Build e modificare in qualche modo il Pipeline.<\/p>\n<p><b>IdentityServer. <\/b>ADFS non \u00e8 la nostra strada, sosteniamo l'open source.<\/p>\n<p>Passiamo ai componenti.<\/p>\n<h2>Magic Box<\/h2>\n<p>\n\u00c8 composto da quattro parti.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/22ea63bcf184046c15e034ec093352bb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Agente Build Linux. <\/b>Linux, perch\u00e9 stiamo costruendo per esso \u2014 \u00e8 logico. Questa parte \u00e8 stata eseguita in tre fasi.<\/p>\n<ul>\n<li><b>Configurare i worker<\/b> e non uno solo, poich\u00e9 si prevedeva una collaborazione distribuita sul progetto.\n<\/li>\n<li><b>Installare .NET Core 1.x<\/b>. Perch\u00e9 proprio 1.x, quando \u00e8 gi\u00e0 disponibile la 2.0 nel repository standard? Perch\u00e9, quando abbiamo iniziato lo sviluppo, la versione stabile era 1.09, e si \u00e8 deciso di realizzare il progetto per essa.\n<\/li>\n<li><b>Git 2.x<\/b>.\n<\/li>\n<\/ul>\n<p>\n<b>RPM-repository. <\/b>I pacchetti RPM dovevano essere archiviati da qualche parte. Si prevedeva che avremmo utilizzato lo stesso repository RPM aziendale, accessibile a tutti gli host Linux. E cos\u00ec \u00e8 stato. Sul server del repository \u00e8 configurato <b>webhook<\/b> che scaricava il pacchetto RPM richiesto dal luogo specificato. La versione del pacchetto veniva comunicata all'agente Build.<\/p>\n<p><b>GitLab. <\/b>Attenzione! GitLab qui \u00e8 utilizzato non dai programmatori, ma dal reparto operativo per il controllo delle versioni dell'applicazione, delle versioni dei pacchetti, del monitoraggio dello stato di tutte le macchine Linux e contiene la ricetta\u2014 tutti i manifesti Puppet. <\/p>\n<p><b>Puppet<\/b>\u00a0\u2014 risolve tutte le questioni controverse e fornisce esattamente quella configurazione che vogliamo, da GitLab.<\/p>\n<p>Iniziamo a immergerci. Come avviene la consegna di DLL in RPM?<\/p>\n<h3>Consegna di DLL in RPM<\/h3>\n<p>\nSupponiamo di avere una rockstar dello sviluppo su .NET. Utilizza Visual Studio e crea un ramo di rilascio. Dopo di che lo carica in Git, e Git qui \u00e8 un'entit\u00e0 TFS, cio\u00e8 \u00e8 il repository dell'applicazione con cui lavora lo sviluppatore.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/978240886981d41fc6d7b17d0a4fcb05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDopo di che TFS vede che \u00e8 arrivato un nuovo commit. Quale applicazione? Nelle impostazioni di TFS c'\u00e8 un'etichetta su quali risorse dispone ciascun agente di Build. In questo caso vede che stiamo costruendo un progetto .NET Core e seleziona un agente di build Linux dal pool. <\/p>\n<p>L'agente di build riceve i sorgenti, scarica i necessari <b>dependencies<\/b> dal repository .NET, npm, ecc. e dopo la compilazione dell'applicazione e l'imballaggio successivo invia il pacchetto RPM nel repository RPM.<\/p>\n<p>Dall'altra parte accade quanto segue. L'ingegnere del reparto operativo si occupa direttamente del rilascio del progetto: cambia le versioni dei pacchetti in\u00a0<b>Hiera<\/b> nel repository dove \u00e8 conservata la ricetta dell'applicazione, dopo di che Puppet attiva <b>Yum<\/b>, recupera il nuovo pacchetto dal repository e la nuova versione dell'applicazione \u00e8 pronta per l'uso.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/6c2db3ce4bd7d4268e88c6c3d3ecbeba.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA parole sembra tutto semplice, ma cosa succede realmente all'interno del Build-agent?<\/p>\n<h3>Imballaggio DLL RPM<\/h3>\n<p>\nI sorgenti del progetto sono stati ricevuti e c'\u00e8 un compito di build da TFS. Il Build-agent <b>avvia la build del progetto stesso dai sorgenti<\/b>. Il progetto costruito \u00e8 disponibile sotto forma di numerosi <b>file DLL<\/b>, che vengono imballati in un archivio zip per ridurre il carico sul sistema file.<\/p>\n<p>L'archivio ZIP viene posizionato <b>nella directory di build del pacchetto RPM.<\/b> Successivamente, uno script Bash inizializza le variabili d'ambiente, trova la versione di Build, la versione del progetto, il percorso della directory di build e avvia RPM-build. Al termine della compilazione, il pacchetto viene pubblicato in\u00a0<b>repository locale<\/b>, che si trova sul Build-agent.<\/p>\n<p>Successivamente, dal Build-agent al server nel repository RPM <b>viene inviato un richiesta JSON<\/b> con specifica del nome della versione e del build. Il webhook di cui parlavo prima scarica proprio questo pacchetto dal repository locale sul build agent e rende il nuovo build disponibile per l'installazione.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/b69cacdadd171f4cbc9913b2ff4b7a79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPerch\u00e9 proprio questo schema di consegna del pacchetto nel repository RPM? Perch\u00e9 non inviare direttamente il pacchetto costruito nel repository? La questione \u00e8 che questa \u00e8 una condizione per garantire la sicurezza. Tale scenario limita la possibilit\u00e0 di caricamento non autorizzato di pacchetti RPM da parte di estranei sul server, accessibile a tutte le macchine Linux.<\/p>\n<h2>Versioning del DB<\/h2>\n<p>\nNel consiglio di sviluppo si \u00e8 scoperto che ai ragazzi piace di pi\u00f9 MS SQL, ma nella maggior parte dei progetti non Windows avevamo gi\u00e0 utilizzato PostgreSQL. Poich\u00e9 avevamo gi\u00e0 deciso di rinunciare a tutto ci\u00f2 che era a pagamento, abbiamo iniziato a utilizzare PostgreSQL anche qui.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/6b6c081344f2408c399248a70a63dccc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn questa parte voglio raccontare come abbiamo effettuato il versioning del DB e come abbiamo scelto tra Flyway e Entity Framework Core. Consideriamo i loro pro e contro.<\/p>\n<h3>Svantaggi<\/h3>\n<p>\nFlyway funziona solo in una direzione, noi\u00a0<b>non possiamo tornare indietro.<\/b>\u00a0\u2014 \u00e8 un grosso svantaggio. \u00c8 possibile confrontarlo con Entity Framework Core sotto altri aspetti \u2014 dal punto di vista della comodit\u00e0 per lo sviluppatore. Dovete ricordare che abbiamo posto questo al centro della nostra attenzione, e il criterio principale era non modificare nulla per lo sviluppo su Windows.<\/p>\n<p>Per Flyway, ci <b>voleva qualche tipo di wrapper<\/b>, in modo che i ragazzi non scrivessero <b>query SQL<\/b>. \u00c8 molto pi\u00f9 vicino a operare in termini di OOP. Abbiamo scritto istruzioni su come lavorare con gli oggetti del DB, si \u00e8 formata la query SQL ed \u00e8 stata eseguita. La nuova versione del DB \u00e8 pronta, ha funzionato \u2014 tutto bene, tutto funziona.<\/p>\n<p>Entity Framework Core ha un difetto \u2014 sotto carichi elevati\u00a0<b>genera query SQL non ottimali<\/b>, e il downgrade del DB pu\u00f2 essere significativo. Ma poich\u00e9 non abbiamo un servizio ad alta intensit\u00e0 di carico, non misuriamo il carico in centinaia di RPS, abbiamo accettato questi rischi e delegato il problema a noi stessi in futuro.<\/p>\n<h3>Pro<\/h3>\n<p>\nEntity Framework Core <b>funziona out-of-the-box ed \u00e8 comodo per lo sviluppo<\/b>, mentre Flyway <b>si integra facilmente nella CI esistente<\/b>. Ma stiamo rendendo tutto pi\u00f9 comodo per i developer :)<\/p>\n<h3>Procedura di rollout<\/h3>\n<p>\nPuppet osserva che c'\u00e8 un cambiamento nella versione dei pacchetti, tra cui quello responsabile della migrazione. Inizia installando il pacchetto che contiene gli script di migrazione e le funzionalit\u00e0 legate al database. Successivamente, riavvia l'applicazione che interagisce con il database. Poi si procede all'installazione dei componenti restanti. L'ordine di installazione dei pacchetti e di avvio delle applicazioni \u00e8 descritto nel manifesto di Puppet.<\/p>\n<p>Le applicazioni utilizzano dati sensibili come token e password del database, tutti questi vengono recuperati nella configurazione dal Puppet master, dove sono memorizzati in forma cifrata.<\/p>\n<h2>Problemi TFS<\/h2>\n<p>\nDopo aver stabilito che tutto funziona correttamente, ho deciso di controllare cosa stava succedendo con le build in TFS in generale per il dipartimento sviluppo Win in altri progetti - se ci stavamo compilando\/rilasciando rapidamente o meno, e ho scoperto problemi significativi con la velocit\u00e0.<\/p>\n<p>Uno dei principali progetti si compila in 12-15 minuti - \u00e8 troppo lungo, non si pu\u00f2 vivere cos\u00ec. Un'analisi rapida ha mostrato una grave flessione delle prestazioni I\/O, e questo sui dischi.<\/p>\n<p>Analizzando i componenti, ho identificato tre aree critiche. La prima - <b>\u00abKaspersky antivirus\u00bb<\/b>, che scansiona i sorgenti su tutti gli agenti di build Windows. Secondo \u2014 <b>Windows<\/b> <b>Indexer.<\/b> Non \u00e8 stato disattivato e durante il deployment tutto veniva indicizzato in tempo reale sugli agenti di build. <\/p>\n<p>Terzo \u2014 <b>Npm install. <\/b>Si \u00e8 scoperto che in gran parte dei pipeline abbiamo utilizzato proprio questo script. Qual \u00e8 il problema? La procedura Npm install viene eseguita durante la creazione dell'albero delle dipendenze in\u00a0<b>package-lock.json<\/b>, dove vengono registrate le versioni dei pacchetti che verranno utilizzate per la costruzione del progetto. Il problema \u00e8 che Npm install recupera ogni volta le versioni attuali dei pacchetti da Internet, e questo richiede tempo in caso di progetti di grandi dimensioni.<\/p>\n<blockquote><p>Gli sviluppatori a volte fanno esperimenti sulla macchina locale per testare una parte separata o l'intero progetto. A volte si scopre che localmente funziona tutto bene, ma quando si compila e si distribuisce, non funziona niente. Iniziamo a capire dove sia il problema \u2014 ecco, versioni diverse dei pacchetti con dipendenze.<\/p><\/blockquote>\n<p><\/p>\n<h3>Soluzione<\/h3>\n<p><\/p>\n<ul>\n<li>Sorgenti nelle esclusioni AV.\n<\/li>\n<li>Disattivazione dell'indicizzazione.\n<\/li>\n<li>Passaggio a\u00a0<b>npm ci<\/b>.\n<\/li>\n<\/ul>\n<p>\nI vantaggi di npm ci sono che\u00a0<b>creiamo l'albero delle dipendenze una sola volta<\/b>, e otteniamo la possibilit\u00e0 di fornire allo sviluppatore <b>un elenco aggiornato dei pacchetti<\/b>, con cui pu\u00f2 sperimentare localmente quanto vuole. Questo <b>risparmia tempo<\/b> agli sviluppatori che scrivono codice.<\/p>\n<h3>Configurazione<\/h3>\n<p>\nOra parliamo un po' della configurazione del repository. Storicamente, usiamo <b>Nexus<\/b> per la gestione dei repository, incluso <b>Internal REPO<\/b>. Questo repository interno contiene tutti i componenti che utilizziamo per scopi interni, come ad esempio i monitoraggi personalizzati.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core su Linux, DevOps a cavallo\" src=\"\/wp-content\/uploads\/2019\/04\/147d7e80bf20e03a232f8b533be316eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUtilizziamo anche <b>NuGet<\/b>, poich\u00e9 gestisce meglio la cache rispetto ad altri gestori di pacchetti.<\/p>\n<h3>Risultato<\/h3>\n<p>\nDopo aver ottimizzato gli agenti di build, il tempo medio di compilazione \u00e8 stato ridotto da 12 minuti a 7.<\/p>\n<blockquote><p>Se si considerano tutte le macchine che avremmo potuto usare per Windows, ma che abbiamo migrato su Linux in questo progetto, abbiamo risparmiato circa $10.000. E questo solo per le licenze; se consideriamo il costo operativo, \u00e8 di pi\u00f9.<\/p><\/blockquote>\n<p><\/p>\n<h2>Piani<\/h2>\n<p>\nPer il prossimo trimestre, abbiamo pianificato di lavorare sull'ottimizzazione della consegna del codice.<\/p>\n<p><b>Transizione a un'immagine Docker pre-costruita<\/b>. TFS \u00e8 fantastico, con molti plugin che consentono di integrare nel pipeline, incluso il build basato su trigger, ad esempio, l'immagine Docker. Questo trigger vogliamo implementarlo per quello specifico <b>package-lock.json<\/b>. Se in qualche modo cambia la composizione dei componenti utilizzati per assemblare il progetto, viene creato una nuova immagine Docker. Questa viene poi utilizzata per distribuire un contenitore con l'applicazione assemblata. Al momento non \u00e8 tutto ci\u00f2 che abbiamo, ma prevediamo di passare a un'architettura a microservizi in Kubernetes, che si sta sviluppando attivamente nella nostra azienda e gestisce da tempo soluzioni di produzione.<\/p>\n<h2>Riepilogo<\/h2>\n<p>\nInvito tutti a abbandonare Windows, ma non perch\u00e9 non sappia prepararlo. La ragione \u00e8 che la maggior parte delle soluzioni open source \u00e8 <b>un stack Linux<\/b>. Risparmierete bene <b>sulle risorse<\/b>. A mio parere, il futuro appartiene alle soluzioni Open Source su Linux con una comunit\u00e0 forte.<\/p>\n<p><i>Profilo del relatore Aleksandr Sinchinov <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/alextuning\">su GitHub<\/a><\/noindex>.<\/i><\/p>\n<blockquote><p><noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOps Conf<\/a><\/noindex>\u00a0\u00e8 una conferenza sull'integrazione dei processi di sviluppo, test e operazioni per professionisti da professionisti. \u00c8 proprio per questo che il progetto di cui parlava Aleksandr \u00e8 stato realizzato e funziona, e nel giorno della presentazione sono stati effettuati due rilascio di successo. Alla\u00a0<noindex><a rel=\"nofollow\" href=\"http:\/\/devopsconf.io\/moscow-rit\/2019\">DevOps Conf presso RIT++<\/a><\/noindex> il 27 e 28 maggio ci saranno ancora pi\u00f9 casi simili da parte di praticanti. C'\u00e8 ancora spazio per salire sull'ultimo vagone e <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/lectures\/propose\/?conference=dc2019-rit\">presentare una relazione<\/a><\/noindex> o farlo con calma <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/conference\/join\/rit2019.html?popup=3\">riservare<\/a><\/noindex> biglietto. Ci vediamo a Skolkovo!<\/p><\/blockquote>\n<p>Fonte: <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 4.9.10 - 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. \u041a\u043e\u0433\u0434\u0430 \u044f \u0432\u044b\u0441\u044b\u043f\u0430\u043b \u043d\u0430 \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 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \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 \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 Windows, \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 Linux,\" \/>\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\/it\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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. \u041a\u043e\u0433\u0434\u0430 \u044f \u0432\u044b\u0441\u044b\u043f\u0430\u043b \u043d\u0430 \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 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \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 \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 Windows, \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 Linux,\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/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 su Linux, DevOps in prima linea | ProHoster","description":"Abbiamo sviluppato DevOps come meglio potevamo. Eravamo in 8 e Vasya era il migliore per Windows. All'improvviso Vasya \u00e8 andato via e ho dovuto affrontare la sfida di avviare un nuovo progetto dedicato allo sviluppo su Windows. Quando ho messo tutto il stack di sviluppo Windows sul tavolo, ho realizzato che la situazione era critica\u2026 Cos\u00ec inizia la storia di Aleksandr Sinchinov al DevOpsConf. Quando il principale esperto di Windows ha lasciato l'azienda, Aleksandr si \u00e8 chiesto cosa fare adesso. Passare a Linux,","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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. \u041a\u043e\u0433\u0434\u0430 \u044f \u0432\u044b\u0441\u044b\u043f\u0430\u043b \u043d\u0430 \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 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \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 \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 Windows, \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 Linux,","og:url":"https:\/\/prohoster.info\/it\/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"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/32217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=32217"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/32217\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/24043"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=32217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=32217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=32217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}