Implementearje applikaasjes oer meardere Kubernetes-klusters mei Helm

Hoe Dailymotion Kubernetes brûkt: Application Deployment

Wy by Dailymotion begon Kubernetes te brûken yn produksje 3 jier lyn. Mar it ynsetten fan applikaasjes oer meardere klusters is leuk, dus de lêste jierren hawwe wy besocht ús ark en workflows te ferbetterjen.

Wêr begûn it

Hjir sille wy dekke hoe't wy ús applikaasjes ynsette oer meardere Kubernetes-klusters oer de hiele wrâld.

Om meardere Kubernetes-objekten tagelyk yn te setten, brûke wy Roer, en al ús charts wurde opslein yn ien git repository. Foar in ynsette in folsleine applikaasje stack út ferskate tsjinsten, wy brûke de saneamde gearfetting chart. Yn essinsje is dit in diagram dat ôfhinklikens ferklearret en jo de API en har tsjinsten mei ien kommando kinne inisjalisearje.

Wy hawwe ek in lyts Python-skript boppe-op Helm skreaun om kontrôles te dwaan, diagrammen te meitsjen, geheimen ta te foegjen en applikaasjes yn te setten. Al dizze taken wurde útfierd op in sintraal CI-platfoarm mei in dockerôfbylding.

Litte wy nei it punt komme.

Noat. Wylst jo dit lêze, is de earste frijlittingskandidaat foar Helm 3 al oankundige. De haadferzje befettet in hiele protte ferbetterings om guon fan 'e problemen oan te pakken dy't wy yn it ferline tsjinkamen.

Chart ûntwikkeling workflow

Wy brûke branching foar applikaasjes, en wy besletten deselde oanpak oan te passen foar diagrammen.

  • Tûke dev brûkt om diagrammen te meitsjen dy't sille wurde hifke op ûntwikkelingsklusters.
  • Wannear't in pull fersyk wurdt yntsjinne oan master, se wurde kontrolearre yn staging.
  • Uteinlik meitsje wy in pull-fersyk om de wizigingen yn 'e branch te begean produksje en tapasse se yn produksje.

Elke omjouwing hat in eigen privee repository dat ús charts opslacht, en wy brûke Chartmuseum mei heul nuttige API's. Op dizze manier soargje wy foar strikte isolaasje tusken omjouwings en testen yn 'e echte wrâld fan kaarten foardat se se brûke yn produksje.

Chart repositories yn ferskate omjouwings

It is de muoite wurdich op te merken dat as ûntwikkelders in dev-tûke triuwe, wurdt in ferzje fan har diagram automatysk nei it dev Chartmuseum stjoerd. Sa brûke alle ûntwikkelders itselde dev-repository, en jo moatte jo ferzje fan 'e kaart foarsichtich spesifisearje om net per ongeluk de wizigingen fan in oar te brûken.

Boppedat validearret ús lytse Python-skript Kubernetes-objekten tsjin de Kubernetes OpenAPI-spesifikaasjes mei Kubeval, foardat se publisearje op Chartmusem.

Algemiene beskriuwing fan 'e workflow foar diagramûntwikkeling

  1. It opsetten fan pipelinetaken neffens spesifikaasje gazr.io foar kwaliteitskontrôle (lint, unit-test).
  2. In docker-ôfbylding drukke mei Python-ark dy't ús applikaasjes ynsette.
  3. It ynstellen fan de omjouwing troch branch namme.
  4. Validearje fan Kubernetes yaml-bestannen mei Kubeval.
  5. Ferheegje automatysk de ferzje fan in diagram en de boppesteande charts (diagrammen dy't ôfhinklik binne fan de grafyk dy't feroare wurdt).
  6. In kaart yntsjinje by in Chartmuseum dat oerienkomt mei syn omjouwing

Behear fan ferskillen oer klusters

Federaasje fan Klusters

Der wie in tiid dat wy brûkten federaasje fan Kubernetes-klusters, wêr't Kubernetes-objekten kinne wurde ferklearre fanút ien API-einpunt. Mar problemen ûntstienen. Guon Kubernetes-objekten koenen bygelyks net makke wurde yn it federaasje-einpunt, wat it dreech makket om federearre objekten en oare objekten foar yndividuele klusters te behâlden.

Om it probleem op te lossen, begûnen wy de klusters selsstannich te behearjen, wat it proses gâns ferienfâldige (wy brûkten de earste ferzje fan federaasje; der kin wat feroare wêze yn 'e twadde).

Geo-ferspraat platfoarm

Us platfoarm is op it stuit ferdield oer 6 regio's - 3 lokaal en 3 yn 'e wolk.


Ferspraat ynset

Global Helm wearden

4 globale Helm-wearden kinne jo ferskillen tusken klusters identifisearje. Al ús charts hawwe standert minimumwearden.

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

Global wearden

Dizze wearden helpe de kontekst foar ús applikaasjes te definiearjen en wurde brûkt foar ferskate doelen: tafersjoch, tracing, logging, eksterne petearen meitsje, skaalfergrutting, ensfh.

  • "wolk": Wy hawwe in hybride Kubernetes platfoarm. Bygelyks, ús API wurdt ynset yn GCP-sônes en yn ús datasintra.
  • "env": Guon wearden kinne feroarje foar net-produksje omjouwings. Bygelyks, boarne definysjes en autoscaling konfiguraasjes.
  • "regio": Dizze ynformaasje helpt om de lokaasje fan it kluster te bepalen en kin brûkt wurde om tichtby einpunten foar eksterne tsjinsten te bepalen.
  • "clusterName": as en wannear wy in wearde foar in yndividuele kluster definiearje wolle.

Hjir is in spesifyk foarbyld:

{{/* 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 -}}

Foarbyld fan Helm template

Dizze logika is definiearre yn in helpersjabloan om te foarkommen dat Kubernetes YAML rommelich is.

Applikaasje Announcement

Us ynsetynstruminten binne basearre op meardere YAML-bestannen. Hjirûnder is in foarbyld fan hoe't wy in tsjinst ferklearje en har skaaltopology (oantal replika's) yn in kluster.

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

Service Definition

Dit is in skets fan alle stappen dy't ús ynset workflow definiearje. De lêste stap set de applikaasje tagelyk yn meardere arbeidersklusters yn.


Jenkins Deployment Steps

Hoe sit it mei geheimen?

Oangeande feiligens folgje wy alle geheimen fan ferskate plakken en bewarje se yn in unike ferwulft Vault yn Parys.

Us ynsetynstruminten ekstrahearje geheime wearden út Vault en, as de ynsettiid komt, ynfoegje se yn Helm.

Om dit te dwaan, definieare wy in mapping tusken de geheimen yn Vault en de geheimen dy't ús applikaasjes nedich binne:

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"

  • Wy hawwe algemiene regels definieare om te folgjen by it opnimmen fan geheimen yn Vault.
  • As it geheim jildt nei in spesifike kontekst of kluster, Jo moatte in spesifike yngong tafoegje. (Hjir hat de kontekstcluster1 syn eigen wearde foar it geheime stack-app1-wachtwurd).
  • Oars wurdt de wearde brûkt standert.
  • Foar elk item yn dizze list yn Kubernetes geheim in kaai-wearde pear wurdt ynfoege. Dêrom is it geheime sjabloan yn ús charts heul ienfâldich.

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

Problemen en beheinings

Wurkje mei meardere repositories

No skiede wy de ûntwikkeling fan charts en applikaasjes. Dit betsjut dat ûntwikkelders moatte wurkje yn twa git-repositories: ien foar de applikaasje, en ien foar it definiearjen fan har ynset nei Kubernetes. 2 git repositories betsjutte 2 workflows, en it is maklik foar in newbie om betize te wurden.

It behearen fan generalisearre diagrammen is in gedoe

Lykas wy al sein hawwe, binne generyske diagrammen heul nuttich foar it identifisearjen fan ôfhinklikens en rappe ynset fan meardere applikaasjes. Mar wy brûke --reuse-valuesom foar te kommen dat alle wearden trochjaan elke kear as wy in applikaasje ynsette dy't diel útmakket fan dizze generalisearre grafyk.

Yn in trochgeande leveringsworkflow hawwe wy mar twa wearden dy't regelmjittich feroarje: it oantal replika's en de ôfbyldingstag (ferzje). Oare, stabiler wearden wurde mei de hân feroare, en dit is frij lestich. Boppedat kin ien flater by it ynsetten fan in generalisearre diagram liede ta serieuze mislearrings, lykas wy hawwe sjoen út ús eigen ûnderfining.

Fernijing meardere konfiguraasje triemmen

As in ûntwikkelder in nije applikaasje tafoegje, moat hy ferskate bestannen feroarje: de applikaasjeferklearring, de list mei geheimen, it tafoegjen fan de applikaasje as ôfhinklikens as it is opnaam yn 'e generalisearre diagram.

Jenkins tagongsrjochten binne te ferlingd yn Vault

No hawwe wy ien AppRole, dy't alle geheimen fan 'e Vault lêst.

It weromdraaiproses is net automatisearre

Om werom te draaien, moatte jo it kommando útfiere op ferskate klusters, en dit is fol mei flaters. Wy fiere dizze operaasje mei de hân om te soargjen dat de juste ferzje ID is oantsjutte.

Wy geane nei GitOps

Ús doel

Wy wolle it diagram weromjaan nei it repository fan 'e applikaasje dy't it ynset.

De workflow sil itselde wêze as foar ûntwikkeling. Bygelyks, as in tûke wurdt drukke om te masterjen, sil de ynset automatysk wurde trigger. It wichtichste ferskil tusken dizze oanpak en de hjoeddeistige workflow soe dat wêze alles sil wurde beheard yn git (de applikaasje sels en de manier wêrop it wurdt ynset yn Kubernetes).

D'r binne ferskate foardielen:

  • Folle dúdliker foar de ûntwikkelder. It is makliker om te learen hoe't jo wizigingen tapasse kinne yn in lokale kaart.
  • De definysje fan tsjinst ynset kin wurde oantsjutte itselde plak as de koade betsjinning.
  • Behear fan it fuortheljen fan generalisearre charts. De tsjinst sil in eigen Helm-release hawwe. Hjirmei kinne jo de libbenssyklus fan 'e applikaasje (weromrol, upgrade) op it lytste nivo beheare, om oare tsjinsten net te beynfloedzjen.
  • Foardielen fan git foar diagram behear: ûngedien meitsje feroarings, audit log, ensfh As jo ​​moatte ûngedien meitsje in feroaring oan in grafyk, kinne jo dwaan dit mei help fan git. De ynset begjint automatysk.
  • Jo kinne beskôgje om jo ûntwikkelingsworkflow te ferbetterjen mei ark lykas Skaffold, wêrmei ûntwikkelders feroarings kinne testen yn in kontekst tichtby produksje.

Twa-stap migraasje

Us ûntwikkelders hawwe dizze workflow no 2 jier brûkt, dus wy wolle dat de migraasje sa pynlik mooglik is. Dêrom hawwe wy besletten om op 'e wei nei it doel in tuskenstap ta te foegjen.
De earste etappe is ienfâldich:

  • Wy hâlde in ferlykbere struktuer foar it ynstellen fan applikaasje-ynset, mar yn in inkeld objekt neamd 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 release per applikaasje (sûnder generalisearre charts).
  • Charts yn it git-repository fan 'e applikaasje.

Wy hawwe mei alle ûntwikkelders praat, dus it migraasjeproses is al begon. De earste etappe wurdt noch kontrolearre mei it CI-platfoarm. Ik sil gau in oare post skriuwe oer faze twa: hoe't wy ferhuze nei in GitOps-workflow mei flow. Ik sil jo fertelle hoe't wy alles ynstelle en hokker swierrichheden wy tsjinkamen (meardere repositories, geheimen, ensfh.). Folgje it nijs.

Hjir hawwe wy besocht ús foarútgong te beskriuwen yn 'e workflow foar applikaasje-ynset yn' e ôfrûne jierren, wat late ta gedachten oer de GitOps-oanpak. Wy hawwe it doel noch net berikt en sille rapportearje oer de resultaten, mar no binne wy ​​derfan oertsjûge dat wy it goede dien hawwe doe't wy besletten alles te ferienfâldigjen en it tichterby de gewoanten fan ûntwikkelders te bringen.

Boarne: www.habr.com

Add a comment