Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar

Med databasen Apache Cassandra och behovet av att driva den inom en infrastruktur baserad pÄ Kubernetes stöter vi regelbundet pÄ utmaningar. I detta material delar vi med oss av vÄr syn pÄ nödvÀndiga steg, kriterier och befintliga lösningar (inklusive en översikt av operatörer) för migrering av Cassandra till K8s.

«Den som kan styra en kvinna kan ocksÄ styra en stat»

Vem Àr egentligen Cassandra? Det Àr ett distribuerat lagringssystem som Àr avsett för att hantera stora datamÀngder och som samtidigt sÀkerstÀller hög tillgÀnglighet utan en enda punkt av fel. Projektet behöver knappast nÄgon lÄng introduktion, sÄ jag kommer att nÀmna bara de grundlÀggande kÀnnetecknen hos Cassandra som Àr relevanta för denna specifika artikel:

  • Cassandra Ă€r skriven i Java.
  • Cassandra-topologin inkluderar flera nivĂ„er:
    • Nod — en distribuerad instans av Cassandra;
    • Rack — en grupp av Cassandra-instanser som Ă€r förenade av nĂ„gon egenskap och befinner sig inom samma datacenter;
    • Datacenter — en samling av alla grupper av Cassandra-instanser som Ă€r belĂ€gna inom ett datacenter;
    • Kluster — en samling av alla datacenter.
  • För att identifiera en nod anvĂ€nder Cassandra IP-adressen.
  • För att snabba upp skriv- och lĂ€soperationer lagrar Cassandra en del av data i det operativa minnet.

Nu gÄr vi till den potentiella flytten till Kubernetes.

Checklista för migration

NÀr vi pratar om migreringen av Cassandra till Kubernetes hoppas vi att det blir mer bekvÀmt att hantera den efter flytten. Vad krÀvs för detta och vad kan hjÀlpa i processen?

1. Lagring för data

Som nĂ€mnts tidigare lagrar Cassandra en del av data i det operativa minnet — i Memtable. Men det finns ocksĂ„ en annan del av data som sparas pĂ„ disken — i form av SSTable. Till dessa data lĂ€ggs en enhet som kallas Commit Log — poster om alla transaktioner som ocksĂ„ sparas pĂ„ disken.

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar
Schema för skrivtransaktioner i Cassandra

I Kubernetes kan vi anvÀnda PersistentVolume för att lagra data. Tack vare beprövade mekanismer blir det enklare att arbeta med data i Kubernetes varje Är.

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar
Vi tilldelar varje pod med Cassandra sitt eget PersistentVolume

Det Àr viktigt att notera att Cassandra i sig sjÀlv innebÀr datareplication och erbjuder inbyggda mekanismer för detta. SÄ om du bygger en Cassandra-kluster med mÄnga noder, finns det ingen anledning att anvÀnda distribuerade system som Ceph eller GlusterFS för lagring av data. I detta fall Àr det logiskt att lagra data pÄ nodens disk med hjÀlp av lokala persistenta diskar eller montering hostPath.

En annan frÄga Àr om du vill skapa en separat miljö för utvecklare för varje funktion-branch. I det hÀr fallet Àr en korrekt metod att sÀtta upp en Cassandra-nod och lagra data i en distribuerad lagringslösning, vilket innebÀr att nÀmnda Ceph och GlusterFS blir ett alternativ. DÄ kan utvecklaren vara sÀker pÄ att de inte förlorar testdata Àven vid förlust av en av noderna i Kubernetes-klustret.

2. Övervakning

NÀstan det enda alternativet för att implementera övervakning i Kubernetes Àr Prometheus (vi har pratat om detta i detalj i den motsvarande rapporten). Hur Àr lÀget med Cassandra nÀr det kommer till exporter för metrik för Prometheus? Och, vad som Àr Ànnu viktigare, med lÀmpliga dashboards för Grafana?

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar
Exempel pÄ utseende av grafer i Grafana för Cassandra

Det finns totalt tvÄ exporters: jmx_exporter och cassandra_exporter.

Vi valde den första, eftersom:

  1. JMX Exporter vÀxer och utvecklas, medan Cassandra Exporter inte har fÄtt tillrÀckligt med stöd frÄn gemenskapen. Cassandra Exporter stöder fortfarande inte de flesta versioner av Cassandra.
  2. Det gÄr att köra den som javaagent genom att lÀgga till flaggan -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. För den finns det en tillfredstÀllande dashboard, som Àr inkompatibel med Cassandra Exporter.

3. Val av Kubernetes-primitiver

Enligt den ovanstÄende strukturen av Cassandra-klustret, lÄt oss försöka översÀtta allt som beskrivs dÀr till Kubernetes-terminologi:

  • Cassandra Node → Pod
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → en pool av StatefulSets
  • Cassandra Cluster → ???

Det visar sig att det saknas en extra entitet för att hantera hela Cassandra-klustret samtidigt. Men om nĂ„got saknas kan vi skapa det! I Kubernetes finns mekanismen för att definiera egna resurser avsedd för detta — ) för sjĂ€lva.

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar
Deklaration av ytterligare resurser för loggar och aviseringar

Men en egen resurs betyder ingenting i sig: det behövs ju en kontroller. Kanske behöver vi hjĂ€lp av Kubernetes-operatorer


4. Identifiering av poddar

Enligt ovanstĂ„ende punkt kom vi överens om att en nod i Cassandra motsvarar en pod i Kubernetes. Men IP-adresserna för poddar kommer att vara olika varje gĂ„ng. Identifieringen av noden i Cassandra sker just baserat pĂ„ IP-adressen
 Det innebĂ€r att efter varje borttagning av en pod kommer Cassandra-klustret att lĂ€gga till en ny nod.

Det finns lösningar, och inte bara en:

  1. Vi kan hÄlla reda pÄ vÀrdidentifierare (UUID:er som entydigt identifierar Cassandra-instans) eller pÄ IP-adresser och spara allt detta i vissa strukturer/tabeller. Metoden har tvÄ huvudsakliga nackdelar:
    • Risk för en kapplöpningstillstĂ„nd om tvĂ„ noder faller ner samtidigt. NĂ€r noderna startas kommer Cassandra-noderna att försöka begĂ€ra en IP-adress frĂ„n tabellen samtidigt och konkurrera om samma resurs.
    • Om en Cassandra-nod har förlorat sina data kan vi inte lĂ€ngre identifiera den.
  2. Den andra lösningen verkar vara en liten hack, men trots det: vi kan skapa Service med ClusterIP för varje Cassandra-nod. Problemet med denna implementation:
    • Om det finns mĂ„nga noder i Cassandra-klustret mĂ„ste vi skapa vĂ€ldigt mĂ„nga Service:er.
    • Möjligheten till ClusterIP implementeras via iptables. Detta kan bli ett problem om det finns mĂ„nga (1000
 eller till och med 100?) noder i Cassandra-klustret. Trots allt kan lastbalansering pĂ„ basis av IPVS lösa detta problem.
  3. Den tredje lösningen Àr att anvÀnda klusternoder för Cassandra-noder istÀllet för en dedikerad pod-nÀtverk genom att aktivera instÀllningen hostNetwork: true. Denna metod medför vissa begrÀnsningar:
    • Vid byte av noder. Den nya noden mĂ„ste ha samma IP-adress som den tidigare (i moln som AWS, GCP Ă€r detta praktiskt taget omöjligt);
    • Genom att anvĂ€nda klusternĂ€tverket börjar vi konkurrera om nĂ€tverksresurser. DĂ€rför blir det problematiskt att ha mer Ă€n en pod med Cassandra pĂ„ samma klusternod.

5. SĂ€kerhetskopior

Vi vill spara en fullstÀndig version av datan för en Cassandra-nod enligt schema. Kubernetes erbjuder en bekvÀm möjlighet med hjÀlp av CronJob, men hÀr stöter vi pÄ hinder pÄ grund av sjÀlva Cassandra.

Jag vill pÄminna att en del av datan i Cassandra lagras i minnet. För att göra en fullstÀndig sÀkerhetskopia mÄste data frÄn minnet (Memtables) överföras till disk (SSTables). Vid detta ögonblick slutar Cassandra-noden ta emot anslutningar och faller helt ur klustrets drift.

DĂ€refter tas en sĂ€kerhetskopia (snapshot) och schemat sparas (keyspace). HĂ€r visar det sig att enbart en sĂ€kerhetskopiering inte ger oss nĂ„got: vi behöver spara identifierarna för de data som noden Cassandra ansvarade för — dessa Ă€r speciella token.

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar
Tokenfördelning för att identifiera vilka data som Cassandra-noder ansvarar för.

Ett exempel pÄ skript för att ta sÀkerhetskopior frÄn Cassandra via Google i Kubernetes kan hittas pÄ denna lÀnk. Den enda punkten som skriptet inte tar hÀnsyn till Àr ÄterstÀllning av data pÄ noden innan en snapshot tas. Det vill sÀga, sÀkerhetskopieringen utförs inte för det aktuella tillstÄndet utan för ett tidigare tillstÄnd. Men detta hjÀlper till att hÄlla noden i drift, vilket verkar vÀldigt logiskt.

set -eu

if [[ -z "$1" ]]; then
  info "VĂ€nligen ange ett keyspace"
  exit 1
fi

KEYSPACE="$1"

result=$(nodetool snapshot "${KEYSPACE}")

if [[ $? -ne 0 ]]; then
  echo "Fel vid skapande av snapshot"
  exit 1
fi

timestamp=$(echo "$result" | awk '/Snapshot directory: / { print $3 }')

mkdir -p /tmp/backup

for path in $(find "/var/lib/cassandra/data/${KEYSPACE}" -name $timestamp); do
  table=$(echo "${path}" | awk -F "[/-]" '{print $7}')
  mkdir /tmp/backup/$table
  mv $path /tmp/backup/$table
done


tar -zcf /tmp/backup.tar.gz -C /tmp/backup .

nodetool clearsnapshot "${KEYSPACE}"

Ett exempel pÄ bash-skript för att ta en sÀkerhetskopia frÄn en Cassandra-nod.

FÀrdiga lösningar för Cassandra i Kubernetes.

Vilka lösningar anvÀnds för att köra Cassandra i Kubernetes just nu, och vilken av dem passar bÀst för de uppsatta kraven?

1. Lösningar baserade pÄ StatefulSet eller Helm-charts.

Att anvÀnda grundlÀggande funktioner i StatefulSets för att starta en Cassandra-kluster Àr ett bra alternativ. Med hjÀlp av en Helm-chart och Go-mallar kan anvÀndaren erbjudas ett flexibelt grÀnssnitt för att implementera Cassandra.

Oftast fungerar det bra
 tills nĂ„got ovĂ€ntat intrĂ€ffar — till exempel nĂ€r en nod gĂ„r sönder. De standardverktyg som Kubernetes tillhandahĂ„ller kan helt enkelt inte ta hĂ€nsyn till alla ovan nĂ€mnda sĂ€rskildheter. Dessutom Ă€r denna metod mycket begrĂ€nsad i hur den kan skalas för mer komplex anvĂ€ndning: byte av noder, sĂ€kerhetskopiering, Ă„terstĂ€llning, övervakning, etc.

Representanter:

BÄda chartsen Àr lika bra, men Àr ÀndÄ mottagliga för de problem som beskrivits ovan.

2. Lösningar baserade pÄ Kubernetes Operator.

Dessa alternativ Àr mer intressanta, eftersom de erbjuder omfattande möjligheter för klusterhantering. För att designa en Cassandra-operator, liksom alla andra databaser, ser en bra mönster ut som Sidecar Controller CRD:

Migrering av Cassandra till Kubernetes: sÀrdrag och lösningar
Schema för nodhantering i en korrekt designad Cassandra-operator.

LÄt oss titta pÄ befintliga operators.

1. Cassandra-operator frÄn Instaclustr

  • GitHub
  • Status: Alpha
  • Licens: Apache 2.0
  • Implementerad pĂ„: Java

Detta Àr verkligen ett mycket lovande och aktivt vÀxande projekt frÄn ett företag som erbjuder hanterade distributioner av Cassandra. Det anvÀnder, som nÀmnts ovan, en sidecar-container som tar emot kommandon via HTTP. Skrivet i Java, sÄ ibland saknar det mer avancerad funktionalitet frÄn biblioteket client-go. Dessutom stöder inte operatören olika Racks för ett och samma Datacenter.

Men operatören har fördelar som stöd för övervakning, högre nivÄhantering av kluster via CRD och till och med dokumentation för att ta sÀkerhetskopior.

2. Navigator frÄn Jetstack

  • GitHub
  • Status: Alpha
  • Licens: Apache 2.0
  • Implementerad pĂ„: Golang

Operatören Àr avsedd för distribution av DB-as-a-Service. För nÀrvarande stöder den tvÄ databaser: Elasticsearch och Cassandra. Den innehÄller intressanta lösningar som databaskontroll via RBAC (för detta startas en separat navigator-apiserver). Ett intressant projekt som Àr vÀrt att titta nÀrmare pÄ, men den senaste committen gjordes för ett och ett halvt Är sedan, vilket uppenbart minskar dess potential.

3. Cassandra-operator frÄn vgkowski

  • GitHub
  • Status: Alpha
  • Licens: Apache 2.0
  • Implementerad pĂ„: Golang

Vi valde att inte ta den "pÄ allvar" eftersom den senaste committen till repositoryn gjordes för mer Àn ett Är sedan. Utvecklingen av operatören har övergetts: den senaste versionen av Kubernetes, som anges som stödd, Àr 1.9.

4. Cassandra-operator frÄn Rook

  • GitHub
  • Status: Alpha
  • Licens: Apache 2.0
  • Implementerad pĂ„: Golang

Operatören utvecklas inte sÄ snabbt som vi skulle vilja. Den har en genomtÀnkt CRD-struktur för klusterhantering, löser problemet med identifikation av noder genom att anvÀnda Service med ClusterIP (den berömda "hacken")... men Àn sÄ lÀnge Àr det allt. Ingen övervakning eller sÀkerhetskopior finns standard just nu (förresten, vi tog oss an övervakningen sjÀlv). Intressant nog kan man ocksÄ distribuera ScyllaDB med hjÀlp av denna operatör.

NB: Denna operatör anvÀndes med nÄgra smÄ modifieringar i ett av vÄra projekt. Inga problem med operatörens funktion över hela tiden (~4 mÄnaders drift) har observerats.

5. CassKop frÄn Orange

  • GitHub
  • Status: Alpha
  • Licens: Apache 2.0
  • Implementerad pĂ„: Golang

Den yngsta operatören pÄ listan: den första committen gjordes den 23 maj 2019. Redan nu har den ett stort antal funktioner frÄn vÄr lista, vilka kan utforskas mer ingÄende i projektets repository. Operatören byggs pÄ den populÀra operator-sdk. Den stöder övervakning "ur lÄdan". Huvudskillnaden frÄn andra operatörer Àr anvÀndningen av CassKop-pluginet, implementerat i Python och anvÀnds för kommunikation mellan Cassandra-noder.

Slutsatser

Antalet metoder och möjliga alternativ för att migrera Cassandra till Kubernetes talar för sig sjÀlv: Àmnet Àr efterfrÄgat.

Vid det hÀr laget kan du prova nÄgot av det ovanstÄende pÄ egen risk: ingen av utvecklarna garanterar 100% drift av sina lösningar i produktionsmiljö. Men redan nu ser mÄnga produkter lovande ut för att kunna anvÀnda dem i utvecklingsmiljöer.

Jag tror att i framtiden kommer denna kvinna pÄ skeppet att vara pÄ sin plats!

P.S.

LÀs Àven i vÄr blogg:

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster