Migració de Cassandra a Kubernetes: característiques i solucions

Migració de Cassandra a Kubernetes: característiques i solucions

Ens trobem regularment amb la base de dades Apache Cassandra i la necessitat d'operar-la dins d'una infraestructura basada en Kubernetes. En aquest material, compartirem la nostra visió dels passos necessaris, els criteris i les solucions existents (inclosa una visió general dels operadors) per migrar Cassandra a K8s.

"Qui pot governar una dona també pot governar l'estat"

Qui és Cassandra? És un sistema d'emmagatzematge distribuït dissenyat per gestionar grans volums de dades alhora que garanteix una alta disponibilitat sense un únic punt d'error. El projecte no necessita una introducció llarga, així que donaré només les característiques principals de Cassandra que seran rellevants en el context d'un article específic:

  • Cassandra està escrit en Java.
  • La topologia Cassandra inclou diversos nivells:
    • Node: una instància de Cassandra desplegada;
    • Rack és un grup d'instàncies de Cassandra, unides per alguna característica, situades al mateix centre de dades;
    • Centre de dades: una col·lecció de tots els grups d'instàncies de Cassandra ubicades en un centre de dades;
    • Clúster és una col·lecció de tots els centres de dades.
  • Cassandra utilitza una adreça IP per identificar un node.
  • Per accelerar les operacions d'escriptura i lectura, Cassandra emmagatzema algunes de les dades a la memòria RAM.

Ara, al moviment potencial real a Kubernetes.

Llista de control per a la transferència

Parlant de la migració de Cassandra a Kubernetes, esperem que amb el trasllat sigui més còmode de gestionar. Què es requerirà per a això, què ajudarà amb això?

1. Emmagatzematge de dades

Com ja s'ha aclarit, Cassanda emmagatzema part de les dades a la memòria RAM Memtable. Però hi ha una altra part de les dades que es desa al disc: en el formulari SSTable. S'afegeix una entitat a aquestes dades Registre de compromís — registres de totes les transaccions, que també es guarden al disc.

Migració de Cassandra a Kubernetes: característiques i solucions
Escriu un diagrama de transaccions a Cassandra

A Kubernetes, podem utilitzar PersistentVolume per emmagatzemar dades. Gràcies a mecanismes provats, treballar amb dades a Kubernetes és cada any més fàcil.

Migració de Cassandra a Kubernetes: característiques i solucions
Assignarem el nostre propi volum persistent a cada pod de Cassandra

És important tenir en compte que la mateixa Cassandra implica la replicació de dades, oferint mecanismes integrats per a això. Per tant, si esteu construint un clúster Cassandra a partir d'un gran nombre de nodes, no cal que utilitzeu sistemes distribuïts com Ceph o GlusterFS per a l'emmagatzematge de dades. En aquest cas, seria lògic emmagatzemar dades al disc amfitrió utilitzant discs locals persistents o muntatge hostPath.

Una altra pregunta és si voleu crear un entorn independent per als desenvolupadors per a cada branca de funcions. En aquest cas, l'enfocament correcte seria augmentar un node Cassandra i emmagatzemar les dades en un emmagatzematge distribuït, és a dir. els esmentats Ceph i GlusterFS seran les vostres opcions. Aleshores, el desenvolupador s'assegurarà que no perdrà les dades de prova encara que es perdi un dels nodes del clúster de Kuberntes.

2. Seguiment

L'opció pràcticament indiscutible per implementar la supervisió a Kubernetes és Prometheus (Vam parlar d'això en detall a informe relacionat). Com està Cassandra amb els exportadors de mètriques per a Prometheus? I, què és encara més important, amb taulers de control coincidents per a Grafana?

Migració de Cassandra a Kubernetes: característiques i solucions
Un exemple de l'aparició de gràfics a Grafana per a Cassandra

Només hi ha dos exportadors: jmx_exporter и cassandra_exporter.

Hem escollit el primer per nosaltres mateixos perquè:

  1. JMX Exporter està creixent i desenvolupant-se, mentre que Cassandra Exporter no ha pogut obtenir prou suport de la comunitat. Cassandra Exporter encara no és compatible amb la majoria de versions de Cassandra.
  2. Podeu executar-lo com a agent java afegint una marca -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. N'hi ha un per a ell quadre de comandament adequat, que és incompatible amb Cassandra Exporter.

3. Selecció de primitives Kubernetes

Segons l'estructura anterior del clúster Cassandra, intentem traduir tot el que s'hi descriu a la terminologia de Kubernetes:

  • Node Cassandra → Pod
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → agrupació de StatefulSets
  • Clúster de Cassandra → ???

Resulta que falta alguna entitat addicional per gestionar tot el clúster Cassandra alhora. Però si alguna cosa no existeix, podem crear-la! Kubernetes disposa d'un mecanisme per definir els seus propis recursos per a aquest propòsit: Definicions de recursos personalitzades.

Migració de Cassandra a Kubernetes: característiques i solucions
Declaració de recursos addicionals per a registres i alertes

Però Custom Resource en si no vol dir res: després de tot, requereix controlador. És possible que hàgiu de buscar ajuda Operador Kubernetes...

4. Identificació de la beina

Al paràgraf anterior, vam acordar que un node Cassandra equivaldrà a un pod a Kubernetes. Però les adreces IP dels pods seran diferents cada vegada. I la identificació d'un node a Cassandra es basa en l'adreça IP... Resulta que després de cada eliminació d'un pod, el clúster Cassandra afegirà un nou node.

Hi ha una sortida, i no només una:

  1. Podem mantenir registres per identificadors d'amfitrió (UUID que identifiquen de manera única les instàncies de Cassandra) o per adreces IP i emmagatzemar-ho tot en algunes estructures/taules. El mètode té dos inconvenients principals:
    • El risc que es produeixi una condició de carrera si dos nodes cauen alhora. Després de l'ascens, els nodes de Cassandra demanaran simultàniament una adreça IP a la taula i competiran pel mateix recurs.
    • Si un node Cassandra ha perdut les seves dades, ja no el podrem identificar.
  2. La segona solució sembla un petit hack, però tanmateix: podem crear un Servei amb ClusterIP per a cada node Cassandra. Problemes amb aquesta implementació:
    • Si hi ha molts nodes en un clúster Cassandra, haurem de crear molts serveis.
    • La funció ClusterIP s'implementa mitjançant iptables. Això pot esdevenir un problema si el clúster Cassandra té molts (1000... o fins i tot 100?) nodes. Encara que equilibri basat en IPVS pot resoldre aquest problema.
  3. La tercera solució és utilitzar una xarxa de nodes per als nodes Cassandra en lloc d'una xarxa dedicada de pods habilitant la configuració hostNetwork: true. Aquest mètode imposa certes limitacions:
    • Per substituir unitats. Cal que el nou node tingui la mateixa adreça IP que l'anterior (en núvols com AWS, GCP això és gairebé impossible de fer);
    • Utilitzant una xarxa de nodes de clúster, comencem a competir pels recursos de la xarxa. Per tant, col·locar més d'un pod amb Cassandra en un node del clúster serà problemàtic.

5. Còpies de seguretat

Volem desar una versió completa de les dades d'un sol node Cassandra en una programació. Kubernetes ofereix una funció convenient per utilitzar CronJob, però aquí la mateixa Cassandra ens posa un radi a les rodes.

Permeteu-me recordar-vos que la Cassandra emmagatzema algunes de les dades a la memòria. Per fer una còpia de seguretat completa, necessiteu dades de la memòria (Memtables) moure al disc (SSTables). En aquest punt, el node Cassandra deixa d'acceptar connexions, tancant completament del clúster.

Després d'això, s'elimina la còpia de seguretat (instantània) i es desa l'esquema (espai de tecles). I aleshores resulta que només una còpia de seguretat no ens dóna res: hem de desar els identificadors de dades dels quals era responsable el node Cassandra: es tracta de fitxes especials.

Migració de Cassandra a Kubernetes: característiques i solucions
Distribució de fitxes per identificar de quines dades són responsables els nodes Cassandra

Es pot trobar un exemple d'script per fer una còpia de seguretat de Cassandra de Google a Kubernetes a aquest enllaç. L'únic punt que l'script no té en compte és restablir les dades al node abans de fer la instantània. És a dir, la còpia de seguretat no es realitza per a l'estat actual, sinó per a un estat una mica anterior. Però això ajuda a no deixar fora de funcionament el node, cosa que sembla molt lògic.

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}"

Un exemple d'un script bash per fer una còpia de seguretat d'un node Cassandra

Solucions preparades per a Cassandra a Kubernetes

Què s'utilitza actualment per desplegar Cassandra a Kubernetes i quin d'aquests s'adapta millor als requisits donats?

1. Solucions basades en gràfics StatefulSet o Helm

L'ús de les funcions bàsiques de StatefulSets per executar un clúster Cassandra és una bona opció. Mitjançant el gràfic Helm i les plantilles Go, podeu proporcionar a l'usuari una interfície flexible per desplegar Cassandra.

Normalment funciona bé... fins que passa alguna cosa inesperada, com ara una fallada del node. Les eines estàndard de Kubernetes simplement no poden tenir en compte totes les funcions descrites anteriorment. A més, aquest enfocament és molt limitat en quant es pot estendre per a usos més complexos: substitució de nodes, còpia de seguretat, recuperació, monitorització, etc.

Representants:

Tots dos gràfics són igualment bons, però estan subjectes als problemes descrits anteriorment.

2. Solucions basades en Kubernetes Operator

Aquestes opcions són més interessants perquè ofereixen àmplies oportunitats per gestionar el clúster. Per dissenyar un operador Cassandra, com qualsevol altra base de dades, un bon patró sembla Sidecar <-> Controller <-> CRD:

Migració de Cassandra a Kubernetes: característiques i solucions
Esquema de gestió de nodes en un operador Cassandra ben dissenyat

Vegem els operadors existents.

1. Cassandra-operador d'instaclustr

  • GitHub
  • Preparació: Alfa
  • Llicència: Apache 2.0
  • Implementat a: Java

De fet, aquest és un projecte molt prometedor i en desenvolupament actiu d'una empresa que ofereix desplegaments gestionats de Cassandra. Com s'ha descrit anteriorment, utilitza un contenidor sidecar que accepta ordres mitjançant HTTP. Escrit en Java, de vegades no té la funcionalitat més avançada de la biblioteca client-go. A més, l'operador no admet diferents bastidors per a un centre de dades.

Però l'operador té avantatges com ara suport per a la supervisió, gestió de clúster d'alt nivell mitjançant CRD i fins i tot documentació per fer còpies de seguretat.

2. Navegador de Jetstack

  • GitHub
  • Preparació: Alfa
  • Llicència: Apache 2.0
  • Implementat a: Golang

Una declaració dissenyada per desplegar DB-as-a-Service. Actualment admet dues bases de dades: Elasticsearch i Cassandra. Té solucions tan interessants com el control d'accés a la base de dades mitjançant RBAC (per a això té el seu propi navegador-apiserver). Un projecte interessant que valdria la pena aprofundir, però l'última aposta es va fer fa un any i mig, fet que en redueix clarament el potencial.

3. Cassandra-operador de vgkowski

  • GitHub
  • Preparació: Alfa
  • Llicència: Apache 2.0
  • Implementat a: Golang

No ho van considerar "de debò", ja que l'últim commit al repositori va ser fa més d'un any. S'ha abandonat el desenvolupament de l'operador: l'última versió de Kubernetes que s'informa com a compatible és la 1.9.

4. Cassandra-operador de Rook

  • GitHub
  • Preparació: Alfa
  • Llicència: Apache 2.0
  • Implementat a: Golang

Un operador el desenvolupament del qual no avança tan ràpid com voldríem. Té una estructura CRD ben pensada per a la gestió de clúster, soluciona el problema d'identificar nodes mitjançant Service with ClusterIP (el mateix "pirateig")... però això és tot de moment. Actualment no hi ha monitorització ni còpies de seguretat fora de la caixa (per cert, estem per a la supervisió ho vam agafar nosaltres mateixos). Un punt interessant és que també podeu implementar ScyllaDB mitjançant aquest operador.

NB: Hem utilitzat aquest operador amb petites modificacions en un dels nostres projectes. No es van notar problemes en el treball de l'operador durant tot el període d'operació (~ 4 mesos de funcionament).

5. CassKop d'Orange

  • GitHub
  • Preparació: Alfa
  • Llicència: Apache 2.0
  • Implementat a: Golang

L'operador més jove de la llista: el primer compromís es va fer el 23 de maig de 2019. Ara ja té al seu arsenal un gran nombre de funcions de la nostra llista, més detalls de les quals es poden trobar al repositori del projecte. L'operador està construït sobre la base del popular operador-sdk. Admet la supervisió fora de la caixa. La principal diferència amb altres operadors és l'ús Connector CassKop, implementat a Python i utilitzat per a la comunicació entre nodes Cassandra.

Troballes

El nombre d'enfocaments i opcions possibles per portar Cassandra a Kubernetes parla per si sol: el tema és molt demandat.

En aquesta etapa, podeu provar qualsevol de les anteriors sota el vostre risc i risc: cap dels desenvolupadors garanteix el 100% del funcionament de la seva solució en un entorn de producció. Però ja, molts productes semblen prometedors per provar-los als bancs de desenvolupament.

Crec que en el futur aquesta dona al vaixell serà útil!

PS

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari