{"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\/de\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","title":{"rendered":"Entfernen des veralteten Feature-Branches im Kubernetes-Cluster.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Entfernen des veralteten Feature-Branches im Kubernetes-Cluster.\" src=\"\/wp-content\/uploads\/2020\/07\/d97c0cce385c587e16f26f6d19b9d108.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Hallo! <b>Feature-Branch<\/b> (auch bekannt als Deploy-Vorschau, Review-App) \u2014 das ist, wenn nicht nur der Master-Zweig, sondern auch jeder Pull Request auf eine einzigartige URL bereitgestellt wird. So kann gepr\u00fcft werden, ob der Code in der Produktionsumgebung funktioniert, und eine Funktion kann anderen Entwicklern oder Produktmanagern pr\u00e4sentiert werden. Solange Sie im Pull Request arbeiten, wird jedes neue Commit das aktuelle Deployment f\u00fcr den alten Code entfernt, und ein neues Deployment f\u00fcr den neuen Code wird bereitgestellt. Fragen k\u00f6nnen auftreten, wenn Sie den Pull Request in den Master-Zweig gemergt haben. Der Feature-Zweig wird nicht mehr ben\u00f6tigt, aber die Ressourcen von Kubernetes befinden sich weiterhin im Cluster.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Noch zu Feature-Zweigen<\/h2>\n<p><\/p>\n<p>Eine M\u00f6glichkeit, wie man Feature-Zweige in Kubernetes erstellen kann, ist die Verwendung von Namespaces. Kurz gesagt, die Produktionskonfiguration sieht so aus:<\/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\u00fcr den Feature-Zweig wird ein Namespace mit seiner Identifikation (zum Beispiel die Nummer des Pull Requests) und einem bestimmten Pr\u00e4fix\/Nachsatz (zum Beispiel <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>Im Allgemeinen habe ich geschrieben <b>Kubernetes Operator<\/b> (eine Anwendung, die Zugriff auf Cluster-Ressourcen hat), <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">Link zum Projekt auf GitHub<\/a><\/noindex>. Es entfernt Namespaces, die zu alten Feature-Zweigen geh\u00f6ren. In Kubernetes werden bei der L\u00f6schung eines Namespaces auch die anderen Ressourcen in diesem Namespace automatisch gel\u00f6scht.<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get pods --all-namespaces | grep -e \"-pr-\"\nNAMESPACE            ... ALTER\nhabr-back-end-pr-264 ... 4d8h\nhabr-back-end-pr-265 ... 5d7h<\/code><\/pre>\n<p><\/p>\n<p>Wie man Feature-Zweige in den Cluster integriert, kann hier nachgelesen werden. <noindex><a rel=\"nofollow\" href=\"https:\/\/itnext.io\/feature-deployments-in-kubernetes-c74bdcff0d8e\">hier<\/a><\/noindex> und <noindex><a rel=\"nofollow\" href=\"https:\/\/codefresh.io\/kubernetes-tutorial\/dynamically-creating-k8s-namespaces-every-branch-pull-request-2\">hier<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2>Motivation<\/h2>\n<p><\/p>\n<p>Lassen Sie uns den typischen Lebenszyklus eines Pull Requests mit kontinuierlicher Integration betrachten (<code>continuous integration<\/code>):<\/p>\n<p><\/p>\n<ol>\n<li>Wir pushen einen neuen Commit in den Branch.<\/li>\n<li>Bei der Erstellung werden Linter und\/oder Tests ausgef\u00fchrt.<\/li>\n<li>Die Kubernetes-Konfigurationen des Pull Requests werden dynamisch generiert (zum Beispiel wird die Nummer in die entsprechende Vorlage eingef\u00fcgt).<\/li>\n<li>Mit kubectl apply gelangen die Konfigurationen in den Cluster (Deployment).<\/li>\n<li>Der Pull Request wird in den Master-Branch gemergt.<\/li>\n<\/ol>\n<p><\/p>\n<p>W\u00e4hrend Sie im Pull Request arbeiten, wird jedes neue Commit die aktuelle Bereitstellung des alten Codes zur\u00fccksetzen und eine neue Bereitstellung des neuen Codes durchf\u00fchren. Wenn der Pull Request jedoch in den Master-Zweig zusammengef\u00fchrt wird, wird nur der Master-Zweig gebaut. Dadurch kann es geschehen, dass wir den Pull Request bereits vergessen haben, w\u00e4hrend seine Kubernetes-Ressourcen weiterhin im Cluster vorhanden sind.<\/p>\n<p><\/p>\n<h2>Wie verwenden<\/h2>\n<p><\/p>\n<p>Installieren Sie das Projekt mit dem folgenden Befehl:<\/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>Erstellen Sie eine Datei mit folgendem Inhalt und wenden Sie sie mit <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> ben\u00f6tigt, um Namespaces f\u00fcr Pull Requests von anderen Namespaces zu filtern. Zum Beispiel, wenn im Cluster folgende Namespaces vorhanden sind: <code>habr-back-end<\/code>, <code>habr-front-end<\/code>, <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>, dann sind die Kandidaten zur L\u00f6schung <code>habr-back-end-pr-17<\/code>, <code>habr-back-end-pr-33<\/code>.<\/p>\n<p><\/p>\n<p>Parameter <b>afterDaysWithoutDeploy<\/b> ben\u00f6tigt, um alte Namespaces zu l\u00f6schen. Zum Beispiel, wenn ein Namespace erstellt wurde <code>3 Tagen 1 Stunde<\/code> erstellt wurde und im Parameter angegeben ist <code>3 Tage<\/code>, wird dieserNamespace gel\u00f6scht. Es funktioniert auch umgekehrt, wenn einNamespace vor <code>2 Tagen 23 Stunden<\/code> erstellt wurde und im Parameter angegeben ist <code>3 Tage<\/code>erstellt wurde, wird dieserNamespace nicht gel\u00f6scht.<\/p>\n<p><\/p>\n<p>Es gibt noch einen weiteren Parameter, der daf\u00fcr verantwortlich ist, wie oft alle Namespaces gescannt werden und auf Tage ohne Bereitstellung \u00fcberpr\u00fcft werden \u2014 <b>checkEveryMinutes<\/b>. Standardm\u00e4\u00dfig betr\u00e4gt er <code>30 Minuten<\/code>.<\/p>\n<p><\/p>\n<h2>Wie es funktioniert<\/h2>\n<p><\/p>\n<p>In der Praxis wird ben\u00f6tigt:<\/p>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/get-docker\">Docker<\/a><\/noindex> um in einer isolierten Umgebung zu arbeiten.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-minikube\">Minikube<\/a><\/noindex> wird einen Kubernetes-Cluster lokal starten.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-kubectl\">kubectl<\/a><\/noindex> \u2014 ein Befehlszeilen-Interface zur Verwaltung des Clusters.<\/li>\n<\/ol>\n<p><\/p>\n<p>Starten wir den Kubernetes-Cluster lokal:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ minikube start --vm-driver=docker\nminikube v1.11.0 on Darwin 10.15.5\nVerwenden des Docker-Treibers basierend auf dem vorhandenen Profil.\nStarte die Steuerungsebene minikube im Cluster minikube.<\/code><\/pre>\n<p><\/p>\n<p>Angeben <code>kubectl<\/code> verwenden Sie den lokalen Standard-Cluster:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl config use-context minikube\nWechsel zu Kontext \"minikube\".<\/code><\/pre>\n<p><\/p>\n<p>Laden der Konfigurationen f\u00fcr die Produktionsumgebung herunter:<\/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 die Produktionskonfigurationen so eingerichtet sind, dass sie alte Namespaces \u00fcberpr\u00fcfen, und in unserem neu gestarteten Cluster keine vorhanden sind, werden wir die Umgebungsvariable ersetzen <code>IS_DEBUG<\/code> findet man <code>true<\/code>. Mit diesem Wert wird der Parameter <code>afterDaysWithoutDeploy<\/code> wird nicht ber\u00fccksichtigt und die Namespaces werden nicht auf Tage ohne Bereitstellung \u00fcberpr\u00fcft, sondern nur auf das Vorhandensein von Unterzeichenfolgen (<code>-pr-<\/code>).<\/p>\n<p><\/p>\n<p>Wenn Sie <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>Wenn Sie <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>Projekt installieren:<\/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>\u00dcberpr\u00fcfung, dass die Ressource im Cluster erschienen ist <code>StaleFeatureBranch<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl api-resources | grep stalefeaturebranches\nNAME                 ... APIGROUP                             ... KIND\nstalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch<\/code><\/pre>\n<p><\/p>\n<p>\u00dcberpr\u00fcfung, dass der Operator im Cluster erschienen ist:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get pods --namespace stale-feature-branch-operator\nNAME                                           ... STATUS  ... AGE\nstale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s<\/code><\/pre>\n<p><\/p>\n<p>Wenn Sie sich seine Protokolle ansehen, ist er bereit, Ressourcen zu verarbeiten. <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>Bereitgestellte <code>Fixtures<\/code> (vordefinierte Konfigurationen zur Modellierung von Clusterressourcen) f\u00fcr die Ressource <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>In den Konfigurationen ist angegeben, dass nach Namespaces mit dem Unterstring gesucht werden soll <code>-pr-<\/code> alle <code>1 Minute<\/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>Der Operator hat reagiert und ist bereit, nach Namespaces zu suchen:<\/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 wird bearbeitet.\",\"namespaceSubstring\":\"-pr-\",\"afterDaysWithoutDeploy\":1,\"checkEveryMinutes\":1,\"isDebug\":\"true\"}<\/code><\/pre>\n<p><\/p>\n<p>Installieren Sie <code>Fixtures<\/code>, die zwei Namespaces enthalten (<code>project-pr-1<\/code>, <code>project-pr-2<\/code>) und deren <code>deployments<\/code>, <code>Services<\/code>, <code>ingress<\/code>, und so weiter:<\/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\/projekt-pr-1 erstellt\ndeployment.apps\/projekt-pr-1 erstellt\nservice\/projekt-pr-1 erstellt\nhorizontalpodautoscaler.autoscaling\/projekt-pr-1 erstellt\nsecret\/projekt-pr-1 erstellt\nconfigmap\/projekt-pr-1 erstellt\ningress.extensions\/projekt-pr-1 erstellt\nnamespace\/projekt-pr-2 erstellt\ndeployment.apps\/projekt-pr-2 erstellt\nservice\/projekt-pr-2 erstellt\nhorizontalpodautoscaler.autoscaling\/projekt-pr-2 erstellt\nsecret\/projekt-pr-2 erstellt\nconfigmap\/projekt-pr-2 erstellt\ningress.extensions\/projekt-pr-2 erstellt<\/code><\/pre>\n<p><\/p>\n<p>\u00dcberpr\u00fcfen Sie, ob alle oben genannten Ressourcen erfolgreich erstellt wurden:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n projekt-pr-1 &amp;&amp; kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n projekt-pr-2\n...\nNAME                              ... READY ... STATUS  ... AGE\npod\/projekt-pr-1-848d5fdff6-rpmzw ... 1\/1   ... Running ... 67s\n\nNAME                         ... READY ... AVAILABLE ... AGE\ndeployment.apps\/projekt-pr-1 ... 1\/1   ... 1         ... 67s\n...<\/code><\/pre>\n<p><\/p>\n<p>Da wir aktiviert haben <code>debug<\/code>, Namespaces <code>project-pr-1<\/code> und <code>project-pr-2<\/code>, sollten auch alle anderen Ressourcen sofort gel\u00f6scht werden, ohne den Parameter <code>afterDaysWithoutDeploy<\/code>. In den Operator-Logs ist das zu sehen:<\/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 sollte gel\u00f6scht werden, da der Debug-Modus aktiviert ist.\",\"namespaceName\":\"project-pr-1\"}\n... \"msg\":\"Namespace wird verarbeitet.\",\"namespaceName\":\"project-pr-1\",\"namespaceCreationTimestamp\":\"2020-06-16 18:43:58 +0300 EEST\"}\n... \"msg\":\"Namespace wurde gel\u00f6scht.\",\"namespaceName\":\"project-pr-1\"}\n... \"msg\":\"Namespace sollte gel\u00f6scht werden, da der Debug-Modus aktiviert ist.\",\"namespaceName\":\"project-pr-2\"}\n... \"msg\":\"Namespace wird verarbeitet.\",\"namespaceName\":\"project-pr-2\",\"namespaceCreationTimestamp\":\"2020-06-16 18:43:58 +0300 EEST\"}\n... \"msg\":\"Namespace wurde gel\u00f6scht.\",\"namespaceName\":\"project-pr-2\"}<\/code><\/pre>\n<p><\/p>\n<p>Wenn Sie die Verf\u00fcgbarkeit von Ressourcen \u00fcberpr\u00fcfen, befinden sie sich im Status <code>Wird beendet<\/code> (L\u00f6schvorgang) oder wurden bereits gel\u00f6scht (Ausgabe des Befehls ist leer).<\/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>Sie k\u00f6nnen den Erstellungsprozess <code>Fixtures<\/code> mehrmals wiederholen und sicherstellen, dass sie innerhalb einer Minute gel\u00f6scht werden.<\/p>\n<p><\/p>\n<h2>Alternativen<\/h2>\n<p><\/p>\n<p>Was kann anstelle des Operators gemacht werden, der im Cluster arbeitet? Es gibt mehrere Ans\u00e4tze, die alle nicht ideal sind (und deren Nachteile subjektiv sind), und jeder entscheidet selbst, was am besten f\u00fcr das jeweilige Projekt geeignet ist:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>Feature-Branch w\u00e4hrend des Builds des Continuous Integration Master-Branches zu l\u00f6schen.<\/p>\n<p><\/p>\n<ul>\n<li>Daf\u00fcr m\u00fcssen Sie wissen, welcher Pull-Request zu dem Commit geh\u00f6rt, der gebaut wird. Da der Feature-Branch-Namespace die Identifikation des Pull-Requests enth\u00e4lt \u2013 seine Nummer oder den Namen des Branches \u2013 m\u00fcssen Sie die Identifikation immer im Commit angeben.<\/li>\n<li>Die Builds der Master-Branches schlagen fehl. Zum Beispiel haben Sie folgende Schritte: Projekt herunterladen, Tests ausf\u00fchren, Projekt erstellen, Release durchf\u00fchren, Benachrichtigungen senden, das Feature-Branch des letzten Pull-Requests bereinigen. Wenn der Build beim Senden der Benachrichtigung fehlschl\u00e4gt, m\u00fcssen Sie alle Ressourcen im Cluster manuell l\u00f6schen.<\/li>\n<li>Ohne den entsprechenden Kontext ist es nicht offensichtlich, warum das L\u00f6schen einer Feature-Branch im Master-Build notwendig ist.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Die Verwendung von Webhooks (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.community\/t\/trigger-jenkins-job-when-a-pull-request-is-merged-to-a-branch\/1169\">Nummer 00 oder<\/a><\/noindex>).<\/p>\n<p><\/p>\n<ul>\n<li>M\u00f6glicherweise ist dies nicht Ihr Ansatz. Zum Beispiel in <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jenkins.io\">Jenkins<\/a><\/noindex>, nur ein Pipelinetyp erm\u00f6glicht es, seine Konfigurationen im Quellcode zu speichern. Bei der Verwendung von Webhooks m\u00fcssen Sie ein eigenes Skript zur Verarbeitung schreiben. Dieses Skript muss im Jenkins-Interface platziert werden, was schwer zu warten ist.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>\n<p>Schreiben Sie <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/cron-jobs\/\">Cronjob<\/a><\/noindex> und f\u00fcgen Sie einen Kubernetes-Cluster hinzu.<\/p>\n<p><\/p>\n<ul>\n<li>Zeitaufwand f\u00fcr das Schreiben und die Wartung.<\/li>\n<li>Der Operator arbeitet bereits in einem \u00e4hnlichen Stil, ist dokumentiert und wird unterst\u00fctzt.<\/li>\n<\/ul>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Vielen Dank f\u00fcr Ihr Interesse an dem Artikel. <strong><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dmytrostriletskyi\/stale-feature-branch-operator\">Link zum Projekt auf Github<\/a><\/noindex><\/strong>.<\/p>\n<p>Quelle: <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 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"\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&#039;\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\" \/>\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\/de\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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! 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&#039;\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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/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\udd47Veralteten Feature Branch im Kubernetes-Cluster l\u00f6schen | ProHoster","description":"Hallo! Der Feature Branch (auch bekannt als Deployment-Vorschau, Review-App) ist eine Funktion, bei der nicht nur der Master-Branch, sondern auch jeder Pull-Request auf eine einzigartige URL bereitgestellt wird. So k\u00f6nnen Sie pr\u00fcfen, ob der Code in der Produktionsumgebung funktioniert, und das Feature anderen Programmierern oder Produktmanagern zeigen. Solange Sie an einem Pull-Request arbeiten, wird jeder neue Commit die aktuelle Bereitstellung f\u00fcr den alten Code entfernen und eine neue erstellen.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/udalyaem-ustarevshuyu-feature-branch-v-kubernetes-klastere","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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! 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'\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","og:url":"https:\/\/prohoster.info\/de\/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"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/86902","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=86902"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/86902\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/86903"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=86902"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=86902"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=86902"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}