{"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\/da\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","title":{"rendered":"Fjerner for\u00e6ldet feature branch i Kubernetes-klyngen","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Fjerner for\u00e6ldet feature branch i Kubernetes-klyngen\" 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 det er n\u00e5r der ikke kun deployeres til master-grenen, men hver pull request til en unik URL. Man kan tjekke, om koden fungerer i production-milj\u00f8et, og funktionen kan vises til andre programm\u00f8rer eller produktfolk. Mens du arbejder i pull requesten, slettes den nuv\u00e6rende deployment for gammel kode, hver gang der laves et nyt commit, og en ny deployment for den nye kode k\u00f8res. Sp\u00f8rgsm\u00e5l kan opst\u00e5, n\u00e5r du har merger'et pull requesten ind i master-grenen. Feature-grenen er ikke l\u00e6ngere n\u00f8dvendig, men ressourcerne i Kubernetes er stadig i klyngen.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Mere om feature-grene<\/h2>\n<p><\/p>\n<p>En m\u00e5de at oprette feature-grene i Kubernetes \u2014 er at anvende namespaces. Kort sagt, production-konfigurationerne ser s\u00e5dan ud:<\/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>For feature-grenen oprettes der et namespace med dens identifikator (for eksempel, nummeret p\u00e5 pull requesten) og et eller andet pr\u00e6fiks\/suffiks (for eksempel, <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>Generelt har jeg skrevet <b>Kubernetes Operator<\/b> (applikationen, der har adgang til klyngens ressourcer), <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">link til projektet p\u00e5 Github<\/a><\/noindex>. Det fjerner namespaces, der tilh\u00f8rer gamle feature-grene. I Kubernetes, hvis du sletter et namespace, slettes andre ressourcer i dette namespace ogs\u00e5 automatisk.<\/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 hvordan man implementerer feature-grene i klyngen, kan du l\u00e6se <noindex><a rel=\"nofollow\" href=\"https:\/\/itnext.io\/feature-deployments-in-kubernetes-c74bdcff0d8e\">her<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/codefresh.io\/kubernetes-tutorial\/dynamically-creating-k8s-namespaces-every-branch-pull-request-2\">her<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2>Motivation<\/h2>\n<p><\/p>\n<p>Lad os se p\u00e5 en typisk livscyklus for en pull request med kontinuerlig integration (<code>kontinuerlig integration<\/code>):<\/p>\n<p><\/p>\n<ol>\n<li>Vi push'er en ny commit til grenen.<\/li>\n<li>Ved bygningene k\u00f8res linters og\/eller tests.<\/li>\n<li>Kubernetes-konfigurationerne for pull requesten dannes on the fly (for eksempel inds\u00e6ttes dens nummer i en f\u00e6rdig skabelon).<\/li>\n<li>Med kubectl apply bliver konfigurationerne sendt til klyngen (deploy).<\/li>\n<li>Pull request'en flettes ind i master-grenen.<\/li>\n<\/ol>\n<p><\/p>\n<p>Mens du arbejder i pull requesten, slettes den aktuelle deployment for gammel kode ved hvert nyt commit, og en ny deployment for ny kode k\u00f8res. Men n\u00e5r pull requesten merges ind i master-grenen, vil der kun blive bygget for master-grenen. Resultatet er, at vi har glemt pull requesten, men dens Kubernetes-ressourcer er stadig i klyngen.<\/p>\n<p><\/p>\n<h2>Hvordan man bruger<\/h2>\n<p><\/p>\n<p>Installer projektet med kommandoen nedenfor:<\/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>Opret en fil med f\u00f8lgende indhold og installer gennem <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> er n\u00f8dvendig for at filtrere namespaces for pull requests fra andre namespaces. For eksempel, hvis der i klyngen er f\u00f8lgende 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>, s\u00e5 vil kandidaterne til sletning v\u00e6re <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>.<\/p>\n<p><\/p>\n<p>Parameter <b>afterDaysWithoutDeploy<\/b> er n\u00f8dvendig for at slette gamle namespaces. For eksempel, hvis namespace er oprettet <code>3 dage 1 time<\/code> siden, og parameteren angiver <code>3 dage<\/code>, vil dette namespace blive slettet. Det fungerer ogs\u00e5 i den modsatte retning; hvis et namespace blev oprettet <code>2 dage 23 timer<\/code> siden, og parameteren angiver <code>3 dage<\/code>, vil dette namespace ikke blive slettet.<\/p>\n<p><\/p>\n<p>Der er ogs\u00e5 en parameter, der angiver hvor ofte der skal scannes i alle namespaces og kontrolleres for dage uden deployment \u2014 <b>checkEveryMinutes<\/b>. Som standard er den sat til <code>30 minutter<\/code>.<\/p>\n<p><\/p>\n<h2>Hvordan fungerer det<\/h2>\n<p><\/p>\n<p>I praksis vil vi have brug for:<\/p>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/get-docker\">Docker<\/a><\/noindex> til drift i et isoleret milj\u00f8.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-minikube\">Minikube<\/a><\/noindex> vil starte Kubernetes-klyngen lokalt.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-kubectl\">kubectl<\/a><\/noindex> \u2014 et kommandolinjeinterface til styring af klyngen.<\/li>\n<\/ol>\n<p><\/p>\n<p>Starter Kubernetes-klyngen 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\nBruger docker-driveren baseret p\u00e5 eksisterende profil.\nStarter kontrolplanet node minikube i klyngen minikube.<\/code><\/pre>\n<p><\/p>\n<p>Angiv <code>kubectl<\/code> for at bruge den lokale klynge som standard:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl config use-context minikube\nSwitched to context \"minikube\".<\/code><\/pre>\n<p><\/p>\n<p>Downloader konfigurationerne til produktionsmilj\u00f8et:<\/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>Da production-konfigurationerne er indstillet til at tjekke gamle namespaces, og der ikke er nogen i vores nyligt oprettede klynge, skal vi \u00e6ndre milj\u00f8variablen <code>IS_DEBUG<\/code> og f\u00e5 en fungerende kommando. <code>true<\/code>. Ved denne v\u00e6rdi vil parameteren <code>afterDaysWithoutDeploy<\/code> overvejes ikke, og namespaces tjekkes ikke for dage uden deployment, kun for tilstedev\u00e6relsen af en substring (<code>-pr-<\/code>).<\/p>\n<p><\/p>\n<p>Hvis du er p\u00e5 <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>Hvis du er p\u00e5 <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>Installerer projektet:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl apply -f stale-feature-branch-production-configs.yml<\/code><\/pre>\n<p><\/p>\n<p>Kontrollerer, at ressourcen er til stede i klyngen <code>StaleFeatureBranch<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl api-resources | grep stalefeaturebranches\nNAVN                 ... APIGROUP                             ... TYPE\nstalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch<\/code><\/pre>\n<p><\/p>\n<p>Kontrollerer, at operat\u00f8ren er til stede i klyngen:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get pods --namespace stale-feature-branch-operator\nNAVN                                           ... STATUS  ... AGE\nstale-feature-branch-operator-6bfbfd4df8-m7sch ... K\u00f8rende ... 38s<\/code><\/pre>\n<p><\/p>\n<p>Hvis du ser i dens logs, er den klar til at behandle ressourcer <code>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>Installerer de f\u00e6rdige <code>fixtures<\/code> (f\u00e6rdige konfigurationer til modellering af clusterressourcer) til ressourcen <code>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>Konfigurationerne angiver at s\u00f8ge efter namespaces med substring <code>-pr-<\/code> en gang hvert <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>Operatoren reagerede og er klar til at tjekke namespaces:<\/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 processing.\",\"namespaceSubstring\":\"-pr-\",\"afterDaysWithoutDeploy\":1,\"checkEveryMinutes\":1,\"isDebug\":\"true\"}<\/code><\/pre>\n<p><\/p>\n<p>Installerer <code>fixtures<\/code>, som indeholder to namespaces (<code>project-pr-1<\/code>, <code>project-pr-2<\/code>) og deres <code>deployments<\/code>, <code>services<\/code>, <code>ingress<\/code>, og s\u00e5 videre:<\/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\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>Vi tjekker, om alle ovenn\u00e6vnte ressourcer er blevet oprettet:<\/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>Da vi har aktiveret <code>debug<\/code>, namespaces <code>project-pr-1<\/code> og <code>project-pr-2<\/code>, vil alle andre ressourcer ogs\u00e5 straks blive fjernet uanset parameteren <code>afterDaysWithoutDeploy<\/code>. Dette ses i operat\u00f8rens logs:<\/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 processing.\",\"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 processing.\",\"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>Hvis du tjekker for ressourcer, vil de v\u00e6re i status <code>Terminating<\/code> (sletningsprocess) eller allerede slettet (kommandoens output er 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 gentage oprettelsesprocessen <code>fixtures<\/code> flere gange og sikre dig, at de vil blive slettet inden for et minut.<\/p>\n<p><\/p>\n<h2>Alternativer<\/h2>\n<p><\/p>\n<p>Hvad kan man g\u00f8re i stedet for en operator, der arbejder i et cluster? Der er flere tilgange, alle har deres mangler (og disse mangler er subjektive), og hver person m\u00e5 selv vurdere, hvad der passer bedst til det specifikke projekt:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>Fjerne feature branch under byggeriet af master-branchens kontinuerlige integration.<\/p>\n<p><\/p>\n<ul>\n<li>For dette skal man vide, hvilken pull request der h\u00f8rer til den commit, der bygges. Da feature branch namespaces indeholder identificatoren for pull requesten \u2014 enten nummeret eller navnet p\u00e5 branchen, skal identificatoren altid angives i commit'en.<\/li>\n<li>Builds af master branches fejler. For eksempel har du de f\u00f8lgende trin: hente projektet, k\u00f8re tests, bygge projektet, lave en release, sende notifikationer, rense feature branch fra den seneste pull request. Hvis buildet fejler ved afsendelse af notifikationen, skal du manuelt slette alle ressourcer i klyngen.<\/li>\n<li>Uden den rette kontekst er sletning af feature branch i master buildet ikke indlysende.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Brug af webhooks (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.community\/t\/trigger-jenkins-job-when-a-pull-request-is-merged-to-a-branch\/1169\">eksempel<\/a><\/noindex>).<\/p>\n<p><\/p>\n<ul>\n<li>M\u00e5ske er dette ikke din tilgang. For eksempel, i <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jenkins.io\">Jenkins<\/a><\/noindex>, kun \u00e9n type pipeline underst\u00f8tter muligheden for at gemme sine konfigurationer i kildekoden. Ved brug af webhooks skal du skrive dit eget script til at behandle dem. Dette script skal placeres i Jenkins' gr\u00e6nseflade, hvilket er sv\u00e6rt at vedligeholde.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Skrive <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/cron-jobs\/\">Cronjob<\/a><\/noindex> og tilf\u00f8je Kubernetes-clusteret.<\/p>\n<p><\/p>\n<ul>\n<li>Tidsforbrug p\u00e5 udvikling og vedligeholdelse.<\/li>\n<li>Operatoren arbejder allerede i en lignende stil, er dokumenteret og vedligeholdt.<\/li>\n<\/ul>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Tak for din opm\u00e6rksomhed p\u00e5 artiklen. <strong><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">Link til projektet p\u00e5 Github<\/a><\/noindex><\/strong>.<\/p>\n<p>Kilde: <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.3 - 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\/da\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\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\/da\/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\udd47Fjerner for\u00e6ldet feature branch i Kubernetes-cluster | ProHoster","description":"Hej!","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/86902","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=86902"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/86902\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/86903"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=86902"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=86902"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=86902"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}