{"id":35955,"date":"2019-10-31T22:08:26","date_gmt":"2019-10-31T19:08:26","guid":{"rendered":"https:\/\/prohoster.info\/blog\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm\/"},"modified":"2019-10-31T22:08:26","modified_gmt":"2019-10-31T19:08:26","slug":"razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm","title":{"rendered":"Bereitstellung von Anwendungen auf mehreren Kubernetes-Clustern mit Helm","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<\/p>\n<p><\/p>\n<h2 id=\"kak-dailymotion-ispolzuet-kubernetes-razvertyvanie-prilozheniy\">Wie Dailymotion Kubernetes nutzt: Anwendungen bereitstellen<\/h2>\n<p><\/p>\n<p>Wir bei Dailymotion haben vor 3 Jahren begonnen, Kubernetes in der Produktion zu verwenden. Das Bereitstellen von Anwendungen auf mehreren Clustern war jedoch eine Herausforderung, weshalb wir in den letzten Jahren daran gearbeitet haben, unsere Tools und Arbeitsabl\u00e4ufe zu verbessern.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"s-chego-nachalos\">Wie alles begann<\/h3>\n<p><\/p>\n<p>Hier erkl\u00e4ren wir, wie wir unsere Anwendungen auf mehreren Kubernetes-Clustern weltweit bereitstellen.<\/p>\n<p><\/p>\n<p>Um mehrere Kubernetes-Objekte gleichzeitig bereitzustellen, verwenden wir <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/\">Helm<\/a><\/noindex>, und alle unsere Charts werden in einem Git-Repository gespeichert. Um einen vollst\u00e4ndigen Anwendungs-Stack aus mehreren Diensten bereitzustellen, nutzen wir ein sogenanntes Oberchart. Im Grunde ist dies ein Chart, das Abh\u00e4ngigkeiten deklariert und es erm\u00f6glicht, API und ihre Dienste mit einem einzigen Befehl zu initialisieren.<\/p>\n<p><\/p>\n<p>Zus\u00e4tzlich haben wir ein kleines Python-Skript \u00fcber Helm geschrieben, um Pr\u00fcfungen durchzuf\u00fchren, Charts zu erstellen, Geheimnisse hinzuzuf\u00fcgen und Anwendungen bereitzustellen. All diese Aufgaben werden auf einer zentralen CI-Plattform mithilfe eines Docker-Images erledigt.<\/p>\n<p><\/p>\n<p>Lassen Sie uns zur Sache kommen.<\/p>\n<p><\/p>\n<blockquote><p>Hinweis: W\u00e4hrend Sie dies lesen, wurde bereits der erste Release-Kandidat von Helm 3 angek\u00fcndigt. Die Hauptversion enth\u00e4lt eine Reihe von Verbesserungen, die darauf abzielen, einige der Probleme zu l\u00f6sen, mit denen wir zuvor konfrontiert waren.<\/p><\/blockquote>\n<p><\/p>\n<h3 id=\"rabochiy-process-razrabotki-chartov\">Entwicklungsworkflow f\u00fcr Charts<\/h3>\n<p><\/p>\n<p>F\u00fcr Anwendungen verwenden wir Branching und haben beschlossen, denselben Ansatz f\u00fcr Charts anzuwenden.<\/p>\n<p><\/p>\n<ul>\n<li>Branch <strong>dev<\/strong> wird verwendet, um Charts zu erstellen, die in Entwicklungsclustern getestet werden.<\/li>\n<li>Wenn ein Pull-Request an <strong>master<\/strong>\u00fcbergeben wird, erfolgt die \u00dcberpr\u00fcfung in der Staging-Umgebung.<\/li>\n<li>Schlie\u00dflich erstellen wir einen Pull-Request, um die \u00c4nderungen in den Branch <strong>prod<\/strong> zu \u00fcbertragen und sie in der Produktion anzuwenden.<\/li>\n<\/ul>\n<p><\/p>\n<p>Jede Umgebung hat ihr eigenes privates Repository, das unsere Charts speichert, und wir verwenden <noindex><a rel=\"nofollow\" href=\"https:\/\/chartmuseum.com\/\">Chartmuseum<\/a><\/noindex> mit \u00e4u\u00dferst n\u00fctzlichen APIs. So gew\u00e4hrleisten wir eine strikte Isolation zwischen den Umgebungen und testen die Charts unter realen Bedingungen, bevor wir sie in der Produktion verwenden.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/rz\/vt\/uk\/rzvtuk6q7b_rkeaxnyujzhmfjog.png\"><\/a><\/noindex><\/p>\n<p><\/p>\n<p><em>Chart-Repositories in verschiedenen Umgebungen<\/em><\/p>\n<p><\/p>\n<p>Es ist wichtig zu erw\u00e4hnen, dass, wenn Entwickler einen dev-Branch einreichen, die Version ihres Charts automatisch in das dev Chartmuseum hochgeladen wird. So benutzen alle Entwickler ein gemeinsames dev-Repository und m\u00fcssen ihre Chart-Version genau angeben, um versehentlich nicht die \u00c4nderungen anderer zu verwenden.<\/p>\n<p><\/p>\n<p>Dar\u00fcber hinaus \u00fcberpr\u00fcft unser kleines Python-Skript Kubernetes-Objekte anhand der Kubernetes OpenAPI-Spezifikationen mit <noindex><a rel=\"nofollow\" href=\"https:\/\/kubeval.instrumenta.dev\/\">Kubeval<\/a><\/noindex>, bevor sie im Chartmuseum ver\u00f6ffentlicht werden.<\/p>\n<p><\/p>\n<h3 id=\"obschee-opisanie-rabochego-processa-razrabotki-charta\">Allgemeine Beschreibung des Chart-Entwicklungsworkflows<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/yd\/cw\/qw\/ydcwqw-vqfitu5bj8ky4nh7xxea.png\"><\/a><\/noindex><\/p>\n<p><\/p>\n<ol>\n<li>Konfiguration der Pipeline-Aufgaben gem\u00e4\u00df den Spezifikationen <noindex><a rel=\"nofollow\" href=\"https:\/\/gazr.io\/\">gazr.io<\/a><\/noindex> zur Qualit\u00e4tssicherung (Linting, Unit-Test).<\/li>\n<li>Hochladen des Docker-Images mit den Python-Tools, die unsere Anwendungen bereitstellen.<\/li>\n<li>Einrichten der Umgebung basierend auf dem Branch-Namen.<\/li>\n<li>\u00dcberpr\u00fcfung der Kubernetes-YAML-Dateien mit Kubeval.<\/li>\n<li>Automatische Erh\u00f6hung der Chart-Version und der seiner \u00fcbergeordneten Charts (Charts, die von dem ver\u00e4nderbaren Chart abh\u00e4ngen).<\/li>\n<li>Hochladen des Charts ins Chartmuseum, das mit seiner Umgebung \u00fcbereinstimmt.<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"upravlenie-razlichiyami-v-klasterah\">Verwaltung der Unterschiede in Clustern<\/h2>\n<p><\/p>\n<h3 id=\"federaciya-klasterov\">Cluster-F\u00f6deration<\/h3>\n<p><\/p>\n<p>Es gab eine Zeit, als wir die <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/cluster-administration\/federation\/\">F\u00f6deration von Kubernetes-Clustern verwendet haben.<\/a><\/noindex>, wo man Kubernetes-Objekte von einem einzigen API-Endpunkt aus deklarieren konnte. Doch es gab Probleme. Einige Kubernetes-Objekte konnten beispielsweise nicht am F\u00f6derationsendpunkt erstellt werden, was die Verwaltung von kombinierten Objekten und anderen f\u00fcr einzelne Cluster erschwerte.<\/p>\n<p><\/p>\n<p>Um das Problem zu l\u00f6sen, begannen wir, die Cluster unabh\u00e4ngig zu verwalten, was den Prozess erheblich vereinfachte (wir nutzten die erste Version der F\u00f6deration; in der zweiten Version k\u00f6nnten \u00c4nderungen vorgenommen worden sein).<\/p>\n<p><\/p>\n<h3 id=\"georaspredelennaya-platforma\">Geodistribuierte Plattform<\/h3>\n<p><\/p>\n<p>Unsere Plattform ist derzeit \u00fcber 6 Regionen verteilt \u2013 3 lokal und 3 in der Cloud.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/jq\/c1\/mr\/jqc1mru36g5byams4wddzducauw.png\"><\/a><\/noindex><br \/>\n<em>Verteilte Bereitstellung<\/em><\/p>\n<p><\/p>\n<h3 id=\"globalnye-znacheniya-helm\">Globale Helm-Werte<\/h3>\n<p><\/p>\n<p>4 globale Helm-Werte erm\u00f6glichen es, Unterschiede zwischen Clustern zu definieren. F\u00fcr alle unsere Charts gibt es minimale Standardwerte.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">global:\n  cloud: True\n  env: staging\n  region: us-central1\n  clusterName: staging-us-central1<\/code><\/pre>\n<p><\/p>\n<p><em>Globale Werte<\/em><\/p>\n<p><\/p>\n<p>Diese Werte helfen, den Kontext f\u00fcr unsere Anwendungen zu definieren und werden f\u00fcr verschiedene Aufgaben verwendet: \u00dcberwachung, Verfolgung, Protokollierung, externe Aufrufe, Skalierung usw.<\/p>\n<p><\/p>\n<ul>\n<li>\u00abcloud\u00bb: Wir bieten eine hybride Kubernetes-Plattform an. Unser API wird beispielsweise in GCP-Zonen sowie in unseren Rechenzentren bereitgestellt.<\/li>\n<li>\u00abenv\u00bb: Einige Werte k\u00f6nnen f\u00fcr nicht-funktionierende Umgebungen variieren. Zum Beispiel die Definitionen von Ressourcen und die Konfiguration der automatischen Skalierung.<\/li>\n<li>\u00abregion\u00bb: Diese Information hilft, den Standort des Clusters zu bestimmen und kann verwendet werden, um die n\u00e4chstgelegenen Endpunkte f\u00fcr externe Dienste zu ermitteln.<\/li>\n<li>\u00abclusterName\u00bb: wenn und wann wir einen Wert f\u00fcr ein einzelnes Cluster festlegen m\u00f6chten.<\/li>\n<\/ul>\n<p><\/p>\n<p>Hier ist ein konkretes Beispiel:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">{{\/* Gibt die Horizontal Pod Autoscaler-Replikate f\u00fcr GraphQL zur\u00fcck *\/}}\n{{- define \"graphql.hpaReplicas\" -}}\n{{- if eq .Values.global.env \"prod\" }}\n{{- if eq .Values.global.region \"europe-west1\" }}\nminReplicas: 40\n{{- else }}\nminReplicas: 150\n{{- end }}\nmaxReplicas: 1400\n{{- else }}\nminReplicas: 4\nmaxReplicas: 20\n{{- end }}\n{{- end -}}<\/code><\/pre>\n<p><\/p>\n<p><em>Beispiel f\u00fcr eine Helm-Vorlage<\/em><\/p>\n<p><\/p>\n<p>Diese Logik ist in einer Hilfs-Vorlage definiert, um das Kubernetes YAML nicht zu \u00fcberf\u00fcllen.<\/p>\n<p><\/p>\n<h3 id=\"obyavlenie-prilozheniya\">Anwendungserkl\u00e4rung<\/h3>\n<p><\/p>\n<p>Unsere Bereitstellungstools basieren auf mehreren YAML-Dateien. Unten sehen Sie ein Beispiel daf\u00fcr, wie wir einen Dienst und dessen Skalierungstopologie (Anzahl der Replikate) im Cluster deklarieren.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Releases:\n  - foo.world\n\nfoo.world:                # Ver\u00f6ffentlichungsname\n  services:               # Liste der Dailymotion Apps\/Projekte\n    foobar:\n      chart_name: foo-foobar\n      repo: git@github.com:dailymotion\/foobar\n      contexts:\n        prod-europe-west1:\n          deployments:\n            - name: foo-bar-baz\n              replicas: 18\n            - name: another-deployment\n              replicas: 3<\/code><\/pre>\n<p><\/p>\n<p><em>Definition des Dienstes<\/em><\/p>\n<p><\/p>\n<p>Dies ist das Schema aller Schritte, die unseren Bereitstellungsprozess definieren. Der letzte Schritt stellt die Anwendung gleichzeitig auf mehreren Arbeitsclustern bereit.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/iu\/qh\/xk\/iuqhxki4nfqoi0mus258j0feylu.png\"><\/a><\/noindex><br \/>\n<em>Bereitstellungsschritte in Jenkins<\/em><\/p>\n<p><\/p>\n<h3 id=\"a-sekrety\">Und die Geheimnisse?<\/h3>\n<p><\/p>\n<p>Was die Sicherheit angeht, verfolgen wir alle Geheimnisse aus verschiedenen Quellen und speichern sie in einem einzigartigen Speicher. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.vaultproject.io\/\">Vault<\/a><\/noindex> in Paris.<\/p>\n<p><\/p>\n<p>Unsere Bereitstellungstools extrahieren die Werte der Geheimnisse aus dem Vault und f\u00fcgen sie, wenn es Zeit f\u00fcr die Bereitstellung ist, in Helm ein.<\/p>\n<p><\/p>\n<p>Zu diesem Zweck haben wir eine Zuordnung zwischen den Geheimnissen im Vault und den geheimen Informationen definiert, die unsere Anwendungen ben\u00f6tigen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">geheimnisse:                                                                                                                                                                                                        \n     - geheimnis_id: \"stack1-app1-passwort\"                                                                                                                                                                                  \n       kontexte:                                                                                                                                                                                                   \n         - name: \"standard\"                                                                                                                                                                                         \n           vaultPfad: \"\/kv\/dev\/stack1\/app1\/test\"                                                                                                                                                               \n           vaultSchl\u00fcssel: \"passwort\"                                                                                                                                                                                    \n         - name: \"cluster1\"                                                                                                                                                                           \n           vaultPfad: \"\/kv\/dev\/stack1\/app1\/test\"                                                                                                                                                               \n           vaultSchl\u00fcssel: \"passwort\"<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>Wir haben allgemeine Richtlinien festgelegt, die beim Speichern von Geheimnissen im Vault beachtet werden m\u00fcssen.<\/li>\n<li>Wenn das Geheimnis sich auf <strong>einen bestimmten Kontext oder Cluster bezieht<\/strong>, Sie m\u00fcssen einen spezifischen Eintrag hinzuf\u00fcgen. (Hier hat der Kontext cluster1 einen eigenen Wert f\u00fcr das Geheimnis stack-app1-password).<\/li>\n<li>Andernfalls wird der Wert <strong>standardm\u00e4\u00dfig verwendet<\/strong>.<\/li>\n<li>F\u00fcr jeden Punkt in dieser Liste wird <strong>das Kubernetes-Geheimnis<\/strong> als Schl\u00fcssel-Wert-Paar eingef\u00fcgt. Daher ist die Vorlage f\u00fcr das Geheimnis in unseren Charts sehr einfach.<\/li>\n<\/ul>\n<p><\/p>\n<pre><code class=\"plaintext\">apiVersion: v1\ndata:\n{{- range $key,$value := .Values.secrets }}\n  {{ $key }}: {{ $value | b64enc | quote }}\n{{ end }}\nkind: Secret\nmetadata:\n  name: \"{{ .Chart.Name }}\"\n  labels:\n    chartVersion: \"{{ .Chart.Version }}\"\n    tillerVersion: \"{{ .Capabilities.TillerVersion.SemVer }}\"\ntype: Opaque<\/code><\/pre>\n<p><\/p>\n<h2 id=\"problemy-i-ogranicheniya\">Probleme und Einschr\u00e4nkungen<\/h2>\n<p><\/p>\n<h3 id=\"rabota-s-neskolkimi-repozitoriyami\">Arbeiten mit mehreren Repositories<\/h3>\n<p><\/p>\n<p>Derzeit trennen wir die Entwicklung von Charts und Anwendungen. Das bedeutet, dass Entwickler in zwei Git-Repositories arbeiten m\u00fcssen: eines f\u00fcr die Anwendung und das andere f\u00fcr die Definition ihrer Bereitstellung in Kubernetes. Zwei Git-Repositories bedeuten zwei Arbeitsabl\u00e4ufe, und es ist f\u00fcr einen Neuling leicht, sich darin zu verwirren.<\/p>\n<p><\/p>\n<h3 id=\"upravlyat-obobschennymi-chartami-hlopotno\">Allgemeine Charts zu verwalten ist m\u00fchsam<\/h3>\n<p><\/p>\n<p>Wie bereits erw\u00e4hnt, sind allgemeine Charts sehr praktisch zur Definition von Abh\u00e4ngigkeiten und zur schnellen Bereitstellung mehrerer Anwendungen. Aber wir verwenden <code>--reuse-values<\/code>, um zu vermeiden, dass alle Werte bei jeder Bereitstellung der in diesem generischen Chart enthaltenen Anwendung \u00fcbertragen werden.<\/p>\n<p><\/p>\n<p>Im kontinuierlichen Lieferprozess haben wir insgesamt nur zwei Werte, die sich regelm\u00e4\u00dfig \u00e4ndern: die Anzahl der Replikate und das Image-Tag (Version). Andere, stabilere Werte werden manuell ge\u00e4ndert, was ziemlich kompliziert ist. Dar\u00fcber hinaus kann ein Fehler bei der Bereitstellung des generischen Charts zu schwerwiegenden Ausf\u00e4llen f\u00fchren, wie wir aus eigener Erfahrung lernen mussten.<\/p>\n<p><\/p>\n<h3 id=\"obnovlenie-neskolkih-faylov-konfiguracii\">Aktualisierung mehrerer Konfigurationsdateien<\/h3>\n<p><\/p>\n<p>Wenn ein Entwickler eine neue Anwendung hinzuf\u00fcgt, muss er mehrere Dateien \u00e4ndern: die Anwendungsdeklaration, die Liste der Geheimnisse, die Hinzuf\u00fcgung der Anwendung zu den Abh\u00e4ngigkeiten, wenn sie im generischen Chart enthalten ist.<\/p>\n<p><\/p>\n<h3 id=\"razresheniya-jenkins-slishkom-rasshireny-v-vault\">Die Berechtigungen von Jenkins sind im Vault zu weitreichend<\/h3>\n<p><\/p>\n<p>Jetzt haben wir einen <noindex><a rel=\"nofollow\" href=\"https:\/\/www.vaultproject.io\/docs\/auth\/approle.html\">AppRole<\/a><\/noindex>, der alle Geheimnisse aus dem Vault liest.<\/p>\n<p><\/p>\n<h3 id=\"process-otkata-ne-avtomatizirovan\">Der Rollback-Prozess ist nicht automatisiert<\/h3>\n<p><\/p>\n<p>F\u00fcr einen Rollback muss ein Befehl auf mehreren Clustern ausgef\u00fchrt werden, was Fehler mit sich bringen kann. Wir f\u00fchren diesen Schritt manuell durch, um sicherzustellen, dass die richtige Versionskennung angegeben wird.<\/p>\n<p><\/p>\n<h2 id=\"my-dvizhemsya-v-storonu-gitops\">Wir bewegen uns in Richtung GitOps<\/h2>\n<p><\/p>\n<h3 id=\"nasha-cel\">Unser Ziel<\/h3>\n<p><\/p>\n<p>Wir m\u00f6chten das Chart im Repository der Anwendung, die es bereitstellt, zur\u00fcckgeben.<\/p>\n<p><\/p>\n<p>Der Arbeitsablauf wird derselbe sein wie bei der Entwicklung. Beispielsweise wird die Bereitstellung automatisch gestartet, wenn ein Branch in den Master-Branch \u00fcbertragen wird. Der Hauptunterschied zwischen diesem Ansatz und dem aktuellen Arbeitsablauf besteht darin, dass <strong>alles in Git verwaltet wird<\/strong> (sowohl die Anwendung als auch die Art und Weise ihrer Bereitstellung in Kubernetes).<\/p>\n<p><\/p>\n<p>Es gibt mehrere Vorteile:<\/p>\n<p><\/p>\n<ul>\n<li>Viel <strong>verst\u00e4ndlicher<\/strong> f\u00fcr den Entwickler. Es ist einfacher, \u00c4nderungen im lokalen Chart anzuwenden.<\/li>\n<li>Die Definition der Bereitstellung eines Services kann <strong>an derselben Stelle wie der Code<\/strong> des Services angegeben werden.<\/li>\n<li><strong>Verwaltung der L\u00f6schung allgemeiner Charts<\/strong>. Der Service wird seine eigene Helm-Version haben. Dies erm\u00f6glicht die Verwaltung des Lebenszyklus der Anwendung (Rollback, Upgrade) auf einem sehr granularen Niveau, um andere Services nicht zu beeintr\u00e4chtigen.<\/li>\n<li><strong>Vorteile von Git<\/strong> zur Verwaltung von Charts: R\u00fcckg\u00e4ngig machen von \u00c4nderungen, Auditprotokoll usw. Wenn eine \u00c4nderung des Charts zur\u00fcckgesetzt werden muss, kann dies mit Git erfolgen. Die Bereitstellung wird automatisch gestartet.<\/li>\n<li>Man kann \u00fcber die Verbesserung des Entwicklungsprozesses mit Tools wie <strong>Skaffold nachdenken.<\/strong>, mit dem Entwickler \u00c4nderungen in einer produktions\u00e4hnlichen Umgebung testen k\u00f6nnen.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"dvuhetapnaya-migraciya\">Zwei-stufige Migration<\/h3>\n<p><\/p>\n<p>Unsere Entwickler verwenden diesen Arbeitsablauf seit 2 Jahren, daher ben\u00f6tigen wir eine m\u00f6glichst reibungslose Migration. Aus diesem Grund haben wir einen Zwischenschritt auf dem Weg zum Ziel hinzugef\u00fcgt.<br \/>\nDer erste Schritt ist einfach:<\/p>\n<p><\/p>\n<ul>\n<li>Wir behalten eine \u00e4hnliche Struktur f\u00fcr die Konfiguration des Anwendungsdeployments bei, jedoch in einem Objekt namens DailymotionRelease.<\/li>\n<\/ul>\n<p><\/p>\n<pre><code class=\"plaintext\">apiVersion: \"v1\"\nkind: \"DailymotionRelease\"\nmetadata:\n  name: \"app1.ns1\"\n  environment: \"dev\"\n  branch: \"mybranch\"\nspec:\n  slack_channel: \"#admin\"\n  chart_name: \"app1\"\n  scaling:\n    - context: \"dev-us-central1-0\"\n      replicas:\n        - name: \"hermes\"\n          count: 2\n    - context: \"dev-europe-west1-0\"\n      replicas:\n        - name: \"app1-deploy\"\n          count: 2\n  secrets:\n    - secret_id: \"app1\"\n      contexts:\n        - name: \"default\"\n          vaultPath: \"\/kv\/dev\/ns1\/app1\/test\"\n          vaultKey: \"password\"\n        - name: \"dev-europe-west1-0\"\n          vaultPath: \"\/kv\/dev\/ns1\/app1\/test\"\n          vaultKey: \"password\"<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>1 Release pro Anwendung (ohne aggregierte Charts).<\/li>\n<li>Charts im Git-Repository der Anwendung.<\/li>\n<\/ul>\n<p><\/p>\n<p>Wir haben mit allen Entwicklern gesprochen, sodass der Migrationsprozess bereits begonnen hat. Der erste Schritt wird weiterhin \u00fcber die CI-Plattform \u00fcberwacht. Bald werde ich einen weiteren Beitrag \u00fcber den zweiten Schritt schreiben: wie wir auf den GitOps-Arbeitsablauf umgestiegen sind mit <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/weaveworks\/flux\">Flux<\/a><\/noindex>Ich werde erz\u00e4hlen, wie wir alles eingerichtet haben und mit welchen Schwierigkeiten wir konfrontiert waren (mehrere Repositories, Geheimnisse usw.). Bleiben Sie dran f\u00fcr Neuigkeiten.<\/p>\n<p><\/p>\n<p>Hier haben wir versucht, unseren Fortschritt im Arbeitsprozess der Anwendungsbereitstellung in den letzten Jahren zu beschreiben, der zu \u00dcberlegungen zum GitOps-Ansatz gef\u00fchrt hat. Wir haben unser Ziel noch nicht erreicht und werden \u00fcber die Ergebnisse berichten, sind aber jetzt \u00fcberzeugt, dass es richtig war, alles zu vereinfachen und an die Gewohnheiten der Entwickler anzun\u00e4hern.<\/p>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/southbridge\/blog\/458934\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041a\u0430\u043a Dailymotion \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Kubernetes: \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u041c\u044b \u0432 Dailymotion \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 3 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434. \u041d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 \u0442\u043e \u0435\u0449\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0435\u0442 \u043c\u044b \u0441\u0442\u0430\u0440\u0430\u043b\u0438\u0441\u044c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 Kubernetes \u043f\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35955","post","type-post","status-publish","format-standard","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=\"\u041a\u0430\u043a Dailymotion \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Kubernetes: \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u041c\u044b \u0432 Dailymotion \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 3 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434. \u041d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 \u0442\u043e \u0435\u0449\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0435\u0442 \u043c\u044b \u0441\u0442\u0430\u0440\u0430\u043b\u0438\u0441\u044c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 Kubernetes \u043f\u043e\" \/>\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\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm\" \/>\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\u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 Kubernetes \u0441 Helm | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041a\u0430\u043a Dailymotion \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Kubernetes: \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u041c\u044b \u0432 Dailymotion \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 3 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434. \u041d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 \u0442\u043e \u0435\u0449\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0435\u0442 \u043c\u044b \u0441\u0442\u0430\u0440\u0430\u043b\u0438\u0441\u044c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 Kubernetes \u043f\u043e\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm\" \/>\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=\"2019-10-31T19:08:26+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:08:26+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\udd47Bereitstellung von Anwendungen auf mehreren Kubernetes-Clustern mit Helm | ProHoster","description":"Wie Dailymotion Kubernetes nutzt: Bereitstellung von Anwendungen. Wir bei Dailymotion haben vor 3 Jahren begonnen, Kubernetes in der Produktion zu verwenden. Aber Anwendungen auf mehreren Clustern bereitzustellen, ist eine echte Herausforderung, weshalb wir in den letzten Jahren versucht haben, unsere Tools und Arbeitsabl\u00e4ufe zu verbessern. So begann es. Hier erkl\u00e4ren wir, wie wir unsere Anwendungen auf mehreren Kubernetes-Clustern bereitstellen.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm","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\u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 Kubernetes \u0441 Helm | ProHoster","og:description":"\u041a\u0430\u043a Dailymotion \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Kubernetes: \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u041c\u044b \u0432 Dailymotion \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 3 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434. \u041d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 \u0442\u043e \u0435\u0449\u0435 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0435\u0442 \u043c\u044b \u0441\u0442\u0430\u0440\u0430\u043b\u0438\u0441\u044c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 Kubernetes \u043f\u043e","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm","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":"2019-10-31T19:08:26+00:00","article:modified_time":"2019-10-31T19:08:26+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35955","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":"2026-01-22 01:25:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:53:31","updated":"2026-01-22 01:25:19"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/35955","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=35955"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/35955\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=35955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=35955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=35955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}