Nasadzujte aplikácie vo viacerých klastroch Kubernetes pomocou Helm

Ako Dailymotion používa Kubernetes: Application Deployment

My v Dailymotion sme začali používať Kubernetes vo výrobe pred 3 rokmi. Nasadzovanie aplikácií do viacerých klastrov je však zábavné, preto sa v posledných rokoch snažíme zlepšovať naše nástroje a pracovné postupy.

Kde to začalo

Tu sa budeme zaoberať tým, ako nasadzujeme naše aplikácie vo viacerých klastroch Kubernetes po celom svete.

Na nasadenie viacerých objektov Kubernetes naraz používame kormidloa všetky naše grafy sú uložené v jednom úložisku git. Na nasadenie plného zásobníka aplikácií z viacerých služieb používame takzvaný sumárny graf. V podstate ide o graf, ktorý deklaruje závislosti a umožňuje inicializovať API a jeho služby jedným príkazom.

Napísali sme tiež malý skript v jazyku Python nad Helm, aby sme mohli vykonávať kontroly, vytvárať grafy, pridávať tajomstvá a nasadzovať aplikácie. Všetky tieto úlohy sa vykonávajú na centrálnej platforme CI pomocou obrazu dockera.

Poďme k veci.

Poznámka. Keď toto čítate, prvý kandidát na vydanie Helm 3 už bol oznámený. Hlavná verzia obsahuje celý rad vylepšení na riešenie niektorých problémov, s ktorými sme sa stretli v minulosti.

Pracovný postup vývoja grafu

Pre aplikácie používame vetvenie a rovnaký prístup sme sa rozhodli aplikovať aj na grafy.

  • Pobočka dev slúži na vytváranie grafov, ktoré budú testované na vývojových klastroch.
  • Keď sa odošle požiadavka na stiahnutie majster, sú kontrolované v stagingu.
  • Nakoniec vytvoríme požiadavku na stiahnutie na odovzdanie zmien do vetvy prod a aplikovať ich vo výrobe.

Každé prostredie má svoje vlastné súkromné ​​úložisko, v ktorom sú uložené naše grafy a ktoré používame Chartmuseum s veľmi užitočnými API. Týmto spôsobom zabezpečujeme prísnu izoláciu medzi prostrediami a testovanie grafov v reálnom svete pred ich použitím vo výrobe.

Repozitáre grafov v rôznych prostrediach

Stojí za zmienku, že keď vývojári vložia vývojovú vetvu, verzia ich grafu sa automaticky presunie do dev Chartmuseum. Všetci vývojári teda používajú rovnaké úložisko pre vývojárov a musíte starostlivo špecifikovať svoju verziu grafu, aby ste náhodou nepoužili zmeny niekoho iného.

Náš malý skript Python navyše overuje objekty Kubernetes podľa špecifikácií Kubernetes OpenAPI pomocou Kubeval, pred ich zverejnením na Chartmusem.

Všeobecný popis pracovného postupu vývoja grafu

  1. Nastavenie potrubných úloh podľa špecifikácie gazr.io na kontrolu kvality (vláknenie, test jednotky).
  2. Vloženie obrazu dockeru pomocou nástrojov Pythonu, ktoré nasadzujú naše aplikácie.
  3. Nastavenie prostredia podľa názvu pobočky.
  4. Overenie súborov yaml Kubernetes pomocou Kubeval.
  5. Automaticky zväčšiť verziu grafu a jeho nadradených grafov (grafy, ktoré závisia od grafu, ktorý sa mení).
  6. Odoslanie grafu do Chartmuseum, ktoré zodpovedá jeho prostrediu

Riadenie rozdielov medzi klastrami

federácie klastrov

Boli časy, keď sme používali federácia klastrov Kubernetes, kde je možné objekty Kubernetes deklarovať z jedného koncového bodu API. Ale nastali problémy. Napríklad niektoré objekty Kubernetes nebolo možné vytvoriť v koncovom bode federácie, čo sťažuje udržiavanie združených objektov a iných objektov pre jednotlivé klastre.

Aby sme problém vyriešili, začali sme klastre spravovať samostatne, čo značne zjednodušilo proces (používali sme prvú verziu federácie, v druhej sa mohlo niečo zmeniť).

Geo-distribuovaná platforma

Naša platforma je v súčasnosti distribuovaná v 6 regiónoch – 3 lokálne a 3 v cloude.


Distribuované nasadenie

Globálne hodnoty kormidla

4 globálne hodnoty Helm ​​umožňujú identifikovať rozdiely medzi klastrami. Všetky naše grafy majú predvolené minimálne hodnoty.

global:
  cloud: True
  env: staging
  region: us-central1
  clusterName: staging-us-central1

Globálne hodnoty

Tieto hodnoty pomáhajú definovať kontext pre naše aplikácie a používajú sa na rôzne účely: monitorovanie, sledovanie, protokolovanie, uskutočňovanie externých hovorov, škálovanie atď.

  • "cloud": Máme hybridnú platformu Kubernetes. Napríklad naše API je nasadené v zónach GCP a v našich dátových centrách.
  • "env": Niektoré hodnoty sa môžu zmeniť pre neprodukčné prostredia. Napríklad definície prostriedkov a konfigurácie automatického škálovania.
  • "región": Tieto informácie pomáhajú určiť umiestnenie klastra a možno ich použiť na určenie blízkych koncových bodov pre externé služby.
  • "clusterName": ak a kedy chceme definovať hodnotu pre individuálny klaster.

Tu je konkrétny príklad:

{{/* Returns Horizontal Pod Autoscaler replicas for GraphQL*/}}
{{- define "graphql.hpaReplicas" -}}
{{- if eq .Values.global.env "prod" }}
{{- if eq .Values.global.region "europe-west1" }}
minReplicas: 40
{{- else }}
minReplicas: 150
{{- end }}
maxReplicas: 1400
{{- else }}
minReplicas: 4
maxReplicas: 20
{{- end }}
{{- end -}}

Príklad šablóny prilby

Táto logika je definovaná v šablóne pomocníka, aby sa predišlo preplneniu Kubernetes YAML.

Oznámenie aplikácie

Naše nástroje na nasadenie sú založené na viacerých súboroch YAML. Nižšie je uvedený príklad, ako deklarujeme službu a jej škálovaciu topológiu (počet replík) v klastri.

releases:
  - foo.world

foo.world:                # Release name
  services:               # List of dailymotion's apps/projects
    foobar:
      chart_name: foo-foobar
      repo: [email protected]:dailymotion/foobar
      contexts:
        prod-europe-west1:
          deployments:
            - name: foo-bar-baz
              replicas: 18
            - name: another-deployment
              replicas: 3

Definícia služby

Toto je prehľad všetkých krokov, ktoré definujú náš pracovný postup nasadenia. Posledný krok nasadí aplikáciu do viacerých pracovných klastrov súčasne.


Kroky nasadenia Jenkinsa

A čo tajomstvá?

Čo sa týka bezpečnosti, sledujeme všetky tajomstvá z rôznych miest a ukladáme ich do unikátneho trezoru Klenba v Paríži.

Naše nástroje na nasadenie extrahujú tajné hodnoty z Vaultu a keď príde čas nasadenia, vložia ich do Helm.

Aby sme to dosiahli, definovali sme mapovanie medzi tajomstvami vo Vaulte a tajomstvami, ktoré naše aplikácie potrebujú:

secrets:                                                                                                                                                                                                        
     - secret_id: "stack1-app1-password"                                                                                                                                                                                  
       contexts:                                                                                                                                                                                                   
         - name: "default"                                                                                                                                                                                         
           vaultPath: "/kv/dev/stack1/app1/test"                                                                                                                                                               
           vaultKey: "password"                                                                                                                                                                                    
         - name: "cluster1"                                                                                                                                                                           
           vaultPath: "/kv/dev/stack1/app1/test"                                                                                                                                                               
           vaultKey: "password"

  • Definovali sme všeobecné pravidlá, ktoré treba dodržiavať pri zaznamenávaní tajomstiev do Vaultu.
  • Ak platí tajomstvo do konkrétneho kontextu alebo klastra, musíte pridať konkrétny záznam. (Tu má kontextový klaster1 svoju vlastnú hodnotu pre tajný zásobník-aplikácia1-heslo).
  • V opačnom prípade sa použije hodnota v predvolenom nastavení.
  • Pre každú položku v tomto zozname v Kubernetes tajomstvo vloží sa pár kľúč – hodnota. Preto je tajná šablóna v našich grafoch veľmi jednoduchá.

apiVersion: v1
data:
{{- range $key,$value := .Values.secrets }}
  {{ $key }}: {{ $value | b64enc | quote }}
{{ end }}
kind: Secret
metadata:
  name: "{{ .Chart.Name }}"
  labels:
    chartVersion: "{{ .Chart.Version }}"
    tillerVersion: "{{ .Capabilities.TillerVersion.SemVer }}"
type: Opaque

Problémy a obmedzenia

Práca s viacerými úložiskami

Teraz oddelíme vývoj grafov a aplikácií. To znamená, že vývojári musia pracovať v dvoch úložiskách git: jedno pre aplikáciu a druhé pre definovanie jej nasadenia do Kubernetes. 2 git repozitáre znamenajú 2 pracovné postupy a nováčik sa môže ľahko zmiasť.

Správa zovšeobecnených grafov je problém

Ako sme už povedali, všeobecné grafy sú veľmi užitočné na identifikáciu závislostí a rýchle nasadenie viacerých aplikácií. Ale používame --reuse-valuesaby sme sa vyhli odovzdávaniu všetkých hodnôt pri každom nasadení aplikácie, ktorá je súčasťou tohto zovšeobecneného grafu.

V nepretržitom pracovnom postupe doručovania máme iba dve hodnoty, ktoré sa pravidelne menia: počet replík a značku obrázka (verziu). Ostatné, stabilnejšie hodnoty sa menia ručne, čo je dosť ťažké. Navyše jedna chyba pri nasadení zovšeobecneného grafu môže viesť k vážnym zlyhaniam, ako sme videli z vlastnej skúsenosti.

Aktualizácia viacerých konfiguračných súborov

Keď vývojár pridá novú aplikáciu, musí zmeniť niekoľko súborov: vyhlásenie aplikácie, zoznam tajomstiev, pridanie aplikácie ako závislosti, ak je zahrnutá do zovšeobecneného grafu.

Povolenia Jenkins sú vo Vaulte príliš rozšírené

Teraz máme jeden AppRole, ktorá číta všetky tajomstvá z Vaultu.

Proces vrátenia nie je automatizovaný

Ak chcete vrátiť späť, musíte príkaz spustiť na niekoľkých klastroch, čo je plné chýb. Túto operáciu vykonávame manuálne, aby sme sa uistili, že je zadané správne ID verzie.

Smerujeme k GitOps

Náš cieľ

Chceme vrátiť graf do úložiska aplikácie, ktorú nasadzuje.

Pracovný postup bude rovnaký ako pri vývoji. Napríklad, keď je vetva posunutá na master, nasadenie sa spustí automaticky. Hlavným rozdielom medzi týmto prístupom a súčasným pracovným postupom by bolo to všetko bude spravované v git (samotná aplikácia a spôsob jej nasadenia v Kubernetes).

Existuje niekoľko výhod:

  • Veľa jasnejšie pre vývojára. Je jednoduchšie naučiť sa, ako aplikovať zmeny v lokálnom grafe.
  • Je možné zadať definíciu nasadenia služby rovnaké miesto ako kód služba.
  • Správa odstraňovania zovšeobecnených grafov. Služba bude mať svoje vlastné vydanie Helm. To vám umožní riadiť životný cyklus aplikácie (rollback, upgrade) na najmenšej úrovni, aby ste neovplyvnili ostatné služby.
  • Výhody git pre správu grafov: vrátiť zmeny, denník auditu atď. Ak potrebujete vrátiť späť zmenu v grafe, môžete to urobiť pomocou git. Nasadenie sa spustí automaticky.
  • Môžete zvážiť zlepšenie pracovného postupu vývoja pomocou nástrojov, ako je napr Skaffold, pomocou ktorého môžu vývojári testovať zmeny v kontexte blízkom produkcii.

Dvojstupňová migrácia

Naši vývojári používajú tento pracovný postup už 2 roky, takže chceme, aby migrácia bola čo najbezbolestnejšia. Preto sme sa rozhodli pridať medzikrok na ceste k cieľu.
Prvá fáza je jednoduchá:

  • Ponechávame podobnú štruktúru pre nastavenie nasadenia aplikácií, ale v jedinom objekte s názvom DailymotionRelease.

apiVersion: "v1"
kind: "DailymotionRelease"
metadata:
  name: "app1.ns1"
  environment: "dev"
  branch: "mybranch"
spec:
  slack_channel: "#admin"
  chart_name: "app1"
  scaling:
    - context: "dev-us-central1-0"
      replicas:
        - name: "hermes"
          count: 2
    - context: "dev-europe-west1-0"
      replicas:
        - name: "app1-deploy"
          count: 2
  secrets:
    - secret_id: "app1"
      contexts:
        - name: "default"
          vaultPath: "/kv/dev/ns1/app1/test"
          vaultKey: "password"
        - name: "dev-europe-west1-0"
          vaultPath: "/kv/dev/ns1/app1/test"
          vaultKey: "password"

  • 1 vydanie na aplikáciu (bez zovšeobecnených grafov).
  • Grafy v úložisku git aplikácie.

Hovorili sme so všetkými vývojármi, takže proces migrácie sa už začal. Prvý stupeň je stále ovládaný pomocou platformy CI. Čoskoro napíšem ďalší príspevok o druhej fáze: ako sme prešli na pracovný postup GitOps Prúdenie. Poviem vám, ako sme všetko nastavili a s akými ťažkosťami sme sa stretli (viacnásobné úložiská, tajomstvá atď.). Sledujte novinky.

Tu sme sa pokúsili opísať náš pokrok v pracovnom postupe nasadzovania aplikácií za posledné roky, čo viedlo k úvahám o prístupe GitOps. Cieľ sme ešte nedosiahli a o výsledkoch budeme referovať, no už teraz sme presvedčení, že sme urobili správne, keď sme sa rozhodli všetko zjednodušiť a priblížiť zvykom vývojárov.

Zdroj: hab.com

Pridať komentár