
Aruanne keskendub Kubernetes'i operaatori arendamise praktilistele küsimustele, selle arhitektuuri projekteerimisele ja põhifunktsioonide toimimisele.
Aruande esimeses osas vaatleme:
- mis on operaator Kubernetes'is ja miks see on vajalik;
- kuidas operaator lihtsustab keeruliste süsteemide haldamist;
- mida operaator suudab, ja mida operaator ei suuda.
Seejärel liigume operaatori sisemiste struktuuride arutamise juurde. Vaatleme operaatori arhitektuuri ja toimimist samm-sammult. Üksikasjalikult käsitleme:
- operaatori ja Kubernetes'i omavaheline suhtlus;
- milliseid funktsioone operaator enda peale võtab ja mida delegatsiooniks Kubernetes'i jätab.
Vaatleme andmebaasi shardi ja repliikide haldamist Kubernetes'is.
Edasi arutame andmete salvestamise küsimusi:
- kuidas töötada Persistent Storage'iga operaatori vaatenurgast;
- kohalikku salvestust kasutamise pöördeid.
Aruande lõpposas vaatame praktilisi näiteid rakendamise kohta Amazoniga või Google Cloud Service'iga. Aruanne põhineb ClickHouse'i operaatori arendamise ja kasutuskogemuste näitel.
Video:

Minu nimi on Vladislav Klimenko. Täna tahaksin rääkida meie kogemustest spetsialiseeritud andmebaasiklusterite halduri arendamise ja opereerimise valdkonnas. Kasutame näitena ClickHouse'i klastrite haldamiseks.

Miks me saame rääkida operaatorist ja ClickHouse'ist?
- Me tegeleme ClickHouse'i toe ja arendamisega.
- Praegu üritame järk-järgult panustada ClickHouse'i arendamisse. Oleme Yandexi järel suuruselt teised muudatuste tegemise osas ClickHouse'is.
- Püüame luua täiendavaid projekte ClickHouse'i ökosüsteemile.
Üks selline projekt, millest tahaksin rääkida, on ClickHouse-operator Kubernetes'e jaoks.
Oma ettekandes tahaksin käsitleda kahte teemat:
- Esimene teema on see, kuidas meie ClickHouse'i andmebaaside haldur töötab Kubernetes'es.
- Teine teema on see, kuidas töötab iga operaator, st kuidas see suhtleb Kubernetes'ega.
Need kaks küsimust kattuvad kogu minu ettekande vältel.

Kellele võiks olla huvitav kuulata, mida ma üritan rääkida?
- Eriti huvitav on see neile, kes haldavad operaatorite.
- Või nende jaoks, kes soovivad luua oma, et mõista, kuidas see sees töötab, kuidas operaator Kubernetesega suhtleb ja millised takistused võivad esineda.

Kuna me täna arutame, oleks hea teada, kuidas Kubernetes töötab ja omada põhiteadmisi pilvetehnoloogiatest.

Mis on ClickHouse? See on veergude andmebaas, mis on suunatud analüütiliste päringute reaalajas töötlemisele. Ja see on täielikult avatud lähtekoodiga.
Ja meil on oluline teada ainult kahte asja. Tuleb tead, et see on andmebaas, seega on see, mida ma räägin, praktikas kohaldatav peaaegu igasuguste andmebaaside suhtes. Ja et andmehaldur ClickHouse on väga hästi skaleeritav, pakkudes praktiliselt lineaarset skaleeritavust. Seega on klastriseisund ClickHouse'i jaoks loomulik seisund. Meid huvitab kõige rohkem arutada, kuidas hooldada ClickHouse'i klastrit Kuberneteses.

Miks on see seal vajalik? Miks me ei saa jätkata selle iseseisvat kasutamist? Vastused on osaliselt tehnilised ja osaliselt organisatsioonilised.
- Praktikas seisame üha sagedamini silmitsi olukorraga, kus suurtes ettevõtetes on peaaegu kõik komponendid juba Kuberneteses. Järele on jäänud vaid andmebaasid.
- Ja üha sagedamini küsitakse: "Kas seda saab ka sinna viia?" Seetõttu püüavad suured ettevõtted võimalikult palju oma andmehalduse kohandamisega unifitseerida, et nad saaksid kiiresti oma andmehoidlaid hallata.
- See on eriti oluline, kui on vajalik maksimaalne korduvus uues kohas, st maksimaalne ülekantavus.

Kui lihtne või keeruline see on? Loomulikult saab seda teha käsitsi. Kuid see ei ole nii lihtne, kuna meil koondub Kubernetesega seotud halduskompleksus, ent lisandub ClickHouse’i spetsiifika. Ja tulemuseks on selline aggregeerimine.
Kõik see kokku annab üsna suure tehnoloogiate komplekti, mille haldamine muutub juba piisavalt keeruliseks, kuna Kubernetes toob endaga igapäevaseid ekspluateerimise küsimusi, samas kui ClickHouse toob oma igapäevased tegevusprobleemid. Eriti, kui meil on mitmeid ClickHouse’i instantsi ja me peame nendega pidevalt midagi ette võtma.

ClickHouse'i dünaamilise konfigureerimise korral on palju küsimusi, mis loovad pidevat koormust DevOps'ile:
- Kui soovime ClickHouse'is midagi muuta, näiteks lisada replika või shard, peame tegema konfigureerimise haldust.
- Siis tuleb muuta andmeskeemi, kuna ClickHouse'il on spetsiifiline shardimise meetod. Seal tuleb andmeskeem ja konfigureerimised õigesti paika panna.
- Peab seadma üles jälgimise.
- Logide kogumine uute shardide ja uute replikate jaoks.
- Tuleb tegeleda taastamisega.
- Ja taaskäivitamisega.
Need on rutiinsed tööd, mida oleks väga soovitav tegevuse osas kergendada.

Kubernetes aitab tegevuse osas hästi, kuid baassüsteemide küsimustes.
Kubernetes hõlbustab ja automatiseerib selliseid asju nagu:
- Taastamine.
- Taaskäivitamine.
- Salvestussüsteemi haldamine.
See on hea, see on õige suund, kuid tal pole üldse aimu, kuidas andmebaasi klastrit kasutada.
Soovime rohkem, tahame, et kogu andmebaas töötaks Kuberneteses.

Tahad midagi nagu suur punane nupp, millele vajutades saate üles seadmiseks ja kogu elutsükli jooksul toetamiseks klastrit, mis käsitleb igapäevaseid ülesandeid, mida tuleb lahendada. ClickHouse klaster Kubernetes'es.
Me oleme püüdnud välja töötada lahenduse, mis aitaks tööd lihtsustada. See on ClickHouse-operaator Kubernetes'e jaoks ettevõttelt Altinity.

Operaator on programm, mille peamine ülesanne on hallata teisi programme, st see on juhtimisseade.
Ja see sisaldab käitumismustreid. Seda võib nimetada kodeeritud teadmiseks ainealasest.
Ja tema peamine ülesanne on lihtsustada DevOpsi elu ja vähendada mikromenetlemist, et ta (DevOps) mõtleks kõrgtasemel, st et ta (DevOps) ei tegeleks mikromenetlemisega ega seadistaks kõiki detaile käsitsi.
Ja operaator on justkui robotabi, mis võitleb mikrotöödega ja aitab DevOps'i.

Miks on operaator vajalik? Ta näitab end eriti hästi kahes küsimuses:
- Kui ClickHouse'i haldumise spetsialistil puudub piisav kogemus, kuid ClickHouse'i kasutamine on juba vajalik, teeb operaator haldamise lihtsamaks ja võimaldab töötada ClickHouse'i klastriga, millel on üsna keeruline konfiguratsioon, samas mitte süvenedes detailidesse, kuidas see kõik seestpoolt töötab. Lihtsalt antakse talle kõrgtasemel ülesanded ja see toimib.
- Teine valdkond, kus ta end kõige paremini tõestab, on olukord, kus tuleb automatiseerida suur hulk tüüpilisi ülesandeid. Ta vabastab süsteemiadministraatoreid mikroulesannetest.

Seda on kõige rohkem vaja kas neile, kes alles alustavad oma teed, või neile, kes peavad palju automatiseerimisega tegelema.

Mis siis eristab operaatoripõhist lähenemist teistest süsteemidest? On ju olemas Helm. See aitab samuti ClickHouse'i paigaldada, võib joonistada helm chart'e, mis isegi paigaldavad terve ClickHouse'i klastr. Mis siis eristab operaatorit näiteks Helm'ist?
Peamine põhierinevus on see, et Helm on paketihaldus, samas kui operaator astub edasi. See hõlmab kogu elutsüklit. See ei ole ainult installimine, vaid igapäevased ülesanded, mis sisaldavad skaleerimist, shardimist ja kõike, mida on vaja elutsükli jooksul teha (vajadusel ka kustutamine) – selle eest hoolitseb operaator. Ta püüab automatiseerida ja hallata kogu tarkvara elutsüklit. See on tema põhierinevus teiste lahenduste seas.

See oli sissejuhatav osa, nüüd liigume edasi.
Kuidas me ehitame oma operaatori? Püüame läheneda küsimusele, et hallata ClickHouse klastrit kui ühte ressurssi.
Siin on meil pildi vasakus osas sisendid. See on YAML, millel on klastrite spesifikatsioon, mis traditsiooniliselt edastatakse Kubernetesesse läbi kubectl. Seal operaator haarab selle, teeb oma maagia ja väljundiks on meil selline skeem. See on ClickHouse’i rakendamine Kuberneteses.
Ja jätkame aeglaselt vaatamist, kuidas operaator töötab ja milliseid tüüpilisi ülesandeid saab lahendada. Käsitleme ainult tüüpilisi ülesandeid, kuna meil on piiratud aeg. Ja me ei räägi kõigest, mida operaator suudab lahendada.

Lähme praktikast lähtuvalt. Meie projekt on täiesti avatud lähtekoodiga, seega saab GitHub'is näha, kuidas see töötab. Ja võime lähtuda sellest, et kui soovite lihtsalt alustada, siis Quick Start Guide'iga saab hakata.
Kui soovite üksikasjalikult süveneda, siis püüame hoida dokumentatsiooni enam-vähem korralikus seisus.

Alustame praktilise ülesandega. Esimene ülesanne, millega kõik tahame alustada, on käivitada esimene näide. Kuidas operaatori abil ClickHouse'i käivitada, isegi kui me ei tea täpselt, kuidas see töötab? Kirjutame manifesti, kuna kogu suhtlus k8s-iga käib manifestide kaudu.

Siin on selline keeruline manifest. See, mis on punasega tähistatud, on see, millele tuleb keskenduda. Palume operaatoril luua kluster nimega demo.
Siiani on põhinäidised. Storage'i kohta veel teavet ei leia, kuid naaseme selle juurde hiljem. Hetkel jälgime klastrite arengut dünaamikas.
Loomisime selle manifesti. Toimime seda meie operaatorile. Ta töötas selle läbi ja tegi oma maagia.

Vaadata konsoli. Huvi pakuvad kolm komponenti – see on Pod, kaks teenust ja StatefulSet.
Operaator töötas ja nüüd saame vaadata, mida ta täpselt lõi.

Ta loob umbes sellise skeemi. Meil on StatefulSet, Pod, iga repliika jaoks ConfigMap ja kogu klastrile ConfigMap. Teenused on kindlasti vajalikud kui sisenemispunktid klastrisse.
Teenused on keskne Load Balancer Service ja samuti võib olla iga repliika jaoks, iga shardi jaoks.
Meie baasklastri välimus on umbes selline. See koosneb ühest ainus nodist.

Liikuge edasi, hakkame keerukamaks minema. Klastrit tuleb shardida.

Meie ülesanded kasvavad, dünaamika algab. Soovime lisada shardi. Jälgime arengu käiku. Muudame meie spetsifikatsiooni. Näitame, et soovime kahte shardi.
See on sama fail, mis dünaamiliselt areneb süsteemi kasvades. Storage'i ei ole, storage'i arutame hiljem, see on eraldi teema.
Toimime YAML-teenuse ja vaatame, mis välja tuleb.

Operaator mõtles ja lõi järgmised üksused. Meil on juba kaks Pod'i, kolm Service'i ja, ootamatult, kaks StatefulSet'i. Miks kaks StatefulSet'i?

Skeem nägi välja selline – see on meie algolek, kui meil oli ainult üks pod.

Nüüd on see selline. Hetkel on kõik lihtne, see on kopeeritud.

Ja miks on StatefulSet kaks? Siin tuleb kõrvale juhtida ja arutada, kuidas Kuberneteses toimub Pod'ide haldus.
On olemas selline objekt nagu StatefulSet, mis võimaldab luua Pod'e mallist. Siin on võtmekoht – see on Mall. Ühes StatefulSet'is saab käitada palju Pod'e sama malliga. Ja siin on võtmefraas "sama malliga palju Pod'e".
Ja oli suur kiusatus teha kogu klaster, pakkides kõik ühte StatefulSet'i. See töötaks, selles pole probleemi. Kuid on üks nüanss. Kui me tahame kokku panna heterogeense klastrit, st mitmest ClickHouse'i versioonist, siis tulevad meil küsimused. Jah, StatefulSet võib teha järkjärgulisi uuendusi, jah, seal saab paigaldada uue versiooni ja selgitada, et ei tohiks proovida rohkem kui nii palju node'e korraga.
Kuid kui ekstrapoleerida ülesannet ja öelda, et soovime luua täielikult heterogeense klastri ning soovime mitte vanalt versioonilt uuele üle minna rolling update'i abil, vaid lihtsalt luua heterogeenne klaster nii erinevate ClickHouse versioonide kui ka erinevate salvestuslahendustega. Soovime näiteks luua mõned repliigid eraldi ketastele, aeglastele ketastele, siis ehitada täiesti heterogeense klastri. Ja kuna StatefulSet loob ühest mallist standardiseeritud lahenduse, pole selle saavutamine võimalik.
Mõtlemise järel tehti otsus, et tegutseme nii. Iga replikal on oma StatefulSet. Sellel lahendusel on mõned puudused, kuid praktikas sisaldab see kõik, mida rakendaja vajab. Ja on palju eeliseid. Saame luua täpselt sellise klastri, nagu soovime, näiteks täiesti heterogeense. Seega klastris, kus on kaks shard'i kummagi replikaga, on meil 2 StatefulSet’i ja 2 Pod’i just seetõttu, et valisime sellise lähenemise, et võimaldada heterogeense klastri ülesehitamist.

Naasume praktilistele ülesannetele. Meie klastris tuleb seadistada kasutajaid, st tuleb teha mingit konfigureerimist ClickHouse'is Kuberneteses. Operaatoreid selleks pakuvad kõik vajalikud võimalused.

Saame otse YAML-is kirjutada, mida me tahame. Kõik konfigureerimise valikud mapitakse otse sellest YAML-ist ClickHouse'i konfigureerimisse, mis siis jaotatakse kogu klastrisse.
Saame ka niimoodi kirjutada. See on näidisena. Parooli saab šifreerida. Kõik ClickHouse'i konfigureerimise valikud on täielikult toetatud. Siin on vaid näidis.
Klastri konfigureerimine laieneb nagu ConfigMap. Praktikas ConfigMap'i uuendamine ei toimu koheselt, seega kui klaster on suur, siis konfigureerimise viimise protsess võtab aega. Kuid see on kõik väga mugav kasutamiseks.

Kompleksitame ülesande. Klaster areneb. Soovime andmeid replikeerida. St meil on juba kaks shard'i, kus kummaski on üks replikatsioon, kasutajad on seadistatud. Meie kasvame ja soovime tegelema replikeerimisega.

Mida me vajame replikeerimiseks?
ZooKeeper on vajalik. ClickHouse'is on replikatsioon üles ehitatud ZooKeeperi abil. ZooKeeper on vajalik, et erinevad ClickHouse'i koopiad saaksid konsensusele, millised andmeplokid on millises ClickHouse'is.
Võid kasutada ükskõik millisest ZooKeeper'i. Kui ettevõttel on väline ZooKeeper, siis seda saab kasutada. Kui ei, siis saame kasutada meie repozitooriumi ZooKeeper'i. Seal on paigaldustööriist, mis lihtsustab kogu seda protsessi.

Ja kogu süsteemi suhtlemine näeb välja selline. Meil on Kubernetes platvormina. Selle peal töötab ClickHouse'i operaator. ZooKeeper on siin kujutatud. Ja operaator suhtleb nii ClickHouse'i kui ka ZooKeeper'iga. See tähendab, et toimub omavaheline suhtlemine.
Ja see on vajalik, et ClickHouse suudaks andmeid k8s-esse tõhusalt replikatsioonida.

Vaatame nüüd ülesannet ja seda, milline näeb välja replikatsiooni manifest.
Lisame meie manifestile kaks sektsiooni. Esimene – kust saada ZooKeeper, mis võib olla nii Kuberneteses sees kui ka väline. See on lihtsalt kirjeldus. Ja tellime koopiad. See tähendab, et soovime kahte koopiat. Seega peaks meil kokku olema 4 pod'i. Storage'i me mäletame, see tuleb hiljem tagasi. Storage on eriline teema.

See oli nii.

Nüüd on see nii. Lisatakse replikaid. Neljas ei mahtunud, usume, et neid võib olla palju. Ja küljele lisatakse ZooKeeper. Skeemid muutuvad keerukamaks.

Nüüd on aeg lisada järgmine ülesanne. Alustame Persistent Storage'i lisamist.
Persistent Storage'i osas on meil erinevad teostusvõimalused.
Kui me töötame pilvepakkujas, näiteks kasutades Amazonit või Google'it, on suur kiusatus kasutada pilve salvestust. See on väga mugav ja hea.
Ja on teine variant. See on lokaalse salvestuse jaoks, kui meil on kohalikud kettad igas sõlmes. See variant on oluliselt keerulisem teostada, kuid samas on see tõhusam.

Vaadakem, mis meil pilves salvestuse osas on.
On eeliseid. Seda on väga lihtne konfigureerida. Me lihtsalt tellime pilvepakkujalt, et anna meile, palun, sellise mahtuvuse ja klassiga salvestus. Klassid on pakkujate poolt iseseisvalt määratud.
Ja on puudus. Mõnele ei ole see kriitiline puudus. Loomulikult on seal mingid jõudlusprobleemid. See on töös väga mugav ja usaldusväärne, kuid on potentsiaalsed jõudluse langevad punktid.

Kuna ClickHouse keskendub tõhususele, võib öelda, et see pigistab välja kõik, mis võimalik, seega püüavad paljud kliendid saada maksimaalset jõudlust.

Selle maksimaalse saavutamiseks vajame local storage'i.
Kubernetes pakub kolme abstraktsiooni local storage'i kasutamiseks. Need on:
- EmptyDir
- HostPath.
- Lokaalne
Vaadake, millised on nende erinevused ja sarnasused.
Esiteks, kõikides kolmes lähenemisviisis on storage – lokaalsed kettad, mis asuvad samal füüsilisel k8s node'il. Kuid neil on mõned erinevused.

Alustame kõige lihtsamast, st emptyDir-st. Mis see praktikas tähendab? Me palume oma spetsifikatsioonis konteinerite süsteemil (enamasti on see Docker) anda meile juurdepääs kaustale lokaalsel kettal.
Tavaselt loob Docker kusagil oma teedel ajutise kausta, nimetab selle pikaks hash'iks ja pakub pääsumehhanismi sellele.
Kuidas see jõudluses töötab? See töötab lokaalse ketta kiirusel, st see on täies ulatuses juurdepääs oma draivile.
Kuid sellel meetodil on oma puudus. Persistent on selles osas piisavalt kahtlane. Vahetult Dockeriga konteinerite liikumisel kaob Persistent ära. Kui Kubernetes mingil põhjusel soovib selle Pod'i teisaldada teisele kettale, siis andmed kaovad.
Selline lähenemine sobib hästi katsetamiseks, kuna see näitab normaalset kiirusnat, kuid tõsiste ülesannete jaoks ei sobi see variant.

Seetõttu on olemas teine lähenemine. See on hostPath. Kui vaadata eelmist slaidi ja seda, siis võib näha ainult ühte erinevust. Meie kaust on välja viidud Dockerist otse Kubernetes'i sõlme. Siin on natuke lihtsam. Me määrame otse kohaliku failisüsteemi tee, kus soovime andmeid hoida.
Selle meetodi eelised on olemas. See on juba tõeline Persistent, ja traditsiooniline. Meie kettale salvestatakse andmed kindlasse aadressi.
Kuna ka puudusi. Üks neist on haldamise keerukus. Meie Kubernetes võib soovida liigutada Pod'i teisele füüsilisele sõlmele. Siin tuleb mängu DevOps, kes peab õigesti seletama kogu süsteemile, et neid pod'e tohib liigutada ainult sellistele sõlmedele, kus sul on nende teede kaudu midagi ühendatud, ja mitte rohkem kui ühte sõlme korraga. See on piisavalt keeruline.
Just nende eesmärkide tarbeks oleme meie operaatoris loonud mallid, et kogu see keerukus peita. Nii saab lihtsalt öelda: „Ma tahan, et mul oleks iga füüsilise sõlme kohta üks ClickHouse'i instance ja sellisel teel.”

Kuid see vajadus on vajalik mitte ainult meile, mistõttu Kubernetes'i härrased mõistavad ka, et inimestele meeldib juurdepääs füüsilistele kettale, ja pakuvad seetõttu kolmandat taset.
See nimetatakse local. Erinevused eelmisest slaidist on praktiliselt olematud. Ainult et varem pidime käsitsi vasestama, et me ei saa neid pod’e ühest sõlmedest teise viia, sest nad peavad olema seotud sellise tee kaudu kohaliku füüsilise kettaga. Nüüd on kogu see teadmine kapseldatud Kubernetesesse. See muudab konfigureerimise palju lihtsamaks.

Naaseme taas meie praktilise ülesande juurde. Naaseme YAML mallide juurde. Siin on meil tõeline storage. Oleme tagasi selle juurde. Määrame klassikalise VolumeClaim malli nagu k8s-is. Ja kirjeldame, millist storage'i soovime.
Pärast seda küsib k8s storage'i. Eraldab sellele meie StatefulSetis. Ja lõpuks saab see ClickHouse'i käsutusse.

Meil oli selline skeem. Meie Persistent Storage oli punane, mis vihjas, et see tuleks teha.

Ja see muutub roheliseks. Nüüd on ClickHouse'i klastrite skeem k8s-is täielikult lõpule viidud. Meil on shard'id, koopiad, ZooKeeper, on olemas tõeline Persistent, mis on ellu viidud eri viisidel. Skeem on juba täielikult töötav.

Me elame edasi. Meie klaster areneb. Ja Aleksei pingutab, et välja anda uus versioon ClickHouse'ist.
Tõuseb praktiline ülesanne – testida uue ClickHouse'i versiooni meie klastris. Loomulikult ei taha me seda kogu aeg uuendada, vaid soovime uue versiooni kuskil kauges nurgas ühte replit panna, võib-olla isegi mitte ühte uut versiooni, vaid kohe kahte, sest need väljuvad üsna tihti.
Mida me selle kohta öelda saame?

Siinkohal on meil just selline võimalus. Need on pod'i mallid. Saame välja kirjutada, meie operaator võimaldab täielikult ehitada heterogeense klastrite. See tähendab, et me saame konfigureerida alates kõigist replitest hunnikus, lõpetades igasuguste isiklike replititega selle kohta, millist versiooni me soovime ClickHouse'ist ja millist versiooni me soovime salvestamisest. Me saame täielikult konfigureerida klastrit selliseks konfiguratsiooniks, nagu me soovime.

Natuke süveneme juba sügavamale. Varem rääkisime sellest, kuidas ClickHouse-operator töötab ClickHouse'i spetsiifika suhtes.
Nüüd tahaksin öelda paar sõna selle kohta, kuidas toimib igasugune operaator, samuti sellest, kuidas see suhtleb K8s-iga.

Vaadakem alustuseks suhet K8s-iga. Mis juhtub, kui teeme kubectl apply? Meie objektid ilmuvad läbi API etcd-sse.

Näiteks Kubernetes'i baikeskonnad: pod, StatefulSet, teenus ja nii edasi.
Samuti ei juhtu veel midagi füüsilist. Need objektid tuleb klastrisse materialiseerida.

Selleks tuleb kontrollija. Kontrollija on eriline komponent k8s, mis oskab neid kirjelduse alusel materialiseerida. Ta teab, kuidas ja mida teha füüsiliselt. Ta teab, kuidas konteinerid käivitada, mida on vajalik serveri töölepanekuks seadistada.

Ja ta materialiseerib meie objektid K8s.
Kuid me ei soovi opereerida vaid pod'ide ja StatefulSet'idega, me tahame luua ClickHouseInstallation, st ClickHouse tüüpi objekti, et hallata seda kui ühtset tervikut. Praegu sellist võimalust ei ole.

Kuid K8s-l on järgmine meeldiv asi. Me soovime, et meil oleks kuskil selline keeruline entiteet, mis koosneks pod'idest ja StatefulSet'ist meie klastrist.

Ja mida selleks teha? Esiteks, astub lavale Custom Resource Definition. Mis see on? See on K8s jaoks kirjeldus, et sul on veel üks andmetüüp, et me soovime pod'ile, StatefulSet'ile lisada kohandatud ressurssi, mis oleks keeruline sees. See on andmestruktuuri kirjeldus.

Me saadame selle ka kubectl apply kaudu sinna. Kubernetes on selle rõõmuga vastu võtnud.
Ja nüüd on meil salvestuses, objekti etcd juures võimalus registreerida kohandatud ressurssi nimega ClickHouseInstallation.
Aga praegu ei juhtu midagi enamat. See tähendab, et kui me praegu loome YAML-faili, mida oleme vaadanud shardide, replikate kirjeldamiseks ja ütleme 'kubectl apply', siis Kubernetes võtab selle vastu, paneb etcd-sse ja ütleb: 'Suurepärane, aga mida sellega teha, ma ei tea. Kuidas ClickHouseInstallation teenindada, ma ei tea.'

Seega on meil vaja kedagi, kes aitab Kubernetesel uue andmetüübi teenindamisel. Vasakul on meil Raudtee Kubernetesi kontroller, mis töötab standardsete andmetüüpidega. Paremal peab ilmuma kohandatud kontroller, mis oskab töötada kohandatud andmetüüpidega.
Ja teistmoodi nimetatakse seda operaatoriks. Olen selle siin spetsiaalselt välja tõstnud, sest see võib töötada ka väljaspool K8s. Enamasti töötavad kõik operaatorid muidugi Kuberneteses, aga miski ei takista tal seista väljas, seetõttu on see siin spetsiaalselt välja tõstetud.

Ja seejärel suhtleb kohandatud kontroller, samuti operaator, Kubernetesega API kaudu. Ta oskab juba suhelda APIga. Ja ta teab, kuidas kohandatud ressursist materialiseerida keeruline skeem, mida soovime luua. Selle tegevusega operaator tegelebki.

Kuidas operaator töötab? Vaatame paremale poole, et teada saada, kuidas ta seda teeb. Saame teada, kuidas operaator kõik selle materialiseerib ja kuidas toimub edasine suhtlemine K8s-iga.

Operaator on programm. See on sündmustele orienteeritud. Operaator registreerib end Kubernetes API kaudu sündmuste osas. Kubernetes API-s on sissepääsupunktid, kuhu saab registreeruda sündmuste jaoks. Ja kui K8s-is midagi muutub, siis saadab Kubernetes sündmused igale soovijale, st see, kes on selle API punkti tellinud, saab teateid.
Operaator registreerib end sündmuste osas ja peab tegema mingi reageeringu. Tema ülesanne on reageerida tekkivatele sündmustele.

Sündmused genereeritakse teatud uuenduste kaudu. Meie YAML-fail koos ClickHouseInstallationi kirjeldusega saadetakse kubectl apply kaudu etcd-sse. Seal toimub sündmus, mis jõuab ClickHouse-i operaatorini. Operaator saab selle kirjelduse kätte ja tema ülesanne on midagi teha. Kui ClickHouseInstallationi objektile on tulnud uuendus, tuleb klastrit uuendada. Operaatori ülesanne on klastrit uuendada.

Mida ta teeb? Esiteks peab ta koostama tegevusplaani, mida me selle uuendusega teeme. Uuendused võivad olla väga väikesed, st YAML-implementatsioonis väikesed, kuid need võivad kutsuda esile suurde klastrisse suuri muudatusi. Seetõttu koostab operaator plaani ja järgib seda edasi.

Ta hakkab vastavalt sellele plaanile vajalikku struktuuri loobuma, et materialiseerida pod'e, teenuseid, st teha seda, mis on tema peamine ülesanne. See on nagu ClickHouse klastrite ehitamine Kuberneteses.

Nüüd puudutame sellist huvitavat teemat. See on vastutuse jagamine Kubernetes'i ja operaatori vahel, st mida teeb Kubernetes, mida teeb operaator ja kuidas nad omavahel suhtlevad.
Kubernetes vastutab süsteemsete asjade eest, st põhikomplekti objektide eest, mida saab tõlgendada süsteemi ulatusena. Kubernetes teab, kuidas käivitada pod'e, kuidas konteinerit restartida, kuidas mountida mahtusid, kuidas töötada ConfigMap'iga — kõik, mida võib nimetada süsteemiks.
Operaatorid töötavad valdkondades. Iga operaator on loodud oma valdkonna jaoks. Me valmistasime selle ClickHouse'i jaoks.
Ja operaator suhtleb just sellistes valdkonna mõistetes nagu uue repliibi lisamine, skeemi loomine, jälgimise seadistamine. Tekib selline jaotus.

Vaatame praktilise näite kaudu, kuidas see vastutuse jaotus toimub, kui teeme tegevuse, et lisada repliik.
Operaator saab ülesande — lisada repliik. Mida operaator teeb? Operaator arvutab välja, et on vaja teha uus StatefulSet, kus tuleb kirjeldada teatud mallid, mahtude nõudmine.

Ta valmistab selle kõik ette ja edastab edasi K8s. Ütleb, et tal on vaja ConfigMap'i, StatefulSet'i ja mahtu. Kubernetes töötab välja. Ta materialiseerib põhielemendid, millega ta opereerib.

Ja jätkab ClickHouse-operator, kellel on juba füüsiline pod, millega midagi teha. ClickHouse-operator töötab taas domeeni mõistetega. See tähendab, et ClickHouse'i puhul tuleb repliika klastrisse lisamiseks kõigepealt seadistada andmeskeem, mis on selles klastris olemas. Teiseks tuleb see repliika integreerida jälgimise, et see oleks hästi jälgitav. Selle seadistab juba operaator.

Ja alles siis astub mängu ClickHouse, st veel üks kõrgem taseme element. See on juba andmebaas, millel on oma instants, uus konfigureeritud repliika, mis on valmis klastrisse astuma.
Tekib piisavalt pikk tegevuste ahela ja vastutuse jaotuse skeem repliika lisamisel.

Jätkame oma praktiliste ülesannetega. Kui klaster on juba olemas, saab teostada konfiguratsiooni migreerimist.

Oleme teinud nii, et olemasolevasse xml-i, mida ClickHouse mõistab, saab andmeid suunata otse.

ClickHouse'i võib täiendavalt häälestada. Zonaalne kaasamine on just see, millest rääkisin selgitades hostPathi ja lokaalset salvestust. See on õige viis zonaalse kaasamise tegemiseks.

Järgmine praktiline ülesanne on jälgimine.

Kui meie klaster muutub, tuleb jälgimist aeg-ajalt seadistada.
Vaadakem skeemi. Oleme juba käsitlenud rohelisi nooli. Nüüd uurime punaseid nooli. See on see, kuidas me tahame oma klastrit jälgida. Kuidas ClickHouse' klastrist pärit mõõdikud lähevad Prometheusesse ja seejärel Grafanasse.

Kus on tõrge jälgimises? Miks see tuuakse esile kui mingi saavutus? Probleem seisneb dünaamikas. Kui meil on üks klaster ja see on staatiline, saab jälgimise seadistada üks kord ja rohkem ei pea muretsema.
Aga kui meil on palju klasse või pidevalt midagi muutub, on protsess dünaamiline. Ja pidev jälgimise seadistamine on ressursi ja aja raiskamine, see on lihtsalt laiskus. See tuleb automatiseerida. Probleem on protsessi dünaamikas. Ja operaator automatiseerib seda väga hästi.

Kuidas meie klaster arenes? Alguses oli see selline.

Siis oli see selline.

Lõpuks sai see selliseks.
Ja jälgimist tehakse operaatori poolt automaatselt. Üksne sisenemiskoht.

Ja jälgime ainult Grafana juhtpaneelil, kuidas meie klastri elu sees toimub.
Muide, Grafana juhtpaneel levib samuti meie operaatoriga otse allikakoodis. Seda saab ühendada ja kasutada. Selle ekraanipildi andsid mulle meie DevOps.

Kuhu tahaksime edasi liikuda? Need on:
- Arendada testimise automatiseerimist. Peamine ülesanne on uute versioonide automatiseeritud testimine.
- Samuti soovime tugevalt automatiseerida integreerimist ZooKeeperiga. Plaanis on integreeruda ZooKeeper-operatoriga. St. ZooKeeperi jaoks on kirjutatud operaator ja oleks loogiline, et kaks operaatorit hakkaksid integreeruma mugavama lahenduse loomiseks.
- Tahame teha keerulisemaid töökindluse kontrolle.
- Rohelisega märkisin, et meil on tulemas mallide pärimise funktsioon – VALMIS, st järgmise operaatori versiooniga on meil juba mallide pärimine. See on võimas tööriist, mis võimaldab koostada keerulisi konfiguratsioone tükkidest.
- Ja tahame keeruliste ülesannete automatiseerimist. Peamine neist on Re-sharding.

Teeme vahekokkuvõtte.

Mida me lõpuks saame? Kas peaksime sellega tegelema või mitte? Kas on üldse mõtet viia andmebaas Kubernetesesse ja rakendada operaatorit laiemalt ning Alitnity operaatorit konkreetselt?
Lõpuks saame:
- Oluliselt lihtsustatud ja automatiseeritud seadistamise, juurutamise ja hooldamise.
- Koheselt sisse ehitatud jälgimine.
- Ja valmis kasutamiseks kooditud mallid keeruliste olukordade jaoks. Näiteks pole enam vaja käsitsi lisada koopiat. Selle teeb operaator.

Jäänud on vaid viimane küsimus. Meil on juba andmebaas Kuberneteses, virtualiseerimine. Kuidas on sellise lahenduse jõudlust, eriti arvestades seda, et ClickHouse on optimeeritud jõudluse jaoks?
Vastus – kõik on korras! Ma ei hakka detailidesse laskuma, see on eraldi ettekande teema.

Aga on selline projekt nagu TSBS. Mis on selle peamine eesmärk? Andmebaaside jõudluse testimine. See on katse võrrelda sooja sooja, pehmet pehme.
Kuidas see töötab? Generatakse üks andmekogum. Siis käib see andmekogum erinevatel andmebaasidel sama testkomplekti peal. Iga andmebaas lahendab ülesande nii, nagu oskab. Ja siis saab tulemusi võrrelda.
See toetab juba suurt hulka andmebaase. Olen välja toonud kolm peamist. Need on:
- TimescaleDB.
- InfluxDB.
- ClickHouse.

Samuti on tehtud võrdlus teise sarnase lahendusega. Võrdlus RedShiftiga. See tehti Amazonis. ClickHouse ületab ka selles osas kõik teised.

Milliseid järeldusi saab teha selle põhjal, mida ma rääkisin?
- Andmebaasid Kuberneteses on võimalikud. Tõenäoliselt saab igasuguseid, aga üldiselt tundub, et see on võimalik. ClickHouse Kuberneteses on kindlasti võimalik meie operaatori abiga.
- Operaator aitab automatiseerida protsesse ja lihtsustab tõeliselt elu.
- Toimevõime on normaalne.
- Ja me arvame, et seda saab ja tuleb kasutada.
Avatud lähtekood – liituge!
Nagu ma juba ütlesin, on operaator täielikult avatud lähtekoodiga toode, seega oleks väga hea, kui võimalikult palju inimesi seda kasutaks. Liituge! Ootame teid kõiki!
Aitäh kõigile!
Küsimused

Aitäh esitlust! Mina olen Anton. Ma olen ettevõttest SEMrush. Mind huvitab, mis logimisega toimub. Jutt on kuulda jälgimisest, aga logimisest ei ole midagi, kui rääkida klastrist tervikuna. Näiteks meil on üles seatud klaster riistvaral. Ja me kasutame tsentraliseeritud logimist, standardsete vahenditega kogume kõik koos. Ja siis sealt võtame välja huvitavad andmed.
Hea küsimus, st logimine on todo nimekirjas. Meie operaator ei automatiseeri seda veel. Ta veel areneb, projekt on ikka veel piisavalt noor. Me mõistame logimise vajadust. See on samuti väga oluline teema. Ja see pole tõenäoliselt vähem oluline kui jälgimine. Kuid esimene teema elluviimiseks oli jälgimine. Logimine tuleb. Me püüame loomulikult automatiseerida kõik klastriga seotud tegevused. Seetõttu on vastus - hetkel operaator, kahjuks, ei oska seda veel teha, kuid see on plaanis ja me teeme seda. Kui on soov liituda, siis palun tee pull request.
Tere! Aitäh ettekande eest! Mul on tavaline küsimus, mis on seotud Persistent Volumes'iga. Kui me loome selle operaatori kaudu konfigureerimise, kuidas operaator määrab, millisel node'il on meil mõni ketas või kaust primountitud? Kas me peame talle eelnevalt selgitama, et palun paigalda meie ClickHouse just nendele node'idele, kus on ketas?
Nii palju, kui ma aru saan, on see küsimus kohaliku salvestuse jätk, eriti selle osa kohta hostPath. See on nagu kogu süsteemile selgitamine, et pod peab töötama just kindlal node'il, kus meil on füüsiliselt ühendatud ketas, mis on mountitud teatud teele. See on terve sektsioon, mida ma katsusin väga pinnapealselt, sest vastus on piisavalt ulatuslik.
Lühidalt öeldes näeb see välja järgmiselt. Loomulikult peame nende mahtude provisionimise ära tegema. Hetkel puudub kohaliku salvestuse dünaamiline provisionimine, seega peavad DevOps ise kettad lõikama, need mahud. Samuti peavad nad Kubernetes'ile selgitama, et sul on teatud klassi Persistent volumes, mis asuvad teatud sõlmedes. Seejärel tuleb Kubernetes'ile selgitada, et pod'id, mis nõuavad sellist klassi kohaliku salvestuse, tuleb labelite järgi graafikule võtta ainult teatud sõlmedes. Selleks on operaatoris võimalus määrata teatud label ja one per host instance. Nii et pod'id marsrutiseeritakse Kubernetes'i poolt käivitamiseks ainult nendel sõlmedel, mis vastavad nõuetele, lihtsustades seda öeldes. Süsteemiadministraatorid määravad labelid ja teevad kettaste provisionimise käsitsi. Siis saab süsteem skaleeruda.
Ja just kolmas variant kohaliku salvestuse abil aitab seda veidi lihtsustada. Nagu ma juba rõhutasin, on see põhjalik seadistustöö, mis aitab saavutada maksimaalset jõudlust.
Mul on selle teemaga seoses teine küsimus. Kubernetes on mõeldud nii, et me ei pea muretsema, kas me kaotame sõlme või mitte. Mida me peaksime tegema, kui me kaotasime sõlme, kus on meie shard?
Jah, Kubernetes on algselt positsioneeritud nii, et meie suhted meie pod‘idega on nagu kariloomadega, aga nüüd on iga ketas midagi nagu lemmikloom. On probleem, et me ei saa neid lihtsalt ära visata. Kubernetes'e areng viib selleni, et ei ole võimalik täielikult suhtuda sellesse filosoofiliselt nagu täielikult ära visatavate ressurssidena.
Nüüd praktiline küsimus. Mida teha, kui sul on kaduma läinud sõlm, kus ketas oli? Siin lahendatakse probleem kõrgemal tasemel. ClickHouse'i puhul on meil replikad, mis töötavad kõrgemal tasemel, st ClickHouse tasemel.
Milline on olukord? Andmete kadumise eest vastutab DevOps. Ta peab korralikult seadistama replikatsiooni ja jälgima, et replikatsioon toimiks. ClickHouse tasemel peavad andmed olema replikas dubleeritud. See ei ole ülesanne, mida lahendab operaator. Ja see ei ole ülesanne, mida lahendab Kubernetes. See on ClickHouse tasemel.
Mis teha, kui teie serveri nodi kukkus? Tundub, et peate seadma teise, õigesti paigaldama kettad ja märkima sildid. Pärast seda peab see vastama nõuetele, et Kubernetes saab sellel käivitada pod'i koopia. Kubernetes käivitab selle. Teil on ju pod'ide arv allapoole seatud. See läbib tsüklit, mida ma näitasin. Ja kõige kõrgemal tasemel mõistab ClickHouse, et meil on sisse tulnud replikatsioon, see on veel tühi ja sellele tuleb hakata andmeid üle kandma. See protsess on veel halvasti automatiseeritud.
Aitäh ettekande eest! Kui midagi hullu juhtub, langeb operaator ja ta taaskäivitub, samal ajal kui toimub sündmuste vastuvõtt, kas te töödeldes seda kuidagi teete?
Mis juhtub, kui operaator kukkus ja ta taaskäivitub, eks?
Jah. Ja sel hetkel toimusid sündmused.
Ülesanne, mida selles olukorras teha, jaguneb osaliselt operaatori ja Kubernetes'i vahel. Kubernetes'il on võimalus juhtunud sündmust uuesti taasesitada. Ta taasesitab selle. Operaatori ülesanne on aga tagada, et kui sündmuste logi taasesitatakse, oleksid need sündmused idempotentsed. Ja et sama sündmuse korduv esinemine ei rikuks meie süsteemi. Meie operaator suudab sellega toime tulla.
Tere! Aitäh ettekande eest! Dmitri Zavyalov, ettevõte Smedova. Kas plaanitakse operaatorisse lisada võimalust seadistada haproxy? Olen huvitatud millestki muust koormustasakaalustajast peale standardse, mis oleks nutikas ja mõistaks, mis seal tegelikult ClickHouse'is toimub.
Kas te räägite Ingress'ist?
Jah, asendame Ingress'i haproxy'ga. Haproxy's saab määrata klooster topoloogia, kus tal on replikad.
Praegu ei ole me selle peale mõelnud. Kui see on teile vajalik ja oskate selgitada, miks see vajalik on, siis on võimalik see ellu viia, eriti kui soovite osaleda. Me hindame hea meelega seda varianti. Lühike vastus – ei, meil ei ole sellist funktsionaalsust hetkel. Aitäh vihje eest, vaatame selle asja üle. Ja kui saaksid veel selgitada kasutusjuhtu ja miks see praktikas vajalik on, näiteks luua GitHubis teemasid, siis oleks see suurepärane.
Juba olemas.
Hea. Oleme avatud igasugustele ettepanekutele. Ja haproxy antakse to-do nimekirja. To-do nimekiri kasvab, mitte ei vähene praegu. Aga see on hea, see tähendab, et toode on nõudlik.
Allikas: habr.com
