
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.

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.

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 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 ). 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?

Exempel pÄ utseende av grafer i Grafana för Cassandra
Det finns totalt tvÄ exporters: och .
Vi valde den första, eftersom:
- 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.
- Det gÄr att köra den som javaagent genom att lÀgga till flaggan
-javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180. - För den finns det , 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 â .

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 âŠ
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:
- 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.
- 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 lösa detta problem.
- 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 , 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.

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Ä . 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:

Schema för nodhantering i en korrekt designad Cassandra-operator.
LÄt oss titta pÄ befintliga operators.
1. Cassandra-operator frÄn Instaclustr
- 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
- 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
- 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
- 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 ). 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
- 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 , 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
