
Rapportet handlar om praktiska frÄgor kring utveckling av operatörer i Kubernetes, design av deras arkitektur och grundlÀggande funktionsprinciper.
I den första delen av rapporten kommer vi att gÄ igenom:
- vad en operatör i Kubernetes Àr och varför den behövs;
- hur en operatör förenklar hanteringen av komplexa system;
- vad en operatör kan och vad den inte kan.
DÀrefter gÄr vi vidare till diskussionen om operatörens interna strukturer. Vi kommer att betrakta arkitekturen och funktionen av en operatör steg för steg. Vi kommer att detaljerat analysera:
- interaktionen mellan operatören och Kubernetes;
- vilka funktioner operatören tar pÄ sig och vad den delegerar till Kubernetes.
Vi kommer att titta pÄ hantering av shardar och repliker av databaser i Kubernetes.
DÀrefter diskuterar vi frÄgor kring datalagring:
- hur man arbetar med Persistent Storage ur operatörens perspektiv;
- fÀllor med anvÀndning av Local Storage.
I den avslutande delen av rapporten ska vi gÄ igenom praktiska exempel pÄ tillÀmpning av med Amazon eller Google Cloud Service. Rapporten bygger pÄ exempel frÄn utvecklingen och driften av en operatör för ClickHouse.
Video:

Jag heter Vladislav Klimenko. Jag ville idag berÀtta om vÄr erfarenhet av utveckling och drift av operatören, som Àr en specialiserad operatör för hantering av databaskluster. Som exempel kommer vi att titta pÄ för att hantera ett ClickHouse-kluster.

Varför har vi möjlighet att tala om operatören och ClickHouse?
- Vi arbetar med support och utveckling av ClickHouse.
- Just nu försöker vi lÄngsamt bidra med det vi kan till utvecklingen av ClickHouse. Vi Àr de nÀst största efter Yandex nÀr det kommer till antalet Àndringar som gjorts i ClickHouse.
- Vi försöker göra ytterligare projekt för ClickHouse-ekosystemet.
Jag skulle vilja berÀtta om ett av dessa projekt. Det handlar om ClickHouse-operatorn för Kubernetes.
I min presentation vill jag ta upp tvÄ Àmnen:
- Det första Àmnet handlar om hur vÄr operatör för hantering av ClickHouse-databaser i Kubernetes fungerar.
- Det andra Àmnet handlar om hur en operatör fungerar generellt, dvs. hur den interagerar med Kubernetes.
Dessa tvÄ frÄgor kommer att korsas genom hela min presentation.

Vem skulle vara intresserad av att lyssna pÄ det jag försöker förmedla?
- Det Àr mest intressant för dem som driver operatörer.
- Eller för dem som vill bygga sin egen för att förstÄ hur den fungerar internt, hur operatören interagerar med Kubernetes och vilka fÀllor som kan dyka upp.

För att bÀttre förstÄ vad vi kommer att diskutera idag, vore det bra att veta hur Kubernetes fungerar och ha en grundlÀggande kunskap om molnteknologier.

Vad Àr ClickHouse? Det Àr en kolumnorienterad databas med fokus pÄ onlinebehandling av analytiska förfrÄgningar. Och den Àr helt öppen kÀllkod.
Och vi behöver veta tvÄ saker. För det första vet vi att detta Àr en databas, sÄ det jag kommer att förklara kommer att vara tillÀmpligt pÄ nÀstan alla databaser. För det andra att databashanteringssystemet ClickHouse skalas mycket bra, det ger praktiskt taget linjÀr skalbarhet. DÀrför Àr klustrets tillstÄnd det normala tillstÄndet för ClickHouse. Det mest intressanta för oss Àr att diskutera hur man underhÄller ett ClickHouse-kluster i Kubernetes.

Varför behövs det dÀr? Varför kan vi inte fortsÀtta att driva det sjÀlva? Svaren Àr delvis tekniska och delvis organisatoriska.
- I praktiken stöter vi allt oftare pÄ situationer dÀr nÀstan alla komponenter i stora företag redan körs i Kubernetes. Databaserna blir kvar utanför.
- Och allt oftare stÀlls frÄgan: "Kan vi integrera detta?". DÀrför försöker stora företag att maximera standardiseringen av hanteringen för att snabbt kunna administrera sina datalagringar.
- Och det hÀr Àr sÀrskilt hjÀlpsamt om det krÀvs maximal möjlighet att Äterskapa samma sak pÄ en ny plats, det vill sÀga maximal portabilitet.

Hur enkelt eller svÄrt Àr det? Det kan sjÀlvklart göras manuellt. Men det Àr inte sÄ enkelt, eftersom vi har den totala komplexiteten av att hantera Kubernetes, samtidigt som vi mÄste ta hÀnsyn till ClickHouse-specifikationen. Resultatet blir en sÄdan aggregering.
Och allt detta ger en ganska stor uppsÀttning teknologier som blir svÄra att hantera, eftersom Kubernetes kommer med sina dagliga driftfrÄgor och ClickHouse med sina specifika dagliga driftutmaningar. SÀrskilt om vi har flera ClickHouse-instanser och stÀndigt mÄste hantera nÄgot med dem.

ClickHouse har med dynamisk konfiguration ett stort antal frÄgor som skapar en konstant belastning pÄ DevOps:
- NÀr vi vill Àndra nÄgot i ClickHouse, till exempel lÀgga till en replik eller shard, mÄste vi hantera konfigurationen.
- Sedan mÄste dataskeman Àndras eftersom ClickHouse har ett speciellt sÀtt att sharda. Man behöver distribuera dataskeman och konfigurationerna.
- Ăvervakning mĂ„ste stĂ€llas in.
- Insamling av loggar för nya shards, för nya repliker.
- Man mÄste ta hand om ÄterstÀllning.
- Och om omstart.
Det Àr sÄdana rutinarbeten som man verkligen skulle vilja underlÀtta i driften.

Kubernetes hjÀlper bra till med driften, men nÀr det gÀller de grundlÀggande systemaspekterna.
Kubernetes underlÀttar och automatiserar saker sÄsom:
- à terstÀllning.
- Omstart.
- Systemlagringshantering.
Detta Àr bra, det Àr rÀtt riktning, men det har ingen komplett förstÄelse för hur man driver en databascluster.
Man vill ha mer, man vill att hela databasen ska fungera i Kubernetes.

Man vill fÄ nÄgot som en stor magisk röd knapp, som man trycker pÄ och fÄr ett cluster som installeras och underhÄlls under hela livscykeln, med dagliga uppgifter som mÄste lösas. ClickHouse-cluster i Kubernetes.
Och vi har försökt skapa en lösning som underlÀttar arbetet. Det Àr ClickHouse-operatören för Kubernetes frÄn Altinity.

Operatören Àr ett program vars huvuduppgift Àr att hantera andra program, det vill sÀga, det Àr en förvaltare.
Och det innehÄller beteendemallar. Man kan kalla det kodifierad kunskap om ÀmnesomrÄdet.
Och dess huvuduppgift Àr att underlÀtta livet för DevOps och minska micromanagement, sÄ att han (DevOps) tÀnker i termer av hög nivÄ, det vill sÀga, att han (DevOps) inte Àgnar sig Ät micromanagement och inte behöver stÀlla in alla detaljer manuellt.
Och just operatören Àr en hjÀlprobot som tacklar mikrouppgifter och hjÀlper DevOps.

Varför behövs en operatör? Den visar sig sÀrskilt bra i tvÄ frÄgor:
- NÀr en specialist som sysslar med ClickHouse har otillrÀcklig erfarenhet, men mÄste börja anvÀnda ClickHouse, underlÀttar operatören driften och möjliggör att driva ClickHouse-cluster med en ganska komplex konfiguration, utan att behöva gÄ in pÄ detaljer om hur allt fungerar inuti. Man ger honom bara högre uppgifter, och det fungerar.
- Och den andra uppgiften, dÀr han verkligen utmÀrker sig, Àr nÀr det handlar om att automatisera ett stort antal repetitiva uppgifter. Han avlastar sysadmins frÄn mikrouppgifter.

Det hÀr behövs mest av allt för antingen de som just har börjat sin resa, eller de som behöver fokusera mycket pÄ automatisering.

Vad Àr dÄ skillnaden mellan ett operatörsbaserat tillvÀgagÄngssÀtt och andra system? Finns det inte Helm? Det hjÀlper ju ocksÄ att installera ClickHouse, man kan rita helm charts som till och med sÀtter upp en hel ClickHouse-kluster. Vad Àr dÄ skillnaden mellan en operatör och till exempel Helm?
Den grundlÀggande skillnaden Àr att Helm Àr en pakethanterare, medan en operatör gÄr ett steg lÀngre. Det handlar om att stödja hela livscykeln. Det handlar inte bara om installation, utan Àven om dagliga uppgifter som inkluderar skalning, sharding, det vill sÀga allt som mÄste utföras under livscykeln (om det behövs, Àven borttagning) - det Àr allt en operatör hanterar. Han försöker automatisera och underhÄlla hela programvarans livscykel. Det Àr hans fundamentala skillnad frÄn andra lösningar pÄ marknaden.

Detta var den inledande delen, lÄt oss gÄ vidare.
Hur bygger vi vÄr operatör? Vi försöker nÀrma oss frÄgan om hur man hanterar en ClickHouse-kluster som en resurs.
HÀr pÄ vÀnster sida av bilden har vi indata. Det hÀr Àr YAML med specifikationen för klustret, som pÄ det klassiska sÀttet överförs till Kubernetes via kubectl. DÀr fÄngar operatören upp det, gör sin magi. Och ut kommer vi med en sÄdan hÀr schema. Detta Àr implementeringen av ClickHouse i Kubernetes.
Och sÄ kommer vi lÄngsamt att se hur operatören faktiskt fungerar, vilka repetitiva uppgifter som kan lösas. Vi kommer endast att titta pÄ typiska uppgifter, eftersom vi har begrÀnsad tid. Det kommer inte att handla om allt vad operatören kan hantera.

LÄt oss basera oss pÄ praktiken. VÄrt projekt Àr helt open source, sÄ man kan titta pÄ GitHub hur det fungerar. Och man kan basera sig pÄ övervÀganden, om man bara vill sÀtta igÄng, kan man börja med Quick Start Guide.
Om man vill gÄ pÄ djupet, försöker vi hÄlla dokumentationen i ett hyfsat skick.

LÄt oss börja med en praktisk uppgift. Den första uppgiften vi vill starta med Àr att köra det första exemplet pÄ nÄgot sÀtt. Hur kör man ClickHouse med hjÀlp av operatören, Àven om man inte riktigt vet hur den fungerar? Vi skriver en manifest, eftersom all kommunikation med k8s sker genom manifester.

HÀr Àr en komplex manifest. Det som vi har markerat i rött Àr det som vi mÄste fokusera pÄ. Vi ber operatören att skapa ett kluster med namnet demo.
Detta Àr grundlÀggande exempel. Storage beskrivs Ànnu inte, men vi kommer tillbaka till storage lite senare. För nu kommer vi att observera utvecklingen av klustret i realtid.
Vi har skapat denna manifest. Vi matar den till vÄr operatör. Den har arbetat, gjort sin magi.

Vi kollar i konsolen. Tre komponenter vĂ€cker intresse â det Ă€r Pod, tvĂ„ tjĂ€nster och StatefulSet.
Operatören har arbetat, och vi kan titta pÄ vad den har skapat.

Den skapar ungefÀr ett sÄdant schema. Vi har StatefulSet, Pod, ConfigMap för varje replika, ConfigMap för hela klustret. TjÀnsterna Àr nödvÀndigtvis ingÄngspunkter för klustret.
TjÀnster Àr den centrala Load Balancer-tjÀnsten och man kan Àven ha en för varje replika, för varje shard.
HÀr Àr vÄrt grundlÀggande kluster som ser ut ungefÀr sÄ hÀr. Det bestÄr av en enda nod.

Vi gÄr vidare och komplicerar saker. Klustret mÄste shardas.

VÄra uppgifter ökar, dynamiken börjar. Vi vill lÀgga till en shard. Vi följer utvecklingen. Vi Àndrar vÄr specifikation. Vi anger att vi vill ha tvÄ shards.
Detta Àr samma fil som dynamiskt utvecklas med systemets tillvÀxt. Storage finns inte, det kommer att diskuteras senare, det Àr ett separat Àmne.
Vi matar YAML-operatören och ser vad som hÀnder.

Operatören tÀnkte efter och skapade följande entiteter. Vi har redan tvÄ Pods, tre tjÀnster och plötsligt, 2 StatefulSets. Varför 2 StatefulSets?

PĂ„ schemat var det sĂ„ hĂ€r â detta Ă€r vĂ„rt ursprungliga tillstĂ„nd, nĂ€r vi hade en pod.

Det blev sÄ hÀr. För nu Àr allt enkelt, det har duplicerats.

Och varför blev StatefulSet tvÄ? HÀr mÄste vi avledas och diskutera hur Kubernetes hanterar Pods.
Det finns ett objekt som heter StatefulSet, som gör att man kan skapa en uppsĂ€ttning Pods frĂ„n en mall. HĂ€r Ă€r nyckelfaktorn â den hĂ€r mallen. Och man kan starta mĂ„nga Pods frĂ„n en mall inom en StatefulSet. Nyckelfrasen hĂ€r Ă€r 'mĂ„nga Pods frĂ„n en och samma mall'.
Det fanns en stor frestelse att skapa hela klustret genom att packa det i en enda StatefulSet. Det skulle fungera, det finns inga problem med det. Men det finns en liten nyans. Om vi vill bygga ett heterogent kluster, det vill sÀga med flera versioner av ClickHouse, sÄ börjar vi fÄ frÄgor. Ja, StatefulSet kan göra en rolling update, och man kan rulla ut en ny version, och förklara att man inte bör försöka uppgradera fler Àn ett visst antal noder samtidigt.
Men om vi extrapolerar uppgiften och sÀger att vi vill skapa ett helt heterogent kluster, dÀr vi vill skapa ett heterogent kluster bÄde med olika versioner av ClickHouse och med olika lagring. Vi vill till exempel skapa vissa repliker pÄ separata diskar, pÄ lÄngsamma diskar, i grunden bygga ett helt heterogent kluster. Och eftersom StatefulSet skapar en standardiserad lösning frÄn en och samma mall, sÄ finns det ingen möjlighet att göra detta.
Efter viss eftertanke togs beslutet att göra sÄ hÀr. Varje replik har sin egen StatefulSet. Det finns vissa nackdelar med denna lösning, men i praktiken inkapslar den fullt ut operatorn. Det finns ocksÄ mÄnga fördelar. Vi kan bygga exakt det kluster vi vill, till exempel helt heterogent. DÀrför, i klustret dÀr vi har tvÄ shardar med en replik vardera, kommer vi att ha 2 StatefulSets och 2 Pods just för att vi valde detta tillvÀgagÄngssÀtt pÄ grund av de ovan nÀmnda skÀlen för möjligheten att bygga ett heterogent kluster.

LÄt oss ÄtergÄ till praktiska uppgifter. I vÄrt kluster behöver vi konfigurera anvÀndare, det vill sÀga vi mÄste göra nÄgon slags konfiguration av ClickHouse i Kubernetes. Operatören tillhandahÄller alla möjligheter för detta.

Vi kan skriva direkt i YAML vad vi vill. Alla konfigurationsalternativ mappas direkt frÄn denna YAML till ClickHouse-konfigurationer, som sedan sprids över hela klustret.
Detta Àr ett alternativ. Som ett exempel kan lösenordet göras krypterat. Alla konfigurationsalternativ för ClickHouse stöds. HÀr Àr det bara ett exempel.
Konfigurationen för klustret distribueras som ConfigMap. I praktiken sker uppdateringen av ConfigMap inte omedelbart, sÄ om klustret Àr stort tar processen att trycka ut konfigurationen en viss tid. Men allt detta Àr mycket praktiskt i drift.

Vi komplicerar uppgiften. Klustret utvecklas. Vi vill replikera data. Det vill sÀga, vi har redan tvÄ shardar, med en replik vardera, och anvÀndarna Àr instÀllda. Vi vÀxer och vill Àgna oss Ät replikering.

Vad behöver vi för replikering?
Vi behöver ZooKeeper. I ClickHouse Àr replikering byggd med hjÀlp av ZooKeeper. ZooKeeper behövs för att olika replikor av ClickHouse ska ha konsensus om vilka datablokkar som finns pÄ vilken ClickHouse.
Vilken ZooKeeper som helst kan anvÀndas. Om företaget har en extern ZooKeeper kan den anvÀndas. Om inte, kan vi installera en frÄn vÄrt repository. Det finns en installationsprogram som underlÀttar detta.

Och interaktionsschemat för hela systemet ser ut sÄ hÀr. Vi har Kubernetes som plattform. PÄ den körs ClickHouse-operatören. ZooKeeper har jag illustrerat hÀr. Operatören interagerar bÄde med ClickHouse och med ZooKeeper. Det vill sÀga, det blir en interaktion.
Och allt detta behövs för att ClickHouse framgÄngsrikt ska kunna replikera data i k8s.

LÄt oss nu titta pÄ sjÀlva uppgiften, hur manifestet för replikering kommer att se ut.
Vi lÀgger till tvÄ sektioner till vÄrt manifest. Den första Àr var vi ska hÀmta ZooKeeper, som kan vara antingen inuti Kubernetes eller extern. Detta Àr bara en beskrivning. Och vi begÀr replikor. Det vill sÀga, vi vill ha tvÄ replikor. SÄ totalt ska vi ha 4 poddar. Vi kommer ihÄg lagringen, den kommer tillbaka lite lÀngre fram. Lagring Àr en egen historia.

Det var sÄ hÀr.

Det blir sÄ hÀr. Replikor lÀggs till. Den fjÀrde fick inte plats, sÄ vi tror att det kan finnas mÄnga dÀr. Och ZooKeeper lÀggs till pÄ sidan. Scheman blir mer komplexa.

Och det Àr dags att lÀgga till nÀsta uppgift. Vi kommer att lÀgga till Persistent Storage.
NÀr det gÀller Persistent Storage har vi olika implementationsalternativ.
Om vi kör i en molnleverantör, till exempel, nÀr vi anvÀnder Amazon, Google, finns det en stark frestelse att anvÀnda molnlagring. Det Àr mycket bekvÀmt, det Àr bra.
Och det finns ett andra alternativ. Det Àr för lokal lagring, nÀr vi har lokala diskar pÄ varje nod. Detta alternativ Àr mycket svÄrare att implementera, men det Àr mer effektivt.

LÄt oss titta pÄ vad vi har nÀr det gÀller molnlagring.
Det finns fördelar. Det Àr mycket enkelt att konfigurera. Vi bestÀller bara hos molnleverantören, att ge oss lagring av viss kapacitet och klass. Klasserna Àr specificerade av leverantörerna sjÀlva.
Och det finns en nackdel. För vissa Àr detta en icke-kritisk nackdel. SjÀlvklart kommer det att finnas vissa prestandaproblem. Det Àr mycket praktiskt att arbeta med, pÄlitligt, men det finns vissa potentiella prestandautmaningar.

Och eftersom ClickHouse fokuserar just pÄ prestanda, kan man till och med sÀga att det pressar allt som gÄr, dÀrför försöker mÄnga kunder maximera prestandan.

För att maximera detta behöver vi lokal lagring.
Kubernetes tillhandahÄller tre abstraktioner för anvÀndning av lokal lagring i Kubernetes. Dessa Àr:
- EmptyDir
- HostPath.
- Local
LÄt oss titta pÄ hur de skiljer sig Ät och vad de har gemensamt.
För det första har vi i alla tre metoderna lagring â det Ă€r lokala diskar som finns pĂ„ samma fysiska k8s-nod. Men de har vissa skillnader.

Vi börjar med det enklaste, dvs. med emptyDir. Vad Àr detta i praktiken? Det Àr nÀr vi ber vÄrt system för containerhantering (oftast Docker) att ge oss Ätkomst till en mapp pÄ den lokala disken.
I praktiken skapar Docker nÄgonstans pÄ sina egna vÀgar en temporÀr mapp, döper den till en lÄng hash. Och ger ett grÀnssnitt för Ätkomst till den.
Hur kommer detta att fungera sett till prestanda? Det kommer att fungera med hastigheten av den lokala disken, dvs. det Àr en fullstÀndig Ätkomst till sin enhet.
Men detta har sin nackdel. Persistent i detta avseende Àr ganska osÀkert. Vid den minsta inverkan av Docker pÄ containrarna förloras persistent data. Om Kubernetes av nÄgon anledning vill flytta denna Pod till en annan disk, sÄ gÄr uppgifterna förlorade.
Denna metod Àr bra för tester, eftersom hastigheten redan Àr acceptabel, men för nÄgot mer seriöst Àr detta alternativ inte lÀmpligt.

DÀrför finns det en andra metod. Det Àr hostPath. Om man tittar pÄ den föregÄende sliden och denna, sÄ kan man se bara en enda skillnad. VÄr mapp har flyttat frÄn Docker direkt till Kubernetes-noden. HÀr Àr det lite enklare. Vi anger direkt sökvÀgen i det lokala filsystemet dÀr vi vill lagra vÄra data.
Fördelar finns med denna metod. Det Àr redan en riktig persistent lagring, och dessutom klassisk. Uppgifterna kommer att skrivas till disken pÄ en viss adress.
Det finns nackdelar. Det handlar om hanteringskomplexitet. VÄr Kubernetes kan vilja flytta en Pod till en annan fysisk nod. HÀr kommer DevOps in i bilden. De mÄste förklara systemet korrekt att dessa pods bara kan flyttas till sÄdana noder som har nÄgot monterat lÀngs dessa vÀgar, och högst en nod Ät gÄngen. Det Àr ganska komplicerat.
För dessa ÀndamÄl har vi skapat mallar hos oss som operatör för att dölja all denna komplexitet. Man skulle enkelt kunna sÀga: "Jag vill ha en instans av ClickHouse pÄ varje fysisk nod och i en specifik sökvÀg."

Men denna nödvÀndighet gÀller inte bara oss, dÀrför förstÄr Àven herrarna frÄn Kubernetes att mÀnniskor vill ha tillgÄng till fysiska diskar, sÄ de erbjuder en tredje nivÄ.
Den kallas local. Det finns praktiskt taget ingen skillnad frÄn föregÄende bild. Tidigare var vi tvungna att manuellt genomföra att dessa pods inte kunde flyttas frÄn nod till nod, eftersom de mÄste vara kopplade langs en specifik sökvÀg till den lokala fysiska disken, men nu inkapslas all denna kunskap inom Kubernetes. Det blir mycket enklare att konfigurera.

LÄt oss ÄtergÄ till vÄr praktiska uppgift. LÄt oss ÄtergÄ till YAML-mallen. HÀr har vi en riktig lagring. Vi kom tillbaka till detta. Vi definierar en klassisk VolumeClaim-mall som i k8s. Och beskriver vilken lagring vi vill ha.
Efter detta kommer k8s att begÀra lagring. Det kommer att tilldela det till oss i StatefulSet. Och slutligen kommer det att bli tillgÀngligt för ClickHouse.

Vi hade en sÄdan hÀr schema. VÄr Persistenta Lagring var röd, vilket liksom antydde att vi borde ÄtgÀrda det.

Och den blir grön. Nu har schemat för ClickHouse-klustret pÄ k8s fullbordats. Vi har shards, repliker, ZooKeeper, och det finns en riktig Persistent, som har realiserats pÄ olika sÀtt. Schemat Àr nu helt fungerande.

Vi fortsÀtter framÄt. VÄrt kluster vÀxer. Och Aleksej anstrÀnger sig och slÀpper en ny version av ClickHouse.
En praktisk uppgift uppstĂ„r â att testa den nya versionen av ClickHouse pĂ„ vĂ„rt kluster. Naturligtvis vill vi inte rulla ut den helt, vi vill kanske sĂ€tta en ny version i ett avlĂ€gset hörn pĂ„ en replika, och kanske inte bara en ny version, utan tvĂ„, eftersom de slĂ€pps ganska ofta.
Vad kan vi sÀga om detta?

HÀr har vi precis en sÄdan möjlighet. Det handlar om mallarna för poddar. Vi kan specificera hur vÄr operator helt och hÄllet tillÄter att bygga en heterogen kluster. Det vill sÀga konfigurera, frÄn att ha alla repliker i en hög, till att ha varje individuell replika med vilken version av ClickHouse vi vill ha, vilken lagringsversion vi vill ha. Vi kan helt konfigurera klustret enligt den konfiguration vi behöver.

Nu kommer vi att fördjupa oss lite mer. Tidigare har vi pratat om hur ClickHouse-operatorn fungerar specifikt för ClickHouse.
Nu skulle jag vilja sÀga nÄgra ord om hur vilken operator som helst fungerar, samt hur den interagerar med K8s.

Vi börjar med att titta pÄ interaktionen med K8s. Vad hÀnder nÀr vi gör kubectl apply? VÄra objekt dyker upp i etcd via API:et.

Till exempel de grundlÀggande objekten i Kubernetes: pod, StatefulSet, service och sÄ vidare.
Ingenting fysiskt hÀnder Ànnu. Dessa objekt mÄste materialiseras i klustret.

För detta kommer en controller in i bilden. En controller Àr en speciell komponent i k8s som vet hur man materialiserar dessa beskrivningar. Den vet hur och vad som mÄste göras fysiskt. Den vet hur man startar containrar och vad som mÄste konfigureras för att servern ska fungera.

Och den materialiserar vÄra objekt i K8s.
Men vi vill inte bara hantera poddar och StatefulSet:er, vi vill skapa ClickHouseInstallation, det vill sÀga ett objekt av typen ClickHouse, för att hantera det som en helhet. För nÀrvarande finns det ingen sÄdan möjlighet.

Men K8s har en annan trevlig funktion. Vi vill att det ska finnas en sÄdan komplex entitet dÀr vÄr kluster sammanstÀlls av poddar och StatefulSet.

Vad behöver vi göra för detta? För det första kommer Custom Resource Definition in pÄ scenen. Vad Àr det? Det Àr en beskrivning för K8s av att du kommer fÄ ytterligare en datatyp, och att vi vill lÀgga till en anpassad resurs för poddar och StatefulSet, som blir komplex inuti. Det Àr en beskrivning av datastukturen.

Vi skickar ocksÄ denna via kubectl apply dit. Kubernetes tar den med glÀdje.
Och nu har vi i lagringen, hos objektet i etcd, möjlighet att registrera den anpassade resursen med namnet ClickHouseInstallation.
Men för nu kommer ingenting att hÀnda. D.v.s. om vi nu skapar en YAML-fil som vi diskuterade med beskrivning av shards, repliker och sÀger "kubectl apply", sÄ kommer Kubernetes att ta emot den, spara den i etcd och sÀga: "Bra, men jag vet inte vad jag ska göra med den. Jag vet inte hur man underhÄller ClickHouseInstallation."

DÀrför behöver vi nÄgon som hjÀlper Kubernetes att underhÄlla den nya datatypen. Till vÀnster har vi den inbyggda Kubernetes-controllern som arbetar med inbyggda datatyper. Och till höger bör vi fÄ en anpassad controller som kan arbeta med anpassade datatyper.
Och pÄ ett annat sÀtt kallas den operatör. Jag har specifikt placerat den utanför Kubernetes, eftersom den kan köras utanför K8s. Oftast körs dock alla operatörer i Kubernetes, men ingenting hindrar den frÄn att stÄ utanför, dÀrför har den placerats externt hÀr.

Och i sin tur interagerar den anpassade controllern, Àven kallad operatör, med Kubernetes via API. Den kan redan interagera med API. Och den vet redan hur man materialiserar en komplex struktur frÄn en anpassad resurs, som vi vill skapa. Det Àr precis det operatören gör.

Hur fungerar operatören? LÄt oss titta pÄ den högra delen för att förstÄ hur den gör detta. Vi ska ta reda pÄ hur operatören materialiserar allt detta och hur interaktionen med K8s gÄr till.

Operatören Àr ett program. Det Àr hÀndelsestyrt. Operatören registrerar sig via Kubernetes API för hÀndelser. I Kubernetes API finns ingÄngspunkter dÀr man kan registrera sig för hÀndelser. Och om nÄgot förÀndras i K8s, skickar Kubernetes hÀndelser till alla som vill, d.v.s. den som har registrerat sig pÄ den hÀr API-punkten fÄr meddelanden.
Operatören registrerar sig för hÀndelser och mÄste reagera pÄ dem. Dess uppgift Àr att reagera pÄ uppkommande hÀndelser.

HÀndelser genereras av vissa uppdateringar. VÄr YAML-fil med beskrivningen av ClickHouseInstallation kommer in. Den har gÄtt till etcd genom kubectl apply. DÀr utlöste det en hÀndelse, och denna hÀndelse kom till ClickHouse-operatören. Operatören fick denna beskrivning. Och den mÄste göra nÄgot. Om en uppdatering av objektet ClickHouseInstallation har kommit, sÄ mÄste klustret uppdateras. Och operatörens uppgift Àr att uppdatera klustret.

Vad gör han? Först och frÀmst mÄste en handlingsplan upprÀttas för vad vi ska göra med denna uppdatering. Uppdateringar kan vara mycket smÄ, det vill sÀga smÄ i YAML-implementering, men de kan leda till mycket stora förÀndringar i klustret. DÀrför skapar operatören en plan och följer den dÀrefter.

Han börjar att enligt denna plan bearbeta denna struktur inuti för att materialisera poddar, tjÀnster, det vill sÀga göra det som Àr hans huvuduppgift. Det Àr som att bygga ett ClickHouse-kluster i Kubernetes.

Nu ska vi ta upp en intressant sak. Det Àr delningen av ansvar mellan Kubernetes och operatören, det vill sÀga vad Kubernetes gör, vad operatören gör och hur de interagerar med varandra.
Kubernetes ansvarar för systemrelaterade saker, det vill sÀga för den grundlÀggande uppsÀttningen objekt som kan tolkas som systemomfattande. Kubernetes vet hur man startar poddar, hur man startar om containrar, hur man monterar volymer, hur man arbetar med ConfigMap, det vill sÀga allt som kan kallas systemet.
Operatörer arbetar inom specifika ÀmnesomrÄden. Varje operatör Àr specifik för sitt ÀmnesomrÄde. Vi har gjort en för ClickHouse.
Och operatören interagerar just i termer av ÀmnesomrÄden, sÄsom att lÀgga till en replik, skapa ett schema, stÀlla in övervakning. Det blir en sÄdan separation.

LÄt oss titta pÄ ett praktiskt exempel pÄ hur denna ansvarsdela sker nÀr vi utför ÄtgÀrden att lÀgga till en replik.
Operatören fÄr i uppdrag att lÀgga till en replik. Vad gör operatören? Operatören berÀknar att en ny StatefulSet mÄste skapas, dÀr sÄdana mallar och volymansprÄk mÄste beskrivas.

Han har förberett allt detta och vidarebefordrar det till K8s. Han sÀger att han behöver ConfigMap, StatefulSet, Volym. Kubernetes utför det. Han materialiserar de grundlÀggande enheter som han arbetar med.

Och sedan kommer ClickHouse-operatören Äterigen in i bilden. Han har redan en fysisk pod dÀr man kan göra nÄgot. Och ClickHouse-operatören arbetar Äterigen i termer av ÀmnesomrÄden. Det vill sÀga för ClickHouse, för att aktivera en replik i klustret, mÄste dataskeman som finns i detta kluster stÀllas in. Och för det andra mÄste denna replik inkluderas i övervakning sÄ att den kan spÄras vÀl. Det Àr operatören som stÀller detta in.

Och först efter detta kommer sjÀlva ClickHouse i spel, det vill sÀga ytterligare en mer högstÄende enhet. Detta Àr redan en databas. Den har sin egen instans, en konfigurerad replika som Àr redo att gÄ in i klustret.
Det blir en lÄng kedja av utförande och ansvarsfördelning vid tillÀgg av en replika.

Vi fortsÀtter med vÄra praktiska uppgifter. Om klustret redan finns kan vi genomföra migrering av konfigurering.

Vi har gjort det sÄ att i den befintliga xml som ClickHouse förstÄr kan vi skicka igenom data.

Det gÄr att göra en finjustering av ClickHouse. Just zonad distribution Àr det jag nÀmnde nÀr jag förklarade hostPath, lokal lagring. Hur man korrekt gör zonad distribution.

Den nÀsta praktiska uppgiften Àr övervakning.

Om vÄrt kluster förÀndras mÄste vi periodiskt stÀlla in övervakningen.
LÄt oss titta pÄ schemat. Vi har redan diskuterat de gröna pilarna. Nu lÄt oss titta pÄ de röda pilarna. Det Àr hur vi vill övervaka vÄrt kluster. Hur mÀtvÀrden frÄn ClickHouse-klustret hamnar i Prometheus, och sedan i Grafana.

Vad Àr svÄrigheten med övervakning? Varför framhÄlls det som nÄgon slags prestation? SvÄrigheten ligger just i dynamiken. NÀr vi har ett kluster och det Àr statiskt kan vi en gÄng stÀlla in övervakningen och sedan inte bekymra oss mer.
Men om vi har mÄnga kluster, eller om nÄgot stÀndigt Àndras, sÄ Àr processen dynamisk. Att stÀndigt behöva omkonfigurera övervakningen Àr en slöseri med resurser och tid, det vill sÀga Àven bara lathet. Detta mÄste automatiseras. SvÄrigheten ligger just i den dynamiska processen. Och operatören automatiserar detta mycket bra.

Hur har vÄrt kluster utvecklats? I början sÄg det ut sÄ hÀr.

Sedan sÄg det ut sÄ hÀr.

I slutÀndan blev det sÄ hÀr.
Och övervakningen görs automatiskt av operatören. En enda ingÄngspunkt.

Och vi tittar bara pÄ utdata i Grafana-dashboarden, hur livet i vÄrt kluster pulserar inuti.
För övrigt sprids ocksÄ Grafana-dashboards med vÄr operatör direkt i kÀllkoden. Man kan ansluta och anvÀnda det. Denna skÀrmdump fick jag av vÄra DevOps.

Vart skulle vi vilja gÄ hÀrifrÄn? Det Àr:
- Att utveckla automatisering av testning. Huvuduppgiften Àr automatisk testning av nya versioner.
- Vi vill ocksÄ automatisera integrationen med ZooKeeper. Vi planerar att integrera med ZooKeeper-operatorn. Det vill sÀga, en operator för ZooKeeper har skrivits och det Àr logiskt att de tvÄ operatorerna börjar integrera sig för att bygga en mer bekvÀm lösning.
- Vi vill göra mer komplexa livscykelkontroller.
- Jag har markerat i grönt det som Ă€r pĂ„ gĂ„ng â arv av mallar â KLAR, alltsĂ„ i nĂ€sta version av operatorn kommer vi redan att ha möjligheten att arva mallar. Detta Ă€r ett kraftfullt verktyg som möjliggör att bygga komplexa konfigurationer frĂ„n bitar.
- Och vi vill automatisera komplexa uppgifter. Den största av dem Àr Re-sharding.

LÄt oss göra en mellanliggande sammanfattning.

Vad fĂ„r vi ut pĂ„ andra sidan? Ăr det vĂ€rt att syssla med detta eller inte? Borde vi alls försöka dra databasen till Kubernetes och anvĂ€nda operatorn i allmĂ€nhet och Alitnity-operatorn i synnerhet?
Resultatet blir:
- VÀsentlig förenkling och automatisering av konfiguration, distribution samt underhÄll.
- Omedelbart inbyggd övervakning.
- Och fÀrdiga, kodifierade mallar för komplexa situationer. Redan ÄtgÀrder som att lÀgga till en replik behöver inte göras manuellt. Det gör operatorn.

Det finns bara en sista frÄga kvar. Vi har redan databasen i Kubernetes, virtualisering. Hur Àr det med prestandan hos en sÄdan lösning, sÀrskilt med tanke pÄ att ClickHouse Àr optimerad för prestanda?
Svaret â allt Ă€r okej! Jag kommer inte att gĂ„ in pĂ„ detaljer, det Ă€r ett Ă€mne för en separat presentation.

Men det finns ett projekt som heter TSBS. Vad Àr dess huvuduppgift? Det Àr en prestandatest av databaser. Det Àr ett försök att jÀmföra lika med lika.
Hur fungerar det? En uppsÀttning data genereras. Sedan körs denna uppsÀttning data genom samma uppsÀttning tester pÄ olika databaser. Och varje databas löser en uppgift pÄ det sÀtt som den kan. Sedan kan resultaten jÀmföras.
Det stöder redan mÄnga databaser. Jag har markerat tre huvudsakliga. Det Àr:
- TimescaleDB.
- InfluxDB.
- ClickHouse.

Det har ocksÄ gjorts en jÀmförelse med en annan liknande lösning. En jÀmförelse med RedShift. JÀmförelsen gjordes pÄ Amazon. ClickHouse slÄr ocksÄ alla i denna frÄga.

Vilka slutsatser kan dras frÄn det jag har berÀttat?
- Databaser i Kubernetes Àr möjliga. Troligtvis kan man anvÀnda vilken som helst, men överlag verkar det som att det Àr möjligt. ClickHouse i Kubernetes kan definitivt anvÀndas av vÄr operatör.
- Operatören hjÀlper till att automatisera processer och förenklar verkligen livet.
- Prestandan Àr normal.
- Och vi tycker att detta Àr nÄgot som bÄde kan och bör anvÀndas.
Ăppen kĂ€llkod â gĂ„ med!
Som jag redan nÀmnt, operatören Àr en helt öppen kÀllkodsprodukt, sÄ det skulle vara mycket bra om sÄ mÄnga som möjligt anvÀnde den. GÄ med! Vi vÀntar pÄ er alla!
Tack alla!
FrÄgor

Tack för presentationen! Jag heter Anton. Jag kommer frÄn företaget SEMrush. Jag undrar över loggning. Jag har hört om övervakning, men inget om loggning nÀr det gÀller hela klustret. Vi har exempelvis satt upp ett kluster pÄ hÄrdvara. Och vi anvÀnder centraliserad loggning, samlar in med standardverktyg till en gemensam plats. Och sedan hÀmtar vi intressanta data dÀrifrÄn.
Bra frÄga, det vill sÀga loggning stÄr pÄ listan över att göra. VÄr operatör automatiserar fortfarande inte detta. Den utvecklas fortfarande, projektet Àr relativt ungt. Vi förstÄr behovet av loggning. Det Àr ocksÄ ett mycket viktigt Àmne. Och det Àr nog inte mindre viktigt Àn övervakning. Men först pÄ listan för implementering var övervakning. Loggning kommer att ske. Vi försöker naturligtvis automatisera alla aspekter av klusterets livscykel. SÄ svaret Àr att i nulÀget kan operatören tyvÀrr inte detta, men det finns pÄ planerna, vi kommer att göra detta. Om det finns intresse att gÄ med, gör gÀrna en pull request.
Hej! Tack för presentationen! Jag har en standardfrÄga som rör Persistenta Volymer. NÀr vi skapar en konfiguration med denna operatör, hur bestÀmmer operatören pÄ vilken nod vi har monterat en viss disk eller mapp? MÄste vi förklara för den att den ska placera vÄr ClickHouse just pÄ dessa noder dÀr det finns en disk?
SÄvitt jag förstÄr, denna frÄga Àr en fortsÀttning pÄ lokal lagring, sÀrskilt delen som rör hostPath. Det handlar om att förklara hela systemet att en pod ska startas pÄ en viss nod, dÀr vi har en fysiskt ansluten disk som Àr monterad pÄ en viss vÀg. Det Àr en hel sektion som jag endast berört ytligt, för svaret Àr ganska omfattande.
Sammanfattningsvis ser det ut sÄ hÀr. SjÀlvklart mÄste vi göra provisioning av dessa volymer. För nÀrvarande finns det ingen dynamisk provisioning i lokal lagring, sÄ DevOps mÄste sjÀlva partitionera diskarna, alltsÄ dessa volymer. Och de mÄste förklara för Kubernetes provisioning att du kommer att ha Persistent volumes av en viss klass som finns pÄ vissa noder. Sen mÄste de förklara för Kubernetes att poddar som krÀver en viss klass av lokal lagring, mÄste schemalÀggas endast pÄ dessa noder. För dessa syften finns det möjlighet att tilldela vissa etiketter och en per vÀrdinstans. Och det kommer att resultera i att poddarna kommer att routas av Kubernetes för att bara köras pÄ noder som uppfyller kraven, etiketter, för att uttrycka det enkelt. Administratörerna tilldelar etiketter, gör provisioning av diskarna manuellt. Och dÄ gÄr det att skala.
Och just den tredje varianten av lokal lagring hjÀlper att förenkla detta nÄgot. Som jag redan har betonat, Àr det ett noggrant arbete med instÀllningar som i slutÀnden hjÀlper att fÄ ut maximal prestanda.
Jag har en andra frÄga som Àr relaterad till detta. Kubernetes Àr utformad sÄ att vi inte ska bry oss om vi förlorar en nod eller inte. Vad ska vi göra i det hÀr fallet om vi har förlorat noden dÀr vÄr shard finns?
Ja, Kubernetes positionerade sig frÄn början sÄ att vÄr relation till vÄra poddar Àr som boskap, men hÀr blir varje disk nÄgot som liknar ett husdjur. Det finns ett problem med att vi inte kan slÀnga dem hur som helst. Och utvecklingen av Kubernetes gÄr i en riktning dÀr vi inte kan helt hantera detta filosofiskt som helt förbrukningsbara resurser.
Nu till den praktiska frÄgan. Vad ska man göra om en nod som hade disken försvann? HÀr löser man problemet pÄ en högre nivÄ. I fallet med ClickHouse har vi replikat som arbetar pÄ en högre nivÄ, alltsÄ pÄ ClickHouse-nivÄ.
Vad blir dispositionen? DevOps ansvarar för att inga data gÄr förlorade. De mÄste korrekt stÀlla in replikeringen och följa upp sÄ att replikeringen utförs. I replikatet pÄ ClickHouse-nivÄ mÄste data duplikeras. Det hÀr Àr inte en uppgift som operatören löser. Och det Àr inte en uppgift som Kubernetes löser. Det ligger pÄ ClickHouse-nivÄ.
Vad ska man göra om ni har en fysisk nod som har fallit bort? SÄ det blir nödvÀndigt att sÀtta upp en ny, korrekt provisionera en disk pÄ den, applicera labels. Och efter det kommer den att uppfylla kraven sÄ att Kubernetes kan starta en instans av podden pÄ den. Kubernetes kommer att starta den. Ni har ju inte tillrÀckligt med pods enligt det angivna antalet. Den kommer att gÄ igenom cykeln som jag visade. Och pÄ den översta nivÄn kommer ClickHouse att förstÄ att en replika har kommit in, den Àr fortfarande tom och vi mÄste börja överföra data till den. D.v.s. den hÀr processen Àr fortfarande dÄligt automatiserad.
Tack för presentationen! NÀr det sker olika problem, faller operatören och startar om, och under den tiden kommer det in hÀndelser, hanterar ni detta pÄ nÄgot sÀtt?
Vad hÀnder om operatören har fallit och startat om, eller hur?
Ja. Och under den tiden kom hÀndelser.
Uppgiften om vad man ska göra i det hÀr fallet delas delvis mellan operatören och Kubernetes. Kubernetes har möjlighet att Äterspela den intrÀffade hÀndelsen. Den Äterspelar. Och operatörens uppgift Àr att se till att nÀr han fÄr en replay av hÀndelselogg, sÄ Àr dessa hÀndelser idempotenta. SÄ att en upprepning av samma hÀndelse inte bryter vÄr system. Och vÄr operatör klarar av den uppgiften.
Hej! Tack för presentationen! Dmitry Zavyalov, företaget Smedova. Planeras det att lÀgga till möjlighet att konfigurera operatören med haproxy? Det skulle vara intressant med nÄgon annan lastbalanserare Àn den standardmÀssiga, som Àr smart och förstÄr att det verkligen handlar om ClickHouse.
Pratar ni om Ingress?
Ja, ersÀtt Ingress med haproxy. I haproxy kan man ange klustrets topologi, dÀr den har repliker.
Vi har Ă€nnu inte tĂ€nkt pĂ„ det. Om ni behöver det och kan förklara varför det behövs, sĂ„ kan det genomföras, speciellt om ni vill delta. Vi kommer gĂ€rna att övervĂ€ga alternativet. Kort svar â nej, vi har för nĂ€rvarande inte den funktionen. Tack för tipset, vi kommer att titta pĂ„ det. Om ni ocksĂ„ kan förklara use case och varför det behövs i praktiken, till exempel, om ni skapar issues pĂ„ GitHub, sĂ„ vore det fantastiskt.
Det finns redan.
Bra. Vi Àr öppna för alla förslag. Och haproxy sÀtts pÄ to-do-listan. To-do-listan vÀxer och minskar inte för tillfÀllet. Men det Àr bra, det betyder att produkten Àr efterfrÄgad.
KĂ€lla: habr.com
