{"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\/sv\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","title":{"rendered":"Tar bort den gamla funktionningsgrenen i Kubernetes-klustret","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Tar bort den gamla funktionningsgrenen i Kubernetes-klustret\" src=\"\/wp-content\/uploads\/2020\/07\/d97c0cce385c587e16f26f6d19b9d108.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Hej! <b>Funktionsgren<\/b> (aka deploy preview, review app) \u2014 detta n\u00e4r inte bara master-grenen deployas, utan \u00e4ven varje pull request till en unik URL. Du kan kontrollera om koden fungerar i produktionsmilj\u00f6n, och funktionen kan visas f\u00f6r andra programmerare eller produkt\u00e4gare. Medan du arbetar i pull request'en tas varje ny commit bort fr\u00e5n den aktuella deployen f\u00f6r den gamla koden, och en ny deploy f\u00f6r den nya koden implementeras. Fr\u00e5gor kan uppst\u00e5 n\u00e4r du har merget pull request'en till master-grenen. Feature-grenen beh\u00f6vs inte l\u00e4ngre, men resurserna i Kubernetes finns fortfarande kvar i klustret.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Mer om feature-grenar<\/h2>\n<p><\/p>\n<p>Ett av s\u00e4tten att skapa feature-grenar i Kubernetes \u00e4r att anv\u00e4nda namespaces. Sammanfattningsvis ser produktionskonfigurationerna ut s\u00e5 h\u00e4r:<\/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>F\u00f6r feature-grenen skapas ett namespace med dess identifierare (till exempel, numret p\u00e5 pull request'en) och n\u00e5got prefix\/suffix (till exempel, <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>Sammanfattningsvis, jag skrev <b>Kubernetes Operator<\/b> (en applikation som har \u00e5tkomst till klustrets resurser), <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">l\u00e4nk till projektet p\u00e5 Github<\/a><\/noindex>. Det tar bort namespaces som tillh\u00f6r gamla feature-grenar. I Kubernetes, n\u00e4r ett namespace tas bort, tas andra resurser i detta namespace ocks\u00e5 bort automatiskt.<\/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>Om hur man implementerar feature-grenar i klustret kan du l\u00e4sa <noindex><a rel=\"nofollow\" href=\"https:\/\/itnext.io\/feature-deployments-in-kubernetes-c74bdcff0d8e\">). Ett typiskt exempel p\u00e5 anv\u00e4ndning:<\/a><\/noindex> och <noindex><a rel=\"nofollow\" href=\"https:\/\/codefresh.io\/kubernetes-tutorial\/dynamically-creating-k8s-namespaces-every-branch-pull-request-2\">). Ett typiskt exempel p\u00e5 anv\u00e4ndning:<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2>Motivation<\/h2>\n<p><\/p>\n<p>L\u00e5t oss titta p\u00e5 en typisk livscykel f\u00f6r en pull request med kontinuerlig integration (<code>kontinuerlig integration<\/code>):<\/p>\n<p><\/p>\n<ol>\n<li>Vi pushar en ny commit till grenen.<\/li>\n<li>Vid bygget k\u00f6rs linters och\/eller tester.<\/li>\n<li>Kubernetes-konfigurationer f\u00f6r pull request'en genereras i realtid (till exempel, numret s\u00e4tts in i en f\u00e4rdig mall).<\/li>\n<li>Med hj\u00e4lp av kubectl apply kommer konfigurationerna att \u00f6verf\u00f6ras till klustret (distribuera).<\/li>\n<li>Pull requesten sl\u00e5s samman med master-grenen.<\/li>\n<\/ol>\n<p><\/p>\n<p>Medan du arbetar i pull request'en tas varje ny commit bort fr\u00e5n den aktuella deployen f\u00f6r den gamla koden, och en ny deploy f\u00f6r den nya koden implementeras. Men n\u00e4r pull request'en sl\u00e5s ihop med master-grenen kommer endast master-grenen att byggas. Resultatet blir att vi redan har gl\u00f6mt pull request'en, men dess Kubernetes-resurser finns fortfarande kvar i klustret.<\/p>\n<p><\/p>\n<h2>Hur man anv\u00e4nder<\/h2>\n<p><\/p>\n<p>Installera projektet med kommandot nedan:<\/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>Skapa en fil med f\u00f6ljande inneh\u00e5ll och installera genom <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>Parameter <b>namespaceSubstring<\/b> Beh\u00f6vs f\u00f6r att filtrera namespaces f\u00f6r pull requests fr\u00e5n andra namespaces. Till exempel, om klustret har f\u00f6ljande namespaces: <code>habr-back-end<\/code>, <code>habr-front-end<\/code>, <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>, d\u00e5 kommer kandidaterna f\u00f6r borttagning att vara <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>.<\/p>\n<p><\/p>\n<p>Parameter <b>afterDaysWithoutDeploy<\/b> Beh\u00f6vs f\u00f6r att ta bort gamla namespaces. Till exempel, om namespace har skapats <code>3 dagar 1 timme<\/code> sedan, och parametern anges som <code>3 dagar<\/code>, kommer detta namespace att tas bort. Det fungerar ocks\u00e5 tv\u00e4rtom; om namespace skapades <code>2 dagar 23 timmar<\/code> sedan, och parametern anges som <code>3 dagar<\/code>, kommer detta namespace inte att tas bort.<\/p>\n<p><\/p>\n<p>Det finns ytterligare en parameter, som ansvarar f\u00f6r hur ofta alla namespaces ska skannas och kontrolleras f\u00f6r dagar utan deploy \u2014 <b>checkEveryMinutes<\/b>. Som standard \u00e4r den inst\u00e4lld p\u00e5 <code>30 minuter<\/code>.<\/p>\n<p><\/p>\n<h2>Hur det fungerar<\/h2>\n<p><\/p>\n<p>I praktiken kommer det att beh\u00f6vas:<\/p>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/get-docker\">Docker<\/a><\/noindex> f\u00f6r att arbeta i en isolerad milj\u00f6.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-minikube\">Minikube<\/a><\/noindex> startar Kubernetes-klustret lokalt.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-kubectl\">kubectl<\/a><\/noindex> \u2014 kommandoradsgr\u00e4nssnitt f\u00f6r att hantera klustret.<\/li>\n<\/ol>\n<p><\/p>\n<p>Startar Kubernetes-klustret lokalt:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ minikube start --vm-driver=docker\nminikube v1.11.0 p\u00e5 Darwin 10.15.5\nAnv\u00e4nder docker-drivrutinen baserat p\u00e5 befintlig profil.\nStartar kontrollplanet nod minikube i klustret minikube.<\/code><\/pre>\n<p><\/p>\n<p>Ange <code>kubectl<\/code> anv\u00e4nda det lokala klustret som standard:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl config use-context minikube\nBytte till kontext \"minikube\".<\/code><\/pre>\n<p><\/p>\n<p>Laddar ner konfigurationerna f\u00f6r produktionsmilj\u00f6n:<\/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>Eftersom produktionskonfigurationerna \u00e4r inst\u00e4llda f\u00f6r att kontrollera gamla namespaces, och i v\u00e5rt nyuppr\u00e4ttade kluster finns det inga, ska vi \u00e4ndra milj\u00f6variabeln <code>IS_DEBUG<\/code> till <code>true<\/code>. N\u00e4r detta v\u00e4rde \u00e4r inst\u00e4llt beaktas inte parametern och namespace kontrolleras inte f\u00f6r dagar utan deploy, endast f\u00f6r f\u00f6rekomsten av delstr\u00e4ngen ( <code>afterDaysWithoutDeploy<\/code> ing\u00e5 och namespaces kontrolleras inte f\u00f6r dagar utan deploy, endast f\u00f6r att hitta delstr\u00e4ngar (<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\">Kontrollerar att resursen har dykt upp i klustret<\/code><\/pre>\n<p><\/p>\n<p>StaleFeatureBranch <code>$ kubectl api-resources | grep stalefeaturebranches\nNAMN                 ... APIGROUP                             ... TYP\nstalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">Kontrollerar att operat\u00f6ren har dykt upp i klustret:<\/code><\/pre>\n<p><\/p>\n<p>$ kubectl get pods --namespace stale-feature-branch-operator\nNAMN                                           ... STATUS  ... \u00c5LDER\nstale-feature-branch-operator-6bfbfd4df8-m7sch ... K\u00f6r ... 38s<\/p>\n<p><\/p>\n<pre><code class=\"bash\">Om man kollar loggarna f\u00f6r det, \u00e4r det redo att hantera resurser<\/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\nNAMN                 ... APIGROUP                             ... TYP\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>armaturer<\/code> (f\u00e4rdiga konfigurationer f\u00f6r resurskluster) f\u00f6r resursen <code>$ kubectl api-resources | grep stalefeaturebranches\nNAMN                 ... APIGROUP                             ... TYP\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>I konfigurationerna anges att s\u00f6ka efter namespace med delstr\u00e4ngar <code>-pr-<\/code> varje <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>Operat\u00f6ren har reagerat och \u00e4r redo att kontrollera namespace:<\/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 bearbetas.\",\"namespaceSubstring\":\"-pr-\",\"afterDaysWithoutDeploy\":1,\"checkEveryMinutes\":1,\"isDebug\":\"true\"}<\/code><\/pre>\n<p><\/p>\n<p>Installera <code>armaturer<\/code>, som inneh\u00e5ller tv\u00e5 namespace (<code>project-pr-1<\/code>, <code>project-pr-2<\/code>) och deras <code>deployment<\/code>, <code>tj\u00e4nster<\/code>, <code>ingress<\/code>, och s\u00e5 vidare:<\/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...\nnamespaces\/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\n-ingress.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\n-ingress.extensions\/project-pr-2 created<\/code><\/pre>\n<p><\/p>\n<p>Vi kontrollerar att alla resurser ovan har skapats framg\u00e5ngsrikt:<\/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...\nNAME                              ... READY ... STATUS  ... AGE\npod\/project-pr-1-848d5fdff6-rpmzw ... 1\/1   ... Running ... 67s\n\nNAME                         ... READY ... AVAILABLE ... AGE\ndeployment.apps\/project-pr-1 ... 1\/1   ... 1         ... 67s\n...<\/code><\/pre>\n<p><\/p>\n<p>Eftersom vi har aktiverat <code>debug<\/code>, namespace <code>project-pr-1<\/code> och <code>project-pr-2<\/code>, m\u00e5ste d\u00e4rf\u00f6r alla andra resurser avl\u00e4gsnas omedelbart oavsett parametern <code>afterDaysWithoutDeploy<\/code>. Detta kan ses i operat\u00f6rens loggar:<\/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 b\u00f6r raderas eftersom debug-l\u00e4get \u00e4r aktiverat.\",\"namespaceName\":\"project-pr-1\"}\n... \"msg\":\"Namespace bearbetas.\",\"namespaceName\":\"project-pr-1\",\"namespaceCreationTimestamp\":\"2020-06-16 18:43:58 +0300 EEST\"}\n... \"msg\":\"Namespace har raderats.\",\"namespaceName\":\"project-pr-1\"}\n... \"msg\":\"Namespace b\u00f6r raderas eftersom debug-l\u00e4get \u00e4r aktiverat.\",\"namespaceName\":\"project-pr-2\"}\n... \"msg\":\"Namespace bearbetas.\",\"namespaceName\":\"project-pr-2\",\"namespaceCreationTimestamp\":\"2020-06-16 18:43:58 +0300 EEST\"}\n... \"msg\":\"Namespace har raderats.\",\"namespaceName\":\"project-pr-2\"}<\/code><\/pre>\n<p><\/p>\n<p>Om du kontrollerar tillg\u00e5ngen till resurser kommer de att vara i status <code>Terminating<\/code> (borttagningsprocess) eller redan borttagna (kommandoutdata \u00e4r tomt).<\/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>Du kan upprepa skapelseprocessen <code>armaturer<\/code> flera g\u00e5nger och se till att de tas bort inom en minut.<\/p>\n<p><\/p>\n<h2>Alternativ<\/h2>\n<p><\/p>\n<p>Vad kan man g\u00f6ra ist\u00e4llet f\u00f6r en operator som arbetar i en kluster? Det finns flera tillv\u00e4gag\u00e5ngss\u00e4tt, alla \u00e4r inte perfekta (och deras nackdelar \u00e4r subjektiva), och varje person m\u00e5ste avg\u00f6ra vad som passar b\u00e4st f\u00f6r just sitt projekt:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>Att ta bort feature branch under bygget av master-grenen f\u00f6r kontinuerlig integration.<\/p>\n<p><\/p>\n<ul>\n<li>F\u00f6r detta m\u00e5ste man veta vilken pull request som \u00e4r kopplad till commit som byggs. Eftersom feature branch namespace inneh\u00e5ller identifikationen av pull requesten - dess nummer eller grenenamn, m\u00e5ste identifieraren alltid anges i commit.<\/li>\n<li>Byggen av master-grenar misslyckas. Till exempel har du f\u00f6ljande steg: ladda ner projektet, k\u00f6r tester, bygg projektet, g\u00f6r en release, skicka aviseringar, rensa feature branch av den senaste pull requesten. Om bygget misslyckas vid aviseringarna m\u00e5ste du ta bort alla resurser i kluster manuellt.<\/li>\n<li>Utan r\u00e4tt kontext \u00e4r det oklart att ta bort feature branch i master bygget.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Anv\u00e4ndning av webhookar (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.community\/t\/trigger-jenkins-job-when-a-pull-request-is-merged-to-a-branch\/1169\">exempel<\/a><\/noindex>).<\/p>\n<p><\/p>\n<ul>\n<li>Kanske \u00e4r det inte din metod. Till exempel, i <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jenkins.io\">Jenkins<\/a><\/noindex>, endast en typ av pipeline st\u00f6der m\u00f6jligheten att spara sina konfigurationer i k\u00e4llkoden. Vid anv\u00e4ndning av webhookar m\u00e5ste du skriva ditt eget skript f\u00f6r att behandla dem. Detta skript m\u00e5ste placeras i Jenkins-gr\u00e4nssnittet, vilket \u00e4r sv\u00e5rt att underh\u00e5lla.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Skriva <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/cron-jobs\/\">Cronjob<\/a><\/noindex> och l\u00e4gga till Kubernetes-klustret.<\/p>\n<p><\/p>\n<ul>\n<li>Tid som l\u00e4ggs p\u00e5 att skriva och underh\u00e5lla.<\/li>\n<li>Operat\u00f6ren fungerar redan i en liknande stil, \u00e4r dokumenterad och underh\u00e5lls.<\/li>\n<\/ul>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Tack f\u00f6r ert intresse f\u00f6r artikeln. <strong><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">L\u00e4nk till projektet p\u00e5 Github<\/a><\/noindex><\/strong>.<\/p>\n<p>K\u00e4lla: <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.4 - 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\/sv\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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\udd47 Tar bort den f\u00f6r\u00e5ldrade feature branch i Kubernetes-klustret | ProHoster","description":"Hej!","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/86902","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=86902"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/86902\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/86903"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=86902"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=86902"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=86902"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}