Migration de Cassandra vers Kubernetes : caractéristiques et solutions

Migration de Cassandra vers Kubernetes : caractéristiques et solutions

Avec la base de données Apache Cassandra et la nécessité de l'exploiter dans une infrastructure basée sur Kubernetes, nous y sommes réguliÚrement confrontés. Dans cet article, nous partagerons notre vision des étapes nécessaires, des critÚres et des solutions existantes (y compris un aperçu des opérateurs) pour la migration de Cassandra vers K8s.

« Qui peut gĂ©rer une femme, peut aussi gĂ©rer un État »

Qui est donc Cassandra ? C'est un systÚme de stockage distribué, conçu pour gérer de grands volumes de données, tout en garantissant une haute disponibilité sans point de défaillance unique. Le projet ne nécessite probablement pas une longue présentation, je vais donc simplement évoquer les principales caractéristiques de Cassandra, qui seront pertinentes dans le contexte de cet article :

  • Cassandra est Ă©crite en Java.
  • La topologie de Cassandra comprend plusieurs niveaux :
    • Node — une instance dĂ©ployĂ©e de Cassandra ;
    • Rack — un groupe d'instances Cassandra rĂ©unies par un critĂšre commun, situĂ©es dans le mĂȘme centre de donnĂ©es ;
    • Datacenter — l'ensemble des groupes d'instances Cassandra se trouvant dans un mĂȘme centre de donnĂ©es ;
    • Cluster — l'ensemble de tous les centres de donnĂ©es.
  • Pour identifier un nƓud, Cassandra utilise une adresse IP.
  • Pour la rapiditĂ© des opĂ©rations d'Ă©criture et de lecture, une partie des donnĂ©es de Cassandra est stockĂ©e en mĂ©moire vive.

Maintenant, passons Ă  la potentielle migration vers Kubernetes.

Check-list pour le transfert

En parlant de la migration de Cassandra vers Kubernetes, nous espérons qu'avec ce déménagement, sa gestion deviendra plus facile. Que faudra-t-il pour cela, et qu'est-ce qui pourra aider ?

1. Stockage pour les données

Comme cela a Ă©tĂ© prĂ©cisĂ©, une partie des donnĂ©es de Cassandra est stockĂ©e en mĂ©moire vive — dans le Memtable. Mais il y a aussi une autre partie des donnĂ©es qui est sauvegardĂ©e sur disque, — sous forme de SSTable. À ces donnĂ©es s'ajoute l'entitĂ© Commit Log — des enregistrements de toutes les transactions, qui sont Ă©galement sauvegardĂ©es sur disque.

Migration de Cassandra vers Kubernetes : caractéristiques et solutions
Schéma des transactions d'écriture dans Cassandra

Dans Kubernetes, nous pouvons utiliser PersistentVolume pour le stockage des données. Grùce à des mécanismes éprouvés, travailler avec les données dans Kubernetes devient chaque année de plus en plus facile.

Migration de Cassandra vers Kubernetes : caractéristiques et solutions
Nous allouerons un PersistentVolume Ă  chaque pod Cassandra.

Il est important de noter que Cassandra implique elle-mĂȘme la rĂ©plication des donnĂ©es, offrant pour cela des mĂ©canismes intĂ©grĂ©s. Ainsi, si vous crĂ©ez un cluster Cassandra Ă  partir d'un grand nombre de nƓuds, il n'est pas nĂ©cessaire d'utiliser des systĂšmes de stockage distribuĂ©s comme Ceph ou GlusterFS. Dans ce cas, il serait logique de stocker les donnĂ©es sur le disque du nƓud en utilisant des disques persistants locaux ou un montage hostPath.

Une autre question se pose si vous souhaitez crĂ©er un environnement distinct pour chaque branche de fonctionnalitĂ©s pour les dĂ©veloppeurs. Dans ce cas, l'approche appropriĂ©e serait de dĂ©ployer un nƓud Cassandra et de stocker les donnĂ©es dans un stockage distribuĂ©, c'est-Ă -dire que les mentions de Ceph et GlusterFS deviendront votre option. Ainsi, le dĂ©veloppeur sera assurĂ© de ne pas perdre les donnĂ©es de test mĂȘme en cas de perte d'un des nƓuds du cluster Kubernetes.

2. Surveillance

Le choix pratiquement sans alternative pour la mise en Ɠuvre de la surveillance dans Kubernetes est Prometheus (nous en avons parlĂ© en dĂ©tail dans le rapport correspondant). Comment se comportent Cassandra et les exportateurs de mĂ©triques pour Prometheus ? Et, ce qui est mĂȘme plus important, en ce qui concerne les tableaux de bord appropriĂ©s pour Grafana ?

Migration de Cassandra vers Kubernetes : caractéristiques et solutions
Exemple de l'apparence des graphiques dans Grafana pour Cassandra

Il n'y a que deux exportateurs : jmx_exporter et cassandra_exporter.

Nous avons choisi le premier car :

  1. Le JMX Exporter évolue et se développe, tandis que le Cassandra Exporter n'a pas réussi à obtenir le soutien nécessaire de la communauté. Le Cassandra Exporter ne prend toujours pas en charge la plupart des versions de Cassandra.
  2. Il peut ĂȘtre lancĂ© comme javaagent en ajoutant le drapeau -javaagent:<plugin-dir-name>\/cassandra-exporter.jar=--listen=:9180.
  3. Pour lui, il existe un tableau de bord adéquat, qui n'est pas compatible avec le Cassandra Exporter.

3. Choix des primitives Kubernetes

Selon la structure du cluster Cassandra exposée ci-dessus, essayons de traduire tout ce qui y est décrit en termes de Kubernetes :

  • NƓud Cassandra → Pod
  • Rack Cassandra → StatefulSet
  • Datacenter Cassandra → pool d’StatefulSets
  • Cluster Cassandra → ???

Il semble qu'il manque une entitĂ© supplĂ©mentaire pour gĂ©rer tout le cluster Cassandra Ă  la fois. Mais s'il n'y a pas quelque chose, nous pouvons le crĂ©er ! Dans Kubernetes, il existe un mĂ©canisme de dĂ©finition des ressources personnalisĂ©es pour cela — Custom Resource Definitions.

Migration de Cassandra vers Kubernetes : caractéristiques et solutions
Déclaration de ressources supplémentaires pour les journaux et les alertes

Mais la ressource personnalisĂ©e en elle-mĂȘme ne signifie rien : car elle a besoin d'un contrĂŽleur. Il peut ĂȘtre nĂ©cessaire de faire appel Ă  un opĂ©rateur Kubernetes


4. Identification des pods

Dans le point précédent, nous avons convenu qu'un noeud Cassandra équivaut à un pod dans Kubernetes. Cependant, les adresses IP des pods seront différentes à chaque fois. Et l'identification d'un noeud dans Cassandra se fait précisément sur la base de l'adresse IP
 Il en découle qu'aprÚs chaque suppression de pod, le cluster Cassandra ajoutera un nouveau noeud.

Il existe des solutions, et mĂȘme plusieurs :

  1. Nous pouvons suivre par identifiants de hosts (UUIDs, qui identifient de maniÚre unique les instances de Cassandra) ou par adresses IP et conserver tout cela dans des structures/tableaux. Cette méthode présente deux principaux inconvénients :
    • Le risque d'une condition de course lors de la chute simultanĂ©e de deux noeuds. AprĂšs leur redĂ©marrage, les noeuds Cassandra iront demander une adresse IP Ă  la table en mĂȘme temps et rivaliseront pour la mĂȘme ressource.
    • Si un noeud Cassandra perd ses donnĂ©es, nous ne pourrons plus l'identifier.
  2. La deuxiĂšme solution semble ĂȘtre un petit hack, mais nĂ©anmoins : nous pouvons crĂ©er un Service avec ClusterIP pour chaque noeud Cassandra. Les problĂšmes de cette implĂ©mentation :
    • S'il y a beaucoup de noeuds dans le cluster Cassandra, nous devrons crĂ©er un grand nombre de Services.
    • La possibilitĂ© de ClusterIP est implĂ©mentĂ©e via iptables. Cela peut poser problĂšme si le cluster Cassandra comporte beaucoup (1000
 ou mĂȘme 100 ?) de noeuds. Bien que la rĂ©partition basĂ©e sur IPVS puisse rĂ©soudre ce problĂšme.
  3. La troisiÚme solution consiste à utiliser le réseau de noeuds Cassandra au lieu d'un réseau dédié pour les pods en activant l'option hostNetwork: true. Cette méthode impose certaines restrictions :
    • Sur le remplacement des noeuds. Il est nĂ©cessaire que le nouveau noeud ait exactement la mĂȘme adresse IP que l'ancien (dans des environnements cloud comme AWS, GCP, cela est pratiquement impossible) ;
    • En utilisant le rĂ©seau de noeuds du cluster, nous commençons Ă  rivaliser pour les ressources rĂ©seau. Par consĂ©quent, dĂ©ployer plus d'un pod Cassandra sur un mĂȘme noeud de cluster sera problĂ©matique.

5. Sauvegardes

Nous souhaitons sauvegarder une version complĂšte des donnĂ©es d'un noeud Cassandra selon un planning. Kubernetes offre une possibilitĂ© pratique via CronJob, mais ici, Cassandra elle-mĂȘme nous complique la tĂąche.

Rappelons que Cassandra stocke une partie de ses donnĂ©es en mĂ©moire. Pour effectuer une sauvegarde complĂšte, il faut transfĂ©rer les donnĂ©es de la mĂ©moire (Memtables) vers le disque (SSTables). À ce moment-lĂ , le noeud Cassandra cesse d'accepter des connexions, se retirant complĂštement des opĂ©rations du cluster.

AprĂšs cela, la sauvegarde (snapshot) est rĂ©alisĂ©e et le schĂ©ma est sauvegardĂ© (keyspace). Et ici, on dĂ©couvre que simplement faire une sauvegarde ne nous donne rien : il faut conserver les identifiants des donnĂ©es pour lesquelles le nƓud Cassandra est responsable — ce sont des jetons spĂ©ciaux.

Migration de Cassandra vers Kubernetes : caractéristiques et solutions
Distribution des jetons d'identification pour savoir quelles donnĂ©es sont gĂ©rĂ©es par les nƓuds Cassandra

Un exemple de script pour effectuer une sauvegarde de Cassandra depuis Google sur Kubernetes peut ĂȘtre trouvĂ© Ă  ce lien. Le seul point que le script ne prend pas en compte est la rĂ©initialisation des donnĂ©es sur le nƓud avant de prendre le snapshot. Cela signifie que la sauvegarde n'est pas effectuĂ©e sur l'Ă©tat actuel, mais sur un Ă©tat lĂ©gĂšrement antĂ©rieur. Mais cela aide Ă  ne pas dĂ©connecter le nƓud, ce qui semble trĂšs logique.

set -eu

if [[ -z "$1" ]]; then
  info "Veuillez fournir un keyspace"
  exit 1
fi

KEYSPACE="$1"

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

if [[ $? -ne 0 ]]; then
  echo "Erreur lors de la création du 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}"

Exemple de script bash pour effectuer une sauvegarde d'un nƓud Cassandra

Solutions prĂȘtes Ă  l'emploi pour Cassandra sur Kubernetes

Que sont actuellement utilisées pour déployer Cassandra sur Kubernetes et quelles sont celles qui répondent le mieux aux exigences données ?

1. Solutions basées sur StatefulSet ou Helm charts

Utiliser les fonctionnalités de base de StatefulSets pour lancer un cluster Cassandra est une bonne option. En utilisant un Helm chart et des modÚles Go, on peut offrir à l'utilisateur une interface flexible pour déployer Cassandra.

Cela fonctionne gĂ©nĂ©ralement bien
 jusqu'Ă  ce qu'un imprĂ©vu survienne — par exemple, qu'un nƓud tombe en panne. Les outils standard de Kubernetes ne peuvent tout simplement pas prendre en compte toutes les caractĂ©ristiques ci-dessus. De plus, cette approche est trĂšs limitĂ©e dans la mesure oĂč elle peut ĂȘtre Ă©tendue pour des utilisations plus complexes : remplacement de nƓuds, sauvegarde, rĂ©cupĂ©ration, surveillance, etc.

Représentants :

Les deux charts sont également bons, mais sont sujets aux problÚmes mentionnés ci-dessus.

2. Solutions basées sur Kubernetes Operator

Ces options sont plus intéressantes car elles offrent de larges possibilités de gestion du cluster. Pour concevoir un opérateur Cassandra, comme pour toute autre base de données, un bon modÚle ressemble à Sidecar Controller CRD :

Migration de Cassandra vers Kubernetes : caractéristiques et solutions
SchĂ©ma de gestion des nƓuds dans un opĂ©rateur Cassandra correctement conçu

Examinons les opérateurs existants.

1. Cassandra-operator d'instaclustr

  • GitHub
  • État : Alpha
  • Licence : Apache 2.0
  • RĂ©alisĂ© en : Java

C'est un projet trĂšs prometteur et en pleine Ă©volution d'une entreprise qui propose des dĂ©ploiements Cassandra gĂ©rĂ©s. Comme mentionnĂ© ci-dessus, il utilise un conteneur sidecar qui reçoit des commandes via HTTP. Écrit en Java, il lui manque parfois certaines fonctionnalitĂ©s avancĂ©es de la bibliothĂšque client-go. De plus, l'opĂ©rateur ne prend pas en charge diffĂ©rents racks pour un mĂȘme datacenter.

Cependant, l'opĂ©rateur possĂšde des avantages, tels que le support de la surveillance, une gestion de cluster Ă  haut niveau par le biais des CRD et mĂȘme une documentation sur la sauvegarde.

2. Navigator de Jetstack

  • GitHub
  • État : Alpha
  • Licence : Apache 2.0
  • RĂ©alisĂ© en : Golang

Un opérateur destiné à déployer DB-as-a-Service. Actuellement, il prend en charge deux bases de données : Elasticsearch et Cassandra. Il comprend des solutions intéressantes, comme le contrÎle d'accÚs à la base de données via RBAC (pour cela, un serveur d'API navigator séparé est mis en place). C'est un projet intéressant, à examiner, mais le dernier commit a été effectué il y a un an et demi, ce qui réduit clairement son potentiel.

3. Cassandra-operator de vgkowski

  • GitHub
  • État : Alpha
  • Licence : Apache 2.0
  • RĂ©alisĂ© en : Golang

Nous n'avons pas considéré son utilisation « sérieusement », car le dernier commit dans le dépÎt a plus d'un an. Le développement de l'opérateur a été abandonné : la derniÚre version de Kubernetes, annoncée comme prise en charge, est la 1.9.

4. Cassandra-operator de Rook

  • GitHub
  • État : Alpha
  • Licence : Apache 2.0
  • RĂ©alisĂ© en : Golang

Un opĂ©rateur dont le dĂ©veloppement n'avance pas aussi rapidement que souhaitĂ©. Il dispose d'une structure CRD bien pensĂ©e pour la gestion de cluster, rĂ©sout le problĂšme d'identification des nƓuds grĂące Ă  un Service avec ClusterIP (ce fameux « hack »)... mais pour l'instant, c'est tout. Il n'y a pas de surveillance et de sauvegarde intĂ©grĂ©es pour le moment (soit dit en passant, pour la surveillance, nous nous en chargeons nous-mĂȘmes). Un point intĂ©ressant est qu'avec cet opĂ©rateur, on peut Ă©galement dĂ©ployer ScyllaDB.

NB : Cet opérateur, avec quelques modifications mineures, a été utilisé dans l'un de nos projets. Aucun problÚme d'exploitation de l'opérateur n'a été observé durant toute la période d'utilisation (~4 mois de fonctionnement).

5. CassKop d'Orange

  • GitHub
  • État : Alpha
  • Licence : Apache 2.0
  • RĂ©alisĂ© en : Golang

Le plus jeune opĂ©rateur de la liste : le premier commit a Ă©tĂ© effectuĂ© le 23 mai 2019. DĂ©jĂ , il possĂšde dans son arsenal un grand nombre de fonctionnalitĂ©s de notre liste, que vous pouvez dĂ©couvrir plus en dĂ©tail dans le rĂ©fĂ©rentiel du projet. L'opĂ©rateur est construit sur la base du populaire operator-sdk. Il prend en charge la surveillance « out of the box ». La principale diffĂ©rence avec d'autres opĂ©rateurs est l'utilisation du plugin CassKop, rĂ©alisĂ© en Python et utilisĂ© pour la communication entre les nƓuds Cassandra.

Conclusions

Le nombre d'approches et de possibilitĂ©s pour migrer Cassandra vers Kubernetes parle de lui-mĂȘme : le sujet est en demande.

À ce stade, essayer quelque chose de ce qui prĂ©cĂšde se fait Ă  vos risques et pĂ©rils : aucun des dĂ©veloppeurs ne garantit un fonctionnement Ă  100 % de sa solution dans un environnement de production. Mais dĂšs maintenant, de nombreux produits semblent prometteurs pour ĂȘtre utilisĂ©s dans des environnements de dĂ©veloppement.

Je pense que dans le futur, cette femme sur le bateau sera utile !

P.S.

Lisez aussi dans notre blog :

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster