
Ettekanne käsitleb praktilisi küsimusi operaatori arendamisest Kubernetes'is, tema arhitektuuri projekteerimisest ja põhifunktsioonide toimimisest.
Ettekanne jaguneb järgmisteks osadeks:
- mis on operaator Kubernetes'is ja milleks see on vajalik;
- kuidas operaator lihtsustab keerukate süsteemide haldamist;
- mida operaator suudab ja mida ta ei suuda.
Järgmisena arutame operaatori sisemist ülesehitust. Vaatame operaatori arhitektuuri ja toimimist samm-sammult. Üksikasjalikult käsitleme:
- koostööd operaatori ja Kubernetes'i vahel;
- milliseid funktsioone operaator enda peale võtab, ning mida ta Kubernetes'ile delegeerib.
Räägime shardide ja andmebaasi koopiate haldamisest Kubernetes'is.
Seejärel arutame andmete salvestamise küsimusi:
- kuidas operaatoriga Persistent Storage'iga töötada;
- kohalikule salvestusele kehtivad probleemid.
Ettekanne lõpus käsitleme praktilisi näiteid rakendustest Amazonist või Google Cloud Services't. Ettekanne põhineb ClickHouse'i operaatori arendamise ja kasutamise kogemustel.
Video:

Minu nimi on Vladislav Klimenko. Soovisin täna rääkida meie kogemusest operaatori arendamisel ja kasutamisel, kusjuures see on spetsialiseeritud operaator andmebaasi klastrite haldamiseks. Näiteks ClickHouse'i klasstri haldamiseks.

Miks me saame rääkida operaatorist ja ClickHouse'ist?
- Tegeleme ClickHouse'i toe ja arendamisega.
- Praegusel hetkel püüame aeglaselt anda oma panuse ClickHouse'i arendamisse. Oleme teised, kes on teinud muudatusi ClickHouse'is pärast Yandexit.
- Püüame luua täiendavaid projekte ClickHouse'i ökosüsteemi jaoks.
Ühest sellisest projektist sooviksin rääkida. See on ClickHouse'i operaator Kubernetes'i jaoks.
Oma ettekandes tahaksin käsitleda kahte teemat:
- Esimene teema – kuidas meie operaator ClickHouse'i andmebaaside haldamisel Kubernetes'is töötab.
- Teine teema – kuidas toimib iga operaator, st kuidas see suhtleb Kubernetes'iga.
Need kaks küsimust kattuvad kogu minu ettekande vältel.

Kellele võiks huvi pakkuda see, millest ma tahan rääkida?
- Eriti huvitav on see neile, kes haldavad operaatoreid.
- Või neile, kes soovivad luua oma operaatorit, et mõista, kuidas see toimib seestpoolt, kuidas operaator suhelda Kubernetese ja millised probleemid võivad tekkida.

Kuna paremini mõista, millest me täna räägime, oleks hea teada, kuidas Kubernetes töötab ja omada alusvalmidust pilvetehnoloogiate osas.

Mis on ClickHouse? See on veergudega andmebaas, millel on spetsiifika analüütiliste päringute online-töötlemiseks. Ja see on täiesti avatud lähtekoodiga.
Ja me peame teadma ainult kahte asja. Peame teadma, et see on andmebaas, seega, mida ma räägin, on kohaldatav praktiliselt igale andmebaasile. Ja et andmebaasihaldussüsteem ClickHouse skaleerub väga hästi, pakkudes praktiliselt lineaarset skaleeritavust. Seetõttu on klastriseisund ClickHouse jaoks loomulik. Ja me tahame arutada, kuidas ClickHouse'i klastrit Kuberneteses hallata.

Miks on see seal vajalik? Miks ei saa me seda iseseisvalt jätkata? Ja vastused on osaliselt tehnilised ja osaliselt organisatsioonilised.
- Praktikas puutume üha enam kokku olukordadega, kus suurtes ettevõtetes on peaaegu kõik komponendid juba Kuberneteses. Andmebaasid jäävad väljapoole.
- Ja üha rohkem küsitakse: "Kas on võimalik see sisse viia?" Seetõttu püüdlevad suured ettevõtted maksimaalse haldamise ühtsuse poole, et kiiresti hallata oma andmesalvestusi.
- See aitab eriti, kui on vajalik maksimaalne kordamine uues kohas, s.t. maksimaalne ülekantavus.

Kui lihtne või keeruline see on? Loomulikult saab seda teha käsitsi. Kuid see ei ole nii lihtne, kuna meil on keerukus Kubernetesega haldamises, millele lisandub ClickHouse'i spetsiifika. Nii tekib kogum.
Ja kõik koos annab piisavalt suure tehnoloogiate kogumi, mille haldamine muutub üsna keeruliseks, kuna Kubernetes toob igapäevaseid probleem küsimusi käitamiseks ning ClickHouse tõstatab igapäevase tööga seotud probleeme. Eriti kui meil on mitu ClickHouse'i, ja me peame pidevalt nendega midagi tegema.

ClickHouse'il on dünaamilise konfiguratsiooniga piisavalt palju küsimusi, mis tekitavad pidevat koormust DevOpsile:
- Kui soovime ClickHouse'is midagi muuta, näiteks lisada koopiat või shard'i, peame tegelema konfiguratsiooni haldamisega.
- Siis tuleks andmemudel vahetada, sest ClickHouse'il on spetsiifiline sharding'i viis. Seal tuleb andmemudelit paigutada ja konfiguratsioone seadistada.
- On vajalik seadistada jälgimine.
- Logide kogumine uute shardide ja uute replikate jaoks.
- On muretes taastumise pärast.
- Ja taaskäivitamise.
Need on rutiinsed tööd, mida oleks väga soovitav lihtsustada.

Kubernetes aitab tõhusalt korraldada, kuid põhitehniliste asjade puhul.
Kubernetes lihtsustab ja automatiseerib selliseid asju nagu:
- Taastumine.
- Taaskäivitamine.
- Süsteemi salvestuse haldamine.
See on hea, see on õige suund, kuid tal ei ole täielikku arusaama, kuidas andmebaasi klastrit hallata.
Soovime rohkem, tahame, et kogu andmebaas töötaks Kuberneteses.

Soovime saada midagi nagu suur maagiline punane nupp, millele vajutada ja mille abil luuakse ja hallatakse klastrit kogu elu tsükli jooksul, lahendades igapäevaseid ülesandeid. ClickHouse klaster Kuberneteses.
Ja me püüdsime luua lahenduse, mis aitaks tööd lihtsustada. See on ClickHouse-operator Kuberneteses ettevõttelt Altinity.

Operator on programm, mille põhiülesanne on hallata teisi programme, st see on haldur.
Ja see sisaldab käitumismalle. Seda võib nimetada kodeeritud teadmusteks teema valdkonnas.
Ja selle peamine eesmärk on lihtsustada DevOpsi elu ning vähendada mikromanageerimist, et ta (DevOps) mõtleks kõrgema taseme mõisted, st et ta (DevOps) ei tegeleks mikromanageerimisega ega seadistaks kõiki detaile käsitsi.
Ja just operator on robotassistend, kes tegeleb mikrotegevustega ja aitab DevOps'i.

Miks on vajalik operator? Ta näitab end eriti hästi kahe küsimuse puhul:
- Kui ClickHouse'i spetsialistil pole piisavalt kogemusi, kuid ClickHouse'i kasutamine on siiski vajalik, lihtsustab operator haldamist ja võimaldab hallata ClickHouse'i klastrit piisavalt keerulise konfiguratsiooniga, samas põhjalikesse detailidesse mitte süvenedes. Lihtsalt antakse talle kõrgetasemelised ülesanded ja see töötab.
- Ja teine ülesanne, kus ta kõige paremini esitleb, on see, kui on vaja automatiseerida suurt hulka tüüpilisi ülesandeid. Eemaldab mikroulesanded süsteemiadminnide käest.

See on kõige vajalikum kas neile, kes just alustavad oma teed, või neile, kellel on palju automatiseerimisega tegeleda.

Mis on siis lähenemise erinevus, mis põhineb operaatoritel, teiste süsteemide puhul? On ju olemas Helm. See aitab samuti installida ClickHouse'i, saab joonistada helm charts, mis isegi paigaldavad terve ClickHouse'i klastrite. Mis siis on erinevus operaatori ja näiteks Helmi vahel?
Peamine fundamentaalne erinevus on see, et Helm on paketihaldus, samas kui operaator läheb kaugemale. See hõlmab kogu elutsükli. See ei ole ainult paigaldamine, need on igapäevased ülesanded, mis sisaldavad skaleerimist, shardeerimist, st kõike, mida tuleb elutsükli jooksul teha (kui vajalik, siis ka eemaldamine) – kõik selle lahendab operaator. Ta püüdleb automatiseerimiseks ja kogu tarkvara elutsükli teenindamiseks. See on tema fundamentaalne erinevus teiste esitatud lahenduste seas.

See oli sissejuhatav osa, liikuge edasi.
Kuidas me oma operaatorit ehitame? Püüame läheneda küsimusele, et hallata ClickHouse'i klastrit kui üht ressurssi.
Siin on meie pildi vasakus osas sisenemisandmed. See on YAML klastrite spetsifikatsioon, mis klassikaliselt edastatakse läbi kubectl Kubernetesesse. Seal operaator haarab selle, teeb oma maagia. Ja väljundina saame sellise skeemi. See on ClickHouse'i rakendamine Kuberneteses.
Ja edaspidi vaatame aeglaselt, kuidas operaator täpselt töötab, milliseid tüüpilisi ülesandeid saab lahendada. Vaatame ainult tüüpilisi ülesandeid, sest meil on piiratud aeg. Ja räägitakse mitte kõigest, mida operaator võib lahendada.

Lähme praktikast lähtudes. Meie projekt on täielikult avatud lähtekoodiga, seega saab vaadata GitHub'is, kuidas see töötab. Ja arominekuga on soovitatav alustada Quick Start Guide'iga.
Kui soovite põhjalikult süveneda, siis püüame hoida dokumentatsiooni enam-vähem korralikus seisundis.

Alustame praktilise ülesandega. Esimene asi, millega me kõik alustada tahame, on käivitada esimene näide kuidagi. Kuidas käivitada ClickHouse'i operaatorit, isegi teadmata, kuidas see töötab? Kirjutame manifesti, kuna kogu suhtlus k8s-iga toimub manifestide kaudu.

Siin on selline keeruline manifest. Punasega välja toodud on see, millele tuleb tähelepanu pöörata. Palume operaatoril luua klastrit nimega demo.
Praegu on need põhinäited. Storage'i pole veel kirjeldatud, kuid me tuleme storage'i juurde hiljem tagasi. Praegu vaatame klastrite arengut dünaamikas.
Oleme selle manifesti loonud. Anname selle meie operaatorile. Tema töötas, tegi oma maagia.

Vaadake konsooli. Kolm komponenti äratavad huvi – need on Pod, kaks teenust ja StatefulSet.
Operaator töötas ja me saame vaadata, mida ta täpselt lõi.

Ta loob ligikaudu sellise skeemi. Meil on StatefulSet, Pod, ConfigMap iga koopiana, ConfigMap kogu klastrile. Teenused peab olema sissepääsu punktid klastrisse.
Teenused – see on keskne Load Balancer Service ja võib olla ka iga koopia jaoks, iga shardi jaoks.
Siin on meie põhikluster, mis välja näeb umbes selliselt. See koosneb ühest ainsast sõlmest.

Liigume edasi, keerame asja keerulisemaks. Klastrit tuleb shardida.

Meie ülesanded kasvavad, algab dünaamika. Tahame lisada shardi. Jälgime arengut. Muudame oma spetsifikatsiooni. Näitame, et soovime kahte shardi.
See on sama fail, mis areneb dünaamiliselt koos süsteemi kasvuga. Storage'i pole, storage'i käsitletakse hiljem, see on eraldi teema.
Anname YAML operaatorile ja vaatame, mis saadakse.

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

Skeem nägi välja nõnda – see on meie algne seis, kui meil oli üks pod.

Nüüd näeb see välja nõnda. Seni on kõik lihtne, see on dubleeritud.

Ja miks StatefulSet'ide arv kasvas kahele? Siin tuleb kõrvale tõmmata ja arutada, kuidas Kuberneteses toimub Pod'ide haldamine.
On selline objekt nagu StatefulSet, mis võimaldab luua Pod'ide komplekti mallist. Siin on võtmetegur Template. Ja ühes StatefulSet'is saab palju Pod'e käivitada ühtede mallide alusel. Ja võtmefraas siin on „ühtede mallide alusel palju Pod'e“.
Ja oli suur kiusatus teha kogu klaster, pakkides kõik ühte StatefulSet'i. See töötab, selles pole mingeid probleeme. Kuid on üks nüanss. Kui soovime luua heterogeense klastri, st mitmest ClickHouse'i versioonist, siis siin tekivad meil küsimused. Jah, StatefulSet võib teha rolling update'i, jah, seal saab uut versiooni rakendada, selgitades, et korraga ei tohiks proovida rohkem kui niivõrd palju noode.
Aga kui extrapoleerida ülesanne ja öelda, et soovime luua täielikult heterogeense klastri ning soovime mitte vanat versioonist uut rakendada rolling update'i abil, vaid soovime lihtsalt luua heterogeense klastri, mis koosneb erinevatest ClickHouse'i versioonidest ja erinevast salvestamisest. Näiteks, tahame teha mõned replikad eraldi ketastele, aeglastele, üldiselt, soovime täielikult üles ehitada heterogeense klastri. Ja kuna StatefulSet teeb ühest šabloonist standardiseeritud lahenduse, siis pole seda võimalik teha.
Pärast mõningast kaalumist otsustasime, et teeme nii. Iga replik on oma StatefulSet'is. Sellel lahendusel on mõned puudused, kuid praktikas kapseldab see kõik täielikult operaator. Ja see toob kaasa palju eeliseid. Saame ehitada täielikult sellise klastri, nagu soovime, näiteks täiesti heterogeense. Seega, klastris, kus meil on kaks shardi ühe replikaga, on meil 2 StatefulSet'i ja 2 Pod'i just sellepärast, et oleme valinud sellise lähenemise eespool nimetatud põhjustel, et luua heterogeenne klaster.

Naaseme praktiliste ülesannete juurde. Meie klastris tuleb seadistada kasutajad, st tuleb teha mingit konfiguratsiooni ClickHouse'is Kuberneteses. Operaator pakub selleks kõik võimalused.

Saame otse YAML-s kirjutada, mida soovime. Kõik konfiguratsiooni valikud kaardistuvad otse sellest YAML-ist ClickHouse'i seadistustesse, mis siis jagatakse üle kogu klastris.
Saame ka niimoodi kirjutada. See on lihtsalt näide. Parool võib olla krüpteeritud. Toetatakse täielikult kõiki ClickHouse'i konfiguratsiooni valikuid. Siin on ainult näidis.
Klastri konfiguratsioon levib nagu ConfigMap. Praktikas ei toimu ConfigMap'i uuendamine hetkega, seega kui klaster on suur, siis konfiguratsiooni surumise protsess võtab aega. Kuid see on kõik väga mugav kasutuses.

Vaatame ülesande keerukust. Klaster areneb. Soovime andmeid replitseerida. Ehk meil on juba kaks shardi, kummalgi üks koopia, kasutajad on seadistatud. Kasvame ja soovime replitseerimisega tegeleda.

Mida vajame replitseerimiseks?
Meile on vajalik ZooKeeper. ClickHouse'is on replitseerimine üles ehitatud ZooKeeperi kasutamisele. ZooKeeper on vajalik, et erinevad ClickHouse'i koopiad jõuaksid kokkuleppele, millised andmeplokid on millises ClickHouse'is.
Iga ZooKeeper sobib kasutamiseks. Kui ettevõttel on väline ZooKeeper, siis võib seda kasutada. Kui ei, siis saab meie repostiitorist paigaldada. On olemas installer, mis teeb selle protsessi lihtsamaks.

Ja kogu süsteemi koostöö skeem näeb välja selline. Meil on Kubernetes platvormina. Sellel töötab ClickHouse'i operaator. ZooKeeper on siin kujutatud. Operaator suhtleb nii ClickHouse'i kui ka ZooKeeperiga. Ehk toimub koostöö.
Ja see on vajalik, et ClickHouse suudaks edukalt andmeid k8s'is replitseerida.

Vaatame nüüd ülesannet ise, kuidas näeb välja replitseerimise mansiif.
Lisame meie mansiifile kaks sektsiooni. Esimene – kust võtta ZooKeeper, mis võib olla kas Kubernetes'es sees või väline. See on lihtsalt kirjeldus. Ja tellime koopiad. Ehk soovime kahte koopiat. Lõpuks peaks meil olema 4 pod'i. Storage'i me mäletame, see tuleb veidi hiljem. Storage – see on eraldi teema.

See oli algne variant.

Nüüd näeb see välja nii. Lisanduvad koopiad. 4. ei mahtunud, usume, et neid võib olla palju. Ja külje peale lisandub ZooKeeper. Skeemid muutuvad keerukamaks.

Ja on aeg lisada järgmine ülesanne. Lisame Püsiva Säilitamise.
Püsiva Säilitamise korral on meil erinevad teostusvariandid.
Kui kasutame pilveteenuse pakkujat, näiteks Amazoni või Google'i, siis on suur kiusatus kasutada pilvepõhist salvestust. See on väga mugav ja hea.
Ja teine variant. See on kohaliku salvestuse jaoks, kui meil on iga nodi peal kohalikud kettad. See variant on palju keerulisem teostada, kuid samas on see tootlikum.

Vaatame, millised on pilvesalvestuse suhtes meie variandid.
On eelised. Selle konfigureerimine on väga lihtne. Me lihtsalt tellime pilveteenuse pakkujalt, et palun anna meile sellise mahutavusega ja sellise klassiga salvestus. Klassid on pakkujate poolt iseseisvalt määratletud.
Ja on puudus. Mõne jaoks ei ole see kriitiline puudus. Loomulikult võivad esineda mõned tootlikkuse probleemid. See töötab väga mugavalt, on usaldusväärne, kuid seal on mõned potentsiaalsed tootlikkuse langused.

Kuna ClickHouse keskendub just tootlikkusele, võib isegi öelda, et pigistab välja kõik, mis võimalik, püüavad väga paljud kliendid saavutada maksimaalset tootlikkust.

Maksimaalse saavutamiseks vajame kohalikke andmesalvestusi.
Kubernetes pakub kolme abstraktsiooni kohaliku andmesalvestuse kasutamiseks Kuberneteses. Need on:
- EmptyDir
- HostPath.
- Local
Vaatame, kuidas nad erinevad ja kuidas nad sarnanevad.
Esiteks, kõigis kolmes lähenemisviisis on andmesalvestus – need on kohalikud kettad, mis asuvad samal füüsilisel k8s sõlmel. Kuid neil on mõned erinevused.

Alustame kõige lihtsamast, st emptyDir. Mis see praktikas on? Palume oma spetsifikatsioonis konteinerisüsteemil (enamasti on see Docker) anda meile juurdepääs kausta kohaliku ketta juurde.
Praktikas loob Docker kuskil seal enda teedel ajutise kausta, nimetab selle pikka hääldamatut numbrit kasutades. Ja pakub sellele juurdepääsu liidest.
Kuidas see tootlikkuse osas töötab? See töötab kohaliku ketta kiirusel, st see on täielik juurdepääs oma kettale.
Kuid sellel on oma puudus. Püsivus on selles osas piisavalt kaheldav. Esimese liikumise korral koos konteineritega kaob püsivus. Kui Kubernetes otsustab mingil põhjusel selle Pod'i teisele kettale viia, kaovad andmed.
See lähenemine sobib hästi katsetamiseks, sest kiirus on juba normaalne, kuid millegi tõsise jaoks ei sobi see variant.

Seega on olemas teine lähenemine. See on hostPath. Kui vaadata eelmist slaidi ja seda, siis võib näha vaid ühte erinevust. Meie kaust on välja viidud Dockerist otse Kubernetesesse. Siin on natuke lihtsam. Me kirjutame otse kohaliku failisüsteemi teed, kuhu tahame oma andmed salvestada.
Selle meetodi eelised on olemas. See on juba tõeline püsivus, ja veel klassikaline. Andmed salvestatakse kettale mingisse aadressi.
Samuti on ka puudusi. See on haldamise keerukus. Meie Kubernetes võib soovida Pod'i liigutada teisele füüsilisele nodile. Siin tuleb mängu DevOps. Tema peab õigesti selgitama kogu süsteemile, et neid pod'e võib liigutada ainult sellistele nodidele, kus sul on nende teede kaudu midagi monteeritud, ja mitte rohkem kui ühte nodi korraga. See on üsna keeruline.
Spetsiaalselt nende eesmärkide jaoks oleme meie operaatoris loonud malle, et kogu see keerukus ära peita. Ja võiks lihtsalt rääkida: „Ma tahan, et mul oleks iga füüsilise nodi kohta üks ClickHouse'i instants ja sellisel teel“.

Aga see vajadus ei ole vajalik ainult meile, seega mehed Kubernetesest mõistavad ka, et inimestele meeldib saada juurdepääs füüsilistele ketastele, seega nad pakuvad kolmandat taset.
See on nimega local. Erinevus eelmisest slaidist on praktiliselt olematu. Ainult varem tuli käsitsi läbi viia, et meil ei tohi neid pod'e nodilt nodile liigutada, sest nad peavad olema seotud selle teega kohaliku füüsilise ketta juurde, ja nüüd on kõik need teadmised kapseldatud ise Kubernetesesse. Ja seadistamine on oluliselt lihtsam.

Naaseme oma praktilise ülesande juurde. Naaseme YAML malli juurde. Siin on meil tõeline salvestus. Oleme tagasi selle juurde. Me määratleme klassikalise VolumeClaim malli nagu k8s. Ja kirjeldame, millist salvestust me tahame.
Pärast seda küsib k8s salvestust. Küllaldab meile selle StatefulSet'is. Ja lõpuks on see ClickHouse'i käsutuses.

Meil oli selline skeem. Meie Persistent Storage oli punane, mis nagu vihjas, et seda oleks mõistlik teha.

Ja see muutub roheliseks. Nüüd on ClickHouse'i k8s klastrite skeem täielikult valmis. Meil on shard'id, replikad, ZooKeeper, on olemas tõeline Persistent, mis on ellu viidud sel või teisel viisil. Skeem on juba täielikult funktsionaalne.

Me jätkame edasiviimist. Meie klaster areneb. Ja Aleksei pingutab, ning väljastab uue ClickHouse'i versiooni.
Tekib praktiline ülesanne - testida uut ClickHouse'i versiooni meie klastris. Ja loomulikult ei taha me seda kogu aeg kasutada, tahaks kuskil kauges nurgas ühte replikat panna uue versiooni, ja võib-olla mitte ühte, vaid kohe kaks, sest neid väljastatakse sageli.
Mida me saame selle kohta öelda?

Siin on meil just selline võimalus. Need on pod'i mallid. Saame neid kirjeldada, meie operaator võimaldab täielikult ehitada heterogeenset klastrit. St. saame konfigureerida alates kõigist replikatest kuni iga isikliku replikani, määrates, millist versiooni soovime ClickHouse'ist, millist versiooni soovime salvestusruumist. Saame täielikult konfigureerida klastrit vastavalt meie vajadustele.

Natuke süveneme nüüd sisemusse. Varem rääkisime, kuidas ClickHouse operaator töötab ClickHouse'i spetsiifikaga seonduvalt.
Nüüd tahaksin öelda paar sõna selle kohta, kuidas töötab igasugune operaator ja kuidas see suhtleb K8s-iga.

Alustame K8siga suhtlemise uurimist. Mis juhtub, kui me saame kubectl apply? Meie objektid ilmuvad API kaudu etcd-sse.

Näiteks Kubernetes'i põhiobjektid: pod, StatefulSet, teenus ja nii edasi.
Sel ajal ei toimu veel füüsiliselt midagi. Need objektid tuleb klastris materialiseerida.

Selleks tuleb kontrollija. Kontrollija on spetsiaalne K8s komponent, mis oskab neid kirjeldusi materialiseerida. Ta teab, kuidas ja mida füüsiliselt teha. Ta teab, kuidas konteinerid käivitada, mida seadistada serveri töölepanemiseks.

Ja ta materialiseerib meie objektid K8s-i.
Aga me tahame hallata mitte ainult pod'e ja StatefulSet'e, vaid tahame luua ClickHouseInstallation'i, st. ClickHouse tüüpi objekti, et saaksime sellega kui tervikuga opereerida. Praegu sellist võimalust ei ole.

Aga K8s-il on järgmine tore asi. Tahame, et meil oleks kuskil selline keeruline struktuur, mis koosneks pod'dest ja StatefulSet'ist meie klastris.

Ja mida selleks teha? Esiteks, tuleb mängu Custom Resource Definition. Mis see on? See on K8si kirjeldus, et sul on veel üks andmetüüp, et me tahame lisada pod'ile ja StatefulSet'ile kohandatud ressursi, mis oleks keeruline seestpoolt. See on andmestruktuuri kirjeldus.

Seda saadame samuti kubectl apply kaudu. Kubernetes on selle rõõmuga vastu võtnud.
Ja nüüd on meie hoidlas, objektil etcd-s, võimalus salvestada kohandatud ressurss nimega ClickHouseInstallation.
Aga praegu ei juhtu midagi. See tähendab, et kui me nüüd loome YAML-faili, mis kirjeldab shard'e, replikaid ja ütleme «kubectl apply», siis Kubernetes aktsepteerib seda, salvestab etcd-sse ja ütleb: «Suurepärane, aga ma ei tea, mida sellega teha. Kuidas hooldada ClickHouseInstallation, ei tea ma».

Seega, meil on vaja kedagi, kes aitaks Kubernetesel hooldada uut andmeformaati. Vasakul on meil Kubernetes'i baasjuht, mis töötab standardsete andmeformaatide kallal. Ja paremal peab olema kohandatud juht, mis oskab töötada kohandatud andmeformaatide kallal.
Ja seda nimetatakse operaatoriks. Ma tõin ta siia teadlikult välja Kubernetes'e kontekstist, sest ta võib töötada ka väljaspool K8s. Enamasti töötavad kõik operaatorid siiski Kubernetes'es, kuid ei ole midagi, mis takistaks tal töötamast ka väljas, seetõttu on ta siin spetsiaalselt esitatud väljaspool.

Kohandatud juht, see on operaator, suhtleb Kubernetes'ega läbi API. Ta teab, kuidas suhelda API-ga. Ja ta juba teab, kuidas kohandatud ressursist luua keerukat struktuuri, mida me tahame saavutada. Just sellega tegeleb operaator.

Kuidas operaator töötab? Vaatame paremat külge, et teada saada, kuidas ta seda teeb. Uurime, kuidas operaator kõik selle materiaalselt ellu viib ja kuidas toimub edasine suhtlemine K8s-iga.

Operaator on programm. See on sündmustele orienteeritud. Operaator registreerib end Kubernetes API-s sündmustele. Kubernetes API-s on sisenemispunkte, kus saab registreeruda sündmustele. Ja kui K8s-is midagi muutub, siis saadab Kubernetes sündmusi kõigile soovijatele, st kes on sellele API punktile registreeritud, need saavad teateid.
Operaator registreerib end sündmustele ja peab tegema mingi reaktsiooni. Tema ülesanne on reageerida tekkivatele sündmustele.

Sündmused genereeritakse teatud uuenduste kaudu. Meie YAML-fail, mis kirjeldab ClickHouseInstallation'i, jõuab kubectl apply kaudu etcd-sse. Seal tekib sündmus, mille tulemusena see sündmus jõuab ClickHouse-operaatorisse. Operaator saab selle kirjelduse. Ja ta peab midagi tegema. Kui ClickHouseInstallation objekti kohta on tulnud uuendus, siis tuleb uuendada klastrit. Ja operaatori ülesanne on uuendada klastri.

Mida ta teeb? Esiteks tuleb koostada tegevusplaan, mida me selle uuendusega teeme. Uuendused võivad olla väga väikesed, st väikestes YAML-esitustes, kuid need võivad tuua kaasa väga suuri muudatusi klastris. Seetõttu koostab operaator plaani ja seejärel järgib seda.

Ta hakkab selle plaani kohaselt ehitama struktuuri sisse, et materialiseerida pod'id, teenuseid, st teha seda, mis on tema põhieesmärk. See on nagu ClickHouse'i klastrite ehitamine Kuberneteses.

Nüüd puudutame 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 aluste objektide põhikomplekti eest, mida saab tõlgendada kui süsteemi ulatust. Kubernetes teab, kuidas käivitada pod'e, kuidas konteinerit taastada, kuidas mountida mahtu, kuidas töötada ConfigMap'i'ga, st kõike, mida saab nimetada süsteemiks.
Operaatorid töötavad spetsiifilistes valdkondades. Iga operaator on loodud oma spetsialiseeritud valdkonna jaoks. Meie oleme loonud ClickHouse'i jaoks.
Ja operaator suhtleb konkreetselt selliste valdkonna termineid kasutades, nagu repliigi lisamine, skeemi loomine, jälgimise seadistamine. Nii toimub selle vastutuse jagamine.

Vaadakem praktilist näidet, kuidas see vastutuse jagamine toimub, kui me teeme tegevuse repliigi lisamiseks.
Operaatorile tuleb ülesanne – lisada replik. Mida operaator teeb? Operaator arvutab, et on vaja luua uus StatefulSet, milles tuleb kirjeldada sellised mallid, mahtude nõuded.

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

Ja siis astub taas mängu ClickHouse-operator. Tal on juba füüsiline pod, mille peal saab juba midagi teha. Ja ClickHouse-operator töötab taas oma valdkonna terminoloogias. St, et ClickHouse'i puhul, et lisada replik klastrisse, tuleb kõigepealt seadistada andmeskeem, mis klastris on. Ja teiseks tuleb see replik lisada jälgimise alla, et see oleks hästi jälgitav. Operaator seadistab selle.

Ja alles sellest hakkab tööle ClickHouse, st veel üks kõrgem tasandi entiteet. See on juba andmebaas. Tal on oma instance, konfigureeritud replikatsioon, mis on valmis klastrisse liituma.
Nii et replikatsiooni lisamise protsess ja vastutuse jagamine on piisavalt pikk.

Jätkame meie praktilisi ülesandeid. Kui klaster on juba olemas, siis saab teostada konfiguratsiooni migreerimist.

Oleme teinud nii, et olemasolevasse xml-faili, mille ClickHouse mõistab, saab läbipääsu luua.

ClickHouse'i saab täpsustada. Just zoned deployment – see on see, millest rääkisin hostPath'i ja kohalikku salvestusse seletades. See on õige viis zoned deployment'i teostamiseks.

Järgmine praktiline ülesanne on jälgimine.

Kui meie klaster muutub, tuleb jälgimist perioodiliselt seadistada.
Vaadakem skeemi. Oleme siin juba arutanud rohelisi nooli. Nüüd vaatame punaseid nooli. See on see, kuidas tahame oma klastrit jälgida. Kuidas mõõdud ClickHouse'i klastri kaudu saavad Prometheusesse, seejärel Grafanasse.

Mis on jälgimise keerukus? Miks see esitatakse kui mingisugune saavutus? Keerukus seisneb dünaamikas. Kui meil on klaster, mis on staatiline, siis võib jälgimise seadistada üks kord ja unustada selle.
Aga kui meil on palju klustreid või pidevalt midagi muutub, siis on protsess dünaamiline. Ja pidev jälgimise seadistamine on ressursi- ja aeganõudev, st isegi lihtsalt tüütav. See tuleb automatiseerida. Keerukus seisneb protsessi dünaamikas. Ja operaator automatiseerib seda väga hästi.

Kuidas meie klaster arenes? Alguses oli see selline.

Siis oli see selline.

Lõppkokkuvõttes sai see selliseks.
Ja jälgimine toimub automaatselt operaatori kaudu. Üks sisenemiskoht.

Ja me vaatame lihtsalt väljundis Grafana juhtpaneeli, kuidas meie klastris elu pulbitseb.
Muide, Grafana juhtpaneel jagatakse ka meie operaatoriga otse lähtekoodis. Seda saab ühendada ja kasutada. See ekraanipilt anti mulle meie DevOps'ilt.

Kuhu tahaksime edasi liikuda? See on:
- Arendada automatiseeritud testimist. Peamine ülesanne on automatiseeritud testimine uute versioonide jaoks.
- Soovime samuti automatiseerida integratsiooni ZooKeeperiga. Plaanis on integreeruda ZooKeeper-operatoriga. See tähendab, et ZooKeeperi jaoks on kirjutatud operaator ja oleks mõistlik, et kaks operaatorit hakkavad integreeruma, et luua mugavamat lahendust.
- Soovime teha keerukamaid elujõudluse kontrollimisi.
- Roheline on see, mida me läheneme, Templatesi pärimise – VALMIS, st järgmise operaatori versiooniga on meil juba šablonite pärimine. See on võimas tööriist, mis võimaldab luua keerulisi konfiguratsioone tükkidest.
- Ja me soovime keeruliste ülesannete automatiseerimist. Üks peamine sellest on Re-sharding.

Teeme vahekokkuvõtte.

Mida me saadame välja? Kas tasub sellega tegeleda või mitte? Kas on mõtet proovida andmebaasi tuua Kubernetesesse ja rakendada operaatorit üldiselt ning Alitnity-operatorit konkreetselt.
Saame välja järgmise:
- Oluline lihtsustamine ja automatiseerimine konfigureerimisest, juurutamisest ning ka tugitegevusest.
- Vahetu sisseehitatud jälgimine.
- Ja valmis kasutamiseks kodeeritud šablonid keeruliste olukordade jaoks. Näiteks ei pea enam käsitsi tegema toimingut nagu replikatsiooni lisamine. Selle teeb operaator.

On jäänud vaid viimane küsimus. Meil on juba andmebaas Kuberneteses, virtualiseerimine. Kuidas on sel lahendusel jõudlusega, eriti arvestades, et ClickHouse on jõudluse poolest optimeeritud?
Vastus – kõik on korras! Ma ei hakka seda üksikasjalikult lahti kirjutama, see on eraldi ettekande teema.

Kuid on projekt nimega TSBS. Mis on selle peamine ülesanne? See on andmebaaside jõudlustest. See on katse võrrelda sooja sooja, pehmet pehme vastu.
Kuidas see töötab? Genereeritakse üks andmebaas. Siis seda andmestikku katsetatakse sama testikomplekti abil erinevates andmebaasides. Iga andmebaas lahendab ühe ülesande selle oskuste kohaselt. Ja siis saab tulemusi võrrelda.
See toetab juba palju andmebaase. Olen esile tõstnud kolm peamist. Need on:
- TimescaleDB.
- InfluxDB.
- ClickHouse.

Samuti on tehtud võrdlus teise sarnase lahendusega. Võrdlus RedShiftiga. Võrdlus tehti Amazonis. ClickHouse ületab ka kõik selles küsimuses hästi.

Milliseid järeldusi saab teha sellest, mida ma rääkisin?
- Andmebaasi kasutamine Kuberneteses on võimalik. Kindlasti saab kasutada erinevaid andmebaase, kuid üldiselt tundub, et see on teostatav. ClickHouse on kindlasti võimalik Kuberneteses meie operaatoriga.
- Operaator aitab protsesside automatiseerimisel ja lihtsustab elu.
- Jõudlus on normaalne.
- Ja me arvame, et seda saaks ja peaks kasutama.
Avaallikas – liituge!
Nagu juba ütlesin, on operaator täielikult avaallika toode, seega oleks väga tore, kui võimalikult palju inimesi seda kasutaks. Liituge! Ootame teid kõiki!
Aitäh kõigile!
Küsimused

Aitäh ettekande eest! Minu nimi on Anton. Olen ettevõttest SEMrush. Mind huvitab logimise teema. Jälgimisest on kuulda, kuid logimise kohta ei ole midagi, kui rääkida terve klastrist. Meie puhul on näiteks klaster loodud raudvaral. Ja me kasutame tsentraliseeritud logimist, kogume standardsete vahenditega kokku. Ja siis tõmbame sealt välja huvitavad andmed.
Hea küsimus, st. logimine on meie to-do nimekirjas. Meie operaator ei automatiseeri seda veel. Ta on endiselt arengus, projekt on veel piisavalt noor. Me mõistame, et logimine on vajalik. See on samuti väga tähtis teema. Ja see on ilmselt vähemalt sama oluline kui jälgimine. Kuid esimene teema, mida ellu viia, oli jälgimine. Logimine tuleb. Loomulikult püüame automatiseerida kõik klastrite elutegevuse aspektid. Seega on vastus – praegu operaator kahjuks ei oska seda teha, kuid see on plaanis, me seda teeme. Kui soovite liituda, palun esitage pull request.
Tere! Aitäh ettekande eest! Mul on standardküsimus, mis on seotud püsivate mahtudega. Kui me loome selle operaatoriga konfiguratsiooni, siis kuidas operaator määrab, millisel sõlmel meil on mountitud disk või kaust? Kas me peaksime talle eelnevalt selgitama, et palun paigaldage meie ClickHouse just nendele sõlmedele, kus on disk?
Nii palju kui ma aru saan, on see küsimus seotud kohaliku salvestusega, eriti selle hostPath-i osaga. See on nagu selgitada kogu süsteemile, et pod peab olema käivitatud just sellel sõlmel, kuhu meil on füüsiliselt ühendatud disk, mis on monteeritud sellisel teel. See on terve sektsioon, mille ma käsitlesin väga pinnapealselt, kuna sealne vastus on küllalt mahukas.
Lühidalt öeldes näeb see välja nii. Me peame loomulikult nende mahtude provisioni tegema. Praegusel hetkel ei ole kohalikes salvestustes dünaamilist provisioni, seega peavad DevOps omaette kettad lõikama, need mahud. Ja nad peavad selgitama Kubernetes'e provisionile, et sul on teatud klassi Püsiv maht, mis asub teatud sõlmedel. Siis tuleb selgitada Kubernetes'ele, et pod'id, mis vajavad teatud klassi kohalikke salvestusi, tuleb sildistada ainult teatud sõlmedele. Nende eesmärkide saavutamiseks on operaatoril võimalus määrata teatud sildid ja ühe hosti eksemplar. Tulemuseks on see, et pod'id marsrutatakse Kubernetes'e poolt ainult sellistele sõlmedele, mis vastavad nõuetele, sildid, räägides lihtsalt. Administratiivtaust määrab sildid, teeb kettade provisioni käsitsi. Ja siis see skaleerub.
Ja just kolmas variant kohaliku salvestuse osas aitab seda veidi kergendada. Nagu ma juba rõhutasin, on see põhjalik seadistustöö, mis aitab lõppkokkuvõttes saavutada maksimaalset jõudlust.
Mul on selle osas teine küsimus. Kubernetes on üles ehitatud nii, et meil ei ole vahet, kas me kaotame sõlme või mitte. Mida me siis teeme, kui me kaotasime sõlme, kus meil oli šard?
Jah, Kubernetes oli algselt positsioneeritud nii, et meie suhtumine oma pod'idesse on nagu karja, kuid siin iga ketas muutub nagu lemmikloom. On probleem, et me ei saa neid lihtsalt kõrvale heita. Ja Kubernetes'e areng liigub sinna suunas, et sellele ei saa täielikult filosoofiliselt läheneda nagu täielikult ära visatud ressurssidele.
Nüüd praktiline küsimus. Mida teha, kui sul on kadunud sõlm, millel oli ketas? Siin lahendatakse probleem juba kõrgemal tasemel. ClickHouse'i korral on meil koopiad, mis töötavad kõrgemal tasemel, st ClickHouse'i tasemel.
Milline on olukord siis? DevOps vastutab selle eest, et andmed ei kaoks. Ta peab õigeaegselt seadistama replikatsiooni ja jälgima, et replikatsioon toimuks. ClickHouse'i tasemel peavad koopiad olema andmeid dubleeritud. See ei ole ülesanne, millega operaator tegeleb. Ja see ei ole ülesanne, millega Kubernetes iseenesest tegeleb. See on ClickHouse'i tasemel.
Mida teha, kui teil on rauanode, mis on välja kukkunud? Tundub, et peate seadma teise, õigesti määrama ketta, rakendama silte. Ja pärast seda vastab see nõuetele, et Kubernetes saab sellel käivitada pod'i instantsi. Kubernetes käivitab selle. Teil ei ole ju pod'ide arvu, mis vastaks määratud nõuetele. See läbib ringi, mida ma näitasin. Ja kõrgeimal tasemel mõistab ClickHouse, et meil on tulnud repliik, see on veel tühi ja sinna tuleb hakata andmeid vedama. Teisisõnu, see protsess on veel halvasti automatiseeritud.
Aitäh ettekande eest! Kui juhtub igasuguseid halbu asju, kukub operaator ja restardib, ja sel ajal saabub sündmusi, kas te töötate neid kuidagi üles?
Mis juhtub, kui operaator kukub ja restardib, eks?
Jah. Ja sel ajal saabusid sündmused.
Ülesanne, mida sel juhul teha, jaguneb osaliselt operaatori ja Kubernetes'i vahel. Kubernetes'il on võimalus juhtuda sündmus uuesti mängida. Ta mängib selle uuesti. Ja operaatori ülesanne on veenduda, et kui sündmuste logi uuesti mängitakse, oleksid need sündmused idempotentsed. Ja et sama sündmuse korduv toimumine ei kahjustaks meie süsteemi. Ja meie operaator tegeleb selle ülesandega.
Tere! Aitäh ettekande eest! Dmitri Zavyalov, ettevõte Smedova. Kas plaanitakse operaatorisse lisada võimalust seadistada haproxy? Huvitavad miski muu koormuse jaotaja peale standardse, et ta oleks intelligentne ja mõistaks, et seal on tegelikult ClickHouse.
Kas räägite Ingress'ist?
Jah, vahetage Ingress haproxy vastu. Haproxy's saab määrata klastri topoloogia, kus on repliigid.
Kuni praeguseni ei ole me selle peale mõelnud. Kui see on vajalik ja saate selgitada, miks see vajalik on, siis saame selle rakendada, eriti kui soovite osaleda. Vastus on lühidalt - ei, praegu meil sellist funktsionaalsust ei ole. Aitäh vihje eest, vaatame selle peale. Ja kui te seletate ka kasutusjuhtumi ja miks see praktikas vajalik on, näiteks loote GitHub'is probleemid, siis oleks see suurepärane.
See on juba olemas.
Hea. Oleme avatud igasugustele ettepanekutele. Ja haproxy lisatakse to-do nimekirja. To-do nimekiri kasvab, mitte ei väheneks. Aga see on hea, see tähendab, et toode on nõutud.
Allikas: habr.com
