{"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\/ro\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm","title":{"rendered":"Implementarea aplica\u021biilor pe mai multe clustere Kubernetes cu Helm","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<\/p>\n<p><\/p>\n<h2 id=\"kak-dailymotion-ispolzuet-kubernetes-razvertyvanie-prilozheniy\">Cum folose\u0219te Dailymotion Kubernetes: implementarea aplica\u021biilor<\/h2>\n<p><\/p>\n<p>Noi, la Dailymotion, am \u00eenceput s\u0103 folosim Kubernetes \u00een produc\u021bie acum 3 ani. \u00cens\u0103 implementarea aplica\u021biilor pe mai multe clustere nu este tocmai pl\u0103cut\u0103, a\u0219a c\u0103 \u00een ultimii c\u00e2\u021biva ani am \u00eencercat s\u0103 ne \u00eembun\u0103t\u0103\u021bim instrumentele \u0219i fluxurile de lucru.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"s-chego-nachalos\">Cum a \u00eenceput totul<\/h3>\n<p><\/p>\n<p>Aici vom explica cum implement\u0103m aplica\u021biile noastre pe mai multe clustere Kubernetes din \u00eentreaga lume.<\/p>\n<p><\/p>\n<p>Pentru a implementa mai multe obiecte Kubernetes deodat\u0103, folosim <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/\">Helm<\/a><\/noindex>, iar toate diagramele noastre sunt stocate \u00eentr-un singur depozit git. Pentru a implementa un \u00eentreg stiv\u0103 de aplica\u021bie din mai multe servicii, utiliz\u0103m a\u0219a-numita diagram\u0103 de agregare. Practic, aceasta este o diagram\u0103 care declar\u0103 dependen\u021bele \u0219i permite ini\u021bializarea API-ului \u0219i a serviciilor sale dintr-o singur\u0103 comand\u0103.<\/p>\n<p><\/p>\n<p>De asemenea, am scris un mic script Python deasupra Helm pentru a efectua verific\u0103ri, a crea diagrame, a ad\u0103uga secrete \u0219i a implementa aplica\u021biile. Toate aceste sarcini sunt realizate pe o platform\u0103 CI centralizat\u0103 folosind o imagine docker.<\/p>\n<p><\/p>\n<p>S\u0103 trecem la subiect.<\/p>\n<p><\/p>\n<blockquote><p>Not\u0103. C\u00e2nd citi\u021bi asta, primul release candidate Helm 3 a fost deja anun\u021bat. Versiunea principal\u0103 con\u021bine un set \u00eentreg de \u00eembun\u0103t\u0103\u021biri menite s\u0103 rezolve unele probleme cu care ne-am confruntat \u00een trecut.<\/p><\/blockquote>\n<p><\/p>\n<h3 id=\"rabochiy-process-razrabotki-chartov\">Fluxul de lucru pentru dezvoltarea diagramelor<\/h3>\n<p><\/p>\n<p>Pentru aplica\u021bii, folosim ramificarea, iar aceea\u0219i abordare am decis s\u0103 o aplic\u0103m \u0219i diagramelor.<\/p>\n<p><\/p>\n<ul>\n<li>Ramura <strong>dev<\/strong> este utilizat\u0103 pentru a crea diagrame care vor fi testate pe clusterele de dezvoltare.<\/li>\n<li>C\u00e2nd un pull request este trimis \u00een <strong>master<\/strong>, acestea sunt verificate \u00een staging.<\/li>\n<li>\u00cen cele din urm\u0103, cre\u0103m un pull request pentru a trimite modific\u0103rile \u00een ramura <strong>prod<\/strong> \u0219i a le aplica \u00een produc\u021bie.<\/li>\n<\/ul>\n<p><\/p>\n<p>Fiecare mediu are un depozit privat care stocheaz\u0103 diagrama noastr\u0103, \u0219i utiliz\u0103m <noindex><a rel=\"nofollow\" href=\"https:\/\/chartmuseum.com\/\">Chartmuseum<\/a><\/noindex> cu API-uri foarte utile. Astfel, garant\u0103m o izolare strict\u0103 \u00eentre medii \u0219i verificarea diagramelor \u00een condi\u021bii reale \u00eenainte de a le utiliza \u00een produc\u021bie.<\/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>Depozitele diagramelor \u00een diferite medii<\/em><\/p>\n<p><\/p>\n<p>Trebuie men\u021bionat c\u0103 atunci c\u00e2nd dezvoltatorii trimit o ramur\u0103 dev, versiunea diagramei lor este trimis\u0103 automat \u00een dev Chartmuseum. Astfel, to\u021bi dezvoltatorii folosesc un singur depozit dev \u0219i trebuie s\u0103 \u00ee\u0219i specifice cu aten\u021bie versiunea diagramei pentru a nu folosi accidental modific\u0103rile altora.<\/p>\n<p><\/p>\n<p>\u00cen plus, scriptul nostru Python mic verific\u0103 obiectele Kubernetes conform specifica\u021biilor OpenAPI Kubernetes cu ajutorul <noindex><a rel=\"nofollow\" href=\"https:\/\/kubeval.instrumenta.dev\/\">Kubeval<\/a><\/noindex>, \u00eenainte de a le publica \u00een Chartmuseum.<\/p>\n<p><\/p>\n<h3 id=\"obschee-opisanie-rabochego-processa-razrabotki-charta\">Descriere general\u0103 a fluxului de lucru pentru dezvoltarea chartului<\/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>Configurarea sarcinilor pipeline-ului conform specifica\u021biei <noindex><a rel=\"nofollow\" href=\"https:\/\/gazr.io\/\">gazr.io<\/a><\/noindex> pentru controlul calit\u0103\u021bii (lint, unit-test).<\/li>\n<li>Trimiterea imaginilor Docker cu instrumentele Python care desf\u0103\u0219oar\u0103 aplica\u021biile noastre.<\/li>\n<li>Configurarea mediului \u00een func\u021bie de numele ramurii.<\/li>\n<li>Verificarea fi\u0219ierelor YAML Kubernetes cu ajutorul Kubeval.<\/li>\n<li>Cre\u0219terea automat\u0103 a versiunii chartului \u0219i a charturilor parent (charturi care depind de chartul modificat).<\/li>\n<li>Trimiterea chartului \u00een Chartmuseum, care corespunde mediului s\u0103u<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"upravlenie-razlichiyami-v-klasterah\">Gestionarea diferen\u021belor \u00eentre clustere<\/h2>\n<p><\/p>\n<h3 id=\"federaciya-klasterov\">Federa\u021bia clusterelor<\/h3>\n<p><\/p>\n<p>A fost un timp c\u00e2nd foloseam <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/cluster-administration\/federation\/\">federarea clusterelor Kubernetes<\/a><\/noindex>, unde puteam declara obiecte Kubernetes dintr-un singur punct final API. Dar au ap\u0103rut probleme. De exemplu, unele obiecte Kubernetes nu puteau fi create la punctul final al federa\u021biei, astfel c\u0103 era dificil s\u0103 \u00eentre\u021binem obiectele consolidate \u0219i alte obiecte pentru clustere individuale.<\/p>\n<p><\/p>\n<p>Pentru a rezolva problema, am \u00eenceput s\u0103 gestion\u0103m clusterele independent, ceea ce a simplificat semnificativ procesul (folosind prima versiune a federa\u021biei; \u00een a doua ceva ar fi putut s\u0103 se schimbe).<\/p>\n<p><\/p>\n<h3 id=\"georaspredelennaya-platforma\">Platform\u0103 geo-distribuit\u0103<\/h3>\n<p><\/p>\n<p>Acum platforma noastr\u0103 este distribuit\u0103 \u00een 6 regiuni \u2014 3 local \u0219i 3 \u00een 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>Desf\u0103\u0219urare distribuit\u0103<\/em><\/p>\n<p><\/p>\n<h3 id=\"globalnye-znacheniya-helm\">Valori globale Helm<\/h3>\n<p><\/p>\n<p>4 valori globale Helm permit definirea diferen\u021belor \u00eentre clustere. Pentru toate charturile noastre exist\u0103 valori minime implicite.<\/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>Valori globale<\/em><\/p>\n<p><\/p>\n<p>Aceste valori ajut\u0103 la definirea contextului pentru aplica\u021biile noastre \u0219i sunt utilizate pentru diferite sarcini: monitorizare, urm\u0103rire, registrare, apeluri externe, scalare etc.<\/p>\n<p><\/p>\n<ul>\n<li>\"cloud\": avem o platform\u0103 Kubernetes hibrid\u0103. De exemplu, API-ul nostru este desf\u0103\u0219urat \u00een zonele GCP \u0219i \u00een centrele noastre de date.<\/li>\n<li>\"env\": unele valori pot varia pentru medii non-production. De exemplu, defini\u021biile resurselor \u0219i configura\u021bia de auto-scaling.<\/li>\n<li>\"region\": aceste informa\u021bii ajut\u0103 la definirea loca\u021biei clusterei \u0219i pot fi folosite pentru a determina cele mai apropiate puncte finale pentru servicii externe.<\/li>\n<li>\"clusterName\": dac\u0103 \u0219i c\u00e2nd dorim s\u0103 definim o valoare pentru un cluster individual.<\/li>\n<\/ul>\n<p><\/p>\n<p>Iat\u0103 un exemplu concret:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">{{\n\/* Returneaz\u0103 replicile Horizontal Pod Autoscaler pentru GraphQL *\/}}\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>Exemplu de \u0219ablon Helm<\/em><\/p>\n<p><\/p>\n<p>Aceast\u0103 logic\u0103 este definit\u0103 \u00eentr-un \u0219ablon auxiliar, pentru a nu aglomera YAML-ul Kubernetes.<\/p>\n<p><\/p>\n<h3 id=\"obyavlenie-prilozheniya\">Declararea aplica\u021biei<\/h3>\n<p><\/p>\n<p>Instrumentele noastre de desf\u0103\u0219urare se bazeaz\u0103 pe mai multe fi\u0219iere YAML. Iat\u0103 un exemplu despre cum declar\u0103m serviciul \u0219i topologia sa de scalare (num\u0103rul de replici) \u00een cluster.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">releases:\n  - foo.world\n\nfoo.world:                # Numele release-ului\n  services:               # Lista aplica\u021biilor\/proiectelor dailymotion\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>Definirea serviciului<\/em><\/p>\n<p><\/p>\n<p>Aceasta este schema tuturor pa\u0219ilor care definesc fluxul nostru de desf\u0103\u0219urare. Ultimul pas desf\u0103\u0219oar\u0103 aplica\u021bia simultan pe mai multe clustere de lucru.<\/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>Pa\u0219ii desf\u0103\u0219ur\u0103rii \u00een Jenkins<\/em><\/p>\n<p><\/p>\n<h3 id=\"a-sekrety\">Dar secretele?<\/h3>\n<p><\/p>\n<p>\u00cen ceea ce prive\u0219te securitatea, urm\u0103ream toate secretele din diferite locuri \u0219i le stoc\u0103m \u00eentr-un depozit unic <noindex><a rel=\"nofollow\" href=\"https:\/\/www.vaultproject.io\/\">Vault<\/a><\/noindex> \u00een Paris.<\/p>\n<p><\/p>\n<p>Instrumentele noastre de desf\u0103\u0219urare extrag valorile secrets din Vault \u0219i, c\u00e2nd vine timpul desf\u0103\u0219ur\u0103rii, le introduc \u00een Helm.<\/p>\n<p><\/p>\n<p>Pentru aceasta, am definit o asociere \u00eentre secretele din Vault \u0219i secretele necesare aplica\u021biilor noastre:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">secrets:                                                                                                                                                                                                        \n     - secret_id: \"stack1-app1-password\"                                                                                                                                                                                  \n       contexts:                                                                                                                                                                                                   \n         - name: \"default\"                                                                                                                                                                                         \n           vaultPath: \"\\\/kv\\\/dev\\\/stack1\\\/app1\\\/test\"                                                                                                                                                               \n           vaultKey: \"password\"                                                                                                                                                                                    \n         - name: \"cluster1\"                                                                                                                                                                           \n           vaultPath: \"\\\/kv\\\/dev\\\/stack1\\\/app1\\\/test\"                                                                                                                                                               \n           vaultKey: \"password\"<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>Am stabilit reguli generale care trebuie respectate la \u00eenregistrarea secretelor \u00een Vault.<\/li>\n<li>Dac\u0103 secretul se refer\u0103 <strong>la un context sau cluster specific<\/strong>, trebuie ad\u0103ugat\u0103 o \u00eenregistrare specific\u0103. (Aici, contextul cluster1 are o valoare proprie pentru secretul stack-app1-password).<\/li>\n<li>\u00cen caz contrar, se folose\u0219te valoarea <strong>implicit<\/strong>.<\/li>\n<li>Pentru fiecare element din aceast\u0103 list\u0103 \u00een <strong>secretul Kubernetes<\/strong> se introduce o pereche cheie-valoare. Prin urmare, \u0219ablonul secretului \u00een graficele noastre este foarte simplu.<\/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 \u0219i limit\u0103ri<\/h2>\n<p><\/p>\n<h3 id=\"rabota-s-neskolkimi-repozitoriyami\">Lucrul cu mai multe repository-uri<\/h3>\n<p><\/p>\n<p>\u00cen prezent, separ\u0103m dezvoltarea graficelor \u0219i aplica\u021biilor. Asta \u00eenseamn\u0103 c\u0103 dezvoltatorii trebuie s\u0103 lucreze \u00een dou\u0103 repository-uri git: unul pentru aplica\u021bie \u0219i al doilea pentru definirea desf\u0103\u0219ur\u0103rii sale \u00een Kubernetes. 2 repository-uri git \u00eenseamn\u0103 2 fluxuri de lucru, iar unui \u00eencep\u0103tor \u00eei este u\u0219or s\u0103 se confunde.<\/p>\n<p><\/p>\n<h3 id=\"upravlyat-obobschennymi-chartami-hlopotno\">Gestionarea graficelor generice este o provocare<\/h3>\n<p><\/p>\n<p>A\u0219a cum am men\u021bionat anterior, graficele generice sunt foarte utile pentru definirea dependen\u021belor \u0219i desf\u0103\u0219urarea rapid\u0103 a mai multor aplica\u021bii. \u00cens\u0103 folosim <code>--reuse-values<\/code>, pentru a evita transmiterea tuturor valorilor de fiecare dat\u0103 c\u00e2nd desf\u0103\u0219ur\u0103m o aplica\u021bie care face parte din acest grafic generic.<\/p>\n<p><\/p>\n<p>\u00cen procesul de livrare continu\u0103 avem doar dou\u0103 valori care se schimb\u0103 \u00een mod regulat: num\u0103rul de replici \u0219i eticheta imaginii (versiunea). Alte valori, mai stabile, se modific\u0103 manual, ceea ce este destul de complicat. Mai mult, o eroare \u00een desf\u0103\u0219urarea unui chart generic poate conduce la defec\u021biuni grave, a\u0219a cum am constatat din propria experien\u021b\u0103.<\/p>\n<p><\/p>\n<h3 id=\"obnovlenie-neskolkih-faylov-konfiguracii\">Actualizarea mai multor fi\u0219iere de configurare<\/h3>\n<p><\/p>\n<p>C\u00e2nd un dezvoltator adaug\u0103 o nou\u0103 aplica\u021bie, trebuie s\u0103 modifice mai multe fi\u0219iere: declara\u021bia aplica\u021biei, lista secretelor, ad\u0103ugarea aplica\u021biei \u00een dependen\u021be, dac\u0103 face parte din chartul generic.<\/p>\n<p><\/p>\n<h3 id=\"razresheniya-jenkins-slishkom-rasshireny-v-vault\">Permisiunile Jenkins sunt prea extinse \u00een Vault<\/h3>\n<p><\/p>\n<p>Acum avem unul <noindex><a rel=\"nofollow\" href=\"https:\/\/www.vaultproject.io\/docs\/auth\/approle.html\">AppRole<\/a><\/noindex>, care cite\u0219te toate secretele din Vault.<\/p>\n<p><\/p>\n<h3 id=\"process-otkata-ne-avtomatizirovan\">Procesul de rollback nu este automatizat<\/h3>\n<p><\/p>\n<p>Pentru rollback, trebuie s\u0103 execut\u0103m comanda pe mai multe clustere, ceea ce este predispus la erori. Facem aceast\u0103 opera\u021biune manual pentru a ne asigura c\u0103 indic\u0103m corect identificatorul versiunii.<\/p>\n<p><\/p>\n<h2 id=\"my-dvizhemsya-v-storonu-gitops\">Ne \u00eendrept\u0103m spre GitOps<\/h2>\n<p><\/p>\n<h3 id=\"nasha-cel\">Scopul nostru<\/h3>\n<p><\/p>\n<p>Vrem s\u0103 aducem chartul \u00een repository-ul aplica\u021biei pe care o desf\u0103\u0219oar\u0103.<\/p>\n<p><\/p>\n<p>Fluxul de lucru va fi acela\u0219i ca pentru dezvoltare. De exemplu, c\u00e2nd o ramur\u0103 este trimis\u0103 \u00een master, desf\u0103\u0219urarea va fi ini\u021biat\u0103 automat. Principala diferen\u021b\u0103 \u00eentre aceast\u0103 abordare \u0219i fluxul de lucru actual va fi c\u0103 <strong>totul va fi gestionat \u00een git<\/strong> (aplica\u021bia \u00een sine \u0219i modul ei de desf\u0103\u0219urare \u00een Kubernetes).<\/p>\n<p><\/p>\n<p>Exist\u0103 mai multe avantaje:<\/p>\n<p><\/p>\n<ul>\n<li>Este mult <strong>mai clar<\/strong> pentru dezvoltator. Este mai simplu s\u0103 \u00eenve\u021bi cum s\u0103 aplici modific\u0103ri \u00een chartul local.<\/li>\n<li>Defini\u021bia desf\u0103\u0219ur\u0103rii serviciului poate fi specificat\u0103 <strong>acolo unde se afl\u0103 codul<\/strong> serviciului.<\/li>\n<li><strong>Gestionarea elimin\u0103rii charturilor generice<\/strong>. Serviciul va avea propria sa eliberare Helm. Aceasta va permite gestionarea ciclului de via\u021b\u0103 al aplica\u021biei (rollback, upgrade) la cel mai mic nivel, f\u0103r\u0103 a afecta alte servicii.<\/li>\n<li><strong>Avantajele git<\/strong> pentru gestionarea charturilor: anularea modific\u0103rilor, jurnalul de audit etc. Dac\u0103 este nevoie s\u0103 anulezi o modificare a chartului, aceasta poate fi realizat\u0103 prin git. Desf\u0103\u0219urarea este ini\u021biat\u0103 automat.<\/li>\n<li>Se poate g\u00e2ndi la \u00eembun\u0103t\u0103\u021birea fluxului de lucru de dezvoltare cu ajutorul unor instrumente precum <strong>Skaffold<\/strong>, cu care dezvoltatorii pot testa modific\u0103rile \u00een context apropiat de produc\u021bie.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"dvuhetapnaya-migraciya\">Migrarea \u00een dou\u0103 etape<\/h3>\n<p><\/p>\n<p>De doi ani, dezvoltatorii no\u0219tri folose\u0219te acest flux de lucru, a\u0219a c\u0103 avem nevoie de o migrare c\u00e2t mai u\u0219oar\u0103. Prin urmare, am decis s\u0103 ad\u0103ug\u0103m o etap\u0103 intermediar\u0103 pe drumul c\u0103tre obiectiv.<br \/>\nPrima etap\u0103 este simpl\u0103:<\/p>\n<p><\/p>\n<ul>\n<li>Men\u021binem o structur\u0103 similar\u0103 pentru configurarea desf\u0103\u0219ur\u0103rii aplica\u021biilor, dar \u00eentr-un singur obiect numit 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 pe aplica\u021bie (f\u0103r\u0103 grafice generalizate).<\/li>\n<li>Grafice \u00een depozitul git al aplica\u021biei.<\/li>\n<\/ul>\n<p><\/p>\n<p>Am discutat cu to\u021bi dezvoltatorii, a\u0219a c\u0103 procesul de migrare a \u00eenceput deja. Prima etap\u0103 este \u00een continuare controlat\u0103 utiliz\u00e2nd platforma CI. \u00cen cur\u00e2nd voi scrie un alt articol despre a doua etap\u0103: cum am trecut la fluxul de lucru GitOps cu <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/weaveworks\/flux\">Flux<\/a><\/noindex>. Voi explica cum am configurat totul \u0219i cu ce dificult\u0103\u021bi ne-am confruntat (c\u00e2teva depozite, secrete etc.). R\u0103m\u00e2ne\u021bi la curent.<\/p>\n<p><\/p>\n<p>Aici am \u00eencercat s\u0103 descriem progresul nostru \u00een fluxul de desf\u0103\u0219urare a aplica\u021biilor din ultimii ani, care ne-a dus la g\u00e2nduri despre abordarea GitOps. \u00cenc\u0103 nu am atins obiectivul \u0219i v\u0103 vom informa despre rezultate, dar acum suntem convin\u0219i c\u0103 am f\u0103cut bine c\u00e2nd am decis s\u0103 simplific\u0103m totul \u0219i s\u0103 ne apropiem de obiceiurile dezvoltatorilor.<\/p>\n<p>Sursa: <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 5.0.3 - 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.\" \/>\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\/ro\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/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\udd47Desf\u0103\u0219urarea aplica\u021biilor pe clustere Kubernetes multiple cu Helm | ProHoster","description":"Cum folose\u0219te Dailymotion Kubernetes: desf\u0103\u0219urarea aplica\u021biilor. La Dailymotion, am \u00eenceput s\u0103 folosim Kubernetes \u00een.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/razvertyvanie-prilozhenij-na-neskolkih-klasterah-kubernetes-s-helm","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","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.","og:url":"https:\/\/prohoster.info\/ro\/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","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/35955","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=35955"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/35955\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=35955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=35955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=35955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}