Alkalmazások telepítése több Kubernetes klaszteren Helm segítségével

Hogyan használja a Dailymotion a Kubernetes-t: alkalmazások telepítése

A Dailymotion-nál három éve kezdtük el a Kubernetes használatát a termelésben. Azonban az alkalmazások telepítése több klaszterre nem éppen egyszerű feladat, ezért az elmúlt néhány évben arra törekedtünk, hogy javítsuk az eszközeinket és a munkafolyamatainkat.

Honnan indult

Itt elmondjuk, hogyan telepítjük az alkalmazásainkat több Kubernetes klaszterre világszerte.

Ahhoz, hogy egyszerre több Kubernetes objektumot telepítsünk, használjuk Helm, és minden chartunkat egy git tárolóban tároljuk. Az alkalmazás teljes stackjének telepítéséhez, amely több szolgáltatást is magában foglal, használunk egy úgynevezett aggregáló chartot. Valójában ez egy chart, amely nyilatkozik a függőségekről, és lehetővé teszi az API és a szolgáltatások inicializálását egyetlen parancs segítségével.

Emellett írtunk egy kis Python szkriptet a Helm fölé, hogy ellenőrzéseket végezzen, chartokat hozzon létre, titkosítók hozzáadását végezze el és alkalmazásokat telepítsen. Mindezeket a feladatokat egy központi CI platformon hajtjuk végre Docker image segítségével.

Térjünk a lényegre.

Megjegyzés. Amikor ezt olvassa, a Helm 3 első jelölt verziója már be lett jelentve. A stabil verzió egy sor fejlesztést tartalmaz, amelyek célja, hogy megoldják azokat a problémákat, amelyekkel korábban szembesültünk.

A chartok fejlesztési munkafolyamata

Az alkalmazásokhoz ágaztatást használunk, és ezt a megközelítést a chartok esetében is alkalmazni kívántuk.

  • Az ágazat dev használatban van a chartok létrehozásához, amelyeket a fejlesztési klasztereken tesztelnek.
  • Amikor a pull-request átkerül a master, először a staging környezetben ellenőrzik.
  • Végül létrehozunk egy pull-requestet, hogy a módosításokat átadjuk az ágazatnak prod és alkalmazzuk azokat a termelésben.

Minden környezetnek saját privát tárolója van, amely a chartjainkat tárolja, és használjuk a Chartmuseum nagyon hasznos API-ját. Így biztosítjuk a szigorú izolációt a környezetek között, és a chartok valós körülmények közötti ellenőrzését, mielőtt azok a termelésben felhasználásra kerülnek.

A chart-tárolók különböző környezetekben

Érdemes megemlíteni, hogy amikor a fejlesztők dev ágat küldenek be, a chartjuk verziója automatikusan a dev Chartmuseum-ba kerül. Így minden fejlesztő egy közös dev tárolót használ, és figyelniük kell a chart verziójuk pontos megadására, hogy véletlenül se használják mások módosításait.

Továbbá, a kis Python szkriptünk ellenőrzi a Kubernetes objektumokat a Kubernetes OpenAPI specifikációjának megfelelően Kubeval, mielőtt közzétennénk őket a Chartmusem-ben.

A diagram fejlesztési folyamatának általános leírása

  1. A pipeline feladatainak beállítása a specifikációnak megfelelően gazr.io a minőségellenőrzés (lint, egységteszt) érdekében.
  2. Docker kép beküldése Python eszközökkel, amelyek telepítik alkalmazásainkat.
  3. Környezeti beállítás a branch neve alapján.
  4. Kubernetes yaml fájlok ellenőrzése a Kubeval segítségével.
  5. A diagram és szülődiagramjainak automatikus verzióemelése (azok a diagramok, amelyek az módosítható diagramtól függenek).
  6. A diagram küldése a Chartmuseum-ba, amely megfelel a környezetének.

A klaszterek közötti eltérések kezelése

Klaszterek föderációja

Volt idő, amikor használtuk a Kubernetes klaszterek föderációját,, ahol API végpontból lehetett bejelenteni a Kubernetes objektumokat. De problémák merültek fel. Például néhány Kubernetes objektumot nem lehetett létrehozni a föderációs végponton, ezért nehéz volt karbantartani a kombinált objektumokat és más objektumokat az egyes klaszterek számára.

A probléma megoldásához elkezdtük a klaszterek független kezelését, ami jelentősen egyszerűsítette a folyamatot (az első verziójú föderációt használtuk; a másodikban valami megváltozhatott).

Földrajzilag elosztott platform

Jelenleg a platformunk 6 régióra van elosztva — 3 helyben és 3 a felhőben.


Elosztott telepítés

Globális Helm értékek

4 globális Helm érték lehetővé teszi a klaszterek közötti eltérések meghatározását. Minden diagramunknak van minimális beállított értéke.

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

Globális értékek

Ezek az értékek segítenek meghatározni az alkalmazásaink kontextusát, és különböző feladatokhoz használják őket: figyelés, nyomkövetés, naplózás, külső hívások végrehajtása, méretezés stb.

  • „cloud”: hibrid Kubernetes platformunk van. Például az API-nk GCP zónákban és a saját adatközpontjainkban van telepítve.
  • „env”: néhány érték változhat a nem működő környezetek esetében. Például az erőforrások és automatikus skálázás beállításai.
  • „region”: ez az információ segít meghatározni a klaszter helyét, és felhasználható a legközelebbi végpontok meghatározására külső szolgáltatásokhoz.
  • „clusterName”: ha és amikor értéket akarunk meghatározni egy külön klaszter számára.

Itt van egy konkrét példa:

{{/* Visszaadja a Horizontal Pod Autoscaler replikáit a GraphQL-hez */}}
{{- 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 -}}

Helm sablon példa

Ez a logika egy segédsablonban van definiálva, hogy ne zavarja a Kubernetes YAML-t.

Alkalmazás bejelentése

Az általunk használt telepítési eszközök több YAML fájlon alapulnak. Az alábbiakban bemutatjuk, hogyan jelöljük be a szolgáltatást és a skálázási topológiáját (replikák száma) a klaszterben.

releases:
  - foo.world

foo.world:                # Kiadás neve
  services:               # Dailymotion alkalmazásainak/projektjeinek listája
    foobar:
      chart_name: foo-foobar
      repo: git@github.com:dailymotion/foobar
      contexts:
        prod-europe-west1:
          deployments:
            - name: foo-bar-baz
              replicas: 18
            - name: another-deployment
              replicas: 3

Szolgáltatás definiálása

Ez az összes lépés ábrázolása, amelyek meghatározzák a telepítési munkafolyamatunkat. Az utolsó lépés az alkalmazás egyidejű telepítése több munkaklaszterre.


Telepítési lépések a Jenkinsben

És a titkok?

A biztonság tekintetében minden titkot nyomon követünk különböző helyekről, és egyedi tárolóban tároljuk őket Vault Párizsban.

A telepítési eszközeink a Vault-ból nyerik a titkok értékeit, és amikor eljön az idő a telepítésre, beillesztik őket a Helm-be.

Ehhez meghatároztunk egy leképezést a Vault titkai és az alkalmazásainknak szükséges titkok között:

titkosok:                                                                                                                                                                                                        
     - titkos_id: "stack1-app1-jelszó"                                                                                                                                                                                  
       kontextusok:                                                                                                                                                                                                   
         - név: "default"                                                                                                                                                                                         
           vaultPath: "\/kv\/dev\/stack1\/app1\/teszt"                                                                                                                                                               
           vaultKey: "jelszó"                                                                                                                                                                                    
         - név: "cluster1"                                                                                                                                                                           
           vaultPath: "\/kv\/dev\/stack1\/app1\/teszt"                                                                                                                                                               
           vaultKey: "jelszó"

  • Megállapítottuk a titkos adatok Vault-ba történő rögzítésére vonatkozó általános szabályokat.
  • Ha a titok egy adott kontextushoz vagy klaszterhez, akkor hozzá kell adni egy konkrét bejegyzést. (Itt a cluster1 kontextusnak saját értéke van a stack-app1-jelszóhoz).
  • Ellenkező esetben az érték alapértelmezett.
  • A lista minden tételénél a Kubernetes titokban egy kulcs-érték pár kerül beillesztésre. Ezért a titok sablonja a chartjainkban nagyon egyszerű.

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émák és korlátozások

Több tárral való munka

Jelenleg a chartok és alkalmazások fejlesztését külön választjuk. Ez azt jelenti, hogy a fejlesztőknek két git tárral kell dolgozniuk: az egyik az alkalmazás számára, a másik pedig a Kubernetes-telepítésének meghatározásához. 2 git tartó = 2 munkafolyamat, és egy újonnan érkező könnyen összezavarodhat.

Az általános chartok kezelése nehézkes

Ahogy már említettük, az általános chartok nagyon kényelmesek a függőségek meghatározására és több alkalmazás gyors telepítésére. De használjuk --reuse-values, hogy elkerüljük az összes érték előző átadást, amikor a telepítést végezzük, amely ebbe az általános chartba tartozik.

A folyamatos szállítási folyamat során két olyan értékünk van, amelyek rendszeresen változnak: a példányok száma és a képcímke (verzió). Más, stabilabb értékek kézzel változnak, ami meglehetősen bonyolult. Ráadásul egy általánosított chart telepítésében elkövetett hiba súlyos leállásokat is okozhat, amit saját tapasztalatainkkal is bizonyíthatunk.

Több konfigurációs fájl frissítése

Amikor a fejlesztő új alkalmazást ad hozzá, több fájlt is módosítania kell: az alkalmazás bejelentése, a titkot tartalmazó lista, az alkalmazás hozzáadása a függőségekhez, ha az belefér az általánosított chartba.

A Jenkins engedélyek túl szélesek a Vaultban

Jelenleg egy van AppRole, amely minden titkot olvas a Vaultból.

A visszagörgetési folyamat nem automatizált

A visszagörgetéshez több klaszteren végre kell hajtani a parancsot, ami hibákat eredményezhet. Ezt a műveletet manuálisan végezzük, hogy biztosak legyünk a helyes verzióazonosító megadásában.

A GitOps felé haladunk

Célunk

Szeretnénk a chartot visszajuttatni az alkalmazás tárhelyébe, amelyet telepít.

A workflow ugyanaz lesz, mint a fejlesztés során. Például, amikor egy ágat masterbe küldenek, a telepítés automatikusan elindul. A legfőbb különbség a jelenlegi workflow és a javasolt megközelítés között az lesz, hogy minden a git-ben lesz kezelve (maga az alkalmazás és annak Kubernetesbe való telepítési módja).

Több előnye van:

  • Sokkal átláthatóbb a fejlesztő számára. Könnyebb megtanulni a változtatásokat alkalmazni a helyi chartban.
  • A szolgáltatás telepítésének meghatározása ott is megadható, ahol a kód van.
  • Az általánosított chartok törlésének kezelése. A szolgáltatásnak saját Helm kiadása lesz. Ez lehetővé teszi az alkalmazás életciklusának (visszagörgetés, frissítés) a legapróbb szinten történő kezelését, anélkül, hogy más szolgáltatásokat érintenénk.
  • A git előnyei chartok kezelésére: változtatások visszavonása, audit napló stb. Ha egy chart változtatását vissza kell vonni, azt a git segítségével lehet megtenni. A telepítés automatikusan elindul.
  • Gondolhatunk a fejlesztési workflow tökéletesítésére olyan eszközökkel, mint Skaffold, amellyel a fejlesztők a produkcióhoz közeli környezetben tudják tesztelni a változtatásokat.

Két lépcsős migráció

Fejlesztőink már 2 éve használják ezt a munkafolyamatot, így a lehető legkevesebb fájdalommentes migrációra van szükségünk. Ezért úgy döntöttünk, hogy hozzáadunk egy közbenső lépést a célunk felé vezető úton.
Az első lépés egyszerű:

  • Megőrizzük a hasonló struktúrát az alkalmazások telepítésének beállításához, de egy "DailymotionRelease" nevű objektumban.

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 kiadás alkalmazásonként (anélkül, hogy összesített chartok lennének).
  • Chartok az alkalmazás git-tárolójában.

Beszéltünk az összes fejlesztővel, így a migrációs folyamat már elkezdődött. Az első lépést továbbra is a CI platform segítségével irányítjuk. Hamarosan írok egy új bejegyzést a második lépésről: hogyan перейти на GitOps munkafolyamathoz Flux. Elmondom, hogyan állítottuk be mindezt és milyen nehézségekkel szembesültünk (több tároló, titkok stb.). Kövessétek a híreket.

Itt próbáltuk leírni a telepítési munkafolyamatunk során elért haladásunkat az elmúlt években, ami GitOps megközelítéshez vezetett. Még nem értük el a célt, és fogjuk jelenteni az eredményeket, de most már biztosak vagyunk abban, hogy helyesen döntöttünk, amikor mindent egyszerűsítettünk és közelebb hoztuk a fejlesztők szokásaihoz.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster