Dreifðu forritum yfir marga Kubernetes klasa með Helm

Hvernig Dailymotion notar Kubernetes: Dreifing forrita

Við hjá Dailymotion byrjuðum að nota Kubernetes í framleiðslu fyrir 3 árum síðan. En það er skemmtilegt að dreifa forritum yfir marga klasa, svo undanfarin ár höfum við verið að reyna að bæta verkfæri okkar og verkflæði.

Hvar byrjaði það

Hér munum við fjalla um hvernig við dreifum forritunum okkar yfir marga Kubernetes klasa um allan heim.

Til að dreifa mörgum Kubernetes hlutum í einu notum við Helm, og öll töflurnar okkar eru geymdar í einni git geymslu. Til að dreifa fullum forritastafla frá nokkrum þjónustum notum við svokallað yfirlitsrit. Í meginatriðum er þetta graf sem lýsir yfir ósjálfstæði og gerir þér kleift að frumstilla API og þjónustu þess með einni skipun.

Við skrifuðum líka lítið Python handrit ofan á Helm til að gera athuganir, búa til töflur, bæta við leyndarmálum og dreifa forritum. Öll þessi verkefni eru unnin á miðlægum CI vettvangi með því að nota docker mynd.

Komum okkur að efninu.

Athugið. Þegar þú lest þetta hefur fyrsti útgáfuframbjóðandinn fyrir Helm 3 þegar verið tilkynntur. Aðalútgáfan inniheldur fjöldann allan af endurbótum til að takast á við sum vandamálin sem við höfum lent í í fortíðinni.

Verkflæði grafaþróunar

Við notum greiningu fyrir forrit og við ákváðum að beita sömu nálgun á töflur.

  • Útibú dev notað til að búa til töflur sem verða prófaðar á þróunarþyrpingum.
  • Þegar pull beiðni er send til húsbóndi, þeir eru innritaðir í sviðsetningu.
  • Að lokum búum við til dráttarbeiðni til að skuldbinda breytingarnar á útibúinu prod og beita þeim í framleiðslu.

Hvert umhverfi hefur sína eigin einkageymslu sem geymir kortin okkar og við notum Kortasafn með mjög gagnlegum API. Þannig tryggjum við stranga einangrun milli umhverfisins og raunveruleikaprófun á kortum áður en þau eru notuð í framleiðslu.

Myndageymslur í mismunandi umhverfi

Það er athyglisvert að þegar forritarar ýta á þróunargrein er útgáfa af myndriti þeirra sjálfkrafa ýtt á dev Chartmuseum. Þannig nota allir forritarar sömu þróunargeymsluna og þú þarft að tilgreina vandlega þína útgáfu af töflunni til að nota ekki óvart breytingar annarra.

Þar að auki staðfestir litla Python handritið okkar Kubernetes hluti gegn Kubernetes OpenAPI forskriftunum með því að nota Kubeval, áður en þær eru birtar á Chartmusem.

Almenn lýsing á vinnuflæði töfluþróunar

  1. Uppsetning leiðsluverkefna samkvæmt forskrift gazr.io fyrir gæðaeftirlit (ló, einingapróf).
  2. Að ýta á bryggjumynd með Python verkfærum sem dreifa forritunum okkar.
  3. Uppsetning umhverfisins eftir heiti útibús.
  4. Staðfestir Kubernetes yaml skrár með Kubeval.
  5. Auka sjálfkrafa útgáfu af myndriti og yfirlitum þess (töflur sem eru háðar því að myndritinu er breytt).
  6. Senda kort til Kortasafns sem passar við umhverfi þess

Stjórna mismun milli klasa

Samtök klasa

Það var tími þegar við notuðum sambands Kubernetes klasa, þar sem hægt var að lýsa yfir Kubernetes hlutum frá einum API endapunkti. En vandamál komu upp. Til dæmis var ekki hægt að búa til suma Kubernetes hluti í sambandsendapunktinum, sem gerir það erfitt að viðhalda sameinuðum hlutum og öðrum hlutum fyrir einstaka klasa.

Til að leysa vandamálið fórum við að stjórna klösunum sjálfstætt, sem einfaldaði ferlið til muna (við notuðum fyrstu útgáfuna af sambandsríkinu; eitthvað gæti hafa breyst í þeirri seinni).

Geo-dreifður vettvangur

Pallurinn okkar er sem stendur dreift yfir 6 svæði - 3 á staðnum og 3 í skýinu.


Dreifð dreifing

Global Helm gildi

4 hnattræn Helm gildi gera þér kleift að bera kennsl á mun á þyrpingum. Öll töflurnar okkar eru með sjálfgefna lágmarksgildi.

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

Hnattræn gildi

Þessi gildi hjálpa til við að skilgreina samhengið fyrir forritin okkar og eru notuð í ýmsum tilgangi: eftirlit, rekja, skráningu, hringja utanaðkomandi símtöl, mælikvarða osfrv.

  • „ský“: Við erum með hybrid Kubernetes vettvang. Til dæmis er API okkar notað á GCP svæðum og í gagnaverum okkar.
  • „env“: Sum gildi geta breyst fyrir umhverfi sem ekki er framleitt. Til dæmis tilfangaskilgreiningar og sjálfvirkar stillingar.
  • „svæði“: Þessar upplýsingar hjálpa til við að ákvarða staðsetningu klasans og er hægt að nota þær til að ákvarða nálæga endapunkta fyrir utanaðkomandi þjónustu.
  • "clusterName": ef og þegar við viljum skilgreina gildi fyrir einstakan klasa.

Hér er ákveðið dæmi:

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

Dæmi um sniðmát hjálm

Þessi rökfræði er skilgreind í hjálparsniðmáti til að forðast ringulreið í Kubernetes YAML.

Umsóknartilkynning

Dreifingartæki okkar eru byggð á mörgum YAML skrám. Hér að neðan er dæmi um hvernig við lýsum yfir þjónustu og stærðarstærð hennar (fjöldi eftirmynda) í klasa.

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

Þjónustuskilgreining

Þetta er yfirlit yfir öll skrefin sem skilgreina innsetningarverkflæði okkar. Síðasta skrefið dreifir forritinu til margra starfsmannaklasa samtímis.


Jenkins dreifingarskref

Hvað með leyndarmál?

Varðandi öryggi fylgjumst við með öllum leyndarmálum frá mismunandi stöðum og geymum þau í einstakri hvelfingu Vault í París.

Uppsetningarverkfærin okkar draga leyndarmál úr Vault og, þegar uppsetningartími kemur, settu þau inn í Helm.

Til að gera þetta skilgreindum við kortlagningu á milli leyndarmálanna í Vault og leyndarmálanna sem forritin okkar þurfa:

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"

  • Við höfum skilgreint almennar reglur til að fylgja þegar leyndarmál eru tekin upp í Vault.
  • Ef leyndarmálið á við við ákveðið samhengi eða klasa, þú þarft að bæta við ákveðinni færslu. (Hér hefur samhengisþyrping1 sitt eigið gildi fyrir leynilega stafla-app1-lykilorðið).
  • Annars er gildið notað sjálfgefið.
  • Fyrir hvert atriði á þessum lista í Kubernetes leyndarmál lykilgildi par er sett inn. Þess vegna er leynisniðmátið í töflunum okkar mjög einfalt.

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

Vandamál og takmarkanir

Vinna með margar geymslur

Nú aðskiljum við þróun korta og forrita. Þetta þýðir að verktaki verða að vinna í tveimur git geymslum: einni fyrir forritið og annað til að skilgreina dreifingu þess á Kubernetes. 2 git geymslur þýða 2 verkflæði og það er auðvelt fyrir nýliða að ruglast.

Það er vandræðalegt að stjórna almennum töflum

Eins og við höfum áður sagt eru almenn töflur mjög gagnlegar til að bera kennsl á ósjálfstæði og fljótt að dreifa mörgum forritum. En við notum --reuse-valuestil að forðast að fara framhjá öllum gildum í hvert skipti sem við sendum inn forrit sem er hluti af þessu almenna töflu.

Í samfelldu afhendingarvinnuflæði höfum við aðeins tvö gildi sem breytast reglulega: fjöldi eftirmynda og myndamerkið (útgáfa). Öðrum, stöðugri gildum er breytt handvirkt og þetta er frekar erfitt. Þar að auki geta ein mistök við að dreifa almennu korti leitt til alvarlegra bilana, eins og við höfum séð af eigin reynslu.

Uppfærir margar stillingarskrár

Þegar verktaki bætir við nýju forriti þarf hann að breyta nokkrum skrám: umsóknaryfirlýsingunni, listanum yfir leyndarmál, bæta forritinu við sem ósjálfstæði ef það er innifalið í almennu töflunni.

Jenkins heimildir eru of rýmkaðar í Vault

Nú höfum við einn AppRole, sem les öll leyndarmálin úr hvelfingunni.

Afturköllunarferlið er ekki sjálfvirkt

Til að snúa aftur til baka þarftu að keyra skipunina á nokkrum klösum og þetta er fullt af villum. Við framkvæmum þessa aðgerð handvirkt til að tryggja að rétt útgáfuauðkenni sé tilgreint.

Við erum að færast í átt að GitOps

Markmið okkar

Við viljum skila töflunni í geymsluna fyrir forritið sem það setur upp.

Verkflæðið verður það sama og fyrir þróun. Til dæmis, þegar útibú er ýtt til að ná tökum, verður dreifingin ræst sjálfkrafa. Helsti munurinn á þessari nálgun og núverandi vinnuflæði væri sá öllu verður stjórnað í git (forritið sjálft og hvernig það er dreift í Kubernetes).

Það eru nokkrir kostir:

  • Mikið skýrari fyrir framkvæmdaraðila. Það er auðveldara að læra hvernig á að beita breytingum á staðbundnu myndriti.
  • Hægt er að tilgreina skilgreiningu þjónustudreifingar sama stað og kóðinn þjónustu.
  • Stjórna því að fjarlægja almennar töflur. Þjónustan mun hafa sína eigin Helm útgáfu. Þetta gerir þér kleift að stjórna líftíma forritsins (til baka, uppfærsla) á minnsta stigi, svo að það hafi ekki áhrif á aðra þjónustu.
  • Kostir git fyrir kortastjórnun: afturkalla breytingar, endurskoðunarskrá osfrv. Ef þú þarft að afturkalla breytingu á myndriti geturðu gert þetta með git. Uppsetningin byrjar sjálfkrafa.
  • Þú gætir íhugað að bæta þróunarvinnuflæðið þitt með verkfærum eins og Skaffold, sem verktaki getur prófað breytingar í samhengi nálægt framleiðslu.

Tveggja þrepa flutningur

Hönnuðir okkar hafa notað þetta verkflæði í 2 ár núna, svo við viljum að flutningurinn sé eins sársaukalaus og mögulegt er. Því ákváðum við að bæta við millistigi á leiðinni að markmiðinu.
Fyrsta stigið er einfalt:

  • Við höldum svipaðri uppbyggingu til að setja upp dreifingu forrita, en í einum hlut sem kallast 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 útgáfa fyrir hverja umsókn (án almennra korta).
  • Gröf í git geymslu forritsins.

Við höfum rætt við alla þróunaraðilana, þannig að flutningsferlið er þegar hafið. Fyrsta stiginu er enn stjórnað með CI pallinum. Ég mun skrifa aðra færslu bráðlega um áfanga tvö: hvernig við fórum yfir í GitOps verkflæði með Flux. Ég skal segja þér hvernig við settum allt upp og hvaða erfiðleika við lentum í (margar geymslur, leyndarmál osfrv.). Fylgstu með fréttum.

Hér höfum við reynt að lýsa framförum okkar í verkflæði forritadreifingar undanfarin ár, sem leiddi til hugsana um GitOps nálgunina. Við höfum ekki enn náð takmarkinu og munum segja frá niðurstöðunum, en nú erum við sannfærð um að við gerðum rétt þegar við ákváðum að einfalda allt og færa það nær venjum þróunaraðila.

Heimild: www.habr.com

Bæta við athugasemd