{"id":86902,"date":"2020-07-01T07:42:28","date_gmt":"2020-07-01T05:42:28","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere"},"modified":"2020-07-01T07:42:28","modified_gmt":"2020-07-01T05:42:28","slug":"udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","title":{"rendered":"Kustutame vananenud feature branch'i Kubernetes klastris","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Kustutame vananenud feature branch&#039;i Kubernetes klastris\" src=\"\/wp-content\/uploads\/2020\/07\/d97c0cce385c587e16f26f6d19b9d108.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Tere! <b>Funktsioonide haru<\/b> (aka deploy preview, review app) \u2014 see, et deployitakse mitte ainult master haru, vaid ka iga pull request unikaalsesse URL-i. Saate kontrollida, kas kood t\u00f6\u00f6tab tootmis keskkonnas, ning funktsiooni saate n\u00e4idata teistele arendajatele v\u00f5i tootearendajatele. Kui t\u00f6\u00f6tate pull request'is, siis iga uus commit eemaldab praeguse deploy vanale koodile ja uue deploy uuele koodile. K\u00fcsimused v\u00f5ivad tekkida, kui olete pull request'i master haru sulandunud. Funktsiooniharu pole enam vajalik, kuid Kubernetes ressursid on endiselt klastri sees.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Veel feature harudest<\/h2>\n<p><\/p>\n<p>\u00dcks l\u00e4henemisviise feature harude loomiseks Kuberneteses \u2014 kasutada namespace'e. L\u00fchidalt, tootmiskonfiguratsioon n\u00e4eb v\u00e4lja j\u00e4rgmiselt:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">kind: Namespace\napiVersion: v1\nmetadata:\n  name: habr-back-end\n...\n\nkind: Deployment\napiVersion: apps\/v1\nmetadata:\n  namespace: habr-back-end\nspec:\n  replicas: 3\n...<\/code><\/pre>\n<p><\/p>\n<p>Funktsiooniharu jaoks luuakse namespace selle identifikaatoriga (nt pull request'i number) ja mingi eel- v\u00f5i j\u00e4rellisa (nt, <b>-pr-<\/b>):<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">kind: Namespace\napiVersion: v1\nmetadata:\n  name: habr-back-end-pr-17\n...\n\nkind: Deployment\napiVersion: apps\/v1\nmetadata:\n  namespace: habr-back-end-pr-17\nspec:\n  replicas: 1\n...<\/code><\/pre>\n<p><\/p>\n<p>\u00dcldiselt, olen kirjutanud <b>Kubernetes Operator<\/b> (rakendus, mis p\u00e4\u00e4seb ligi klastrite ressurssidele), <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">link projekti kohta Githubis<\/a><\/noindex>. See kustutab namespace'd, mis kuuluvad vanadele funktsiooniharudele. Kuberneteses, kui kustutada namespace, kustutatakse automaatselt ka teised ressursid selle namespace'i sees.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get pods --all-namespaces | grep -e \"-pr-\"\nNAMESPACE            ... AGE\nhabr-back-end-pr-264 ... 4d8h\nhabr-back-end-pr-265 ... 5d7h<\/code><\/pre>\n<p><\/p>\n<p>Kuidas rakendada feature harusid klastrisse, saate lugeda <noindex><a rel=\"nofollow\" href=\"https:\/\/itnext.io\/feature-deployments-in-kubernetes-c74bdcff0d8e\">siit<\/a><\/noindex> ja <noindex><a rel=\"nofollow\" href=\"https:\/\/codefresh.io\/kubernetes-tutorial\/dynamically-creating-k8s-namespaces-every-branch-pull-request-2\">siit<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2>Motivatsioon<\/h2>\n<p><\/p>\n<p>Vaadakem t\u00fc\u00fcpilist pull request'i eluts\u00fckli koos pideva integreerimisega (<code>continuous integration<\/code>):<\/p>\n<p><\/p>\n<ol>\n<li>Pusime uue commit'i harusse.<\/li>\n<li>Build'i ajal k\u00e4ivitatakse lintimise ja\/v\u00f5i testimise protsessid.<\/li>\n<li>Kubernetes pull request'i konfiguratsioonid vormitakse jooksvalt (nt selle numbri lisamine valmis mallile).<\/li>\n<li>Konfiguratsioonide juurutamine klastrisse toimub kubectl apply abil (deploy).<\/li>\n<li>Pull request sulandub master harusse.<\/li>\n<\/ol>\n<p><\/p>\n<p>Kui t\u00f6\u00f6tate pull request'is, siis iga uus commit eemaldab praeguse deploy vanale koodile ja uue deploy uuele koodile. Kuid kui pull request liidetakse master haru, ehitatakse ainult master haru. Tulemuseks on see, et unustame pull request'i, kuid selle Kubernetes ressursid on endiselt klastri sees.<\/p>\n<p><\/p>\n<h2>Kuidas kasutada<\/h2>\n<p><\/p>\n<p>Paigaldage projekt j\u00e4rgmisel k\u00e4sul:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl apply -f https:\/\/raw.githubusercontent.com\/dmytrostriletskyi\/stale-feature-branch-operator\/master\/configs\/production.yml<\/code><\/pre>\n<p><\/p>\n<p>Looge fail j\u00e4rgmise sisuga ja paigaldage see kaudu <code>kubectl apply -f<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">apiVersion: feature-branch.dmytrostriletskyi.com\/v1\nkind: StaleFeatureBranch\nmetadata:\n  name: stale-feature-branch\nspec:\n  namespaceSubstring: -pr-\n  afterDaysWithoutDeploy: 3<\/code><\/pre>\n<p><\/p>\n<p>Parameeter <b>namespaceSubstring<\/b> on vajalik, et filtreerida pull request'i namespace'd teistest namespace'dest. N\u00e4iteks, kui klastris on j\u00e4rgmised namespace'd: <code>habr-back-end<\/code>, <code>habr-front-end<\/code>, <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>, siis kaotsitavaks on <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>.<\/p>\n<p><\/p>\n<p>Parameeter <b>afterDaysWithoutDeploy<\/b> on vajalik, et kustutada vanad namespace'd. N\u00e4iteks, kui namespace on loodud <code>3 p\u00e4eva 1 tund<\/code> tagasi, ja parameetriks on m\u00e4\u00e4ratud <code>3 p\u00e4eva<\/code>, siis see namespace kustutatakse. See t\u00f6\u00f6tab ka vastupidiselt, kui namespace on loodud <code>2 p\u00e4eva 23 tundi<\/code> tagasi, ja parameetriks on m\u00e4\u00e4ratud <code>3 p\u00e4eva<\/code>, siis see namespace ei kustutata.<\/p>\n<p><\/p>\n<p>On veel \u00fcks parameeter, mis m\u00e4\u00e4rab, kui tihti skannitakse k\u00f5iki namespace'e ja kontrollitakse, kui palju p\u00e4evi on m\u00f6\u00f6dunud ilma deploy'ta \u2014 <b>checkEveryMinutes<\/b>. Vaikimisi on see m\u00e4\u00e4ratud <code>30 minutiks<\/code>.<\/p>\n<p><\/p>\n<h2>Kuidas see t\u00f6\u00f6tab<\/h2>\n<p><\/p>\n<p>Praktikas on vajalik:<\/p>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/get-docker\">Docker<\/a><\/noindex> t\u00f6\u00f6tamiseks isoleeritud keskkonnas.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-minikube\">Minikube<\/a><\/noindex> \u00fcles t\u00f5sta Kubernetes kluster kohalikult.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-kubectl\">kubectl<\/a><\/noindex> \u2014 k\u00e4surealiides klustere haldamiseks.<\/li>\n<\/ol>\n<p><\/p>\n<p>T\u00f5stame Kubernetes klustrit kohalikult:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ minikube start --vm-driver=docker\nminikube v1.11.0 Darwin 10.15.5 peal\nKasutades docker draiverit olemasoleva profiili p\u00f5hjal.\nK\u00e4ivitame kontrollplaani s\u00f5lme minikube klustrites minikube.<\/code><\/pre>\n<p><\/p>\n<p>M\u00e4\u00e4rame <code>kubectl<\/code> kasutame kohalikku klustrit vaikimisi:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl config use-context minikube\nL\u00fclitud konteksti \"minikube\".<\/code><\/pre>\n<p><\/p>\n<p>Laadime alla produktsioonikeskkonna konfiguratsioonid:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ curl https:\/\/raw.githubusercontent.com\/dmytrostriletskyi\/stale-feature-branch-operator\/master\/configs\/production.yml &gt; stale-feature-branch-production-configs.yml<\/code><\/pre>\n<p><\/p>\n<p>Kuna tootmiskonfiguratsioonid on seadistatud kontrollima vanu namespace'e ning meie uues klastris neid ei ole, asendame keskkonnamuutuja <code>IS_DEBUG<\/code> . Tundub, et <code>true<\/code>. Sellise v\u00e4\u00e4rtuse puhul ei arvestata parameetrit ja namespace'e ei kontrollita p\u00e4evade puudumise t\u00f5ttu deploy'ide osas, vaid ainult alamt\u00e4he sisaldumise p\u00f5hjal ( <code>afterDaysWithoutDeploy<\/code> ei arvestata ja namespace'e ei kontrollita p\u00e4evade kaupa ilma deploy'ta, vaid ainult alamstringi esinemise p\u00f5hjal (<code>-pr-<\/code>).<\/p>\n<p><\/p>\n<p>$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml <code>Linux<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ sed -i \"\" 's|false|true|g' stale-feature-branch-production-configs.yml<\/code><\/pre>\n<p><\/p>\n<p>$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml <code>macOS<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ sed -i \"\" 's|false|true|g' stale-feature-branch-production-configs.yml<\/code><\/pre>\n<p><\/p>\n<p>$ kubectl apply -f stale-feature-branch-production-configs.yml<\/p>\n<p><\/p>\n<pre><code class=\"bash\">Kontrollime, et klusteris on ilmunud ressurss<\/code><\/pre>\n<p><\/p>\n<p>StaleFeatureBranch <code>$ kubectl api-resources | grep stalefeaturebranches\nNAME                 ... APIGROUP                             ... KIND\nstalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">Kontrollime, et klusteris on ilmunud operaator:<\/code><\/pre>\n<p><\/p>\n<p>$ kubectl get pods --namespace stale-feature-branch-operator\nNAME                                           ... STATUS  ... AGE\nstale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s<\/p>\n<p><\/p>\n<pre><code class=\"bash\">Kui vaatame tema logisid, on ta valmis t\u00f6\u00f6tlema ressursse<\/code><\/pre>\n<p><\/p>\n<p>$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator\n... \"msg\":\"Operator Version: 0.0.1\"}\n...\n... \"msg\":\"Starting EventSource\", ... , \"source\":\"kind source: \/, Kind=\"}\n... \"msg\":\"Starting Controller\", ...}\n... \"msg\":\"Starting workers\", ..., \"worker count\":1} <code>$ kubectl api-resources | grep stalefeaturebranches\nNAME                 ... APIGROUP                             ... KIND\nstalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator\n... \"msg\":\"Operator Version: 0.0.1\"\n...\n... \"msg\":\"Starting EventSource\", ... , \"source\":\"kind source: \/, Kind=\"}\n... \"msg\":\"Starting Controller\", ...}\n... \"msg\":\"Starting workers\", ..., \"worker count\":1}<\/code><\/pre>\n<p><\/p>\n<p>fixtures <code>kinnitusvahendid<\/code> (valmis konfiguratsioon klastrite ressursi mudeldamiseks) ressursi jaoks <code>$ kubectl api-resources | grep stalefeaturebranches\nNAME                 ... APIGROUP                             ... KIND\nstalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl apply -f https:\/\/raw.githubusercontent.com\/dmytrostriletskyi\/stale-feature-branch-operator\/master\/fixtures\/stale-feature-branch.yml<\/code><\/pre>\n<p><\/p>\n<p>Konfiguratsioonides on m\u00e4rgitud, et otsitakse namespace'e, mis sisaldavad alams\u00f5na <code>-pr-<\/code> iga <code>1 minut<\/code>.:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">apiVersion: feature-branch.dmytrostriletskyi.com\/v1\nkind: StaleFeatureBranch\nmetadata:\n  name: stale-feature-branch\nspec:\n  namespaceSubstring: -pr-\n  afterDaysWithoutDeploy: 1 \n  checkEveryMinutes: 1<\/code><\/pre>\n<p><\/p>\n<p>Operaator reageeris ja on valmis kontrollima namespace'e:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator\n... \"msg\":\"Stale feature branch is being processed.\",\"namespaceSubstring\":\"-pr-\",\"afterDaysWithoutDeploy\":1,\"checkEveryMinutes\":1,\"isDebug\":\"true\"}<\/code><\/pre>\n<p><\/p>\n<p>Paigaldame <code>kinnitusvahendid<\/code>, sisaldades kahte namespace'i (<code>project-pr-1<\/code>, <code>project-pr-2<\/code>) ja nende <code>deployments<\/code>, <code>teenused<\/code>, <code>ingress<\/code>, ja nii edasi:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl apply -f https:\/\/raw.githubusercontent.com\/dmytrostriletskyi\/stale-feature-branch-operator\/master\/fixtures\/first-feature-branch.yml -f https:\/\/raw.githubusercontent.com\/dmytrostriletskyi\/stale-feature-branch-operator\/master\/fixtures\/second-feature-branch.yml\n...\nnamespace\/project-pr-1 created\ndeployment.apps\/project-pr-1 created\nservice\/project-pr-1 created\nhorizontalpodautoscaler.autoscaling\/project-pr-1 created\nsecret\/project-pr-1 created\nconfigmap\/project-pr-1 created\ningress.extensions\/project-pr-1 created\nnamespace\/project-pr-2 created\ndeployment.apps\/project-pr-2 created\nservice\/project-pr-2 created\nhorizontalpodautoscaler.autoscaling\/project-pr-2 created\nsecret\/project-pr-2 created\nconfigmap\/project-pr-2 created\ningress.extensions\/project-pr-2 created<\/code><\/pre>\n<p><\/p>\n<p>Kontrollime, et k\u00f5ik \u00fclaltoodud ressursid on edukalt loodud:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 &amp;&amp; kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2\n...\nNIMI                              ... VALMIS ... SEISUND  ... VANUS\npod\/project-pr-1-848d5fdff6-rpmzw ... 1\/1   ... Jookseb ... 67s\n\nNIMI                            ... VALMIS ... SAADAV ... VANUS\ndeployment.apps\/project-pr-1 ... 1\/1   ... 1         ... 67s\n...<\/code><\/pre>\n<p><\/p>\n<p>Kuna oleme l\u00fclitanud <code>debug<\/code>, namespace'id <code>project-pr-1<\/code> ja <code>project-pr-2<\/code>, seega peavad ka k\u00f5ik teised ressursid kohe kustutama, arvestamata parameetrit <code>afterDaysWithoutDeploy<\/code>. Operaatori logides on see n\u00e4htav:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator\n... \"msg\":\"Namespace should be deleted due to debug mode is enabled.\",\"namespaceName\":\"project-pr-1\"\n... \"msg\":\"Namespace is being processed.\",\"namespaceName\":\"project-pr-1\",\"namespaceCreationTimestamp\":\"2020-06-16 18:43:58 +0300 EEST\"\n... \"msg\":\"Namespace has been deleted.\",\"namespaceName\":\"project-pr-1\"\n... \"msg\":\"Namespace should be deleted due to debug mode is enabled.\",\"namespaceName\":\"project-pr-2\"\n... \"msg\":\"Namespace is being processed.\",\"namespaceName\":\"project-pr-2\",\"namespaceCreationTimestamp\":\"2020-06-16 18:43:58 +0300 EEST\"\n... \"msg\":\"Namespace has been deleted.\",\"namespaceName\":\"project-pr-2\"}<\/code><\/pre>\n<p><\/p>\n<p>Kui kontrollida ressursside olemasolu, on need olekus <code>Termineeritud<\/code> (kustutusprotsess) v\u00f5i on juba kustutatud (k\u00e4skluse v\u00e4ljund on t\u00fchi).<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 &amp;&amp; kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2\n...<\/code><\/pre>\n<p><\/p>\n<p>Saate protsessi loomist uuesti korrata <code>kinnitusvahendid<\/code> kontrollige mitu korda ja veenduge, et need eemaldatakse minuti jooksul.<\/p>\n<p><\/p>\n<h2>Alternatiivid<\/h2>\n<p><\/p>\n<p>Mida teha, kui klastris t\u00f6\u00f6tavat operaatori asemel? L\u00e4henemisviise on mitu, k\u00f5ik ei ole ideaalsed (ja nende puudused on subjektiivsed), ning iga\u00fcks peab ise otsustama, mis sobib k\u00f5ige paremini konkreetsele projektile:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>Eemaldage feature branch pideva integratsiooni master haru ehitamise ajal.<\/p>\n<p><\/p>\n<ul>\n<li>Selleks tuleb teada, milline pull request on seotud commit'iga, mida ehitatakse. Kuna feature branch namespace sisaldab pull request'i numbrit v\u00f5i haru nime, tuleb identifikaator alati commit'is \u0443\u043a\u0430\u0437\u0430\u0442\u044c.<\/li>\n<li>Master harude ehitused katkestatakse. N\u00e4iteks on teil j\u00e4rgmised etapid: projekt alla laadida, testid k\u00e4ivitada, projekt kokku panna, versioon v\u00e4lja anda, teavitused saata, puhastada feature branch viimase pull request'i osas. Kui ehitus katkeb teavituse saatmise ajal, tuleb k\u00f5ik ressursid klastris k\u00e4sitsi eemaldada.<\/li>\n<li>Ilma korraliku kontekstita, feature branch'i eemaldamine master ehituses ei ole ilmselge.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Webhook'ide kasutamine (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.community\/t\/trigger-jenkins-job-when-a-pull-request-is-merged-to-a-branch\/1169\">n\u00e4ide<\/a><\/noindex>).<\/p>\n<p><\/p>\n<ul>\n<li>V\u00f5ib-olla ei ole see teie l\u00e4henemine. N\u00e4iteks, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jenkins.io\">Jenkinsile<\/a><\/noindex>, vaid \u00fcks pipeline'i t\u00fc\u00fcp toetab selles konfigureerimise salvestamise v\u00f5imalust l\u00e4htekoodis. Webhook'ide kasutamisel tuleb kirjutada oma skript nende t\u00f6\u00f6tlemiseks. See skript tuleb paigutada Jenkins'i liidesesse, mida on keeruline hooldada.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Kirjutage <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/cron-jobs\/\">Cronjob<\/a><\/noindex> ja lisage Kubernetes klaster.<\/p>\n<p><\/p>\n<ul>\n<li>Aja kulu skripti kirjutamiseks ja hooldamiseks.<\/li>\n<li>Operaator t\u00f6\u00f6tab juba sarnasel stilil, on dokumenteeritud ja toetatud.<\/li>\n<\/ul>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Ait\u00e4h artikli eest. <strong><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">Projektiga seotud link Github'is<\/a><\/noindex><\/strong>.<\/p>\n<p>Allikas: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/508534\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442! Feature branch (aka deploy preview, review app) \u2014 \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e master \u0432\u0435\u0442\u043a\u0430, \u043d\u043e \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 pull request \u043d\u0430 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 URL. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u0438 \u043a\u043e\u0434 \u0432 production-\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438, \u0444\u0438\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c \u0438\u043b\u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043b\u043e\u0433\u0430\u043c. \u041f\u043e\u043a\u0430 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435 \u0432 pull request&#8217;\u0435, \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u043e\u0432\u044b\u0439 commit \u0442\u0435\u043a\u0443\u0449\u0438\u0439 deploy \u0434\u043b\u044f \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f, \u0430 \u043d\u043e\u0432\u044b\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":86903,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-86902","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.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442!\" \/>\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\/et\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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\u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0443\u044e feature branch \u0432 Kubernetes \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere\" \/>\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-07-01T05:42:28+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-01T05:42:28+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\udd47Eemaldame aegunud feature branch'i Kubernetes klastris | ProHoster","description":"Tere!","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","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\u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0443\u044e feature branch \u0432 Kubernetes \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442!","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","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-07-01T05:42:28+00:00","article:modified_time":"2020-07-01T05:42:28+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"86902","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 14:03:55","updated":"2022-10-03 08:48:02","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/86902","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=86902"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/86902\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/86903"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=86902"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=86902"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=86902"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}