Migration de Cassandra vers Kubernetes: fonctionnalités et solutions



Nous rencontrons régulièrement la base de données Apache Cassandra et la nécessité de l'exploiter dans le cadre de l'infrastructure basée sur Kubernetes. 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 les K8.

«Qui peut contrôler une femme fera face à l'État»


Qui est Cassandra? Il s'agit d'un système de stockage distribué conçu pour gérer de grandes quantités de données tout en offrant une haute disponibilité sans un seul point de défaillance. Le projet n'a guère besoin d'une longue introduction, donc je ne donnerai que les principales caractéristiques de Cassandra, qui seront pertinentes dans le contexte d'un article spécifique:

  • Cassandra est Ă©crite en Java.
  • La topologie Cassandra comprend plusieurs niveaux:
    • Node - une instance dĂ©ployĂ©e de Cassandra;
    • Rack - un groupe d'instances Cassandra, unies par n'importe quel attribut, situĂ©es dans un centre de donnĂ©es;
    • Datacenter - la totalitĂ© de tous les groupes d'instances Cassandra situĂ©s dans un centre de donnĂ©es;
    • Cluster - une collection de tous les centres de donnĂ©es.
  • Cassandra utilise une adresse IP pour identifier l'hĂ´te.
  • Pour la vitesse des opĂ©rations de lecture et d'Ă©criture, Cassandra stocke une partie des donnĂ©es dans la RAM.

Maintenant, pour le déplacement potentiel réel vers Kubernetes.

Liste de contrĂ´le pour la migration


En parlant de la migration de Cassandra vers Kubernetes, nous espérons qu'il deviendra plus pratique de la gérer avec le déménagement. Qu'est-ce qui sera nécessaire pour cela, qu'est-ce qui vous aidera?

1. Stockage des données


Comme déjà spécifié, une partie des données que Cassanda stocke dans la RAM - dans Memtable . Mais il existe un autre élément de données qui est enregistré sur le disque - sous la forme de SSTable . À ces données s'ajoute le journal de l'entité - les enregistrements de toutes les transactions qui sont également enregistrées sur le disque.


Schéma de transaction d'écriture Cassandra

Dans Kubernetes, nous pouvons utiliser PersistentVolume pour stocker des données. Grâce à des mécanismes bien développés, l'utilisation des données dans Kubernetes devient plus facile chaque année.


Pour chaque pod avec Cassandra, nous allouerons notre volume persistant

Il est important de noter que Cassandra elle-même implique la réplication des données, offrant des mécanismes intégrés pour cela. Par conséquent, 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 distribués tels que Ceph ou GlusterFS pour stocker des données. Dans ce cas, il sera logique de stocker des données sur le disque hôte en utilisant des disques persistants locaux ou en montant hostPath .

Une autre question est de savoir si vous souhaitez créer un environnement de développement distinct pour chaque branche de fonctionnalité. Dans ce cas, l'approche correcte serait de soulever un nœud Cassandra et de stocker les données dans un stockage distribué, c'est-à-dire Ceph et GlusterFS mentionnés seront votre option. Le développeur sera alors sûr de ne pas perdre de données de test même si l'un des nœuds du cluster Kuberntes est perdu.

2. Suivi


Prometheus est un choix pratiquement non alternatif pour la surveillance dans Kubernetes (nous en avons parlé en détail dans le rapport correspondant ) . Comment Cassandra s'en sort-elle avec les exportateurs de métriques pour Prometheus? Et qu'est-ce qui est encore plus important en quelque sorte, avec des tableaux de bord qui leur conviennent pour Grafana?


Un exemple de l'apparition de graphiques dans Grafana pour Cassandra

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

Nous avons choisi le premier pour nous, car:

  1. JMX Exporter se développe et se développe, tandis que Cassandra Exporter n'a pas pu obtenir le soutien approprié de la communauté. Cassandra Exporter ne prend toujours pas en charge la plupart des versions de Cassandra.
  2. Vous pouvez l'exécuter en tant que javaagent en ajoutant l'indicateur -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180 .
  3. Pour lui, il existe un tableau de bord adéquat qui est incompatible avec Cassandra Exporter.

3. SĂ©lection des primitives Kubernetes


Selon la structure ci-dessus du cluster Cassandra, nous essaierons de traduire tout ce qui y est décrit dans la terminologie Kubernetes:

  • Noeud Cassandra → Pod
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → pool de StatefulSets
  • Cluster Cassandra → ???

Il s'avère qu'il manque une entité supplémentaire pour gérer l'ensemble du cluster Cassandra à la fois. Mais si quelque chose n'est pas là, nous pouvons le créer! Kubernetes dispose d'un moteur de définition de ressources dédié appelé Définitions de ressources personnalisées .


Annonce de ressources supplémentaires pour les journaux et les alertes

Mais Custom Resource seul ne veut rien dire: vous avez besoin d'un contrôleur pour cela. Vous devrez peut-être recourir à l'aide d'un opérateur Kubernetes ...

4. Identification des gousses


Le point ci-dessus, nous avons convenu qu'un nœud Cassandra équivaudrait à un pod dans Kubernetes. Mais les adresses IP du pod seront différentes à chaque fois. Et l'identification du nœud dans Cassandra se produit précisément sur la base de l'adresse IP ... Il s'avère qu'après chaque retrait du pod, le cluster Cassandra ajoutera un nouveau nœud.

Il existe une issue, pas mĂŞme une:

  1. Nous pouvons conserver des enregistrements par des identifiants d'hôte (UUID qui identifient de manière unique les instances de Cassandra) ou par des adresses IP et enregistrer tout cela dans certaines structures / tableaux. La méthode présente deux inconvénients principaux:

    • Le risque d'une condition de concurrence lorsque deux nĹ“uds tombent Ă  la fois. Après la mise Ă  niveau, les nĹ“uds Cassandra iront simultanĂ©ment demander une adresse IP pour eux-mĂŞmes Ă  partir de la table et rivaliser pour la mĂŞme ressource.
    • Si le nĹ“ud Cassandra a perdu 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 nœud Cassandra. Problèmes avec cette implémentation:

    • S'il y a beaucoup de nĹ“uds dans un cluster Cassandra, nous devrons crĂ©er beaucoup de services.
    • La fonctionnalitĂ© ClusterIP est implĂ©mentĂ©e via iptables. Cela peut ĂŞtre un problème si le cluster Cassandra a plusieurs (1000 ... ou mĂŞme 100?) NĹ“uds. Bien que l' Ă©quilibrage basĂ© sur IPVS puisse rĂ©soudre ce problème.
  3. La troisième solution consiste à utiliser un réseau de nœuds pour les nœuds Cassandra au lieu d'un réseau de pod dédié en activant le hostNetwork: true . Cette méthode impose certaines restrictions:

    • Pour remplacer les nĹ“uds. Il est nĂ©cessaire que le nouvel hĂ´te doit avoir la mĂŞme adresse IP que le prĂ©cĂ©dent (dans les nuages ​​comme AWS, GCP, c'est presque impossible Ă  faire);
    • En utilisant le rĂ©seau de nĹ“uds de cluster, nous commençons Ă  rivaliser pour les ressources rĂ©seau. Par consĂ©quent, mettre sur un nĹ“ud de cluster plus d'un pod avec Cassandra sera problĂ©matique.

5. Sauvegardes


Nous voulons garder la version complète des données pour un nœud Cassandra sur un calendrier. Kubernetes offre une opportunité pratique en utilisant CronJob , mais ici Cassandra insère les bâtons dans les roues.

Permettez-moi de vous rappeler qu'une partie des données que Cassandra stocke en mémoire. Pour effectuer une sauvegarde complète, vous devez transférer les données de la mémoire ( Memtables ) vers le disque ( SSTables ). À ce stade, le nœud Cassandra cesse d'accepter les connexions, s'arrêtant complètement à partir du cluster.

Après cela, une sauvegarde ( instantané ) est supprimée et le schéma ( espace de clés ) est enregistré . Et puis il s'avère que juste une sauvegarde ne nous donne rien: vous devez enregistrer les identifiants de données dont le nœud Cassandra était responsable - ce sont des jetons spéciaux.


Distribution de jetons pour identifier les données responsables des nœuds Cassandra

Un exemple de script pour supprimer Cassandra de Google dans Kubernetes peut être trouvé sur ce lien . Le seul point que le script ne prend pas en compte est le vidage des données sur le nœud avant de supprimer l'instantané. Autrement dit, la sauvegarde n'est pas effectuée pour l'état actuel, mais pour l'état un peu plus tôt. Mais cela aide à ne pas mettre le nœud hors de travail, ce qui semble très logique.

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

Exemple de script bash pour supprimer la sauvegarde d'un seul nœud Cassandra

Solutions prĂŞtes Ă  l'emploi pour Cassandra Ă  Kubernetes


Que utilisent-ils actuellement pour déployer Cassandra dans Kubernetes, et lequel est le plus adapté aux exigences données?

1. Solutions StatefulSet ou Helm Chart


L'utilisation des StatefulSets de base pour démarrer un cluster Cassandra est une bonne option. En utilisant le modèle Helm chart et Go, vous pouvez fournir à l'utilisateur une interface flexible pour déployer Cassandra.

Habituellement, cela fonctionne bien ... jusqu'à ce que quelque chose d'inattendu se produise - par exemple, un nœud tombe en panne. Les outils Kubernetes standard ne peuvent tout simplement pas prendre en compte toutes les fonctionnalités ci-dessus. De plus, cette approche est très limitée dans la façon dont elle peut être étendue pour une utilisation plus complexe: remplacement de nœud, sauvegarde, restauration, surveillance, etc.

Représentants:


Les deux graphiques sont également bons, mais sont sujets aux problèmes décrits ci-dessus.

2. Solutions basées sur Kubernetes Operator


Ces options sont plus intéressantes car elles offrent des capacités de gestion de cluster étendues. Pour concevoir une instruction Cassandra, comme toute autre base de données, un bon modèle ressemble à Sidecar <-> Controller <-> CRD:


Diagramme de gestion des nœuds dans une instruction Cassandra correctement conçue

Considérez les opérateurs existants.

1. Cassandra-operator par instaclustr


  • Github
  • VolontĂ©: Alpha
  • Licence: Apache 2.0
  • ImplĂ©mentĂ© en: Java

Il s'agit en effet d'un projet très prometteur et en développement rapide d'une entreprise qui propose des déploiements gérés par Cassandra. Il, comme décrit ci-dessus, utilise un conteneur sidecar qui accepte les commandes via HTTP. Il est écrit en Java, donc il lui manque parfois la fonctionnalité de bibliothèque client-go plus avancée. En outre, l'opérateur ne prend pas en charge différents racks pour un centre de données.

Mais l'opérateur a des avantages tels que la prise en charge de la surveillance, la gestion de cluster de haut niveau à l'aide de CRD et même la documentation sur la suppression des sauvegardes.

2. Navigator par Jetstack


  • Github
  • VolontĂ©: Alpha
  • Licence: Apache 2.0
  • Mis en Ĺ“uvre en: Golang

Une déclaration pour le déploiement de DB-as-a-Service. Prend actuellement en charge deux bases de données: Elasticsearch et Cassandra. Il a des solutions intéressantes comme le contrôle d'accès à la base de données via RBAC (pour cela, son propre navigateur-apiserver distinct est levé). Un projet intéressant, qui mériterait un examen plus approfondi, mais le dernier engagement a été pris il y a un an et demi, ce qui réduit clairement son potentiel.

3. Cassandra-opérateur de vgkowski


  • Github
  • VolontĂ©: Alpha
  • Licence: Apache 2.0
  • Mis en Ĺ“uvre en: Golang

Ils ne l'ont pas considéré «sérieusement», car le dernier commit sur le référentiel remonte à plus d'un an. Le développement des opérateurs est abandonné: la dernière version de Kubernetes, déclarée prise en charge, est la 1.9.

4. Cassandra-opérateur de Rook


  • Github
  • VolontĂ©: Alpha
  • Licence: Apache 2.0
  • Mis en Ĺ“uvre en: Golang

Un opérateur dont le développement ne va pas aussi vite que nous le souhaiterions. Il a une structure CRD bien pensée pour gérer le cluster, résout le problème de l'identification des nœuds en utilisant Service avec ClusterIP (le même "hack") ... mais pour l'instant c'est tout. Il n'y a pas de surveillance et de sauvegardes prêtes à l'emploi pour l'instant (au fait, nous avons commencé à nous surveiller). Un point intéressant est qu'en utilisant cet opérateur, vous pouvez également déployer ScyllaDB.

NB: Nous avons utilisé cet opérateur avec des modifications mineures dans l'un de nos projets. Il n'y a eu aucun problème dans le travail de l'opérateur pendant toute l'opération (~ 4 mois de fonctionnement).

5. CassKop par Orange


  • Github
  • VolontĂ©: Alpha
  • Licence: Apache 2.0
  • Mis en Ĺ“uvre en: Golang

Le plus jeune opérateur de la liste: le premier commit a été effectué le 23 mai 2019. Déjà, il a dans son arsenal un grand nombre de fonctionnalités de notre liste, dont plus de détails peuvent être trouvés dans le référentiel du projet. L'opérateur est basé sur le populaire operator-sdk. Prend en charge la surveillance prête à l'emploi. La principale différence avec les autres opérateurs est l'utilisation du plugin CassKop , implémenté en Python et utilisé pour la communication entre les nœuds Cassandra.

Conclusions


Le nombre d'approches et d'options possibles pour porter Cassandra vers Kubernetes parle de lui-mĂŞme: le sujet est en demande.

À ce stade, vous pouvez essayer l'une des solutions ci-dessus à vos risques et périls: aucun des développeurs ne garantit le travail à 100% de leur solution dans l'environnement de production. Mais maintenant, de nombreux produits semblent prometteurs d'essayer de les utiliser dans les stands de développement.

Je pense qu'Ă  l'avenir, cette femme sur le navire devra partir!

PS


Lisez aussi dans notre blog:

Source: https://habr.com/ru/post/fr475036/


All Articles