{"id":96065,"date":"2020-10-07T13:42:09","date_gmt":"2020-10-07T11:42:09","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf"},"modified":"2020-10-07T13:42:09","modified_gmt":"2020-10-07T11:42:09","slug":"problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","title":{"rendered":"Probl\u00e9m \"inteligentn\u00edho\" \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Probl\u00e9m &quot;inteligentn\u00edho&quot; \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf\" src=\"\/wp-content\/uploads\/2020\/10\/1410cea46bb8dcdc3ac06db11ed5a402.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u010cl\u00e1nek se zab\u00fdv\u00e1 problematikou \u010di\u0161t\u011bn\u00ed obraz\u016f, kter\u00e9 se hromad\u00ed v registrech kontejner\u016f (Docker Registry a jeho obdob\u00e1ch) v re\u00e1li\u00edch modern\u00edch CI\/CD pipeline pro cloud native aplikace dod\u00e1van\u00e9 do Kubernetes. Uvedeny jsou hlavn\u00ed krit\u00e9ria relevance obraz\u016f a vypl\u00fdvaj\u00edc\u00ed slo\u017eitosti p\u0159i automatizaci \u010di\u0161t\u011bn\u00ed, zachov\u00e1n\u00ed m\u00edsta a uspokojov\u00e1n\u00ed pot\u0159eb t\u00fdm\u016f. Nakonec na p\u0159\u00edkladu konkr\u00e9tn\u00edho open source projektu uk\u00e1\u017eeme, jak tyto slo\u017eitosti lze p\u0159ekonat.<\/p>\n<h2>\u00davod<\/h2>\n<p>\nPo\u010det obraz\u016f v registru kontejner\u016f m\u016f\u017ee rychle r\u016fst, zab\u00edrat v\u00edce m\u00edsta ve storage a t\u00edm p\u00e1dem v\u00fdrazn\u011b zvy\u0161ovat jeho n\u00e1klady. Pro kontrolu, omezen\u00ed \u010di udr\u017een\u00ed p\u0159ijateln\u00fd r\u016fst m\u00edsta, kter\u00e9 zauj\u00edmaj\u00ed v registry, je obvykl\u00e9:<\/p>\n<ol>\n<li>pou\u017e\u00edvat pevn\u00fd po\u010det tag\u016f pro obrazy;<\/li>\n<li>n\u011bjak\u00fdm zp\u016fsobem o\u010di\u0161\u0165ovat obrazy.<\/li>\n<\/ol>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nPrvn\u00ed omezen\u00ed je ob\u010das p\u0159ijateln\u00e9 pro mal\u00e9 t\u00fdmy. Pokud v\u00fdvoj\u00e1\u0159\u016fm sta\u010d\u00ed st\u00e1l\u00e9 tagy (<code>latest<\/code>, <code>main<\/code>, <code>test<\/code>, <code>boris<\/code> atd.), registr se nebude roz\u0161i\u0159ovat a dlouho se nemus\u00ed p\u0159em\u00fd\u0161let o \u010di\u0161t\u011bn\u00ed. V\u0161echny neaktu\u00e1ln\u00ed obrazy se p\u0159episuj\u00ed a pro \u010di\u0161t\u011bn\u00ed zkr\u00e1tka nez\u016fst\u00e1v\u00e1 \u017e\u00e1dn\u00e1 pr\u00e1ce (v\u0161e d\u011bl\u00e1 syst\u00e9mov\u00fd garbage collector).<\/p>\n<p>Nicm\u00e9n\u011b takov\u00fd p\u0159\u00edstup siln\u011b omezuje v\u00fdvoj a z\u0159\u00eddka se uplat\u0148uje v CI\/CD modern\u00edch projekt\u016f. Nezbytnou sou\u010d\u00e1st\u00ed v\u00fdvoje se stala <strong>automatizace<\/strong>, kter\u00e1 umo\u017e\u0148uje mnohem rychleji testovat, nasazovat a dod\u00e1vat nov\u00e9 funkce u\u017eivatel\u016fm. Nap\u0159\u00edklad ve v\u0161ech na\u0161ich projektech se p\u0159i ka\u017ed\u00e9m commitu automaticky vytv\u00e1\u0159\u00ed CI pipeline. V n\u00ed se sestavuje obraz, testuje se, nasazuje do r\u016fzn\u00fdch Kubernetes okruh\u016f pro lad\u011bn\u00ed a zb\u00fdvaj\u00edc\u00ed kontroly, a pokud je v\u0161e v po\u0159\u00e1dku \u2014 zm\u011bny se dostanou k koncov\u00e9mu u\u017eivateli. A to u\u017e d\u00e1vno nen\u00ed rocket science, ale b\u011b\u017enost pro mnoh\u00e9 \u2014 pravd\u011bpodobn\u011b i pro v\u00e1s, kdy\u017e \u010dtete tento \u010dl\u00e1nek.<\/p>\n<p>Jeliko\u017e eliminace chyb a v\u00fdvoj nov\u00fdch funkc\u00ed prob\u00edh\u00e1 paraleln\u011b, a vyd\u00e1n\u00ed mohou prob\u00edhat n\u011bkolikr\u00e1t denn\u011b, je jasn\u00e9, \u017ee proces v\u00fdvoje je prov\u00e1zen v\u00fdznamn\u00fdm mno\u017estv\u00edm commit\u016f, co\u017e znamen\u00e1 \u2014 <strong>velk\u00e9 mno\u017estv\u00ed obraz\u016f v registry<\/strong>. V d\u016fsledku toho se nal\u00e9hav\u011b vyno\u0159uje ot\u00e1zka organizace efektivn\u00edho \u010di\u0161t\u011bn\u00ed registry, tj. odstran\u011bn\u00ed neaktu\u00e1ln\u00edch obraz\u016f.<\/p>\n<p>Ale jak v\u016fbec ur\u010dit, zda je obraz aktu\u00e1ln\u00ed?<\/p>\n<h2>Krit\u00e9ria aktu\u00e1lnosti obrazu<\/h2>\n<p>\nVe v\u011bt\u0161in\u011b p\u0159\u00edpad\u016f budou hlavn\u00ed krit\u00e9ria n\u00e1sleduj\u00edc\u00ed:<\/p>\n<p>1. Prvn\u00ed (nejz\u0159ejm\u011bj\u0161\u00ed a nejkriti\u010dt\u011bj\u0161\u00ed ze v\u0161ech) \u2014 to jsou obrazy, kter\u00e9 <strong>jsou aktu\u00e1ln\u011b pou\u017e\u00edv\u00e1ny v Kubernetes<\/strong>. Odstran\u011bn\u00ed t\u011bchto obraz\u016f m\u016f\u017ee v\u00e9st k v\u00e1\u017en\u00fdm n\u00e1klad\u016fm v d\u016fsledku prostoj\u016f production (nap\u0159\u00edklad obrazy mohou b\u00fdt pot\u0159ebn\u00e9 p\u0159i replikaci) nebo zma\u0159it \u00fasil\u00ed t\u00fdmu, kter\u00fd se zab\u00fdv\u00e1 lad\u011bn\u00edm na n\u011bkter\u00e9m z kontur. <i>(Z tohoto d\u016fvodu jsme dokonce vytvo\u0159ili speci\u00e1ln\u00ed <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/k8s-image-availability-exporter\"><i>Prometheus exporter<\/i><\/a><\/noindex><i>, kter\u00fd sleduje nep\u0159\u00edtomnost takov\u00fdch obraz\u016f v jak\u00e9mkoli Kubernetes clusteru.)<\/i><\/p>\n<p>2. Druh\u00e9 (m\u00e9n\u011b z\u0159ejm\u00e9, ale tak\u00e9 velmi d\u016fle\u017eit\u00e9 a op\u011bt se vztahuje k provozu) \u2014 to jsou obrazy, kter\u00e9 <strong>jsou pot\u0159ebn\u00e9 pro rollback v p\u0159\u00edpad\u011b odhalen\u00ed z\u00e1va\u017en\u00fdch probl\u00e9m\u016f<\/strong> v aktu\u00e1ln\u00ed verzi. Nap\u0159\u00edklad v p\u0159\u00edpad\u011b Helm to jsou obrazy, kter\u00e9 se pou\u017e\u00edvaj\u00ed ve ulo\u017een\u00fdch verz\u00edch vyd\u00e1n\u00ed. (Mimochodem, ve v\u00fdchoz\u00edm nastaven\u00ed m\u00e1 Helm limit 256 reviz\u00ed, ale t\u011b\u017eko by n\u011bkdo m\u011bl skute\u010dnou pot\u0159ebu uchov\u00e1vat <i>takov\u00e9<\/i> velk\u00e9 mno\u017estv\u00ed verz\u00ed?..) V\u017edy\u0165 pr\u00e1v\u011b kv\u016fli tomu uchov\u00e1v\u00e1me verze, abychom je mohli pozd\u011bji pou\u017e\u00edt, tj. \u201evr\u00e1tit se\u201c k nim v p\u0159\u00edpad\u011b pot\u0159eby.<\/p>\n<p>3. T\u0159et\u00ed \u2014 <strong>pot\u0159eby v\u00fdvoj\u00e1\u0159\u016f<\/strong>: v\u0161echny obrazy, kter\u00e9 souvisej\u00ed s jejich aktu\u00e1ln\u00edmi pracemi. Nap\u0159\u00edklad pokud zva\u017eujeme PR, m\u00e1 smysl ponechat obraz odpov\u00eddaj\u00edc\u00ed posledn\u00edmu commitu a, dejme tomu, p\u0159edchoz\u00edmu commitu: tak se m\u016f\u017ee v\u00fdvoj\u00e1\u0159 rychle vr\u00e1tit k jak\u00e9koli \u00faloze a pracovat s posledn\u00edmi zm\u011bnami. <\/p>\n<p>4. \u010ctvrt\u00fd \u2014 obrazy, kter\u00e9 <strong>odpov\u00eddaj\u00ed verz\u00edm na\u0161\u00ed aplikace<\/strong>, tj. p\u0159edstavuj\u00ed kone\u010dn\u00fd produkt: v1.0.0, 20.04.01, sierra atd.<\/p>\n<p>NB: Krit\u00e9ria uveden\u00e1 zde byla formulov\u00e1na na z\u00e1klad\u011b zku\u0161enost\u00ed z interakc\u00ed s des\u00edtkami v\u00fdvoj\u00e1\u0159sk\u00fdch t\u00fdm\u016f z r\u016fzn\u00fdch spole\u010dnost\u00ed. Nicm\u00e9n\u011b samoz\u0159ejm\u011b mohou tato krit\u00e9ria v z\u00e1vislosti na specifik\u00e1ch v procesech v\u00fdvoje a pou\u017e\u00edvan\u00e9 infrastruktu\u0159e (nap\u0159\u00edklad pokud se Kubernetes nepou\u017e\u00edv\u00e1) li\u0161it. <\/p>\n<h2>Soulad s krit\u00e9rii a existuj\u00edc\u00edmi \u0159e\u0161en\u00edmi<\/h2>\n<p>\nPopul\u00e1rn\u00ed slu\u017eby s registry kontejner\u016f obvykle nab\u00edzej\u00ed sv\u00e9 politiky pro \u010di\u0161t\u011bn\u00ed obraz\u016f: v nich m\u016f\u017eete definovat podm\u00ednky, za kter\u00fdch je tag odstran\u011bn z registry. Mo\u017enosti t\u011bchto podm\u00ednek jsou v\u0161ak omezeny na takov\u00e9 parametry, jako jsou n\u00e1zvy, \u010das vytvo\u0159en\u00ed a po\u010det tag\u016f*.<\/p>\n<p><i>* Z\u00e1vis\u00ed na konkr\u00e9tn\u00edch implementac\u00edch registru kontejner\u016f. Zva\u017eovali jsme mo\u017enosti n\u00e1sleduj\u00edc\u00edch \u0159e\u0161en\u00ed: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io \u2014 k datu z\u00e1\u0159\u00ed 2020.<\/i><\/p>\n<p>Takov\u00fd set parametr\u016f je zcela dostate\u010dn\u00fd k tomu, aby splnil \u010dtvrt\u00e9 krit\u00e9rium \u2014 tedy vyb\u00edrat obrazy odpov\u00eddaj\u00edc\u00ed verz\u00edm. Nicm\u00e9n\u011b pro v\u0161echna ostatn\u00ed krit\u00e9ria je nutn\u00e9 zvolit n\u011bjak\u00e9 kompromisn\u00ed \u0159e\u0161en\u00ed (p\u0159\u00edsn\u011bj\u0161\u00ed nebo naopak m\u00edrn\u011bj\u0161\u00ed politiku) \u2014 v z\u00e1vislosti na o\u010dek\u00e1v\u00e1n\u00edch a finan\u010dn\u00edch mo\u017enostech.<\/p>\n<p>Nap\u0159\u00edklad t\u0159et\u00ed krit\u00e9rium \u2014 souvisej\u00edc\u00ed s pot\u0159ebami v\u00fdvoj\u00e1\u0159\u016f \u2014 m\u016f\u017ee b\u00fdt \u0159e\u0161eno organizac\u00ed proces\u016f uvnit\u0159 t\u00fdm\u016f: specifick\u00fdm pojmenov\u00e1n\u00edm obraz\u016f, veden\u00edm speci\u00e1ln\u00edch allow list\u016f a vnit\u0159n\u00edmi dohodami. Ale nakonec je stejn\u011b t\u0159eba to automatizovat. A pokud schopnosti hotov\u00fdch \u0159e\u0161en\u00ed nesta\u010d\u00ed, mus\u00ed se d\u011blat n\u011bco vlastn\u00edho.<\/p>\n<p>Podobn\u011b je tomu i s dv\u011bma prvn\u00edmi krit\u00e9rii: nelze je splnit bez z\u00edsk\u00e1n\u00ed dat z extern\u00edho syst\u00e9mu \u2014 toho sam\u00e9ho, kde doch\u00e1z\u00ed k nasazov\u00e1n\u00ed aplikac\u00ed (v na\u0161em p\u0159\u00edpad\u011b je to Kubernetes).<\/p>\n<h3>Ilustrace workflow v Gitu<\/h3>\n<p>\nP\u0159edpokl\u00e1dejme, \u017ee pracujete p\u0159ibli\u017en\u011b podle t\u00e9to sch\u00e9my v Gitu:<\/p>\n<p><img decoding=\"async\" alt=\"Probl\u00e9m &quot;inteligentn\u00edho&quot; \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf\" src=\"\/wp-content\/uploads\/2020\/10\/45c9bfb6755da1b4d6be05b51ab17429.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<i>Ikonou s hlavou na sch\u00e9matu jsou ozna\u010deny obrazy kontejner\u016f, kter\u00e9 jsou v sou\u010dasnosti nasazeny v Kubernetes pro jak\u00e9koli u\u017eivatele (koncov\u00e9 u\u017eivatele, testery, mana\u017eery atd.) nebo je pou\u017e\u00edvaj\u00ed v\u00fdvoj\u00e1\u0159i k lad\u011bn\u00ed a podobn\u00fdm \u00fa\u010del\u016fm.<\/i><\/p>\n<p>Co se stane, pokud politiky \u010di\u0161t\u011bn\u00ed umo\u017e\u0148uj\u00ed ponech\u00e1vat (neodstra\u0148ovat) obrazy pouze <b>podle zadan\u00fdch n\u00e1zv\u016f tag\u016f<\/b>?<\/p>\n<p><img decoding=\"async\" alt=\"Probl\u00e9m &quot;inteligentn\u00edho&quot; \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf\" src=\"\/wp-content\/uploads\/2020\/10\/e57ff24cb818799d28e8eb006aea2eb5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJe z\u0159ejm\u00e9, \u017ee takov\u00fd sc\u00e9n\u00e1\u0159 nikoho nepot\u011b\u0161\u00ed.<\/p>\n<p>Co se zm\u011bn\u00ed, pokud politiky umo\u017e\u0148uj\u00ed neodstra\u0148ovat obrazy <b>podle zadan\u00e9ho \u010dasov\u00e9ho intervalu \/ po\u010dtu posledn\u00edch commit\u016f<\/b>?<\/p>\n<p><img decoding=\"async\" alt=\"Probl\u00e9m &quot;inteligentn\u00edho&quot; \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf\" src=\"\/wp-content\/uploads\/2020\/10\/7743581e6e64affb0a207ee156c00f6e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV\u00fdsledek se stal v\u00fdrazn\u011b lep\u0161\u00edm, nicm\u00e9n\u011b st\u00e1le je daleko od ide\u00e1lu. V\u017edy\u0165 st\u00e1le m\u00e1me v\u00fdvoj\u00e1\u0159e, kte\u0159\u00ed pot\u0159ebuj\u00ed obrazy v registru (nebo dokonce nasazen\u00e9 v K8s) k lad\u011bn\u00ed chyb...<\/p>\n<p>Shrnuj\u00edc\u00ed situaci na trhu: dostupn\u00e9 funkce v registrech kontejner\u016f nenab\u00edzej\u00ed dostate\u010dnou flexibilitu p\u0159i \u010di\u0161t\u011bn\u00ed, a hlavn\u00ed p\u0159\u00ed\u010dinou toho je \u2014 <strong>nedostatek mo\u017enosti interakce se zevn\u00edm sv\u011btem<\/strong>. Zd\u00e1 se, \u017ee t\u00fdmy, kter\u00e9 vy\u017eaduj\u00ed takovou flexibilitu, jsou nuceny samy implementovat odstra\u0148ov\u00e1n\u00ed obraz\u016f \u201ezvenku\u201c, pomoc\u00ed Docker Registry API (nebo nativn\u00edho API p\u0159\u00edslu\u0161n\u00e9 implementace).<\/p>\n<p>Hledali jsme v\u0161ak univerz\u00e1ln\u00ed \u0159e\u0161en\u00ed, kter\u00e9 by automatizovalo \u010di\u0161t\u011bn\u00ed obraz\u016f pro r\u016fzn\u00e9 t\u00fdmy pou\u017e\u00edvaj\u00edc\u00ed r\u016fzn\u00e9 registry\u2026<\/p>\n<h2>Na\u0161e cesta k univerz\u00e1ln\u00edmu \u010di\u0161t\u011bn\u00ed obraz\u016f<\/h2>\n<p>\nOdkud takov\u00e1 pot\u0159eba? Jde o to, \u017ee nejsme samostatn\u00e1 skupina v\u00fdvoj\u00e1\u0159\u016f, ale t\u00fdm, kter\u00fd obsluhuje hned n\u011bkolik takov\u00fdch, a pom\u00e1h\u00e1 komplexn\u011b \u0159e\u0161it ot\u00e1zky CI\/CD. A hlavn\u00edm technick\u00fdm n\u00e1strojem pro toto je Open Source utility <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.werf.io\/\">werf<\/a><\/noindex>. Jej\u00edm znakem je, \u017ee nevykon\u00e1v\u00e1 jedinou funkci, ale doprov\u00e1z\u00ed procesy kontinu\u00e1ln\u00ed dod\u00e1vky na v\u0161ech \u00farovn\u00edch: od sestaven\u00ed po nasazen\u00ed.<\/p>\n<p>Publikov\u00e1n\u00ed v registru* obraz\u016f (ihned po jejich sestaven\u00ed) \u2014 je z\u0159ejm\u00e1 funkce takov\u00e9 utility. A proto\u017ee se obrazy ukl\u00e1daj\u00ed na uchov\u00e1n\u00ed, pak \u2014 pokud va\u0161e \u00falo\u017ei\u0161t\u011b nen\u00ed nekone\u010dn\u00e9 \u2014 mus\u00edte zaji\u0161\u0165ovat i jejich n\u00e1sledn\u00e9 \u010di\u0161t\u011bn\u00ed. O tom, jak jsme toho dos\u00e1hli, a to spln\u011bn\u00edm v\u0161ech stanoven\u00fdch krit\u00e9ri\u00ed, bude d\u00e1le \u0159e\u010deno.<\/p>\n<p><i>* I kdy\u017e se samotn\u00e9 registry mohou li\u0161it (Docker Registry, GitLab Container Registry, Harbor atd.), jejich u\u017eivatel\u00e9 \u010del\u00ed stejn\u00fdm probl\u00e9m\u016fm. Univerz\u00e1ln\u00ed \u0159e\u0161en\u00ed v na\u0161em p\u0159\u00edpad\u011b nez\u00e1vis\u00ed na implementaci registru, proto\u017ee prob\u00edh\u00e1 mimo samotn\u00e9 registry a nab\u00edz\u00ed stejnou funk\u010dnost pro v\u0161echny.<\/i><\/p>\n<p>I kdy\u017e pou\u017e\u00edv\u00e1me werf jako p\u0159\u00edklad realizace, douf\u00e1me, \u017ee pou\u017eit\u00e9 p\u0159\u00edstupy budou p\u0159\u00ednosn\u00e9 i dal\u0161\u00edm t\u00fdm\u016fm, kter\u00e9 se setkaly s podobn\u00fdmi obt\u00ed\u017eemi.<\/p>\n<p>Tak\u017ee jsme se pustili do <i>extern\u00ed<\/i> implementace mechanismu pro \u010di\u0161t\u011bn\u00ed obraz\u016f \u2014 m\u00edsto t\u011bch mo\u017enost\u00ed, kter\u00e9 ji\u017e jsou vestav\u011bny v registrech pro kontejnery. Prvn\u00edm krokem bylo vyu\u017eit\u00ed Docker Registry API k vytvo\u0159en\u00ed stejn\u00fdch primitivn\u00edch politik ohledn\u011b po\u010dtu tag\u016f a doby jejich vytvo\u0159en\u00ed (jak bylo uvedeno v\u00fd\u0161e). K nim byl p\u0159id\u00e1n <strong>allow list zalo\u017een\u00fd na obrazech pou\u017e\u00edvan\u00fdch v nasazen\u00e9 infrastruktu\u0159e<\/strong>, tj. Kubernetes. Pro posledn\u00ed bylo dost prost\u011b proch\u00e1zet v\u0161echny nasazen\u00e9 zdroje p\u0159es Kubernetes API a z\u00edskat seznam hodnot <code>obr\u00e1zek<\/code>.<\/p>\n<p>Takov\u00e9 trivi\u00e1ln\u00ed \u0159e\u0161en\u00ed vy\u0159e\u0161ilo nejkriti\u010dt\u011bj\u0161\u00ed probl\u00e9m (krit\u00e9rium \u010d. 1), ale bylo to jen za\u010d\u00e1tkem na\u0161\u00ed cesty k vylep\u0161en\u00ed mechanismu \u010di\u0161t\u011bn\u00ed. Dal\u0161\u00edm \u2014 a mnohem zaj\u00edmav\u011bj\u0161\u00edm \u2014 krokem bylo rozhodnut\u00ed <strong>sv\u00e1zat publikovan\u00e9 obrazy s histori\u00ed Git<\/strong>.<\/p>\n<h3>Sch\u00e9my tagov\u00e1n\u00ed<\/h3>\n<p>\nNa za\u010d\u00e1tku jsme zvolili p\u0159\u00edstup, p\u0159i kter\u00e9m koncov\u00fd obraz mus\u00ed obsahovat pot\u0159ebn\u00e9 informace pro \u010di\u0161t\u011bn\u00ed, a vybudovali jsme proces na z\u00e1klad\u011b sch\u00e9mat tagov\u00e1n\u00ed. P\u0159i publikaci obrazu si u\u017eivatel vybral ur\u010ditou mo\u017enost tagov\u00e1n\u00ed (<code>git-branch<\/code>, <code>git-commit<\/code> nebo <code>git-tag<\/code>) a pou\u017eil odpov\u00eddaj\u00edc\u00ed hodnotu. V CI syst\u00e9mech byla tato hodnota automaticky nastavena na z\u00e1klad\u011b prom\u011bnn\u00fdch prost\u0159ed\u00ed. V podstat\u011b <strong>byl koncov\u00fd obraz sv\u00e1z\u00e1n s ur\u010ditou Git primitivou,<\/strong>, uchov\u00e1vaj\u00edc\u00ed pot\u0159ebn\u00e1 data pro \u010di\u0161t\u011bn\u00ed v labelech.<\/p>\n<p>V r\u00e1mci takov\u00e9ho p\u0159\u00edstupu vznikl soubor politik, kter\u00fd umo\u017enil pou\u017e\u00edvat Git jako jedin\u00fd zdroj pravdy:<\/p>\n<ul>\n<li>P\u0159i odstran\u011bn\u00ed v\u011btve\/tagu v Gitu byly automaticky odstran\u011bny i souvisej\u00edc\u00ed obrazy v registry.<\/li>\n<li>Po\u010det obraz\u016f spojen\u00fdch s Git tagy a commity bylo mo\u017en\u00e9 regulovat mno\u017estv\u00edm tag\u016f pou\u017eit\u00fdch ve zvolen\u00e9 \u0441\u0445\u0435\u043c\u011b a \u010dasem vytvo\u0159en\u00ed souvisej\u00edc\u00edho commitu.<\/li>\n<\/ul>\n<p>\nCelkov\u011b spln\u011bn\u00e1 implementace vyhovovala na\u0161im pot\u0159eb\u00e1m, ale brzy n\u00e1s \u010dekala nov\u00e1 v\u00fdzva. Skute\u010dnost je takov\u00e1, \u017ee b\u011bhem pou\u017e\u00edv\u00e1n\u00ed sch\u00e9mat tagov\u00e1n\u00ed podle Git primitiv\u016f jsme narazili na \u0159adu nedostatk\u016f. <i>(Proto\u017ee jejich popis vych\u00e1z\u00ed mimo r\u00e1mec tohoto \u010dl\u00e1nku, v\u0161ichni z\u00e1jemci se mohou sezn\u00e1mit s podrobnostmi <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\"><i>zde<\/i><\/a><\/noindex><i>.)<\/i> Proto, kdy\u017e jsme se rozhodli pro p\u0159echod na efektivn\u011bj\u0161\u00ed p\u0159\u00edstup k tagov\u00e1n\u00ed (tagov\u00e1n\u00ed na z\u00e1klad\u011b obsahu), museli jsme p\u0159ehodnotit i implementaci \u010di\u0161t\u011bn\u00ed obraz\u016f.<\/p>\n<h3>Nov\u00fd algoritmus<\/h3>\n<p>\nPro\u010d? P\u0159i tagov\u00e1n\u00ed na z\u00e1klad\u011b obsahu m\u016f\u017ee ka\u017ed\u00fd tag spl\u0148ovat v\u00edce commit\u016f v Gitu. P\u0159i \u010di\u0161t\u011bn\u00ed obraz\u016f u\u017e nem\u016f\u017eeme vych\u00e1zet <i>pouze<\/i> z commitu, ve kter\u00e9m byl nov\u00fd tag p\u0159id\u00e1n do registry.<\/p>\n<p>Pro nov\u00fd algoritmus \u010di\u0161t\u011bn\u00ed bylo rozhodnuto opustit sch\u00e9my tagov\u00e1n\u00ed a vybudovat <strong>proces na meta-obrazech,<\/strong>, ka\u017ed\u00fd z nich\u017e uchov\u00e1v\u00e1 vazbu z:<\/p>\n<ul>\n<li>komit, na kter\u00e9m bylo provedeno publikov\u00e1n\u00ed (p\u0159itom nez\u00e1le\u017e\u00ed na tom, zda byl p\u0159id\u00e1n, zm\u011bn\u011bn, nebo z\u016fstal p\u016fvodn\u00ed obraz v registru kontejner\u016f);<\/li>\n<li>a na\u0161eho intern\u00edho identifik\u00e1toru odpov\u00eddaj\u00edc\u00edho sestaven\u00e9mu obrazu.<\/li>\n<\/ul>\n<p>\nJin\u00fdmi slovy, byla zaji\u0161t\u011bna <strong>v\u011bc publikovan\u00fdch tag\u016f s commity v Git.<\/strong>.<\/p>\n<h3>Kone\u010dn\u00e1 konfigurace a obecn\u00fd algoritmus<\/h3>\n<p>\nU\u017eivatel\u016fm p\u0159i konfiguraci \u010dist\u011bn\u00ed se staly dostupn\u00e9 politiky, podle kter\u00fdch se vyb\u00edraj\u00ed aktu\u00e1ln\u00ed obrazy. Ka\u017ed\u00e1 takov\u00e1 politika je definov\u00e1na:<\/p>\n<ul>\n<li>mno\u017estv\u00edm reference, tj. Git-tag\u016f nebo Git-v\u011btv\u00ed, kter\u00e9 se pou\u017e\u00edvaj\u00ed p\u0159i skenov\u00e1n\u00ed;<\/li>\n<li>a limitem hledan\u00fdch obraz\u016f pro ka\u017edou referenci z mno\u017estv\u00ed.<\/li>\n<\/ul>\n<p>\nPro ilustraci \u2014 takto za\u010dala vypadat konfigurace politik podle defaultu:<\/p>\n<pre><code class=\"plaintext\">cleanup:\n  keepPolicies:\n  - references:\n      tag: \\\/.*\\\/\n      limit:\n        last: 10\n  - references:\n      branch: \\\/.*\\\/\n      limit:\n        last: 10\n        in: 168h\n        operator: And\n    imagesPerReference:\n      last: 2\n      in: 168h\n      operator: And\n  - references:\n      branch: \\\/^(main|staging|production)$\\\/\n    imagesPerReference:\n      last: 10\n<\/code><\/pre>\n<p>\nTato konfigurace obsahuje t\u0159i politiky, kter\u00e9 odpov\u00eddaj\u00ed n\u00e1sleduj\u00edc\u00edm pravidl\u016fm:<\/p>\n<ol>\n<li>Udr\u017eovat obraz pro 10 posledn\u00edch Git-tag\u016f (podle data vytvo\u0159en\u00ed tagu).<\/li>\n<li>Udr\u017eovat maxim\u00e1ln\u011b 2 obrazy publikovan\u00e9 za posledn\u00ed t\u00fdden pro maxim\u00e1ln\u011b 10 v\u011btv\u00ed s aktivitou za posledn\u00ed t\u00fdden.<\/li>\n<li>Udr\u017eovat 10 obraz\u016f pro v\u011btve <code>main<\/code>, <code>staging<\/code> a <code>production<\/code>.<\/li>\n<\/ol>\n<p>\nKone\u010dn\u00fd algoritmus se tedy skl\u00e1d\u00e1 z n\u00e1sleduj\u00edc\u00edch krok\u016f:<\/p>\n<ul>\n<li>Z\u00edsk\u00e1n\u00ed manifest\u016f z registru kontejner\u016f.<\/li>\n<li>Vylou\u010den\u00ed obraz\u016f pou\u017e\u00edvan\u00fdch v Kubernetes, proto\u017ee ty jsme ji\u017e p\u0159edem vybrali, dotazem na K8s API.<\/li>\n<li>Skenov\u00e1n\u00ed Git historie a vylou\u010den\u00ed obraz\u016f podle zadan\u00fdch politik.<\/li>\n<li>Odstran\u011bn\u00ed zb\u00fdvaj\u00edc\u00edch obraz\u016f.<\/li>\n<\/ul>\n<p>\nVrac\u00edm se k na\u0161\u00ed ilustraci, takto to vypad\u00e1 s werf:<\/p>\n<p><img decoding=\"async\" alt=\"Probl\u00e9m &quot;inteligentn\u00edho&quot; \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf\" src=\"\/wp-content\/uploads\/2020\/10\/c453092dca23860a0dda604843845507.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNicm\u00e9n\u011b, i kdy\u017e nepou\u017e\u00edv\u00e1te werf, podobn\u00fd p\u0159\u00edstup k pokro\u010dil\u00e9mu \u010di\u0161t\u011bn\u00ed obraz\u016f \u2014 v jak\u00e9koli implementaci (v souladu s preferovan\u00fdm p\u0159\u00edstupem k tagov\u00e1n\u00ed obraz\u016f) \u2014 m\u016f\u017ee b\u00fdt aplikov\u00e1n i v jin\u00fdch syst\u00e9mech\/n\u00e1stroj\u00edch. Sta\u010d\u00ed si vzpomenout na probl\u00e9my, kter\u00e9 vznikaj\u00ed, a naj\u00edt ty mo\u017enosti ve va\u0161em stacku, kter\u00e9 umo\u017e\u0148uj\u00ed integrovat jejich \u0159e\u0161en\u00ed nejplynuleji. Douf\u00e1me, \u017ee cesta, kterou jsme pro\u0161li, pom\u016f\u017ee pod\u00edvat se i na v\u00e1\u0161 specifick\u00fd p\u0159\u00edpad s nov\u00fdmi detaily a my\u0161lenkami.<\/p>\n<h2>Z\u00e1v\u011br<\/h2>\n<p><\/p>\n<ul>\n<li>D\u0159\u00edve \u010di pozd\u011bji se v\u011bt\u0161ina t\u00fdm\u016f setk\u00e1 s probl\u00e9mem p\u0159epln\u011bn\u00ed registru. <\/li>\n<li>P\u0159i hled\u00e1n\u00ed \u0159e\u0161en\u00ed je nejprve t\u0159eba ur\u010dit krit\u00e9ria relevance obrazu.<\/li>\n<li>N\u00e1stroje nab\u00edzen\u00e9 popul\u00e1rn\u00edmi slu\u017ebami container registry umo\u017e\u0148uj\u00ed velmi jednoduch\u00e9 \u010di\u0161t\u011bn\u00ed, kter\u00e9 nebere v \u00favahu \"vn\u011bj\u0161\u00ed sv\u011bt\": obrazy pou\u017e\u00edvan\u00e9 v Kubernetes a specifika pracovn\u00edch proces\u016f v t\u00fdmu.<\/li>\n<li>Flexibiln\u00ed a efektivn\u00ed algoritmus by m\u011bl m\u00edt p\u0159ehled o CI\/CD procesech a pracovat nejen s daty Docker obraz\u016f.<\/li>\n<\/ul>\n<p><\/p>\n<h2>P.S.<\/h2>\n<p>\nP\u0159e\u010dt\u011bte si tak\u00e9 n\u00e1\u0161 blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\">Tagov\u00e1n\u00ed zalo\u017een\u00e9 na obsahu ve sb\u011brn\u00e9m n\u00e1stroji werf: pro\u010d a jak to funguje?<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476646\/\">3-cestn\u00e9 slou\u010den\u00ed v werf: nasazen\u00ed v Kubernetes s Helmem \u201ena steroidech\u201c<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Podpora monorepo a multirepo v werf a jak to souvis\u00ed s Docker Registry<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/493170\/\">Vyd\u00e1n\u00ed werf 1.1: vylep\u0161en\u00ed ve sb\u011brn\u00e9m n\u00e1stroji dnes a pl\u00e1ny do budoucna<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/522024\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 (Docker Registry \u0438 \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0430\u0445) \u0432 \u0440\u0435\u0430\u043b\u0438\u044f\u0445 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432 \u0434\u043b\u044f cloud native-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0432 Kubernetes. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438 \u0432\u044b\u0442\u0435\u043a\u0430\u044e\u0449\u0438\u0435 \u0438\u0437 \u043d\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0441\u0442\u0430 \u0438 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044f\u043c \u043a\u043e\u043c\u0430\u043d\u0434. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e Open Source-\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u044d\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":96066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-96065","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\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\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\/cs\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\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\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u00ab\u0443\u043c\u043d\u043e\u0439\u00bb \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 werf | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf\" \/>\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=\"2020-10-07T11:42:09+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-10-07T11:42:09+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\udd47Probl\u00e9m \u201einteligentn\u00edho\u201c \u010di\u0161t\u011bn\u00ed obraz\u016f kontejner\u016f a jeho \u0159e\u0161en\u00ed v werf | ProHoster","description":"\u010cl\u00e1nek se zab\u00fdv\u00e1.","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","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\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u00ab\u0443\u043c\u043d\u043e\u0439\u00bb \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 werf | ProHoster","og:description":"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","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":"2020-10-07T11:42:09+00:00","article:modified_time":"2020-10-07T11:42:09+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"96065","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:52:24","updated":"2022-10-01 08:58:07","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/96065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=96065"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/96065\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/96066"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=96065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=96065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=96065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}