Si si Dailymotion përdor Kubernetes: implementimi i aplikacioneve
Ne në Dailymotion filluam të përdorim Kubernetes në prodhim 3 vjet më parë. Por implementimi i aplikacioneve në disa klasterë është një kënaqësi e madhe, prandaj në vitet e fundit kemi punuar për të përmirësuar mjetet dhe proceset tona.
Si filloi
Këtu do të tregojmë se si ne implementojmë aplikacionet tona në disa klasterë Kubernetes në mbarë botën.
Për të implementuar disa objekte Kubernetes njëkohësisht, ne përdorim , dhe të gjitha chartet tona ruhen në një depo git. Për të implementuar stack-un e plotë të aplikacionit nga disa shërbime, ne përdorim atë që quhet chart përmbledhës. Në thelb, ky është një chart që shpall varësitë dhe lejon inicializimin e API-së dhe shërbimeve të saj me një komandë.
Gjithashtu kemi shkruar një skript të vogël Python mbi Helm, për të bërë verifikime, për të krijuar chartet, për të shtuar sekrete dhe për të implementuar aplikacionet. Të gjitha këto detyra kryhen në një platformë CI qendrore duke përdorur një imazh docker.
Le të kalojmë në thelb.
Shënim. Kur ju e lexoni këtë, versioni i parë kandidat i Helm 3 është shpallur tashmë. Versioni kryesor përmban një mori përmirësimesh, të destinuara për të zgjidhur disa probleme që kemi përballuar në të kaluarën.
Procesi i zhvillimit të chart-ve
Për aplikacionet ne përdorim degëzim, dhe këtë qasje e kemi vendosur ta përdorim në chartet.
- Dega dev përdoret për të krijuar chartet, të cilat do të testohen në klasterët e zhvillimit.
- Kur kërkesa për ndihmë dërgohet në master, ato kontrollohen në staging.
- Përfundimisht, ne krijojmë një kërkesë për ndihmë, për të dërguar ndryshimet në degën prod dhe për t'i aplikuar ato në prodhim.
Ădo mjedis ka depozitat e tij private, tĂ« cilat ruajnĂ« chartet tona, dhe ne pĂ«rdorim me API shumĂ« tĂ« dobishme. KĂ«shtu ne sigurojmĂ« njĂ« ndarje strikte midis ambienteve dhe verifikimin e chart-ve nĂ« kushte reale, para se t'i pĂ«rdorim ato nĂ« prodhim.
Repot e chart-ve në ambiente të ndryshme
Vlen të theksohet se kur zhvilluesit dërgojnë degën dev, versioni i chart-it të tyre dërgohet automatikisht në dev Chartmuseum. Kështu të gjithë zhvilluesit përdorin një depo dev dhe duhet të tregojnë kujdes me versionin e tyre të chart-it, për të mos përdorur rastësisht ndryshimet e të tjerëve.
PĂ«r mĂ« tepĂ«r, skripti ynĂ« i vogĂ«l Python kontrollon objektet Kubernetes sipas specifikimeve tĂ« Kubernetes OpenAPI me anĂ« tĂ« , para se tâi publikojĂ« ato nĂ« Chartmusem.
Përshkrimi i përgjithshëm i procesit të zhvillimit të chartit
- Konfigurimi i detyrave të pipeline sipas specifikimit për kontrollin e cilësisë (lint, testim të njësi).
- Dërgimi i imazhit docker me mjetet Python, të cilat shpërndajnë aplikacionet tona.
- Konfigurimi i mjedisit sipas emrit të degës.
- Kontrollimi i skedarëve yaml të Kubernetes me anë të Kubeval.
- Rritja automatike e versionit të chartit dhe të chartëve të tij prind, (chartëve që varen nga charti në ndryshim).
- Dërgimi i chartit në Chartmuseum, i cili përputhet me mjedisin e tij
Menaxhimi i diferencave në klasterë
Federata e klasterëve
Ishte një kohë kur ne përdornim , ku mund të shpalleshin objektet Kubernetes nga një pikë përfundimtare API. Por lindën probleme. Për shembull, disa objekte Kubernetes nuk mund të krijoheshin në pikën përfundimtare të federatës, duke e bërë të vështirë mbështetje për objektet e bashkuara dhe objekte të tjera për klasterë të veçantë.
Për të zgjidhur problemin, ne filluam të menaxhonim klasterët në mënyrë të pavarur, duke e thjeshtuar ndjeshëm procesin (përdoruam versionin e parë të federatës; në të dytin, diçka mund të ketë ndryshuar).
Platforma e shpërndarë gjeografikisht
Aktualisht, platforma jonĂ« Ă«shtĂ« e shpĂ«rndarĂ« nĂ« 6 rajone â 3 lokale dhe 3 nĂ« cloud.
Depoja e shpërndarë
Vlerat globale të Helm-it
4 vlera globale të Helm-it lejojnë të përcaktohen ndryshimet mes klasterëve. Të gjithë chartët e tanishëm kanë vlera minimale parazgjedhore.
global:
cloud: True
env: staging
region: us-central1
clusterName: staging-us-central1Vlerat globale
Këto vlera ndihmojnë në përcaktimin e kontekstit për aplikacionet tona dhe përdoren për detyra të ndryshme: monitorim, gjurmim, regjistrim, thirrje të jashtme, shkallëzim etj.
- "cloud": ne kemi një platformë hibride Kubernetes. Për shembull, API-ja jonë shpërndahet në zonat GCP dhe në qendrat tona të të dhënave.
- "env": disa vlera mund të ndryshojnë për mjediset jo-funksionale. Për shembull, përcaktimi i burimeve dhe konfigurimi i automatikës.
- "region": kjo informacion ndihmon në përcaktimin e vendndodhjes së klasterit dhe mund të përdoret për të përcaktuar pikët më të afërta për shërbimet e jashtme.
- "clusterName": nëse dhe kur dëshirojmë të përcaktojmë një vlerë për një klaster të veçantë.
Ja një shembull konkret:
{{
/* Kthen kopjet e Horizontal Pod Autoscaler për GraphQL*/}}
{{- definoni "graphql.hpaReplicas" -}}
{{- nëse eq .Values.global.env "prod" }}
{{- nëse eq .Values.global.region "europe-west1" }}
minReplicas: 40
{{- përndryshe }}
minReplicas: 150
{{- përfundoni }}
maxReplicas: 1400
{{- përndryshe }}
minReplicas: 4
maxReplicas: 20
{{- përfundoni }}
{{- përfundoni -}}Shembulli i shablonit Helm
Kjo logjikë përcaktohet në një shabllon ndihmës, për të mos ndotur YAML-në e Kubernetes.
Deklarata e aplikacionit
Veglat tona të shpërndarjes bazohen në disa skedarë YAML. Më poshtë është një shembull se si ne shpallim shërbimin dhe topologjinë e tij të shkallëzimit (numrin e kopjeve) në klaster.
lëshime:
- foo.world
foo.world: # Emri i lëshimit
shërbimet: # Lista e aplikacioneve/projekteve të dailymotion
foobar:
chart_name: foo-foobar
repo: git@github.com:dailymotion/foobar
kontekstet:
prod-europe-west1:
shpërndarjet:
- emri: foo-bar-baz
kopjet: 18
- emri: shpërndarja-tjetër
kopjet: 3Përcaktimi i shërbimit
Kjo është një skemë e të gjitha hapave që përcaktojnë rrjedhën tonë të shpërndarjes. Hapi përfundimtar shpërndan aplikacionin njëkohësisht në disa klasterë pune.
Hapat e shpërndarjes në Jenkins
Dhe sekretet?
Sa i përket sigurisë, ne përcjellim të gjitha sekretet nga vende të ndryshme dhe i ruajmë ato në një depot unik në Paris.
Veglat tona të shpërndarjes nxjerrin vlerat e sekretet nga Vault dhe, kur vjen koha për shpërndarje, i futin ato në Helm.
Për këtë, ne kemi përcaktuar një përputhje midis sekretet në Vault dhe sekretet që nevojiten nga aplikacionet tona:
sekretet:
- sekret_id: "stack1-app1-password"
kontekstet:
- emri: "default"
rrugaVault: "\/kv\/dev\/stack1\/app1\/test"
çelësiVault: "password"
- emri: "cluster1"
rrugaVault: "\/kv\/dev\/stack1\/app1\/test"
çelësiVault: "password"- Ne kemi përcaktuar rregullat e përgjithshme që duhet të ndiqen gjatë regjistrimit të sekretëve në Vault.
- Nëse sekreti i përket një konteksti apo klasteri të caktuar, është e nevojshme të shtoni një regjistrim të veçantë. (Këtu konteksti cluster1 ka një vlerë të vetme për sekretin stack-app1-password).
- Në të kundërt, përdoret vlera si parazgjedhje.
- Për çdo pikë në këtë listë, në sekretin Kubernetes në vendoset një çift çelës-vlerë. Prandaj, modeli i sekretit në diagramet tona është shumë i thjeshtë.
apiVersion: v1
data:
{{- range $key,$value := .Values.secrets }}
{{ $key }}: {{ $value | b64enc | quote }}
{{ end }}
lloji: Secret
metadata:
emri: "{{ .Chart.Name }}"
etiketa:
versioniChart: "{{ .Chart.Version }}"
versioniTiller: "{{ .Capabilities.TillerVersion.SemVer }}"
tipi: OpaqueProblemet dhe kufizimet
Puna me disa depo
Tani ne ndajmë zhvillimin e diagrameve dhe aplikacioneve. Kjo do të thotë se zhvilluesit duhet të punojnë në dy depo git: një për aplikacionin dhe një tjetër për përcaktimin e shpërndarjes së tij në Kubernetes. 2 depo git janë 2 procese pune, dhe për një fillestar është e lehtë të ngatërrohet.
Të menaxhosh diagramet e përgjithshme është e mërzitshme
Siç e përmendëm, diagramet e përgjithshme janë shumë të dobishme për përcaktimin e varësive dhe shpërndarjen e shpejtë të disa aplikacioneve. Por ne përdorim --reuse-values, për të shmangur kalimin e të gjitha vlerave çdo herë kur ne shpërndajmë një aplikacion që bën pjesë në këtë diagram të përgjithshëm.
Në procesin e punës së dërgesës së vazhdueshme kemi vetëm dy vlera që ndryshojnë rregullisht: numri i kopjeve dhe etiketa e imazhit (versioni). Vlera të tjera, më të qëndrueshme, ndryshojnë manualisht dhe kjo është mjaft e ndërlikuar. Më tepër, një gabim në shpërndarjen e diagramit të përgjithshëm mund të sjellë dështime të rënda, siç e kemi provuar në përvojën tonë të vet.
Përditësimi i disa skedave të konfigurimit
Kur një zhvillues shton një aplikacion të ri, ai duhet të ndryshojë disa skeda: shpallja e aplikacionit, lista e sekreteve, shtimi i aplikacionit në varësi, nëse ai bën pjesë në diagramin e përgjithshëm.
Lejet e Jenkins janë tepër të gjera në Vault
Tani kemi një , e cila lexon të gjitha sekretet nga Vault.
Procesi i rikthimit nuk është automatizuar
Për rikthimin, duhet të ekzekutohet një komandë në disa klastera, gjë që është e rrezikshme për gabimet. Ne e kryejmë këtë operacion manualisht për të garantuar identifikimin e saktë të versionit.
Ne po shkëputemi drejt GitOps
Qëllimi ynë
Duam ta kthejmë diagramin në repositorin e aplikacionit që ai shpërndan.
Procesi do të jetë i njëjtë si për zhvillimin. Për shembull, kur degësohet në master, shpërndarja do të fillojë automatikisht. Diferenca kryesore midis këtij qasjet dhe procesit aktual do të jetë që të gjitha do të menaxhohen në git (vetë aplikacioni dhe mënyra e shpërndarjes së tij në Kubernetes).
Ka disa përparësi:
- Shumë më e kuptueshme për zhvilluesin. Më e lehtë për t'u mësuar për të aplikuar ndryshimet në diagramin lokal.
- Definimi i shpërndarjes së shërbimit mund të specifikohet atje ku është kodi i shërbimit.
- Menaxhimi i fshirjes së diagrameve të përgjithshme. Shërbimi do të ketë lëshimin e tij Helm. Kjo do të lejojë menaxhimin e ciklit të jetës së aplikacionit (rikthimi, azhurnimi) në nivelin më të hollësishëm, për të mos prekur shërbime të tjera.
- Përfitimet e git për menaxhimin e diagrameve: anulimi i ndryshimeve, regjistri i auditet dhe etj. Nëse duhet të anuloni një ndryshim në diagram, kjo mund të bëhet përmes git. Shpërndarja fillon automatikisht.
- Mund të mendohet për përmirësimin e procesit të zhvillimit me ndihmën e mjeteve si Skaffold, me të cilat zhvilluesit mund të testojnë ndryshimet në një kontekst të afërt me prodhimin.
Migroni në dy etapa
Zhvilluesit tanë e kanë përdorur këtë proces pune tash e 2 vjet, kështu që na nevojitet një migrim sa më paqësor. Prandaj, vendosëm të shtojmë një hap ndërmjetës në rrugën drejt qëllimit.
Hapi i parë është i thjeshtë:
- Ne ruajmë një strukturë të ngjashme për konfigurimin e shpërndarjes së aplikacioneve, por në një objekt me emrin 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 riliz për aplikacion (pa grafikë të përgjithshme).
- Grafikat në depozitën git të aplikacionit.
Biseduam me të gjithë zhvilluesit, kështu që processi i migrimit ka filluar. Hapi i parë ende kontrollohet duke përdorur platformën CI. Së shpejti do të shkruaj një postim tjetër për hapat e dytë: si kaluam në procesin GitOps me . Do t'ju tregoj si e konfiguruan gjithçka dhe me cilat sfida u përballëm (disa depo, sekrete etj.). Qëndroni të informuar.
Këtu përpiqemi të përshkruajmë përparimin tonë në procesin e shpërndarjes së aplikacioneve gjatë viteve të fundit, i cili na çoi në mendime mbi qasjen GitOps. Ende nuk e kemi arritur qëllimin dhe do t'i raportojmë rezultatet, por tani jemi të bindur se bëmë mirë që vendosëm gjithçka ta thjeshtojmë dhe ta afrojmë me zakonet e zhvilluesve.
Burimi: habr.com
