Migrering af Cassandra til Kubernetes: funktioner og løsninger

Migrering af Cassandra til Kubernetes: funktioner og løsninger

Vi støder jævnligt på Apache Cassandra-databasen og behovet for at betjene den i en Kubernetes-baseret infrastruktur. I dette materiale vil vi dele vores vision om de nødvendige trin, kriterier og eksisterende løsninger (herunder en oversigt over operatører) til at migrere Cassandra til K8s.

"Den, der kan regere en kvinde, kan også regere staten"

Hvem er Cassandra? Det er et distribueret lagringssystem designet til at håndtere store mængder data og samtidig sikre høj tilgængelighed uden et enkelt fejlpunkt. Projektet behøver næppe en lang introduktion, så jeg vil kun give de vigtigste træk ved Cassandra, som vil være relevante i forbindelse med en specifik artikel:

  • Cassandra er skrevet på Java.
  • Cassandra-topologien omfatter flere niveauer:
    • Node - en installeret Cassandra-instans;
    • Rack er en gruppe af Cassandra-forekomster, forenet af nogle karakteristika, placeret i det samme datacenter;
    • Datacenter - en samling af alle grupper af Cassandra-instanser placeret i ét datacenter;
    • Cluster er en samling af alle datacentre.
  • Cassandra bruger en IP-adresse til at identificere en node.
  • For at fremskynde skrive- og læseoperationer gemmer Cassandra nogle af dataene i RAM.

Nu - til den faktiske potentielle flytning til Kubernetes.

Tjekliste for overførsel

Når vi taler om migreringen af ​​Cassandra til Kubernetes, håber vi, at det med flytningen bliver mere bekvemt at administrere. Hvad vil der kræves til dette, hvad vil hjælpe med dette?

1. Datalagring

Som det allerede er blevet afklaret, gemmer Cassanda en del af dataene i RAM - in Huskes. Men der er en anden del af dataene, der gemmes på disken - i formen SSTable. En enhed føjes til disse data Commit Log — registreringer af alle transaktioner, som også gemmes på disken.

Migrering af Cassandra til Kubernetes: funktioner og løsninger
Skriv transaktionsdiagram i Cassandra

I Kubernetes kan vi bruge PersistentVolume til at gemme data. Takket være gennemprøvede mekanismer bliver arbejdet med data i Kubernetes lettere hvert år.

Migrering af Cassandra til Kubernetes: funktioner og løsninger
Vi vil allokere vores egen PersistentVolume til hver Cassandra pod

Det er vigtigt at bemærke, at Cassandra selv indebærer datareplikering og tilbyder indbyggede mekanismer til dette. Derfor, hvis du bygger en Cassandra-klynge fra et stort antal noder, er der ingen grund til at bruge distribuerede systemer som Ceph eller GlusterFS til datalagring. I dette tilfælde ville det være logisk at gemme data på værtsdisken vha lokale persistente diske eller montering hostPath.

Et andet spørgsmål er, om du vil oprette et separat miljø for udviklere for hver funktionsgren. I dette tilfælde ville den korrekte tilgang være at rejse én Cassandra-node og gemme dataene i et distribueret lager, dvs. de nævnte Ceph og GlusterFS vil være dine muligheder. Så vil udvikleren være sikker på, at han ikke vil miste testdata, selvom en af ​​Kuberntes-klyndeknuderne går tabt.

2. Overvågning

Det praktisk talt ubestridte valg til implementering af overvågning i Kubernetes er Prometheus (vi talte om dette i detaljer i relateret rapport). Hvordan har Cassandra det med metrik-eksportører til Prometheus? Og hvad er endnu vigtigere, med matchende dashboards til Grafana?

Migrering af Cassandra til Kubernetes: funktioner og løsninger
Et eksempel på udseendet af grafer i Grafana for Cassandra

Der er kun to eksportører: jmx_eksportør и cassandra_eksportør.

Vi valgte den første for os selv, fordi:

  1. JMX Exporter vokser og udvikler sig, mens Cassandra Exporter ikke har været i stand til at få tilstrækkelig fællesskabsstøtte. Cassandra Exporter understøtter stadig ikke de fleste versioner af Cassandra.
  2. Du kan køre det som en javaagent ved at tilføje et flag -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Der er en til ham passende dashboard, som er inkompatibelt med Cassandra Exporter.

3. Valg af Kubernetes primitiver

I henhold til ovenstående struktur af Cassandra-klyngen, lad os prøve at oversætte alt, hvad der er beskrevet der, til Kubernetes-terminologi:

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

Det viser sig, at der mangler en ekstra enhed til at administrere hele Cassandra-klyngen på én gang. Men hvis noget ikke eksisterer, kan vi skabe det! Kubernetes har en mekanisme til at definere sine egne ressourcer til dette formål - Brugerdefinerede ressourcedefinitioner.

Migrering af Cassandra til Kubernetes: funktioner og løsninger
Erklærer yderligere ressourcer til logfiler og advarsler

Men Custom Resource i sig selv betyder ikke noget: det kræver trods alt controller. Du skal muligvis søge hjælp Kubernetes operatør...

4. Identifikation af bælg

I afsnittet ovenfor blev vi enige om, at én Cassandra-node vil svare til én pod i Kubernetes. Men podernes IP-adresser vil være forskellige hver gang. Og identifikationen af ​​en node i Cassandra er baseret på IP-adressen... Det viser sig, at efter hver fjernelse af en pod, vil Cassandra-klyngen tilføje en ny node.

Der er en vej ud og ikke kun én:

  1. Vi kan føre optegnelser efter værtsidentifikatorer (UUID'er, der unikt identificerer Cassandra-forekomster) eller efter IP-adresser og gemme det hele i nogle strukturer/tabeller. Metoden har to hovedulemper:
    • Risikoen for, at en racetilstand opstår, hvis to noder falder på én gang. Efter stigningen vil Cassandra noder samtidig anmode om en IP-adresse fra bordet og konkurrere om den samme ressource.
    • Hvis en Cassandra-node har mistet sine data, vil vi ikke længere være i stand til at identificere dem.
  2. Den anden løsning virker som et lille hack, men ikke desto mindre: vi kan oprette en tjeneste med ClusterIP for hver Cassandra-node. Problemer med denne implementering:
    • Hvis der er mange noder i en Cassandra-klynge, bliver vi nødt til at oprette en masse tjenester.
    • ClusterIP-funktionen implementeres via iptables. Dette kan blive et problem, hvis Cassandra-klyngen har mange (1000... eller endda 100?) noder. Selvom afbalancering baseret på IPVS kan løse dette problem.
  3. Den tredje løsning er at bruge et netværk af noder til Cassandra noder i stedet for et dedikeret netværk af pods ved at aktivere indstillingen hostNetwork: true. Denne metode pålægger visse begrænsninger:
    • For at udskifte enheder. Det er nødvendigt, at den nye node skal have samme IP-adresse som den forrige (i skyer som AWS, GCP er dette næsten umuligt at gøre);
    • Ved at bruge et netværk af klynge noder begynder vi at konkurrere om netværksressourcer. Derfor vil det være problematisk at placere mere end én pod med Cassandra på én klyngenode.

5. Sikkerhedskopier

Vi ønsker at gemme en fuld version af en enkelt Cassandra-nodes data på en tidsplan. Kubernetes giver en praktisk funktion ved hjælp af CronJob, men her sætter Cassandra selv en eger i vores hjul.

Lad mig minde dig om, at Cassandra gemmer nogle af dataene i hukommelsen. For at lave en fuld sikkerhedskopi skal du bruge data fra hukommelsen (Memtables) flyt til disk (SSTables). På dette tidspunkt holder Cassandra-knuden op med at acceptere forbindelser og lukker fuldstændigt ned fra klyngen.

Herefter fjernes sikkerhedskopien (snapshot) og skemaet er gemt (tasterum). Og så viser det sig, at bare en sikkerhedskopi ikke giver os noget: vi skal gemme de dataidentifikatorer, som Cassandra-knuden var ansvarlig for - disse er specielle tokens.

Migrering af Cassandra til Kubernetes: funktioner og løsninger
Distribution af tokens for at identificere, hvilke data Cassandra noder er ansvarlige for

Et eksempel på script til at tage en Cassandra backup fra Google i Kubernetes kan findes på dette link. Det eneste punkt, som scriptet ikke tager højde for, er at nulstille data til noden, før det tages snapshot. Det vil sige, at sikkerhedskopieringen ikke udføres for den aktuelle tilstand, men for en tilstand lidt tidligere. Men dette hjælper med ikke at tage noden ud af drift, hvilket virker meget logisk.

set -eu

if [[ -z "$1" ]]; then
  info "Please provide a keyspace"
  exit 1
fi

KEYSPACE="$1"

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

if [[ $? -ne 0 ]]; then
  echo "Error while making 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}"

Et eksempel på et bash-script til at tage en sikkerhedskopi fra en Cassandra-node

Klare løsninger til Cassandra i Kubernetes

Hvad bruges i øjeblikket til at implementere Cassandra i Kubernetes, og hvilken af ​​disse passer bedst til de givne krav?

1. Løsninger baseret på StatefulSet- eller Helm-diagrammer

Brug af de grundlæggende StatefulSets-funktioner til at køre en Cassandra-klynge er en god mulighed. Ved at bruge Helm-diagrammet og Go-skabelonerne kan du give brugeren en fleksibel grænseflade til at implementere Cassandra.

Dette fungerer normalt fint... indtil der sker noget uventet, såsom en knudefejl. Standard Kubernetes-værktøjer kan simpelthen ikke tage højde for alle de funktioner, der er beskrevet ovenfor. Derudover er denne tilgang meget begrænset med hensyn til, hvor meget den kan udvides til mere komplekse anvendelser: nodeudskiftning, backup, gendannelse, overvågning osv.

Repræsentanter:

Begge diagrammer er lige gode, men er underlagt de ovenfor beskrevne problemer.

2. Løsninger baseret på Kubernetes Operator

Sådanne muligheder er mere interessante, fordi de giver rigelige muligheder for at styre klyngen. For at designe en Cassandra-operatør, som enhver anden database, ser et godt mønster ud som Sidecar <-> Controller <-> CRD:

Migrering af Cassandra til Kubernetes: funktioner og løsninger
Nodestyringsskema i en veldesignet Cassandra-operatør

Lad os se på eksisterende operatører.

1. Cassandra-operatør fra instaclustr

  • GitHub
  • Beredskab: Alpha
  • Licens: Apache 2.0
  • Implementeret i: Java

Dette er virkelig et meget lovende og aktivt udviklende projekt fra en virksomhed, der tilbyder administrerede Cassandra-implementeringer. Den bruger, som beskrevet ovenfor, en sidevognsbeholder, der accepterer kommandoer via HTTP. Skrevet i Java, mangler det nogle gange den mere avancerede funktionalitet i client-go-biblioteket. Operatøren understøtter heller ikke forskellige racks til ét datacenter.

Men operatøren har sådanne fordele som støtte til overvågning, klyngestyring på højt niveau ved hjælp af CRD og endda dokumentation til at lave sikkerhedskopier.

2. Navigator fra Jetstack

  • GitHub
  • Beredskab: Alpha
  • Licens: Apache 2.0
  • Implementeret i: Golang

En erklæring designet til at implementere DB-as-a-Service. Understøtter i øjeblikket to databaser: Elasticsearch og Cassandra. Den har så interessante løsninger som databaseadgangskontrol via RBAC (til dette har den sin egen separate navigator-apiserver). Et interessant projekt, der ville være værd at se nærmere på, men den sidste commit blev lavet for halvandet år siden, hvilket klart reducerer potentialet.

3. Cassandra-operatør af vgkowski

  • GitHub
  • Beredskab: Alpha
  • Licens: Apache 2.0
  • Implementeret i: Golang

De betragtede det ikke "seriøst", da den sidste commit til depotet var for mere end et år siden. Operatørudvikling er opgivet: den seneste version af Kubernetes rapporteret som understøttet er 1.9.

4. Cassandra-operatør af Rook

  • GitHub
  • Beredskab: Alpha
  • Licens: Apache 2.0
  • Implementeret i: Golang

En operatør, hvis udvikling ikke går så hurtigt, som vi gerne ville. Det har en gennemtænkt CRD-struktur til klyngestyring, løser problemet med at identificere noder ved hjælp af Service med ClusterIP (det samme "hack")... men det var alt for nu. Der er i øjeblikket ingen overvågning eller sikkerhedskopier ud af boksen (i øvrigt er vi til overvågning tog det selv). Et interessant punkt er, at du også kan implementere ScyllaDB ved hjælp af denne operatør.

NB: Vi brugte denne operatør med mindre ændringer i et af vores projekter. Der blev ikke bemærket problemer i operatørens arbejde i hele driftsperioden (~4 måneders drift).

5. CassKop fra Orange

  • GitHub
  • Beredskab: Alpha
  • Licens: Apache 2.0
  • Implementeret i: Golang

Den yngste operatør på listen: den første commit blev foretaget den 23. maj 2019. Allerede nu har det i sit arsenal et stort antal funktioner fra vores liste, hvoraf flere detaljer kan findes i projektarkivet. Operatøren er bygget på basis af det populære operatør-sdk. Understøtter overvågning ud af æsken. Den største forskel fra andre operatører er brugen CassKop plugin, implementeret i Python og brugt til kommunikation mellem Cassandra noder.

Fund

Antallet af tilgange og mulige muligheder for at overføre Cassandra til Kubernetes taler for sig selv: emnet er efterspurgt.

På dette stadium kan du prøve noget af ovenstående på egen risiko og risiko: ingen af ​​udviklerne garanterer 100 % drift af deres løsning i et produktionsmiljø. Men allerede nu ser mange produkter lovende ud at prøve at bruge i udviklingsbænke.

Jeg tror, ​​at denne kvinde på skibet i fremtiden vil komme til nytte!

PS

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar