{"id":33654,"date":"2019-10-31T21:53:58","date_gmt":"2019-10-31T18:53:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/deploj-prilozhenij-v-vm-nomad-i-kubernetes\/"},"modified":"2019-10-31T21:53:58","modified_gmt":"2019-10-31T18:53:58","slug":"deploj-prilozhenij-v-vm-nomad-i-kubernetes","status":"publish","type":"post","link":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes","title":{"rendered":"Applicaties implementeren in VM, Nomad en Kubernetes","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hallo allemaal! Mijn naam is Pavel Agaletsky. Ik werk als teamleider in het team dat het bezorgsysteem van Lamoda ontwikkelt. In 2018 sprak ik op de HighLoad++ conferentie en vandaag wil ik de transcriptie van mijn presentatie delen.<\/p>\n<p>Mijn onderwerp gaat over de ervaring van ons bedrijf met het uitrollen van systemen en diensten naar verschillende omgevingen. We beginnen bij onze pr\u00e9historische tijd, toen we alle systemen op gewone virtuele servers uitrollden, en eindigen met de geleidelijke overstap van Nomad naar uitrollen op Kubernetes. Ik zal uitleggen waarom we dit deden en welke problemen we onderweg tegenkwamen.<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"oqrb7dWECSo\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/oqrb7dWECSo\/hqdefault.jpg\" alt=\"Video afspelen\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>Toepassingen uitrollen op VM<\/h1>\n<p>\nLaten we beginnen met het feit dat 3 jaar geleden alle systemen en diensten van het bedrijf op gewone virtuele servers werden uitgerold. Technisch gezien was het zo georganiseerd dat alle code van onze systemen werd opgeslagen en samengevoegd met behulp van een automatische build, door Jenkins. Met behulp van Ansible werd het vanuit ons versiebeheersysteem uitgerold naar de virtuele servers. Elke systeem die we in ons bedrijf hadden, werd uitgerold op ten minste 2 servers: een daarvan was de hoofdserver, de andere de bijserver. Deze twee systemen waren op alle instellingen, capaciteit, configuratie enzovoorts volledig identiek. Het enige verschil was dat de hoofdserver het gebruikersverkeer ontving, terwijl de bijserver nooit gebruikersverkeer kreeg. <\/p>\n<p>Waarom was dit nodig? <\/p>\n<p>Wanneer we nieuwe versies van onze applicatie uitrolden, wilden we een naadloze uitrol mogelijk maken, dus zonder merkbare gevolgen voor de gebruikers. Dit werd bereikt doordat de laatst gebouwde release met behulp van Ansible op de bijserver werd uitgerold. Daar konden de mensen die met de uitrol bezig waren controleren en zich ervan verzekeren dat alles goed was: alle metrics, secties en applicaties werkten; de juiste scripts werden uitgevoerd. Pas nadat ze zich ervan verzekerden dat alles goed was, werd het verkeer omgeleid. Dit begon naar de server die daarvoor de bijserver was. En de server die daarvoor de hoofdserver was, bleef zonder gebruikersverkeer, met de bestaande versie van onze applicatie die erop stond.<\/p>\n<p>Voor gebruikers was dit dus naadloos. De overschakeling is onmiddellijk, omdat het gewoon een switch van de load balancer is. Je kunt heel gemakkelijk terugschakelen naar de vorige versie door de load balancer weer terug te zetten. We konden ook de prestaties van de applicatie in productie verifi\u00ebren voordat er daadwerkelijk gebruikersverkeer naartoe ging, wat erg handig was. <\/p>\n<p>Wat hebben we hierin als voordelen gezien?<\/p>\n<ol>\n<li>Allereerst is het voldoende <b>gewoon werkend.<\/b> Iedereen begrijpt hoe zo'n implementatieschema functioneert, omdat de meeste mensen ooit op reguliere virtuele servers hebben ge\u00efmplementeerd.<\/li>\n<li>Het is voldoende <b>betrouwbaar<\/b>, omdat de implementatietechnologie eenvoudig is, getest door duizenden bedrijven. Miljoenen servers worden op deze manier ge\u00efmplementeerd. Het is moeilijk om iets kapot te maken. <\/li>\n<li>Ten slotte konden we <b>atomische implementaties<\/b>krijgen. Implementaties die voor de gebruikers onmiddellijk plaatsvinden, zonder een merkbare overstap tussen de oude versie en de nieuwe. <\/li>\n<\/ol>\n<p>\nMaar hierin zagen we ook enkele nadelen: <\/p>\n<ol>\n<li>Naast de productieomgeving zijn er ook ontwikkelomgevingen en andere omgevingen. Bijvoorbeeld, qa en preproductie. Op dat moment hadden we veel servers en ongeveer 60 diensten. Daarom moesten we <b>voor elke dienst de actuele versie <\/b>van de virtuele machine bijhouden. En als je bibliotheken wilt updaten of nieuwe afhankelijkheden wilt installeren, moet je dat in alle omgevingen doen. Ook moest de timing van de implementatie van je nieuwe applicatieversie worden gesynchroniseerd met de tijd waarop devops de noodzakelijke omgevingsinstellingen zou uitvoeren. In dat geval is het gemakkelijk om in een situatie te komen waarin de omgeving in alle opvolgende omgevingen iets verschilt. Bijvoorbeeld, in de QA-omgeving kunnen er andere versies van bibliotheken zijn dan in productie, wat tot problemen leidt. <\/li>\n<li><b>De complexiteit van het updaten van afhankelijkheden<\/b> van je applicatie. Dit hangt niet van jou af, maar van een ander team. Namelijk, van het devops-team dat de servers beheert. Je moet hen een relevante taak geven en een beschrijving geven van wat je wilt doen.<\/li>\n<li>In die tijd wilden we ook de grote monolithen die we hadden, splitsen in kleinere services, omdat we begrepen dat er steeds meer bij zouden komen. Op dat moment hadden we er al meer dan 100. Voor elke nieuwe service moest er een aparte nieuwe virtuele machine worden aangemaakt, die ook onderhouden en gedeployed moest worden. Daarnaast was er niet \u00e9\u00e9n machine nodig, maar minimaal twee. Daarbij kwam ook nog eens een QA-omgeving. Dit veroorzaakt problemen en maakt het voor jou moeilijker om nieuwe systemen op te zetten en te lanceren. <b>een complexer, kostbaarder en tijdrovender proces.<\/b><\/li>\n<\/ol>\n<p>\nDaarom hebben we besloten dat het handiger zou zijn om over te stappen van het deployen van gewone virtuele machines naar het deployen van onze applicaties in een Docker-container. Bij het gebruik van Docker is er een systeem nodig dat de applicatie in een cluster kan starten, aangezien je een container niet zomaar kunt opzetten. Gewoonlijk wil je bijhouden hoeveel containers actief zijn, zodat ze automatisch opstarten. Om deze reden moesten we een beheersysteem kiezen. <\/p>\n<p>We hebben lang nagedacht over welke we konden gebruiken. Feit is dat onze deployment stack voor gewone virtuele servers op dat moment een beetje verouderd was, omdat daar niet de nieuwste versies van besturingssystemen op stonden. Op een gegeven moment draaide er zelfs FreeBSD, wat niet erg gemakkelijk te onderhouden was. We begrepen dat we zo snel mogelijk naar Docker moesten migreren. Onze DevOps-kernteam heeft gekeken naar hun ervaringen met verschillende oplossingen en besloot Nomad te kiezen. <\/p>\n<h1>Overstappen naar Nomad<\/h1>\n<p>\nNomad is een product van het bedrijf 'HashiCorp'. Ze zijn ook bekend om andere oplossingen:<\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/25dfbfe20b92f6e6865bdd8a2f15d8fa.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>\u2018Consul\u2019<\/b> is een middel voor service discovery.<\/p>\n<p><b>\u2018Terraform\u2019<\/b> is een systeem voor serverbeheer, waarmee je servers kunt configureren via wat men infrastructure-as-code noemt.<\/p>\n<p><b>\u2018Vagrant\u2019<\/b> maakt het mogelijk om virtuele machines lokaal of in de cloud te implementeren met behulp van specifieke configuratiebestanden. <\/p>\n<p>Nomad leek op dat moment een vrij eenvoudige oplossing die snel kon worden overgenomen zonder dat de hele infrastructuur veranderd hoefde te worden. Bovendien is het relatief eenvoudig te leren. Daarom hebben we voor hem gekozen als ons container filteringssysteem. <\/p>\n<p>Wat heb je nodig om je systeem \u00fcberhaupt in Nomad te deployen? <\/p>\n<ol>\n<li>Ten eerste heb je nodig <b>een Docker-image<\/b> van uw applicatie. Het is noodzakelijk om het te verzamelen en in een Docker-image-opslag te plaatsen. In ons geval is dit artifactory - zo'n systeem dat het mogelijk maakt om verschillende artefacten van verschillende types erin te pushen. Het kan archieven, Docker-images, PHP Composer-pakketten, NPM-pakketten, enzovoort opslaan. <\/li>\n<li>Ook nodig<b> configur bestand<\/b>, dat Nomad vertelt wat, waar en in welke hoeveelheid u wilt implementeren. <\/li>\n<\/ol>\n<p>\nWanneer we het over Nomad hebben, gebruikt het HCL als bestandsformaat, wat staat voor <i>HashiCorp Configuration Language<\/i>. Dit is een superset van YAML, waarmee u uw service in termen van Nomad kunt beschrijven. <\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/bee3d1feedd52249c4325d8a3984a766.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHet stelt u in staat om aan te geven hoeveel containers u wilt implementeren, uit welke images, en hen verschillende parameters mee te geven tijdens de implementatie. Op deze manier voegt u dit bestand toe aan Nomad, en deze start de containers in productie overeenkomstig. <\/p>\n<p>In ons geval hebben we bedacht dat het niet handig zou zijn om voor elke service precies dezelfde, identieke HCL-bestanden te schrijven, omdat er veel services zijn en we ze soms willen bijwerken. Er zijn gevallen waarin een service niet in \u00e9\u00e9n exemplaar is ge\u00efmplementeerd, maar in verschillende. Bijvoorbeeld, een van de systemen dat we in productie hebben, heeft meer dan 100 instanties in productie. Ze worden gestart vanuit dezelfde images, maar verschillen in configuratie-instellingen en configuratiebestanden. <\/p>\n<p>Daarom hebben we besloten dat het handig zou zijn om al onze configuratiebestanden voor implementatie in \u00e9\u00e9n gezamenlijke repository op te slaan. Op deze manier zijn ze te bekijken: ze waren gemakkelijk te onderhouden en je kon zien welke systemen we hebben. In geval van nood was het ook niet moeilijk om iets bij te werken of te veranderen. Een nieuw systeem toevoegen is ook geen probleem - het is voldoende om eenvoudig een configuratiebestand binnen een nieuwe directory aan te maken. Hierin bevinden zich bestanden: service.hcl, dat de beschrijving van onze service bevat, en enkele env-bestanden, die het mogelijk maken om deze service, zijnde ge\u00efmplementeerd in productie, in te stellen. <\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/c0b0bdb763d3c3bb84fbc9e5dfecff82.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEchter, sommige van onze systemen zijn in productie niet in \u00e9\u00e9n exemplaar ge\u00efmplementeerd, maar in meerdere tegelijk. Daarom hebben we besloten dat het handig zou zijn om niet de configuraties in pure vorm op te slaan, maar hun getemplate versie. Als sjabloontaal hebben we gekozen voor <i>jinja 2<\/i>. In dit formaat zijn zowel de configuraties van de service zelf als de benodigde env-bestanden opgeslagen. <\/p>\n<p>Daarnaast hebben we in de repository een algemene deploy-script toegevoegd voor alle projecten, waarmee je je service kunt starten en deployen naar productie, in de gewenste omgeving en naar de gewenste target. Wanneer we onze HCL-configuratie in een sjabloon hebben omgezet, ziet het HCL-bestand, dat voorheen een gewone Nomad-configuratie was, er nu iets anders uit.<\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/202472f109ba09798d592418b1774a29.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDit betekent dat we bepaalde variabelen in de configuratie hebben vervangen door invoegingen van variabelen die uit env-bestanden of andere bronnen komen. Bovendien hebben we de mogelijkheid gekregen om HCL-bestanden dynamisch te genereren, wat betekent dat we niet alleen gewone variabelen kunnen invoegen. Aangezien jinja loops en voorwaarden ondersteunt, kunnen we ook configuratiebestanden maken die veranderen afhankelijk van waar je je applicaties deployt. <\/p>\n<p>Bijvoorbeeld, je wilt je service in een pre-productie en in productie deployen. Stel dat je in de pre-productie geen cron-scripts wilt draaien, maar gewoon de service op een apart domein wilt zien om te controleren dat deze functioneert. Voor iedereen die de service deployt, lijkt het proces erg eenvoudig en transparant. Het enige wat je hoeft te doen is het bestand deploy.sh uit te voeren, aan te geven welke service je wilt deployen en naar welke target. Bijvoorbeeld, je wilt een systeem in Rusland, Wit-Rusland of Kazachstan deployen. Hiervoor is het voldoende om een van de parameters te wijzigen, en dan wordt het juiste configuratiebestand gegenereerd. <\/p>\n<p>Wanneer de Nomad-service eenmaal in je cluster is gedeployed, ziet het er als volgt uit.<\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/60e2e2b5502936809d643d73c6d853e2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAllereerst heb je een externe load balancer nodig die al het gebruikersverkeer aanneemt. Deze werkt samen met Consul en vraagt aan Consul waar, op welke node, en middels welk <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/nl\/lir\/ipv4\/\"   title=\"het IP-adres\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"585\">het IP-adres<\/a> een specifieke service zich bevindt die overeenkomt met een bepaald domeinnaam. Diensten in Consul verschijnen vanuit Nomad zelf. Aangezien dit producten van dezelfde onderneming zijn, zijn ze goed met elkaar verbonden. Je zou kunnen zeggen dat Nomad standaard alle services die erin worden gestart, registreert binnen Consul. <\/p>\n<p>Zodra uw externe load balancer weet naar welke service het verkeer moet worden gestuurd, leidt het dit om naar de bijbehorende container of naar meerdere containers die bij uw applicatie horen. Uiteraard moet hierbij ook aan de veiligheid worden gedacht. Zelfs als alle services worden uitgevoerd op dezelfde virtuele machines in containers, is het doorgaans nodig om onbeperkte toegang van de ene service tot de andere te verbieden. We hebben dit bereikt door segmentatie. Elke service werd uitgevoerd in zijn eigen virtuele netwerk, waarop de routeringsregels en de regels voor toegang tot andere systemen en services waren ingesteld. Ze konden zich zowel binnen als buiten dit cluster bevinden. Bijvoorbeeld, als u wilt voorkomen dat een service verbinding maakt met een bepaalde database, kan dit worden gedaan via segmentatie op netwerkniveau. Dat betekent dat u zelfs per ongeluk niet van de testomgeving naar uw productie database kunt verbinden.<\/p>\n<p>Wat heeft het ons gekost in termen van menselijke middelen voor het overgangsproces? <\/p>\n<p>De overgang van het hele bedrijf naar Nomad heeft ongeveer 5-6 maanden geduurd. We hebben service voor service overgeschakeld, maar wel in een behoorlijk snel tempo. Elk team moest zijn eigen containers voor services cre\u00ebren. <\/p>\n<p>Wij hanteren de benadering dat elk team verantwoordelijk is voor de docker images van hun systemen. DevOps biedt de algemene infrastructuur die nodig is voor de deployment, dat wil zeggen ondersteuning voor het cluster zelf, ondersteuning voor het CI-systeem, enzovoort. Op dat moment waren er meer dan 60 systemen naar Nomad verhuisd, wat resulteerde in ongeveer 2000 containers. <\/p>\n<p>DevOps is verantwoordelijk voor de algemene infrastructuur die verband houdt met de deployment en servers. Elk ontwikkelteam is op zijn beurt verantwoordelijk voor de implementatie van containers voor hun specifieke systeem, aangezien het team precies weet wat ze in die of die container nodig hebben.<\/p>\n<h1>Redenen om Nomad te verlaten<\/h1>\n<p>\nWelke voordelen hebben wij behaald door over te stappen op deployment met behulp van Nomad en Docker?<\/p>\n<ol>\n<li>Wij<b> we hebben gelijke omstandigheden verzekerd<\/b> voor alle omgevingen. In de ontwikkeling, QA-omgeving, pre-productie en productie worden dezelfde containerafbeeldingen met dezelfde afhankelijkheden gebruikt. Hierdoor is de kans praktisch nihil dat er iets anders in de productie komt dan wat je eerder lokaal of in de testomgeving hebt getest. <\/li>\n<li>Ook hebben we ontdekt dat het voldoende is <b>om eenvoudig een nieuwe service toe te voegen<\/b>. In feite starten alle nieuwe systemen qua deployment heel eenvoudig op. Je hoeft alleen maar naar de repository te gaan die de configuraties opslaat, daar een nieuwe configuratie voor jouw systeem aan toe te voegen, en je bent klaar. Je kunt jouw systeem naar productie deployen zonder extra inspanningen van de DevOps. <\/li>\n<li>Alle <b>configuratiebestanden<\/b> in \u00e9\u00e9n gezamenlijke repository <b>bleken doorzoekbaar<\/b>. Op het moment dat we onze systemen implementeerden met behulp van <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/nl\/vps\/\"   title=\"virtuele servers\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"791\">virtuele servers<\/a>, gebruikten we Ansible, waarbij de configuraties in dezelfde repository lagen. Voor de meeste ontwikkelaars was het echter iets moeilijker om hiermee om te gaan. Hierdoor werd de hoeveelheid configuraties en code die je moest toevoegen om een service te deployen aanzienlijk kleiner. Bovendien is het voor DevOps heel gemakkelijk om het aan te passen of te wijzigen. In het geval van migraties, bijvoorbeeld naar een nieuwe versie van Nomad, kunnen ze eenvoudig alle uitvoerende bestanden die zich op dezelfde locatie bevinden, massaal bijwerken.<\/li>\n<\/ol>\n<p>\nMaar we kwamen ook enkele nadelen tegen: <\/p>\n<p>Het bleek dat we <b>geen naadloze deployments konden bereiken <\/b>met Nomad. Bij het uitrollen van containers uit verschillende omgevingen kon het gebeuren dat een container al werd gestart, en Nomad het beschouwde als klaar om verkeer te accepteren. Dit gebeurde nog voordat de applicatie erin was gestart. Om deze reden begon het systeem gedurende een korte periode 500-fouten te geven, omdat het verkeer begon te sturen naar een container die nog niet klaar was om het te ontvangen. <\/p>\n<p>We stuiten op enkele <b>bugs<\/b>. De grootste uitdaging is dat Nomad niet goed omgaat met grote clusters, vooral als je veel systemen en containers hebt. Wanneer je een van de servers die deel uitmaakt van het Nomad-cluster wilt onderhouden, is er een aanzienlijke kans dat het cluster destabiliseert en uit elkaar valt. Een deel van de containers kan bijvoorbeeld crashen en niet herstarten \u2014 dit kan je later veel kosten als al je systemen in productie zich in het cluster bevinden dat door Nomad wordt beheerd. <\/p>\n<p>Daarom hebben we besloten na te denken over onze volgende stappen. Op dat moment waren we veel beter bewust van wat we wilden bereiken. Namelijk: we willen betrouwbaarheid, iets meer functionaliteit dan Nomad biedt, en een volwassener, stabieler systeem. <\/p>\n<p>In dit opzicht hebben we voor Kubernetes gekozen als de meest populaire platform voor het draaien van clusters. Vooral gezien het feit dat de grootte en het aantal van onze containers behoorlijk groot was. Voor deze doeleinden leek Kubernetes het meest geschikte systeem uit de opties die we konden bekijken. <\/p>\n<h1>Overstap naar Kubernetes<\/h1>\n<p>\nIk wil kort de belangrijkste concepten van Kubernetes bespreken en hoe ze verschillen van Nomad. <\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/5723a69309f387e6cc6c5959b62ca18b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn de eerste plaats is het meest basale begrip in Kubernetes de pod. <b>Pod<\/b> is een groep van \u00e9\u00e9n of meerdere containers die altijd samen worden uitgevoerd. Ze functioneren alsof ze altijd op \u00e9\u00e9n virtuele machine draaien. Ze zijn toegankelijk voor elkaar via het IP-adres 127.0.0.1 op verschillende poorten. <\/p>\n<p>Stel dat je een PHP-applicatie hebt die bestaat uit nginx en php-fpm \u2013 een klassieke opzet. Waarschijnlijk wil je dat zowel de nginx- als de php-fpm-containers altijd samen zijn. Kubernetes maakt dit mogelijk door ze als \u00e9\u00e9n gezamenlijke pod te beschrijven. Dit was precies wat we niet konden bereiken met Nomad.<\/p>\n<p>Een tweede begrip is <b>deployment<\/b>. Het punt is dat een pod op zich een ephemeraal iets is, het wordt opgestart en verdwijnt. Wil je eerst al je eerdere containers stoppen en dan meteen nieuwe versies lanceren, of wil je ze geleidelijk uitrollen \u2013 dit proces valt onder het begrip deployment. Het beschrijft hoe je je pods implementeert, in welke hoeveelheid en hoe je ze updatet. <\/p>\n<p>Een derde begrip is <b>voor het SystemD-initiesysteem:<\/b>. Uw service is feitelijk uw systeem dat enig verkeer ontvangt en dit vervolgens naar een of meerdere pods leidt die bij uw service passen. Dit betekent dat u kunt aangeven dat al het inkomende verkeer voor een bepaalde service met een bepaalde naam naar specifiek deze pods moet worden gestuurd. En tegelijkertijd zorgt het voor traffic balancing. U kunt bijvoorbeeld twee pods van uw applicatie starten, en al het inkomende verkeer wordt gelijkmatig verdeeld tussen de betreffende pods van deze service.<\/p>\n<p>En het vierde belangrijke concept \u2014 <b>Ingress<\/b>. Dit is een service die wordt uitgevoerd in een Kubernetes-cluster. Het fungeert als een externe load balancer die alle aanvragen op zich neemt. Via de Kubernetes API kan Ingress bepalen waar deze aanvragen naartoe moeten worden gestuurd. En dat kan heel flexibel. U kunt aangeven dat alle aanvragen naar deze host en deze bepaalde URL naar deze service moeten worden gestuurd. En de aanvragen die komen naar deze host en een andere URL, moeten naar een andere service worden gestuurd. <\/p>\n<p>Het mooiste voor de ontwikkelaar van de applicatie is dat je hieraan zelf kunt beheren. Door de Ingress-configuratie in te stellen, kunt u al het verkeer dat binnenkomt op een bepaalde API, naar afzonderlijke containers sturen, bijvoorbeeld geschreven in Go. En dat verkeer, dat binnenkomt op dezelfde domein, maar naar een andere URL, naar containers sturen die zijn geschreven in PHP, waar veel logica aanwezig is, maar die niet erg snel zijn.<\/p>\n<p>Als we al deze concepten vergelijken met Nomad, kunnen we zeggen dat de eerste drie concepten samen een Service vormen. Het laatste concept ontbreekt in Nomad. We gebruikten hiervoor een externe load balancer: dat kan haproxy, nginx, nginx+ enzovoort zijn. In het geval van Kubernetes hoeft u dit extra concept niet apart in te voeren. Echter, als we Ingress intern bekijken, is het \u043b\u0438\u0431\u043e nginx, \u043b\u0438\u0431\u043e haproxy, \u043b\u0438\u0431\u043e traefik, maar ingebouwd in Kubernetes. <\/p>\n<p>Al deze concepten die ik beschrijf, zijn in wezen bronnen die bestaan binnen het Kubernetes-cluster. Voor hun beschrijving in Kubernetes wordt het yaml-formaat gebruikt, dat leesbaarder en gebruikelijker is dan HCL-bestanden in het geval van Nomad. Maar structureel beschrijven ze in het geval van bijvoorbeeld een pod hetzelfde. Ze zeggen: ik wil deze pods daar implementeren, met deze imago's, in deze hoeveelheid. <\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/13836e7474b377a5e6b05112a53bfedd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBovendien hebben we begrepen dat we niet handmatig elke afzonderlijke resource willen maken: deployment, services, Ingress, en meer. In plaats daarvan willen we bij het implementeren ons elke systeem beschrijven in termen van Kubernetes, zodat we niet handmatig alle benodigde afhankelijkheden van resources in de juiste volgorde hoeven te recre\u00ebren. Helm werd gekozen als het systeem dat ons dit mogelijk maakt. <\/p>\n<h1>Basisconcepten in Helm<\/h1>\n<p>\nHelm is een <b>pakketbeheerder<\/b> voor Kubernetes. Het lijkt erg op hoe pakketbeheerders in programmeertalen werken. Ze stellen je in staat om een service, bestaande uit bijvoorbeeld een nginx deployment, een php-fpm deployment, configuratie voor Ingress, configmaps (dit is een entiteit waarmee je env en andere parameters voor je systeem kunt instellen) in de vorm van zogenaamde charts op te slaan. Helm <b>werkt bovenop Kubernetes<\/b>. Dit is dus niet een systeem dat aan de zijlijn staat, maar gewoon weer een service die binnen de cluster draait. Je interacteert met het via zijn API via een commandoregelopdracht. Het gemak en de schoonheid ervan liggen in het feit dat zelfs als Helm kapot gaat of je het uit de cluster verwijdert, jouw services niet verdwijnen, aangezien Helm in wezen alleen dient om het systeem te starten. De werking en status van de services blijft verder het verantwoordelijk van Kubernetes. <\/p>\n<p>We hebben ook begrepen dat <b>sjablonering<\/b>, die we tot nu toe gedwongen waren zelf te doen door jinja in onze configuraties te integreren, een van de belangrijkste mogelijkheden van Helm is. Alle configuraties die je maakt voor jouw systemen, worden in Helm opgeslagen als sjablonen, die een beetje op jinja lijken, maar in werkelijkheid gebruik maken van de templating van de Go-taal, waarop Helm is geschreven, net als Kubernetes. <\/p>\n<p>Helm voegt ons nog een paar extra concepten toe. <\/p>\n<p><b>Chart<\/b> is de beschrijving van jouw service. In andere pakketbeheerders zou dit een pakket, bundle of iets dergelijks worden genoemd. Hier heet het chart. <\/p>\n<p><b>Values <\/b>zijn de variabelen die je wilt gebruiken om jouw configuraties uit sjablonen te bouwen. <\/p>\n<p><b>Release<\/b>Elke keer dat een service via helm wordt gedeployed, krijgt het een incrementele versie van de release. Helm onthoudt welke configuratie de service had bij de vorige, voorlaatste release, en zo verder. Dus als het nodig is om terug te rollen, volstaat het om de helm callback-opdracht uit te voeren, waarbij je de vorige versie van de release opgeeft. Zelfs als de overeenkomstige configuratie op dat moment niet beschikbaar is in jouw repository, onthoudt helm nog steeds hoe deze was en zal het jouw systeem terugzetten naar de staat waarin het zich bevond bij de vorige release. <\/p>\n<p>Wanneer we helm gebruiken, worden de gebruikelijke configuraties voor Kubernetes ook sjablonen waarin je variabelen, functies en conditionele operators kunt gebruiken. Op deze manier kun je de configuratie van jouw service samenstellen afhankelijk van de omgeving.<\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/b70ba431211038eacf911ba3aee22363.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn de praktijk hebben we besloten het iets anders aan te pakken dan we deden met Nomad. In Nomad werden in \u00e9\u00e9n repository zowel de configuraties voor de deploy als de n-variabelen die nodig zijn om onze service te deployen opgeslagen, maar hier hebben we ervoor gekozen om ze in twee aparte repositories te splitsen. In de 'deploy'-repository worden alleen de n-variabelen opgeslagen die nodig zijn voor de deploy, terwijl de 'helm'-repository de configuraties of charts opslaat.<\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/4add11a8f9d9a9244127f0b07d027fa2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWat heeft dit ons gebracht? <\/p>\n<p>Hoewel we in de configuratiebestanden zelf geen echt gevoelige gegevens opslaan, zoals wachtwoorden voor databases. Deze worden opgeslagen als secrets in Kubernetes, maar toch zijn er specifieke elementen waartoe we niet willen dat iedereen toegang heeft. Daarom is de toegang tot de 'deploy'-repository beperkter, terwijl de 'helm'-repository gewoon een beschrijving van de service bevat. Om deze reden kan er veilig toegang worden gegeven aan een breder publiek. <\/p>\n<p>Omdat we niet alleen productieomgevingen hebben, maar ook andere omgevingen, kunnen we dankzij deze scheiding onze helm-charts hergebruiken om services niet alleen in productie te deployen, maar ook bijvoorbeeld in een QA-omgeving. Zelfs om ze lokaal te draaien met behulp van <i>Minikube<\/i> \u2014 dit is een tool voor het lokaal draaien van Kubernetes. <\/p>\n<p>Binnen elke repository hebben we de structuur verdeeld in aparte directories voor elke service. Dat wil zeggen, binnen elke directory bevinden zich sjablonen die betrekking hebben op de respectieve chart en de middelen beschrijven die moeten worden gedeployed om ons systeem op te starten. In de repository 'deploy' hebben we alleen de envs achtergelaten. In dit geval hebben we geen sjabloonverwerking met jinja gebruikt, omdat helm zelf sjabloonverwerking out-of-the-box biedt - dit is een van zijn belangrijkste functies. <\/p>\n<p>We hebben een script voor de deployment achtergelaten - deploy.sh, dat het starten van de deployment met helm vereenvoudigt en standaardiseert. Op deze manier ziet de deployment-interface voor iedereen die wil deployen er exact hetzelfde uit als bij een deployment via Nomad. Hetzelfde deploy.sh, de naam van uw service, en waar u deze wilt deployen. Dit leidt ertoe dat helm van binnenuit wordt gestart. Het verzamelt op zijn beurt de configuraties uit de sjablonen, vult deze aan met de benodigde values-bestanden en deployt vervolgens in Kubernetes. <\/p>\n<h1>Conclusies<\/h1>\n<p>\nDe Kubernetes-service lijkt ingewikkelder dan Nomad. <\/p>\n<p><img decoding=\"async\" alt=\"Applicaties implementeren in VM, Nomad en Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/5a9b5636ab4721acde096fea986ba38b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHier komt het uitgaande verkeer binnen via Ingress. Dit is de front-controller die alle verzoeken aanneemt en deze vervolgens naar de overeenkomstige services voor de gegeven verzoeken stuurt. Hij bepaalt deze op basis van de configuraties, die deel uitmaken van de beschrijving van uw applicatie in helm en die door de ontwikkelaars zelf worden ingesteld. De service stuurt de verzoeken naar zijn pods, dat zijn specifieke containers, waarbij het verkeer balans wordt gehouden tussen alle containers die bij deze service horen. En natuurlijk mogen we de netwerkbeveiliging niet vergeten; we moeten hierin consistent blijven. Daarom werkt segmentatie in het Kubernetes-cluster, gebaseerd op tagging. Alle services hebben specifieke tags waaraan de toegangsrechten van de services tot bepaalde externe\/interne bronnen binnen of buiten het cluster zijn gekoppeld. <\/p>\n<p>Tijdens de overgang zagen we dat Kubernetes alle functies heeft die Nomad, dat we eerder gebruikten, biedt, en voegt bovendien veel nieuwe mogelijkheden toe. Het kan worden uitgebreid via plug-ins en daadwerkelijk via aangepaste type middelen. Dit betekent dat je niet alleen iets kunt gebruiken dat standaard in Kubernetes zit, maar ook je eigen bron en service kunt cre\u00ebren die je bron leest. Dit biedt extra mogelijkheden om je systeem uit te breiden zonder Kubernetes opnieuw te installeren of wijzigingen aan te brengen. <\/p>\n<p>Een voorbeeld van dit gebruik is Prometheus, dat binnen ons Kubernetes-cluster draait. Om metrics van een bepaalde service te beginnen verzamelen, moeten we een extra type bron, de zogenaamde service-monitor, aan de servicebeschrijving toevoegen. Omdat Prometheus, als het draait in Kubernetes, aangepaste type middelen kan uitlezen, begint het automatisch met het verzamelen van metrics van het nieuwe systeem. Dit is erg handig. <\/p>\n<p>De eerste deployment die we in Kubernetes hebben gedaan was in maart 2018. En in die tijd hebben we nooit problemen ervaren. Het werkt vrij stabiel zonder significante bugs. Bovendien kunnen we het verder uitbreiden. Tot op heden voldoen de mogelijkheden die het heeft aan onze eisen en we zijn erg tevreden met de ontwikkeling van Kubernetes. Op dit moment zijn er meer dan 3000 containers in Kubernetes. Het cluster bestaat uit verschillende nodes. Het is goed beheerd, stabiel en zeer controleerbaar.<br \/>\n<br \/>Bron: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/lamoda\/blog\/451644\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda. \u0412 2018 \u0433\u043e\u0434\u0443 \u044f \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 HighLoad++, \u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430. \u041c\u043e\u044f \u0442\u0435\u043c\u0430 \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u043e\u043f\u044b\u0442\u0443 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043f\u043e \u0434\u0435\u043f\u043b\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u043d\u0430\u0448\u0438\u0445 \u0434\u043e\u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u0440\u0435\u043c\u0435\u043d, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u0435\u043f\u043b\u043e\u0438\u043b\u0438 \u0432\u0441\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":25343,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-33654","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=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda.\" \/>\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\/nl\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\u0414\u0435\u043f\u043b\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 VM, Nomad \u0438 Kubernetes | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes\" \/>\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:53:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:53:58+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\udd47Applicaties implementeren in VM, Nomad en Kubernetes | ProHoster","description":"Hallo allemaal! Mijn naam is Pavel Agaletski. Ik werk als teamleider in het team dat het leveringssysteem van Lamoda ontwikkelt.","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\u0414\u0435\u043f\u043b\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 VM, Nomad \u0438 Kubernetes | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda.","og:url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes","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:53:58+00:00","article:modified_time":"2019-10-31T18:53:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"33654","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-02-08 20:38:40","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:36:34","updated":"2026-02-08 20:38:40","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/33654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=33654"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/33654\/revisions"}],"predecessor-version":[{"id":157982,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/33654\/revisions\/157982"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/25343"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=33654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=33654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=33654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}