{"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\/da\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","title":{"rendered":".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Vi udviklede DevOps s\u00e5 godt, vi kunne. Vi var 8 personer, og Vasha var den bedste til Windows. Pludselig forlod Vasha, og jeg fik ansvaret for at f\u00f8re et nyt projekt, der skulle levere Windows-udvikling. Da jeg spredte hele stakken af Windows-udvikling ud p\u00e5 bordet, inds\u00e5 jeg, at situationen var problematisk\u2026<\/p>\n<p>S\u00e5dan begynder historien <b>Alexander Sinchivnov<\/b> og f\u00e5 en fungerende kommando. <noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOpsConf<\/a><\/noindex>. Da virksomhedens f\u00f8rende specialist i Windows forlod, stillede Alexander sig selv sp\u00f8rgsm\u00e5let, hvad han nu skulle g\u00f8re. Selvf\u00f8lgelig skulle han overg\u00e5 til Linux! Alexander vil fort\u00e6lle, hvordan han lykkedes med at skabe et pr\u00e6cedens og overf\u00f8re en del af Windows-udviklingen til Linux ved hj\u00e6lp af et projekt med 100.000 slutbrugere.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/3c944351864df95217e133236542c9b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHvordan kan man nemt og ubesv\u00e6ret levere et projekt i RPM ved brug af TFS, Puppet, Linux .NET core? Hvordan kan man opretholde versionering af projektets database, hvis udviklingen aldrig har h\u00f8rt om Postgres og Flyway, og deadline er i overmorgen? Hvordan integreres man med Docker? Hvordan motiverer man .NET-udviklere til at give afkald p\u00e5 Windows og smoothies til fordel for Puppet og Linux? Hvordan l\u00f8ser man ideologiske konflikter, hvis man ikke har hverken kr\u00e6fter, vilje eller ressourcer til at vedligeholde Windows i produktionen? Om dette, samt Web Deploy, test, CI, brugen af TFS i eksisterende projekter, og selvf\u00f8lgelig om de \u00f8delagte st\u00f8ttepiller og fungerende l\u00f8sninger, tales der i transkriptionen af Alexanders pr\u00e6sentation.<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=\"Afspil video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nS\u00e5 Vasha forlod, opgaven l\u00e5 p\u00e5 mig, udviklerne ventede ut\u00e5lmodigt. Da jeg endelig inds\u00e5, at jeg ikke kunne f\u00e5 Vasha tilbage, gik jeg i gang. F\u00f8rst vurderede jeg procentdelen af Windows VM i vores park. Resultatet var ikke til fordel for Windows.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/836e47372126b6ba369ac494b91c7d3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDa vi aktivt udvikler DevOps, inds\u00e5 jeg, at jeg m\u00e5tte \u00e6ndre tilgangen til udskiftningen af den nye applikation. Der var kun \u00e9n l\u00f8sning - at overf\u00f8re alt muligt til Linux. Google hjalp mig - p\u00e5 det tidspunkt var .Net allerede blevet porteret til Linux, og jeg inds\u00e5, at det var l\u00f8sningen!<\/p>\n<h2>Hvorfor .NET core i forbindelse med Linux?<\/h2>\n<p>\nDer var flere grunde til det. Mellem at \u00abbetale penge\u00bb og \u00abikke betale\u00bb vil de fleste v\u00e6lge det andet - ligesom jeg. Licensen til MSDB koster omkring 1.000 $, og vedligeholdelse af parken af Windows virtuelle maskiner koster hundredvis af dollars. For en stor virksomhed er det store omkostninger. Derfor <b>besparelser\u00a0<\/b>\u2014<b> er den f\u00f8rste grund<\/b>. Ikke den vigtigste, men en af de v\u00e6sentlige.<\/p>\n<p>Windows virtuelle maskiner kr\u00e6ver flere ressourcer end deres Linux-br\u00f8dre - <b>de er tunge<\/b>. I betragtning af skalaen af en stor virksomhed valgte vi Linux.<\/p>\n<p><b>Systemet integreres nemt i den eksisterende CI<\/b>. Vi betragter os som progressive DevOps'ere, bruger Bamboo, Jenkins og GitLab CI, s\u00e5 st\u00f8rstedelen af vores arbejde k\u00f8rer p\u00e5 Linux.<\/p>\n<p>Den sidste \u00e5rsag er <b>bekvem vedligeholdelse. <\/b>Vi havde brug for at s\u00e6nke indgangsbarriererne for \"vedligeholdere\" - folk, der forst\u00e5r den tekniske del, sikrer driften og vedligeholder tjenesterne fra anden linje. De var allerede bekendte med Linux-stakken, s\u00e5 det var meget nemmere for dem at forst\u00e5 det nye produkt, vedligeholde og supportere det, end at bruge ekstra ressourcer p\u00e5 at s\u00e6tte sig ind i tilsvarende funktionalitet for Windows-platforme.<\/p>\n<h2>Krav<\/h2>\n<p>\nF\u00f8rst og fremmest er <b>bekvemmeligheden ved den nye l\u00f8sning for udviklerne<\/b>. Ikke alle af dem var klar til \u00e6ndringer, is\u00e6r efter at have h\u00f8rt ordet Linux. Udviklerne \u00f8nsker deres elskede Visual Studio, TFS med automatiserede tests til builds og smoothies. Hvordan leveringen til produktionen sker, er ikke vigtigt for dem. Derfor besluttede vi at bevare den velkendte proces og lade Windows-udviklingen forblive u\u00e6ndret. <\/p>\n<p>Det nye projekt skal <b>integreres i den eksisterende CI<\/b>. Railsene var allerede p\u00e5 plads, og alt arbejde skulle udf\u00f8res med hensyntagen til konfigurationsstyringssystemets parametre, de vedtagne leveringsstandarder og overv\u00e5gningssystemerne.<\/p>\n<p><b>Simplicitet i vedligeholdelse og drift<\/b>, som en betingelse for den minimale indgangsbarriere for alle nye deltagere fra forskellige afdelinger og supportafdelingen.<\/p>\n<p><b>Deadline - i g\u00e5r<\/b>.<\/p>\n<h2>Windows-udviklingsgruppen<\/h2>\n<p>\nHvad arbejdede Windows-teamet s\u00e5 med?<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/6e6e128ef3d49410c260d05114f819a4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNu kan jeg med sikkerhed sige, at <b>IdentityServer4<\/b>\u00a0\u2014 det er et fantastisk gratis alternativ til ADFS med lignende funktionalitet, eller at <b>Entity Framework Core<\/b>\u00a0\u2014 er et paradis for udvikleren, hvor du ikke beh\u00f8ver at bekymre dig om at skrive SQL-scripts, men i stedet kan beskrive databaseforesp\u00f8rgsler i OOP-termer. Men dengang, under diskussionen af handlingsplanen, s\u00e5 jeg p\u00e5 dette stak som p\u00e5 sumerisk kileskrift og genkendte kun PostgreSQL og Git.<\/p>\n<p>P\u00e5 det tidspunkt brugte vi aktivt <b>Puppet<\/b> som konfigurationsstyringssystem. I de fleste af vores projekter anvendte vi <b>GitLab CI<\/b>, <b>Elastic<\/b>, balancerede h\u00f8jbelastede tjenester ved hj\u00e6lp af <b>HAProxy,<\/b> holdt \u00f8je med alt ved hj\u00e6lp af <b>Zabbix<\/b>, s\u00e6ttet <b>Grafana<\/b> og\u00a0<b>Prometheus<\/b>, <b>Jaeger<\/b>, og alt dette k\u00f8rte p\u00e5 hardware\u00a0<b>HP<\/b> c\u00a0<b>ESXi<\/b> og f\u00e5 en fungerende kommando.\u00a0<b>VMware<\/b>. Alle kender det - klassikeren i genren.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/f4ffcac7a7fbb4fa48d47f07bed52610.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLad os se og fors\u00f8ge at forst\u00e5, hvad der skete, f\u00f8r vi begyndte med alle disse indgreb.<\/p>\n<h2>Hvad der skete<\/h2>\n<p>\nTFS er et ret kraftfuldt system, der ikke kun leverer kode fra udvikleren til den endelige produktionsmaskine, men ogs\u00e5 har et s\u00e6t til meget fleksibel integration med forskellige tjenester - for at sikre CI p\u00e5 tv\u00e6rplatformsniveau.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/ea448b38e321a8350468d69f3e45e429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nTidligere var det blot et hav af vinduer. TFS brugte flere build-agenter, hvor mange projekter blev samlet. I hver agent var der 3-4 workere for at parallellisere opgaverne og optimere processen. Derefter, i henhold til udgivelsesplanerne, leverede TFS den friskbagte build til Windows-applikationsserveren.<\/p>\n<h2>Hvor vi \u00f8nskede at komme hen<\/h2>\n<p>\nTil levering og udvikling bruger vi TFS, og vi k\u00f8rer applikationen p\u00e5 Linux-applikationsserveren, og mellem dem er der en slags magi. Denne <b>Magic Box<\/b> er essensen af det kommende arbejde. F\u00f8r jeg g\u00e5r videre med at dele det op, vil jeg tage et skridt til siden og sige et par ord om applikationen.<\/p>\n<h2>Projekt<\/h2>\n<p>\nApplikationen giver funktionalitet til at h\u00e5ndtere forudbetalte kort. <\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/c93aa67b340c45ad279330466fc4f776.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Client<\/h3>\n<p>\nDer var to typer brugere. <b>F\u00f8rste<\/b> fik adgang ved at autentificere sig med et SSL SHA-2 certifikat. Den\u00a0<b>den anden<\/b> hadde adgang via login og adgangskode.<\/p>\n<h3>HAProxy<\/h3>\n<p>\nDerefter blev klientens anmodning sendt til HAProxy, som havde f\u00f8lgende opgaver:<\/p>\n<ul>\n<li>prim\u00e6r autorisering;\n<\/li>\n<li>terminering af SSL;\n<\/li>\n<li>tuning af HTTP-anmodninger;\n<\/li>\n<li>overs\u00e6ttelse af anmodninger.\n<\/li>\n<\/ul>\n<p>\nKontrol af klientens certifikat foregik i k\u00e6den. Vi - <b>myndighed <\/b>og vi kan tillade os det, da vi selv udsteder certifikater til servicekunderne.<\/p>\n<p>Bem\u00e6rk den tredje punkt, vi vil vende tilbage til det om lidt.<\/p>\n<h3>Backend<\/h3>\n<p>\nBackend blev planlagt til at blive lavet p\u00e5 Linux. Backend interagerer med databasen, henter den n\u00f8dvendige liste over privilegier, og derefter, afh\u00e6ngigt af hvilke privilegier den autoriserede bruger har, giver adgang til at underskrive finansielle dokumenter og sende dem til udf\u00f8relse, eller generere en eller anden rapport.<\/p>\n<h2>Besparelser med HAProxy<\/h2>\n<p>\nUdover de to kontekster, som hver af klienterne bev\u00e6gede sig igennem, var der ogs\u00e5 konteksten identity. <b>IdentityServer4<\/b> som netop tillader autentificering, det er et gratis og kraftfuldt alternativ til <b>ADFS\u00a0<\/b>\u2014<b> Active Directory Federation Services<\/b>.<\/p>\n<p>Anmodningen i identity blev behandlet i flere trin. Det f\u00f8rste trin - <b>client<\/b> <b>blev sendt til backend<\/b>, som udvekslede data med denne server og kontrollerede for tilstedev\u00e6relsen af en token for klienten. Hvis den ikke blev fundet, blev foresp\u00f8rgslen sendt tilbage til den sammenh\u00e6ng, som den kom fra, men allerede med en omdirigering, og med omdirigeringen gik den til identity.<\/p>\n<p>Det andet skridt var, at foresp\u00f8rgslen kom <b>til login-siden i IdentityServer,<\/b> hvor klienten registrerede sig, og i IdentityServer-databasen blev den eftertragtede token oprettet. <\/p>\n<p>Det tredje skridt var, <b>at klienten blev omdirigeret tilbage <\/b>til den sammenh\u00e6ng, som den kom fra.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/e052c408d67485ab9aa10d0fd25df57e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIdentityServer4 har en funktion: <b>svaret p\u00e5 den omvendte foresp\u00f8rgsel returneres via HTTP<\/b>. Uanset hvor meget vi k\u00e6mpede med serverkonfigurationen, hvor meget vi studerede dokumentationen, fik vi hver gang den oprindelige klientforesp\u00f8rgsel med en URL, der kom via HTTPS, og IdentityServer returnerede den samme sammenh\u00e6ng, men med HTTP. Vi var chokerede! Og vi mappede alt dette gennem identity-sammenh\u00e6ngen p\u00e5 HAProxy, hvor vi i headere m\u00e5tte \u00e6ndre protokollen fra HTTP til HTTPS. <\/p>\n<p>Hvad er forbedringen, og hvor sparede vi?<\/p>\n<blockquote><p>Vi sparede penge ved at bruge en gratis l\u00f8sning til godkendelse af en gruppe brugere, ressourcer, da vi ikke k\u00f8rte IdentityServer4 som en separat node i et separat segment, men brugte det sammen med backend'en p\u00e5 den samme server, hvor applikationens backend k\u00f8rer.<\/p><\/blockquote>\n<p><\/p>\n<h2>Hvordan det skal fungere<\/h2>\n<p>\nS\u00e5, som jeg lovede - Magic Box. Vi forst\u00e5r allerede, at vi garanteret bev\u00e6ger os mod Linux. Lad os formulere de specifikke opgaver, der kr\u00e6vede l\u00f8sning.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/cc59632aa0e5c65fe0efc754311ecf5e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Puppet-manifest. <\/b>For at levere og administrere konfigurationen af tjenesten og applikationen var det n\u00f8dvendigt at skrive fede opskrifter. Ruller med en blyant viser tydeligt, hvor hurtigt og effektivt dette blev gjort.<\/p>\n<p><b>Leveringsmetode. <\/b>Standarden er RPM. Alle forst\u00e5r, at man ikke kan undv\u00e6re det i Linux, men selve projektet efter kompilering bestod af et s\u00e6t k\u00f8rbare DLL-filer. Der var omkring 150, projektet var ret tungt. Den eneste harmoniske l\u00f8sning var at pakke dette bin\u00e6re i et RPM og derfra implementere applikationen.<\/p>\n<p><b>Versionering. <\/b>Vi skulle udgive meget ofte, og derfor skulle vi finde ud af, hvordan vi skulle danne pakke-navnet. Dette er et integrationssp\u00f8rgsm\u00e5l med TFS. Vores Build-agent var p\u00e5 Linux. N\u00e5r TFS sender en opgave til behandleren - worker - p\u00e5 Build-agenten, sender den ogs\u00e5 et b\u00e5nd af variabler, som kommer ind i milj\u00f8et af behandlingsprocessen. I disse milj\u00f8variabler overf\u00f8res navnet p\u00e5 Build, versionsnavnet og andre variabler. L\u00e6s mere om dette i afsnittet \"opbygning af RPM-pakke\".<\/p>\n<p><b>TFS-ops\u00e6tning<\/b> bestod i ops\u00e6tning af Pipeline. Tidligere samlede vi alle Windows-projekter p\u00e5 Windows-agenter, men nu kommer Linux-agenten - Build-agenten - som skal inkluderes i byggegruppen, beriges med nogle artefakter og specificeres hvilken type projekter der skal samles p\u00e5 denne Build-agent, og hvordan man modifiserer Pipeline.<\/p>\n<p><b>IdentityServer. <\/b>ADFS er ikke vores vej, vi st\u00f8tter Open Source.<\/p>\n<p>Lad os se n\u00e6rmere p\u00e5 komponenterne.<\/p>\n<h2>Magic Box<\/h2>\n<p>\nDen best\u00e5r af fire dele.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/22ea63bcf184046c15e034ec093352bb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Linux Build-agent. <\/b>Linux, fordi vi udvikler til det - logisk. Denne del blev udf\u00f8rt i tre trin.<\/p>\n<ul>\n<li><b>Konfigurer workerne<\/b> og ikke kun \u00e9n, da der var planlagt distribueret arbejde p\u00e5 projektet.\n<\/li>\n<li><b>Installer .NET Core 1.x<\/b>. Hvorfor netop 1.x, n\u00e5r 2.0 allerede er tilg\u00e6ngelig i det standardrepository? Fordi, da vi startede udviklingen, var den stabile version 1.09, og projektet blev besluttet at blive lavet til det.\n<\/li>\n<li><b>Git 2.x<\/b>.\n<\/li>\n<\/ul>\n<p>\n<b>RPM-repository. <\/b>RPM-pakkerne skulle opbevares et sted. Det var meningen, at vi skulle bruge det samme virksomhedsRPM-repository, som var tilg\u00e6ngeligt for alle Linux-hosts. S\u00e5dan gjorde vi det. P\u00e5 serveren hvor repository'en er oprettet <b>webhook<\/b> som downloader den n\u00f8dvendige RPM-pakke fra det angivne sted. Versionen af pakken blev meddelt webhook'en af Build-agenten.<\/p>\n<p><b>GitLab. <\/b>Opm\u00e6rksomhed! GitLab bruges her ikke af udviklerne, men af driftstabellen til versionskontrol af applikationen, versionerne af pakkerne, overv\u00e5gning af tilstanden p\u00e5 alle Linux-maskiner, og her opbevares opskriften - alle Puppet-manifestationer. <\/p>\n<p><b>Puppet<\/b>\u00a0\u2014\u2014 h\u00e5ndterer alle tvister og leverer netop den konfiguration, vi \u00f8nsker, fra Gitlab.<\/p>\n<p>Lad os dykke ned. Hvordan sker leveringen af DLL til RPM?<\/p>\n<h3>Levering af DLL til RPM<\/h3>\n<p>\nLad os sige, at vi har en rockstjerne udvikler p\u00e5 .NET. Han bruger Visual Studio og opretter en release-gren. Derefter uploader han den til Git, og Git her er en TFS-enhed, det vil sige, at det er repository'et for applikationen, som udvikleren arbejder med.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/978240886981d41fc6d7b17d0a4fcb05.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHereafter, TFS sees that a new commit has arrived. Which application? In the TFS settings, there is a label indicating what resources a particular Build agent has. In this case, it sees that we are building a .NET Core project and selects a Linux Build agent from the pool. <\/p>\n<p>The Build agent receives the sources, fetches the necessary <b>dependencies<\/b> from the .NET repository, npm, etc., and after building the application and subsequent packaging, sends the RPM package to the RPM repository.<\/p>\n<p>On the other hand, the following occurs. An engineer from the operations department is directly involved in deploying the project: changing package versions in\u00a0<b>Hiera<\/b> in the repository where the application recipe is stored, after which Puppet triggers <b>Yum<\/b>, retrieves the new package from the repository, and the new version of the application is ready for use.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/6c2db3ce4bd7d4268e88c6c3d3ecbeba.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn theory, it all sounds simple, but what happens inside on the Build agent?<\/p>\n<h3>Packaging DLL RPM<\/h3>\n<p>\nThe project sources have been received, and a build task from TFS is assigned. The Build agent <b>starts building the project from the sources.<\/b>The assembled project becomes available in the form of multiple <b>DLL files<\/b>, which are packed into a zip archive to reduce the load on the file system.<\/p>\n<p>The ZIP archive is thrown <b>into the RPM package build directory.<\/b> Next, a Bash script initializes environment variables, finds the Build version, the project version, the path to the build directory, and launches RPM-build. Upon completion of the build, the package is published to the\u00a0<b>local repository<\/b>, which is located on the Build agent.<\/p>\n<p>Next, from the Build agent to the server in the RPM repository <b>a JSON request is sent<\/b> indicating the version name and build. The webhook I mentioned earlier fetches this package from the local repository on the Build agent and makes the new build available for installation.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/b69cacdadd171f4cbc9913b2ff4b7a79.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWhy this specific package delivery scheme to the RPM repository? Why can\u2019t we immediately send the built package to the repository? The point is that this condition ensures security. This scenario limits the possibility of unauthorized uploads of RPM packages by outsiders to the server, which is accessible to all Linux machines.<\/p>\n<h2>Database versioning<\/h2>\n<p>\nAt a meeting with development, it turned out that the guys preferred MS SQL, but in most non-Windows projects, we had already been using PostgreSQL extensively. Since we decided to move away from all paid options, we started using PostgreSQL here as well.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/6b6c081344f2408c399248a70a63dccc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI denne del vil jeg fort\u00e6lle, hvordan vi implementerede versionering af databaser og hvordan vi valgte mellem Flyway og Entity Framework Core. Lad os se p\u00e5 deres fordele og ulemper.<\/p>\n<h3>Ulemper<\/h3>\n<p>\nFlyway fungerer kun i en retning, vi\u00a0<b>kan ikke rulle tilbage<\/b>\u00a0\u2014 det er en betydelig ulempe. Man kan sammenligne med Entity Framework Core p\u00e5 andre parametre \u2014 set fra udviklerens perspektiv. Du husker jo, at vi satte dette i h\u00f8js\u00e6det, og det prim\u00e6re kriterium var ikke at \u00e6ndre noget for Windows-udvikling.<\/p>\n<p>For Flyway kr\u00e6vede vi <b>en eller anden wrapper<\/b>, s\u00e5 folk ikke skulle skrive <b>SQL-foresp\u00f8rgsler<\/b>. De har det meget nemmere med at operere i termer af OOP. Vi skrev instruktioner til arbejdet med databaseobjekter, dannede SQL-foresp\u00f8rgslen og fik den udf\u00f8rt. Den nye databaseversion er klar, den har k\u00f8rt \u2014 alt er godt, alt fungerer.<\/p>\n<p>Entity Framework Core har en ulempe \u2014 under h\u00f8j belastning\u00a0<b>genererer den ikke optimale SQL-foresp\u00f8rgsler<\/b>, og faldet i databasen kan v\u00e6re betydeligt. Men da vi ikke har en h\u00f8jtydende tjeneste, m\u00e5ler vi ikke belastningen i hundreder af RPS, vi accepterede disse risici og delegerede problemet til fremtiden.<\/p>\n<h3>Fordele<\/h3>\n<p>\nEntity Framework Core <b>den fungerer ud af boksen og er praktisk for udviklere<\/b>, mens Flyway <b>nemt integreres i eksisterende CI<\/b>. Men vi \u00f8nsker jo at g\u00f8re det nemt for udviklerne :)<\/p>\n<h3>Proceduren for deployment<\/h3>\n<p>\nPuppet ser, at der kommer en \u00e6ndring i versionen af pakkerne, herunder den, der ansvarer for migration. F\u00f8rst installeres pakken, som indeholder migrationsscripts og funktionalitet knyttet til databasen. Derefter genstarter applikationen, der arbejder med databasen. Dern\u00e6st installeres de resterende komponenter. R\u00e6kkef\u00f8lgen af pakkeinstallationer og applikationsstart er beskrevet i Puppet-manifestet.<\/p>\n<p>Applikationerne bruger f\u00f8lsomme data, s\u00e5som token, adgangskoder til databasen, alt dette hentes i konfigurationen fra Puppet master, hvor de opbevares i krypteret form.<\/p>\n<h2>Problemer med TFS<\/h2>\n<p>\nEfter at vi havde fastsl\u00e5et og forst\u00e5et, at alt faktisk fungerede, besluttede jeg at se, hvad der skete med bygningerne i TFS generelt for afdelingen for Windows-udvikling p\u00e5 andre projekter \u2014 om vi hurtigt kan bygge\/release, og jeg opdagede betydelige problemer med hastigheden.<\/p>\n<p>Et af hovedprojekterne bygger p\u00e5 12-15 minutter \u2014 det er lang tid, s\u00e5 kan vi ikke leve s\u00e5dan. En hurtig analyse viste en skr\u00e6kkelig fald i I\/O, og det var p\u00e5 arrays.<\/p>\n<p>Ved at analysere komponent for komponent, identificerede jeg tre br\u00e6ndpunkter. Den f\u00f8rste \u2014 <b>\u00abKaspersky antivirus\u00bb<\/b>, der scanner kildekoden p\u00e5 alle Windows Build-agenter. Den anden - <b>Windows<\/b> <b>Indexer.<\/b> Den blev ikke deaktiveret, og alt blev indekseret i realtid p\u00e5 Build-agenterne under implementeringen. <\/p>\n<p>Den tredje - <b>Npm install. <\/b>Det viste sig, at vi i de fleste pipelines brugte netop dette script. Hvad er problemet? Npm install-proceduren k\u00f8res under opbygningen af afh\u00e6ngighedstr\u00e6et i\u00a0<b>package-lock.json<\/b>, hvor versionerne af de pakker, der skal anvendes til opbygning af projektet, bliver dokumenteret. Ulempen er, at Npm install hver gang henter de nyeste versioner af pakkerne fra internettet, hvilket kan tage lang tid i tilf\u00e6lde af et stort projekt.<\/p>\n<blockquote><p>Udviklere eksperimenterer nogle gange p\u00e5 deres lokale maskiner for at teste en bestemt del eller hele projektet. Nogle gange viste det sig, at alt fungerede fint lokalt, men n\u00e5r vi buildede og implementerede - s\u00e5 fungerede ingenting. Vi begynder at finde ud af, hvad problemet er - aha, forskellige versioner af pakker med afh\u00e6ngigheder.<\/p><\/blockquote>\n<p><\/p>\n<h3>L\u00f8sning<\/h3>\n<p><\/p>\n<ul>\n<li>Kildekoden i AV-udsagn.\n<\/li>\n<li>Deaktivering af indeksering.\n<\/li>\n<li>Overgang til\u00a0<b>npm ci<\/b>.\n<\/li>\n<\/ul>\n<p>\nFordelene ved npm ci er, at vi\u00a0<b>bygger afh\u00e6ngighedstr\u00e6et \u00e9n gang<\/b>, og f\u00e5r muligheden for at give udvikleren <b>en opdateret liste over pakker<\/b>, som han kan eksperimentere med lokalt s\u00e5 meget som han vil. Dette <b>spare tid<\/b> for udviklere, der skriver kode.<\/p>\n<h3>Konfiguration<\/h3>\n<p>\nLad os nu tales lidt om konfigurationen af repository'et. Historisk set bruger vi <b>Nexus<\/b> til styring af repositories, herunder <b>Internal REPO<\/b>. I dette interne repository leveres alle komponenter, som vi bruger til interne form\u00e5l, f.eks. brugerdefinerede overv\u00e5gninger.<\/p>\n<p><img decoding=\"async\" alt=\".NET Core p\u00e5 Linux, DevOps p\u00e5 toppen\" src=\"\/wp-content\/uploads\/2019\/04\/147d7e80bf20e03a232f8b533be316eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVi bruger ogs\u00e5 <b>NuGet<\/b>, da det bedre cache'er sammenlignet med andre pakkeforvaltere.<\/p>\n<h3>Resultat<\/h3>\n<p>\nEfter vi har optimeret Build-agenterne, er den gennemsnitlige opbygningstid reduceret fra 12 minutter til 7.<\/p>\n<blockquote><p>Hvis man tager h\u00f8jde for alle de maskiner, vi kunne have brugt til Windows, men i stedet valgte at bruge Linux i dette projekt, har vi sparet omkring $10.000. Og det er kun for licenser, og hvis man tager vedligeholdelsen med, s\u00e5 er det endnu mere.<\/p><\/blockquote>\n<p><\/p>\n<h2>Planer<\/h2>\n<p>\nFor det n\u00e6ste kvartal har vi planlagt arbejde med optimisering af kodeleveringen.<\/p>\n<p><b>Overgang til prebuild Docker-billede<\/b>. TFS er et fantastisk v\u00e6rkt\u00f8j med mange plugins, der muligg\u00f8r integration i pipeline, herunder bygning ved trigger, for eksempel Docker-billede. Denne trigger \u00f8nsker vi at lave p\u00e5 netop den <b>package-lock.json<\/b>. Hvis sammens\u00e6tningen af komponenter, der bruges til at samle projektet, \u00e6ndres p\u00e5 nogen m\u00e5de, s\u00e5 oprettes der et nyt Docker-billede. Dette billede bruges fremadrettet til at implementere en container med den samlede applikation. Dette er ikke aktuelt nu, men vi planl\u00e6gger at skifte til en mikrotjenestearkitektur i Kubernetes, som aktivt udvikles i vores virksomhed og l\u00e6nge har betjent produktionsl\u00f8sninger.<\/p>\n<h2>CV<\/h2>\n<p>\nJeg opfordrer alle til at kaste Windows v\u00e6k, men det er ikke, fordi jeg ikke kan lave den. \u00c5rsagen er, at st\u00f8rstedelen af opensource-l\u00f8sningerne er <b>Linux-stakken<\/b>. I skal spare godt <b>p\u00e5 ressourcer<\/b>. Efter min mening er fremtiden i open source-l\u00f8sninger p\u00e5 Linux med et st\u00e6rkt community.<\/p>\n<p><i>Profilen af taleren Alexander Sinchinov <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/alextuning\">p\u00e5 GitHub<\/a><\/noindex>.<\/i><\/p>\n<blockquote><p><noindex><a rel=\"nofollow\" href=\"https:\/\/devopsconf.io\/\">DevOps Conf<\/a><\/noindex>\u00a0\u2014 det er en konference om integration af udviklings-, test- og driftsprocesser for fagfolk af fagfolk. Derfor er projektet, som Alexander fortalte om, blevet realiseret og fungerer, og der er blevet gennemf\u00f8rt to succesfulde udgivelser p\u00e5 dagen for pr\u00e6sentationen.\u00a0<noindex><a rel=\"nofollow\" href=\"http:\/\/devopsconf.io\/moscow-rit\/2019\">P\u00e5 DevOps Conf p\u00e5 RIT++<\/a><\/noindex> den 27. og 28. maj vil der v\u00e6re endnu flere s\u00e5danne casestudier fra praktikere. Du kan stadig n\u00e5 at komme med i sidste \u00f8jeblik og <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/lectures\/propose\/?conference=dc2019-rit\">indgive et opl\u00e6g<\/a><\/noindex> eller tage det roligt <noindex><a rel=\"nofollow\" href=\"https:\/\/conf.ontico.ru\/conference\/join\/rit2019.html?popup=3\">at reservere<\/a><\/noindex> billet. Vi ses i Skolkovo!<\/p><\/blockquote>\n<p>Kilde: <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.3 - 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\/da\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:45:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:45:43+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47.NET Core p\u00e5 Linux, DevOps p\u00e5 toppen | ProHoster","description":"Vi har udviklet DevOps, som vi kunne. Vi var 8 personer, og Vasya var den bedste til Windows. Pludselig forlod Vasya, og jeg fik til opgave at tage et nyt projekt, der leverer Windows-udvikling.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/net-core-na-linux-devops-na-kone","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/32217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=32217"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/32217\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/24043"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=32217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=32217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=32217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}