{"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\/fr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","title":{"rendered":".NET Core sur Linux, DevOps en pleine forme","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Nous avons \u00e9volu\u00e9 DevOps comme nous le pouvions. Nous \u00e9tions 8 personnes, et Vasya \u00e9tait le meilleur en Windows. Soudain, Vasya est parti, et j'avais la t\u00e2che de lancer un nouveau projet fournissant des d\u00e9veloppements Windows. Quand j'ai \u00e9tal\u00e9 toute la stack de d\u00e9veloppement Windows sur la table, j'ai r\u00e9alis\u00e9 que la situation \u00e9tait douloureuse...<\/p>\n<p>C'est ainsi que commence l'histoire <b>Alexandra Sinchinova<\/b> sur <noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOpsConf<\/a><\/noindex>. Lorsque le sp\u00e9cialiste principal des Windows a quitt\u00e9 l'entreprise, Alexandre s'est demand\u00e9 quoi faire maintenant. Passer \u00e0 Linux, bien s\u00fbr ! Alexandre expliquera comment il a r\u00e9ussi \u00e0 cr\u00e9er un pr\u00e9c\u00e9dent et \u00e0 transf\u00e9rer une partie du d\u00e9veloppement Windows sur Linux \u00e0 travers un projet r\u00e9alis\u00e9 pour 100 000 utilisateurs finaux.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/3c944351864df95217e133236542c9b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComment d\u00e9ployer facilement et sans tracas un projet en RPM, en utilisant TFS, Puppet et Linux .NET core ? Comment g\u00e9rer la version de la base de donn\u00e9es du projet, si les d\u00e9veloppeurs entendent pour la premi\u00e8re fois les mots Postgres et Flyway, et que la date limite est apr\u00e8s-demain ? Comment int\u00e9grer avec Docker ? Comment motiver les d\u00e9veloppeurs .NET \u00e0 renoncer \u00e0 Windows et \u00e0 leurs smoothies au profit de Puppet et de Linux ? Comment r\u00e9soudre les conflits id\u00e9ologiques, lorsque soutenir Windows en production devient insupportable ? \u00c0 propos de cela, ainsi que de Web Deploy, des tests, de CI, des pratiques d'utilisation de TFS dans les projets existants, et bien s\u00fbr des b\u00e9quilles cass\u00e9es et des solutions fonctionnelles, dans la transcription de la pr\u00e9sentation d'Alexandre.<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=\"Lire la vid\u00e9o\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nDonc, Vasya est parti, la t\u00e2che est maintenant sur moi, les d\u00e9veloppeurs attendent impatiemment avec des fourches. Quand j'ai finalement r\u00e9alis\u00e9 que je ne pouvais pas ramener Vasya, je me suis attel\u00e9 \u00e0 la t\u00e2che. D'abord, j'ai \u00e9valu\u00e9 le pourcentage de VM Windows dans notre parc. Le d\u00e9compte n'\u00e9tait pas en faveur de Windows.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/836e47372126b6ba369ac494b91c7d3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComme nous d\u00e9veloppons activement DevOps, j'ai compris qu'il fallait changer notre approche pour le lancement d'une nouvelle application. La solution \u00e9tait claire : essayer de migrer tout vers Linux. Google m'a aid\u00e9 \u2013 \u00e0 ce moment-l\u00e0, .Net avait d\u00e9j\u00e0 \u00e9t\u00e9 port\u00e9 sous Linux, et j'ai compris que c'\u00e9tait la solution !<\/p>\n<h2>Pourquoi .NET core associ\u00e9 \u00e0 Linux ?<\/h2>\n<p>\nIl y avait plusieurs raisons \u00e0 cela. Entre 'payer de l'argent' et 'ne pas payer', la plupart des gens choisiront la seconde option \u2013 tout comme moi. La licence pour MSDB co\u00fbte environ 1 000 $. L'entretien du parc de machines virtuelles Windows s'\u00e9l\u00e8ve \u00e0 des centaines de dollars. Pour une grande entreprise, c'est un co\u00fbt significatif. Donc <b>les \u00e9conomies\u00a0<\/b>\u2014<b> la premi\u00e8re raison<\/b>. Ce n'est pas la plus importante, mais c'est l'une des plus significatives.<\/p>\n<p>Les machines virtuelles Windows consomment plus de ressources que leurs homologues Linux \u2013 <b>elles sont lourdes<\/b>. \u00c9tant donn\u00e9 l'\u00e9chelle d'une grande entreprise, nous avons choisi Linux.<\/p>\n<p><b>Le syst\u00e8me s'int\u00e8gre simplement dans le CI existant.<\/b>. Nous nous consid\u00e9rons comme des DevOps progressistes, utilisant Bamboo, Jenkins et GitLab CI, donc la plupart de nos op\u00e9rations se font sur Linux.<\/p>\n<p>La derni\u00e8re raison est <b>un accompagnement pratique. <\/b>Nous devions r\u00e9duire la barri\u00e8re d'entr\u00e9e pour les 'accompagnateurs' \u2013 les personnes qui comprennent la partie technique, assurent la continuit\u00e9 et g\u00e8rent les services de deuxi\u00e8me ligne. Ils \u00e9taient d\u00e9j\u00e0 familiaris\u00e9s avec l'\u00e9cosyst\u00e8me Linux, il leur \u00e9tait donc beaucoup plus facile de comprendre, soutenir et accompagner le nouveau produit que de consacrer des ressources suppl\u00e9mentaires \u00e0 d\u00e9couvrir des fonctionnalit\u00e9s similaires de logiciels pour la plateforme Windows.<\/p>\n<h2>Exigences<\/h2>\n<p>\nLa premi\u00e8re et principale est <b>la commodit\u00e9 de la nouvelle solution pour les d\u00e9veloppeurs<\/b>. Tous ne se sont pas montr\u00e9s pr\u00eats au changement, surtout apr\u00e8s avoir entendu le mot Linux. Les d\u00e9veloppeurs veulent leur Visual Studio pr\u00e9f\u00e9r\u00e9, TFS avec des tests automatis\u00e9s sur les builds et des smoothies. Peu importe comment cela arrive en production pour eux. C'est pourquoi nous avons d\u00e9cid\u00e9 de ne pas changer le processus habituel et de laisser tout inchang\u00e9 pour le d\u00e9veloppement Windows. <\/p>\n<p>Le nouveau projet doit <b>s'int\u00e9grer dans le CI existant.<\/b>. Les rails \u00e9taient d\u00e9j\u00e0 en place et tout le travail devait \u00eatre effectu\u00e9 en tenant compte des param\u00e8tres du syst\u00e8me de gestion de configuration, des standards de livraison accept\u00e9s et des syst\u00e8mes de monitoring.<\/p>\n<p><b>La simplicit\u00e9 de maintenance et d'exploitation<\/b>, comme condition pour un faible seuil d'entr\u00e9e pour tous les nouveaux participants des diff\u00e9rents d\u00e9partements et du service de support.<\/p>\n<p><b>La date limite \u00e9tait hier.<\/b>.<\/p>\n<h2>L'\u00e9quipe de d\u00e9veloppement Win.<\/h2>\n<p>\nAvec quoi travaillait alors l'\u00e9quipe Windows ?<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/6e6e128ef3d49410c260d05114f819a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMaintenant, je peux dire avec confiance que <b>IdentityServer4<\/b>\u00a0c'est une excellente alternative gratuite \u00e0 ADFS avec des capacit\u00e9s similaires, ou que <b>Entity Framework Core<\/b>\u00a0est un paradis pour les d\u00e9veloppeurs, o\u00f9 il n'est pas n\u00e9cessaire de se soucier d'\u00e9crire des scripts SQL, mais de d\u00e9crire les requ\u00eates dans la base de donn\u00e9es en termes de POO. Mais \u00e0 cette \u00e9poque, lors de la discussion du plan d'action, je consid\u00e9rais cette pile comme une \u00e9criture cun\u00e9iforme sum\u00e9rienne, ne reconnaissant que PostgreSQL et Git.<\/p>\n<p>\u00c0 ce moment-l\u00e0, nous utilisions activement <b>Puppet<\/b> comme syst\u00e8me de gestion de configuration. Dans la plupart de nos projets, nous appliquions <b>GitLab CI<\/b>, <b>Elastic<\/b>, nous \u00e9quilibrions des services \u00e0 forte charge \u00e0 l'aide de <b>HAProxy,<\/b> nous surveillions tout gr\u00e2ce \u00e0 <b>Zabbix<\/b>, li\u00e9 \u00e0 <b>Grafana<\/b> et\u00a0<b>Prometheus<\/b>, <b>Jaeger<\/b>, et tout cela tournait sur du mat\u00e9riel\u00a0<b>HP<\/b> c\u00a0<b>ESXi.<\/b> sur\u00a0<b>VMware<\/b>Tout le monde conna\u00eet \u2013 la classe du genre.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/f4ffcac7a7fbb4fa48d47f07bed52610.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nExaminons et essayons de comprendre ce qui s'est pass\u00e9 avant que nous ne commencions toutes ces interventions.<\/p>\n<h2>Ce qui s'est pass\u00e9<\/h2>\n<p>\nTFS est un syst\u00e8me assez puissant qui non seulement livre le code du d\u00e9veloppeur au serveur de production final, mais qui dispose \u00e9galement d'un ensemble pour une int\u00e9gration tr\u00e8s flexible avec divers services pour assurer l'int\u00e9gration continue au niveau multiplateforme.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/ea448b38e321a8350468d69f3e45e429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nAuparavant, il y avait de nombreuses fen\u00eatres. TFS utilisait plusieurs agents de build, sur lesquels de nombreux projets \u00e9taient construits. Chaque agent avait 3-4 travailleurs pour parall\u00e9liser les t\u00e2ches et optimiser le processus. Ensuite, selon les plans de publication, TFS livrait le Build fra\u00eechement cuit sur un serveur Windows.<\/p>\n<h2>Vers quoi nous visions<\/h2>\n<p>\nPour la livraison et le d\u00e9veloppement, nous utilisons TFS, et nous ex\u00e9cutons l'application sur un serveur d'applications Linux, avec un peu de magie entre les deux. Cette <b>bo\u00eete magique<\/b> est l'essence du travail \u00e0 venir. Avant de la d\u00e9composer, je vais faire une pause et dire quelques mots sur l'application.<\/p>\n<h2>Projet<\/h2>\n<p>\nL'application fournit des fonctionnalit\u00e9s pour g\u00e9rer des cartes pr\u00e9pay\u00e9es. <\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/c93aa67b340c45ad279330466fc4f776.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Client<\/h3>\n<p>\nIl y avait deux types d'utilisateurs. <b>Premier<\/b> acqu\u00e9rait l'acc\u00e8s en s'authentifiant avec un certificat SSL SHA-2. Le\u00a0<b>deuxi\u00e8me<\/b> avait acc\u00e8s par identifiant et mot de passe.<\/p>\n<h3>HAProxy<\/h3>\n<p>\nEnsuite, la demande client passait par HAProxy, qui r\u00e9solvait les t\u00e2ches suivantes :<\/p>\n<ul>\n<li>premi\u00e8re autorisation;\n<\/li>\n<li>terminaison SSL;\n<\/li>\n<li>optimisation des requ\u00eates HTTP;\n<\/li>\n<li>transmission des requ\u00eates.\n<\/li>\n<\/ul>\n<p>\nLa v\u00e9rification du certificat client se faisait en cha\u00eene. Nous sommes <b>autorit\u00e9 <\/b>et nous pouvons nous permettre cela car nous d\u00e9livrons nous-m\u00eames des certificats aux clients du service.<\/p>\n<p>Faites attention au troisi\u00e8me point, nous y reviendrons un peu plus tard.<\/p>\n<h3>Backend<\/h3>\n<p>\nNous pr\u00e9voyions de faire le backend sur Linux. Le backend interagit avec la base de donn\u00e9es, charge la liste n\u00e9cessaire des privil\u00e8ges et ensuite, en fonction des privil\u00e8ges du utilisateur authentifi\u00e9, donne acc\u00e8s \u00e0 la signature de documents financiers et \u00e0 leur envoi pour ex\u00e9cution, ou \u00e0 la g\u00e9n\u00e9ration de tout rapport.<\/p>\n<h2>\u00c9conomie avec HAProxy<\/h2>\n<p>\nEn plus des deux contextes par lesquels chaque client passait, il y avait \u00e9galement un contexte d'identit\u00e9. <b>IdentityServer4<\/b> qui permet justement de s'authentifier, c'est un analogue gratuit et puissant de <b>ADFS\u00a0<\/b>\u2014<b> Services d'Application de F\u00e9d\u00e9ration Active Directory<\/b>.<\/p>\n<p>La requ\u00eate dans l'identit\u00e9 \u00e9tait trait\u00e9e en plusieurs \u00e9tapes. La premi\u00e8re \u00e9tape <b>client<\/b> <b>\u00e9tait envoy\u00e9e au backend<\/b>, qui \u00e9changeait des donn\u00e9es avec ce serveur et v\u00e9rifiait la pr\u00e9sence d'un jeton pour le client. S'il n'en trouvait pas, la requ\u00eate \u00e9tait renvoy\u00e9e au contexte d'origine, mais avec une redirection, et la redirection se faisait vers identity.<\/p>\n<p>La deuxi\u00e8me \u00e9tape consistait \u00e0 ce que la requ\u00eate atteigne <b>la page d'authentification dans IdentityServer,<\/b> o\u00f9 le client s'enregistrait, et dans la base de donn\u00e9es d'IdentityServer apparaissait ce fameux jeton tant attendu. <\/p>\n<p>La troisi\u00e8me \u00e9tape \u2013 <b>le client \u00e9tait redirig\u00e9 vers <\/b>le contexte d'origine.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/e052c408d67485ab9aa10d0fd25df57e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIdentityServer4 a une particularit\u00e9 : <b>la r\u00e9ponse \u00e0 la requ\u00eate inverse est renvoy\u00e9e par HTTP<\/b>. Peu importe combien nous avons bataill\u00e9 avec la configuration du serveur, peu importe combien nous nous sommes \u00e9clair\u00e9s gr\u00e2ce \u00e0 la documentation, nous recevions \u00e0 chaque fois la requ\u00eate initiale du client avec une URL venant par HTTPS, tandis qu'IdentityServer renvoyait le m\u00eame contexte, mais avec HTTP. Nous \u00e9tions choqu\u00e9s ! Nous avons donc transf\u00e9r\u00e9 tout cela \u00e0 travers le contexte identity sur HAProxy, et avons d\u00fb modifier le protocole HTTP en HTTPS dans les en-t\u00eates. <\/p>\n<p>Quelle am\u00e9lioration et o\u00f9 avons-nous \u00e9conomis\u00e9 ?<\/p>\n<blockquote><p>Nous avons \u00e9conomis\u00e9 de l'argent en utilisant une solution gratuite pour l'authentification d'un groupe d'utilisateurs, des ressources, car nous n'avons pas extran\u00e9 IdentityServer4 en tant que n\u0153ud distinct dans un segment s\u00e9par\u00e9, mais l'avons utilis\u00e9 conjointement avec le backend sur le m\u00eame serveur que celui o\u00f9 le backend de l'application fonctionne.<\/p><\/blockquote>\n<p><\/p>\n<h2>Comment cela devrait fonctionner<\/h2>\n<p>\nAlors, comme je l'ai promis \u2013 Magic Box. Nous comprenons d\u00e9j\u00e0 que nous nous dirigeons assur\u00e9ment vers Linux. Formulons les t\u00e2ches sp\u00e9cifiques qui n\u00e9cessitaient une solution.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/cc59632aa0e5c65fe0efc754311ecf5e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Les manifestes Puppet. <\/b>Pour livrer et g\u00e9rer la configuration du service et de l'application, il fallait \u00e9crire de superbes recettes. Le petit rouleau avec un crayon montre clairement \u00e0 quelle vitesse et qualit\u00e9 cela a \u00e9t\u00e9 effectu\u00e9.<\/p>\n<p><b>Mode de livraison. <\/b>La norme est RPM. Tout le monde sait qu'en Linux, c'est indispensable, mais le projet lui-m\u00eame, une fois construit, se composait d'un ensemble de fichiers DLL ex\u00e9cutables. Il y en avait environ 150, le projet \u00e9tant assez lourd. La seule solution harmonieuse \u00e9tait d'emballer ce binaire dans un RPM et de d\u00e9ployer l'application \u00e0 partir de celui-ci.<\/p>\n<p><b>Versioning. <\/b>Nous devions d\u00e9ployer tr\u00e8s souvent et il fallait d\u00e9cider comment former le nom du paquet. C'est une question d'int\u00e9gration avec TFS. L'agent de build que nous avions \u00e9tait sous Linux. Lorsque TFS envoie une t\u00e2che au worker sur l'agent de build, il lui transmet \u00e9galement un ensemble de variables qui sont int\u00e9gr\u00e9es dans l'environnement du processus du worker. Ces variables d'environnement incluent le nom du Build, le nom de la version et d'autres variables. Plus de d\u00e9tails \u00e0 ce sujet dans la section \u00ab construction du paquet RPM \u00bb.<\/p>\n<p><b>Configuration de TFS<\/b> se limitait \u00e0 la configuration du Pipeline. Auparavant, nous construisions tous les projets Windows sur des agents Windows, mais maintenant un agent Linux - l'agent de build - doit \u00eatre int\u00e9gr\u00e9 dans le groupe de construction, enrichi avec certains artefacts, et il faut sp\u00e9cifier quels types de projets seront construits sur cet agent de build et comment modifier le Pipeline.<\/p>\n<p><b>IdentityServer. <\/b>ADFS n'est pas notre voie, nous optons pour l'Open Source.<\/p>\n<p>Passons en revue les composants.<\/p>\n<h2>bo\u00eete magique<\/h2>\n<p>\nIl se compose de quatre parties.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" 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, car nous d\u00e9veloppons pour lui - c'est logique. Cette partie s'est d\u00e9roul\u00e9e en trois \u00e9tapes.<\/p>\n<ul>\n<li><b>Configurer les workers<\/b> et pas un seul, car un travail distribu\u00e9 \u00e9tait pr\u00e9vu sur le projet.\n<\/li>\n<li><b>Installer .NET Core 1.x<\/b>. Pourquoi 1.x, alors que 2.0 est d\u00e9j\u00e0 disponible dans le d\u00e9p\u00f4t standard ? Parce que, lorsque nous avons commenc\u00e9 le d\u00e9veloppement, la version stable \u00e9tait 1.09, et le projet a \u00e9t\u00e9 d\u00e9cid\u00e9 de le faire pour cette version.\n<\/li>\n<li><b>Git 2.x<\/b>.\n<\/li>\n<\/ul>\n<p>\n<b>D\u00e9p\u00f4t RPM. <\/b>Les paquets RPM devaient \u00eatre stock\u00e9s quelque part. Il \u00e9tait pr\u00e9vu que nous utiliserions le m\u00eame d\u00e9p\u00f4t RPM d'entreprise qui est accessible \u00e0 tous les h\u00f4tes Linux. C'est ce que nous avons fait. Sur le serveur du d\u00e9p\u00f4t, un <b>webhook<\/b> a \u00e9t\u00e9 configur\u00e9 pour t\u00e9l\u00e9charger le paquet RPM requis \u00e0 partir de l'emplacement sp\u00e9cifi\u00e9. La version du paquet \u00e9tait communiqu\u00e9e au webhook par l'agent de build.<\/p>\n<p><b>GitLab. <\/b>Attention ! GitLab ici n'est pas utilis\u00e9 par les d\u00e9veloppeurs, mais par le service d'exploitation pour le contr\u00f4le de version des applications, des versions de paquets, le suivi de l'\u00e9tat de toutes les machines Linux et il contient la recette - tous les manifestes Puppet. <\/p>\n<p><b>Puppet<\/b>\u00a0\u2013 r\u00e9sout tous les probl\u00e8mes discutables et fournit exactement la configuration que nous voulons, depuis GitLab.<\/p>\n<p>Nous commen\u00e7ons \u00e0 plonger. Comment se fait la livraison de DLL dans RPM ?<\/p>\n<h3>Livraison DDL dans RPM<\/h3>\n<p>\nSupposons que nous avons une rock star du d\u00e9veloppement sous .NET. Il utilise Visual Studio et cr\u00e9e une branche de release. Apr\u00e8s cela, il la t\u00e9l\u00e9charge sur Git, et Git ici est une entit\u00e9 TFS, c'est-\u00e0-dire que c'est le d\u00e9p\u00f4t de l'application avec lequel le d\u00e9veloppeur travaille.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/978240886981d41fc6d7b17d0a4fcb05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nApr\u00e8s quoi TFS constate qu'un nouveau commit a \u00e9t\u00e9 re\u00e7u. Quelle application ? Dans les param\u00e8tres de TFS, il existe une \u00e9tiquette indiquant quelles ressources poss\u00e8de chaque agent de Build. Dans ce cas, il voit que nous construisons un projet .NET Core et s\u00e9lectionne un agent de Build Linux dans le pool. <\/p>\n<p>L'agent de Build obtient les sources, t\u00e9l\u00e9charge les n\u00e9cessaires <b>d\u00e9pendances<\/b> du d\u00e9p\u00f4t .NET, npm, etc. et apr\u00e8s la construction de l'application elle-m\u00eame et l'emballage ult\u00e9rieur, envoie le paquet RPM dans le d\u00e9p\u00f4t RPM.<\/p>\n<p>D'un autre c\u00f4t\u00e9, cela se passe ainsi. L'ing\u00e9nieur du d\u00e9partement d'exploitation s'occupe de la mise en production du projet : il modifie les versions des paquets dans\u00a0<b>Hiera<\/b> dans le d\u00e9p\u00f4t o\u00f9 est stock\u00e9e la recette de l'application, apr\u00e8s quoi Puppet d\u00e9clenche <b>Yum<\/b>, prend le nouveau paquet du d\u00e9p\u00f4t, et la nouvelle version de l'application est pr\u00eate \u00e0 \u00eatre utilis\u00e9e.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/6c2db3ce4bd7d4268e88c6c3d3ecbeba.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn th\u00e9orie, tout est simple, mais que se passe-t-il \u00e0 l'int\u00e9rieur de l'agent de Build ?<\/p>\n<h3>Emballage DLL RPM<\/h3>\n<p>\nLes sources du projet ont \u00e9t\u00e9 re\u00e7ues et la t\u00e2che de construction de TFS. L'agent de Build <b>d\u00e9marre la construction du projet \u00e0 partir des sources.<\/b>Le projet construit est disponible sous la forme de plusieurs <b>fichiers DLL<\/b>, qui sont emball\u00e9s dans une archive zip pour r\u00e9duire la charge sur le syst\u00e8me de fichiers.<\/p>\n<p>L'archive ZIP est plac\u00e9e <b>dans le r\u00e9pertoire de construction du paquet RPM.<\/b> Ensuite, un script Bash initialise les variables d'environnement, trouve la version du Build, la version du projet, le chemin vers le r\u00e9pertoire de construction, et lance RPM-build. \u00c0 la fin de la construction, le paquet est publi\u00e9 dans\u00a0<b>le d\u00e9p\u00f4t local<\/b>, qui se trouve sur l'agent de Build.<\/p>\n<p>Ensuite, de l'agent de Build au serveur dans le d\u00e9p\u00f4t RPM <b>un JSON est envoy\u00e9<\/b> indiquant le nom de la version et du Build. Le webhook, dont j'ai parl\u00e9 pr\u00e9c\u00e9demment, r\u00e9cup\u00e8re ce paquet dans le d\u00e9p\u00f4t local sur l'agent de Build et rend une nouvelle construction disponible pour installation.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/b69cacdadd171f4cbc9913b2ff4b7a79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPourquoi ce sch\u00e9ma de livraison du paquet dans le d\u00e9p\u00f4t RPM ? Pourquoi ne pas envoyer directement le paquet construit au d\u00e9p\u00f4t ? Cela est d\u00fb au fait que cette condition garantit la s\u00e9curit\u00e9. Un tel sc\u00e9nario limite la possibilit\u00e9 de chargement non autoris\u00e9 de paquets RPM par des personnes ext\u00e9rieures sur le serveur, qui est accessible \u00e0 toutes les machines Linux.<\/p>\n<h2>Versionnage de la BDD<\/h2>\n<p>\nLors d'un conseil avec le d\u00e9veloppement, il est apparu que les gars pr\u00e9f\u00e9raient MS SQL, mais dans la plupart des projets non-Windows, nous utilisions d\u00e9j\u00e0 PostgreSQL. Comme nous avions d\u00e9cid\u00e9 de nous passer de tout ce qui \u00e9tait payant, nous avons commenc\u00e9 \u00e0 utiliser PostgreSQL ici aussi.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/6b6c081344f2408c399248a70a63dccc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDans cette partie, je vais expliquer comment nous avons g\u00e9r\u00e9 la versionnage de la base de donn\u00e9es et comment nous avons choisi entre Flyway et Entity Framework Core. Examinons leurs avantages et inconv\u00e9nients.<\/p>\n<h3>Inconv\u00e9nients<\/h3>\n<p>\nFlyway n'op\u00e8re que dans un sens, nous\u00a0<b>ne pouvons pas revenir en arri\u00e8re<\/b>\u00a0\u2014 c'est un inconv\u00e9nient majeur. La comparaison avec Entity Framework Core peut se faire sur d'autres crit\u00e8res \u2014 en termes de commodit\u00e9 pour le d\u00e9veloppeur. Vous vous rappelez que nous avons mis cela en avant, et le crit\u00e8re principal \u00e9tait de ne rien changer pour le d\u00e9veloppement sous Windows.<\/p>\n<p>Pour Flyway, nous <b>avions besoin d'une sorte d'enveloppe<\/b>, afin que les d\u00e9veloppeurs n'\u00e9crivent pas <b>des requ\u00eates SQL<\/b>. Il leur est beaucoup plus facile de travailler en termes de POO. Nous avons r\u00e9dig\u00e9 des instructions pour travailler avec les objets de la base de donn\u00e9es, une requ\u00eate SQL a \u00e9t\u00e9 form\u00e9e et ex\u00e9cut\u00e9e. La nouvelle version de la base de donn\u00e9es est pr\u00eate, \u00e7a a fonctionn\u00e9 \u2014 tout va bien, tout fonctionne.<\/p>\n<p>Entity Framework Core a un inconv\u00e9nient \u2014 sous de fortes charges, il\u00a0<b>g\u00e9n\u00e8re des requ\u00eates SQL non optimales<\/b>, et la diminution de la base de donn\u00e9es peut \u00eatre significative. Mais comme nous n'avons pas un service \u00e0 forte charge, nous ne mesurons pas la charge en centaines de RPS, nous avons pris ces risques et avons d\u00e9l\u00e9gu\u00e9 le probl\u00e8me \u00e0 notre futur nous.<\/p>\n<h3>Avantages<\/h3>\n<p>\nEntity Framework Core <b>fonctionne d\u00e8s la sortie de la bo\u00eete et est pratique pour le d\u00e9veloppement<\/b>, tandis que Flyway <b>s'int\u00e8gre facilement dans le CI existant<\/b>. Mais nous voulons rendre les choses simples pour les d\u00e9veloppeurs :)<\/p>\n<h3>La proc\u00e9dure de d\u00e9ploiement<\/h3>\n<p>\nPuppet v\u00e9rifie les modifications de version des paquets, y compris celui qui est responsable de la migration. Il commence par installer le paquet contenant les scripts de migration et les fonctions li\u00e9es \u00e0 la base de donn\u00e9es. Ensuite, l'application qui interagit avec la base de donn\u00e9es red\u00e9marre. Ensuite, les composants restants sont install\u00e9s. L'ordre d'installation des paquets et de lancement des applications est d\u00e9crit dans le manifeste Puppet.<\/p>\n<p>Les applications utilisent des donn\u00e9es sensibles, telles que des tokens, des mots de passe de base de donn\u00e9es, tout cela est r\u00e9cup\u00e9r\u00e9 dans la configuration depuis Puppet master, o\u00f9 elles sont stock\u00e9es sous forme chiffr\u00e9e.<\/p>\n<h2>Probl\u00e8mes TFS<\/h2>\n<p>\nApr\u00e8s avoir confirm\u00e9 que tout fonctionne r\u00e9ellement, j'ai d\u00e9cid\u00e9 de v\u00e9rifier les constructions dans TFS pour l'ensemble du d\u00e9partement de d\u00e9veloppement Windows sur d'autres projets \u2014 pour voir si nous construisons\/relan\u00e7ons rapidement ou non, et j'ai d\u00e9couvert des probl\u00e8mes majeurs de vitesse.<\/p>\n<p>Un des projets principaux se construit en 12-15 minutes \u2014 c'est long, il est impossible de fonctionner ainsi. Une analyse rapide a montr\u00e9 un ralentissement terrible au niveau des E\/S, et cela sur des tableaux.<\/p>\n<p>Apr\u00e8s une analyse par composant, j'ai identifi\u00e9 trois foyers. Le premier \u2014 <b>\u00abKaspersky antivirus\u00bb<\/b>, qui scanne les sources sur tous les agents de build Windows. Deuxi\u00e8me \u2014 <b>Windows<\/b> <b>Indexeur.<\/b> Il n'a pas \u00e9t\u00e9 d\u00e9sactiv\u00e9, et tout \u00e9tait index\u00e9 en temps r\u00e9el sur les agents de build durant le processus de d\u00e9ploiement. <\/p>\n<p>Troisi\u00e8me \u2014 <b>Npm install. <\/b>Il s'est av\u00e9r\u00e9 que dans la plupart des Pipelines, nous utilisions ce script. Quel est son probl\u00e8me ? La proc\u00e9dure Npm install s'ex\u00e9cute lors de la construction de l'arbre des d\u00e9pendances dans\u00a0<b>package-lock.json<\/b>, o\u00f9 les versions des paquets qui seront utilis\u00e9es pour construire le projet sont enregistr\u00e9es. Le probl\u00e8me, c'est que Npm install tire \u00e0 chaque fois les versions les plus r\u00e9centes des paquets depuis internet, ce qui prend beaucoup de temps dans le cas d'un grand projet.<\/p>\n<blockquote><p>Les d\u00e9veloppeurs exp\u00e9rimentent parfois sur leur machine locale pour v\u00e9rifier le bon fonctionnement d'une partie ou du projet dans son ensemble. Parfois, il arrivait que tout fonctionne bien localement, mais en construisant et d\u00e9ployant \u2014 rien ne marchait. Nous commen\u00e7ons \u00e0 enqu\u00eater sur le probl\u00e8me \u2014 ah, diff\u00e9rentes versions des paquets avec d\u00e9pendances.<\/p><\/blockquote>\n<p><\/p>\n<h3>Solution<\/h3>\n<p><\/p>\n<ul>\n<li>Sources dans les exceptions AV.\n<\/li>\n<li>D\u00e9sactivation de l'indexation.\n<\/li>\n<li>Passage \u00e0\u00a0<b>npm ci<\/b>.\n<\/li>\n<\/ul>\n<p>\nL'avantage de npm ci, c'est que nous\u00a0<b>construisons l'arbre des d\u00e9pendances une seule fois<\/b>, et avons la possibilit\u00e9 de fournir au d\u00e9veloppeur <b>une liste \u00e0 jour des paquets<\/b>, avec laquelle il peut exp\u00e9rimenter localement autant qu'il veut. Cela <b>\u00e9conomise du temps<\/b> des d\u00e9veloppeurs qui \u00e9crivent le code.<\/p>\n<h3>Configuration<\/h3>\n<p>\n\u00c0 pr\u00e9sent, un peu sur la configuration du d\u00e9p\u00f4t. Historiquement, nous utilisons <b>Nexus<\/b> pour la gestion des d\u00e9p\u00f4ts, y compris <b>REPO Interne<\/b>. Ce d\u00e9p\u00f4t interne re\u00e7oit tous les composants que nous utilisons pour des besoins internes, comme nos propres outils de monitoring.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core sur Linux, DevOps en pleine forme\" src=\"\/wp-content\/uploads\/2019\/04\/147d7e80bf20e03a232f8b533be316eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNous utilisons \u00e9galement <b>NuGet<\/b>, car il met en cache mieux par rapport aux autres gestionnaires de paquets.<\/p>\n<h3>R\u00e9sultat<\/h3>\n<p>\nApr\u00e8s avoir optimis\u00e9 les agents de build, le temps moyen de construction a \u00e9t\u00e9 r\u00e9duit de 12 minutes \u00e0 7.<\/p>\n<blockquote><p>Si l'on compte toutes les machines que nous aurions pu utiliser pour Windows, mais que nous avons transf\u00e9r\u00e9es sur Linux dans ce projet, nous avons \u00e9conomis\u00e9 environ 10 000 $. Et cela ne concerne que les licences, sans compter les co\u00fbts d'exploitation \u2014 c'est plus.<\/p><\/blockquote>\n<p><\/p>\n<h2>Plans<\/h2>\n<p>\nPour le prochain trimestre, nous avons planifi\u00e9 de travailler sur l'optimisation de la livraison du code.<\/p>\n<p><b>Passage \u00e0 une image Docker pr\u00e9-construite<\/b>. TFS est un excellent outil avec de nombreux plugins qui permettent d'int\u00e9grer dans le Pipeline, y compris la construction sur un d\u00e9clencheur, comme par exemple, l'image Docker. Nous voulons mettre en place ce d\u00e9clencheur sur celui-ci. <b>package-lock.json<\/b>. Si la composition des composants utilis\u00e9s pour assembler le projet change d'une mani\u00e8re ou d'une autre, nous construisons une nouvelle image Docker. Celle-ci est ensuite utilis\u00e9e pour d\u00e9ployer un conteneur avec l'application construite. Actuellement, cela n'existe pas, mais nous pr\u00e9voyons de nous orienter vers une architecture microservices dans Kubernetes, qui se d\u00e9veloppe activement dans notre entreprise et g\u00e8re depuis longtemps des solutions en production.<\/p>\n<h2>R\u00e9sum\u00e9<\/h2>\n<p>\nJ\u2019invite tout le monde \u00e0 abandonner Windows, mais ce n\u2019est pas parce que je ne sais pas le pr\u00e9parer. La raison est que la majeure partie des solutions open source est <b>une pile Linux<\/b>. Vous \u00e9conomiserez bien <b>sur les ressources<\/b>. \u00c0 mon avis, l'avenir appartient aux solutions open source sur Linux avec une communaut\u00e9 solide.<\/p>\n<p><i>Profil du conf\u00e9rencier Alexandre Sinchinov <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/alextuning\">sur GitHub<\/a><\/noindex>.<\/i><\/p>\n<blockquote><p><noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOps Conf<\/a><\/noindex>\u00a0est une conf\u00e9rence sur l'int\u00e9gration des processus de d\u00e9veloppement, de test et d'exploitation pour les professionnels par des professionnels. C'est pourquoi le projet dont Alexandre a parl\u00e9 est r\u00e9alis\u00e9 et fonctionne, et deux mises \u00e0 jour r\u00e9ussies ont \u00e9t\u00e9 effectu\u00e9es le jour de la pr\u00e9sentation.\u00a0<noindex><a rel=\"nofollow\" href=\"http:\/\/devopsconf.io\/moscow-rit\/2019\">DevOps Conf \u00e0 RIT++<\/a><\/noindex> Les 27 et 28 mai, il y aura encore plus de cas similaires de praticiens. Vous pouvez encore monter dans le dernier train et <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/lectures\/propose\/?conference=dc2019-rit\">soumettre une pr\u00e9sentation<\/a><\/noindex> ou tranquillement <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/conference\/join\/rit2019.html?popup=3\">r\u00e9server<\/a><\/noindex> votre billet. Nous nous retrouverons \u00e0 Skolkovo !<\/p><\/blockquote>\n<p>Source : <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 - 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\/fr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\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\/fr\/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 sur Linux, DevOps dans le vent | ProHoster","description":"Nous avons d\u00e9velopp\u00e9 DevOps autant que possible. Nous \u00e9tions 8 personnes, et Vasya \u00e9tait le meilleur pour Windows. Soudain, Vasya est parti, et j'ai eu la t\u00e2che de lancer un nouveau projet qui fournit le d\u00e9veloppement Windows.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/32217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=32217"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/32217\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/24043"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=32217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=32217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=32217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}