Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις

Αντιμετωπίζουμε τακτικά τη βάση δεδομένων Apache Cassandra και την ανάγκη να τη λειτουργήσουμε σε μια υποδομή που βασίζεται στο Kubernetes. Σε αυτό το υλικό, θα μοιραστούμε το όραμά μας για τα απαραίτητα βήματα, τα κριτήρια και τις υπάρχουσες λύσεις (συμπεριλαμβανομένης της επισκόπησης των χειριστών) για τη μετεγκατάσταση της Κασσάνδρας στα K8.

«Όποιος μπορεί να κυβερνήσει μια γυναίκα μπορεί να κυβερνήσει και το κράτος»

Ποια είναι η Κασσάνδρα; Είναι ένα κατανεμημένο σύστημα αποθήκευσης σχεδιασμένο να διαχειρίζεται μεγάλους όγκους δεδομένων διασφαλίζοντας παράλληλα υψηλή διαθεσιμότητα χωρίς ούτε ένα σημείο αστοχίας. Το έργο δύσκολα χρειάζεται μεγάλη εισαγωγή, οπότε θα δώσω μόνο τα κύρια χαρακτηριστικά της Κασσάνδρας που θα είναι σχετικά στο πλαίσιο ενός συγκεκριμένου άρθρου:

  • Η Κασσάνδρα είναι γραμμένη σε Java.
  • Η τοπολογία Cassandra περιλαμβάνει διάφορα επίπεδα:
    • Κόμβος - ένα αναπτυγμένο παράδειγμα Cassandra.
    • Το Rack είναι μια ομάδα περιπτώσεων Cassandra, που ενώνονται με κάποιο χαρακτηριστικό, που βρίσκεται στο ίδιο κέντρο δεδομένων.
    • Datacenter - μια συλλογή όλων των ομάδων παρουσιών Cassandra που βρίσκονται σε ένα κέντρο δεδομένων.
    • Το Cluster είναι μια συλλογή από όλα τα κέντρα δεδομένων.
  • Η Cassandra χρησιμοποιεί μια διεύθυνση IP για να αναγνωρίσει έναν κόμβο.
  • Για να επιταχύνει τις λειτουργίες εγγραφής και ανάγνωσης, η Cassandra αποθηκεύει ορισμένα από τα δεδομένα στη μνήμη RAM.

Τώρα - στην πραγματική πιθανή μετάβαση στο Kubernetes.

Λίστα ελέγχου για μεταφορά

Μιλώντας για τη μετανάστευση της Κασσάνδρας στο Kubernetes, ελπίζουμε ότι με τη μετακόμιση θα γίνει πιο βολικό στη διαχείριση. Τι θα απαιτηθεί για αυτό, τι θα βοηθήσει σε αυτό;

1. Αποθήκευση δεδομένων

Όπως έχει ήδη διευκρινιστεί, η Cassanda αποθηκεύει μέρος των δεδομένων σε RAM - in Memtable. Αλλά υπάρχει ένα άλλο μέρος των δεδομένων που αποθηκεύεται στο δίσκο - στη μορφή SSTable. Σε αυτά τα δεδομένα προστίθεται μια οντότητα Καταγραφή δεσμεύσεων — εγγραφές όλων των συναλλαγών, οι οποίες αποθηκεύονται επίσης στο δίσκο.

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις
Γράψτε διάγραμμα συναλλαγής στην Κασσάνδρα

Στο Kubernetes, μπορούμε να χρησιμοποιήσουμε το PersistentVolume για την αποθήκευση δεδομένων. Χάρη σε αποδεδειγμένους μηχανισμούς, η εργασία με δεδομένα στο Kubernetes γίνεται ευκολότερη κάθε χρόνο.

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις
Θα διαθέσουμε το δικό μας PersistentVolume σε κάθε Cassandra pod

Είναι σημαντικό να σημειωθεί ότι η ίδια η Cassandra συνεπάγεται αναπαραγωγή δεδομένων, προσφέροντας ενσωματωμένους μηχανισμούς για αυτό. Επομένως, εάν δημιουργείτε ένα σύμπλεγμα Cassandra από μεγάλο αριθμό κόμβων, τότε δεν χρειάζεται να χρησιμοποιείτε κατανεμημένα συστήματα όπως το Ceph ή το GlusterFS για αποθήκευση δεδομένων. Σε αυτήν την περίπτωση, θα ήταν λογικό να αποθηκεύονται δεδομένα στον κεντρικό δίσκο χρησιμοποιώντας τοπικούς μόνιμους δίσκους ή τοποθέτηση hostPath.

Μια άλλη ερώτηση είναι εάν θέλετε να δημιουργήσετε ένα ξεχωριστό περιβάλλον για προγραμματιστές για κάθε κλάδο χαρακτηριστικών. Σε αυτήν την περίπτωση, η σωστή προσέγγιση θα ήταν να δημιουργηθεί ένας κόμβος Cassandra και να αποθηκεύονται τα δεδομένα σε μια κατανεμημένη αποθήκευση, δηλ. τα αναφερόμενα Ceph και GlusterFS θα είναι οι επιλογές σας. Στη συνέχεια, ο προγραμματιστής θα είναι σίγουρος ότι δεν θα χάσει τα δεδομένα δοκιμής ακόμη και αν χαθεί ένας από τους κόμβους συμπλέγματος Kuberntes.

2. Παρακολούθηση

Η ουσιαστικά αδιαμφισβήτητη επιλογή για την εφαρμογή παρακολούθησης στο Kubernetes είναι ο Prometheus (μιλήσαμε για αυτό αναλυτικά στο σχετική έκθεση). Πώς τα πάει η Κασσάνδρα με τους εξαγωγείς μετρικών για τον Προμηθέα; Και, τι είναι ακόμα πιο σημαντικό, με τους αντίστοιχους πίνακες εργαλείων για το Grafana;

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις
Ένα παράδειγμα εμφάνισης γραφημάτων στα Γραφάνα για την Κασσάνδρα

Υπάρχουν μόνο δύο εξαγωγείς: jmx_exporter и cassandra_exporter.

Επιλέξαμε το πρώτο για εμάς γιατί:

  1. Το JMX Exporter αναπτύσσεται και αναπτύσσεται, ενώ το Cassandra Exporter δεν μπόρεσε να λάβει αρκετή υποστήριξη από την κοινότητα. Το Cassandra Exporter εξακολουθεί να μην υποστηρίζει τις περισσότερες εκδόσεις του Cassandra.
  2. Μπορείτε να το εκτελέσετε ως javaagent προσθέτοντας μια σημαία -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Υπάρχει ένα για αυτόν επαρκές ταμπλό, το οποίο δεν είναι συμβατό με το Cassandra Exporter.

3. Επιλέγοντας Kubernetes primitives

Σύμφωνα με την παραπάνω δομή του συμπλέγματος Κασσάνδρα, ας προσπαθήσουμε να μεταφράσουμε όλα όσα περιγράφονται εκεί στην ορολογία Kubernetes:

  • Κόμβος Κασσάνδρας → Λοβ
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → πισίνα από StatefulSets
  • Σμήνος Κασσάνδρας → ???

Αποδεικνύεται ότι λείπει κάποια επιπλέον οντότητα για τη διαχείριση ολόκληρου του συμπλέγματος Κασσάνδρας ταυτόχρονα. Αλλά αν κάτι δεν υπάρχει, μπορούμε να το δημιουργήσουμε! Η Kubernetes έχει έναν μηχανισμό για τον καθορισμό των δικών της πόρων για το σκοπό αυτό - Προσαρμοσμένοι ορισμοί πόρων.

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις
Δήλωση πρόσθετων πόρων για αρχεία καταγραφής και ειδοποιήσεις

Αλλά ο ίδιος ο Προσαρμοσμένος πόρος δεν σημαίνει τίποτα: τελικά, απαιτεί ελεγκτής. Ίσως χρειαστεί να αναζητήσετε βοήθεια Χειριστής Kubernetes...

4. Αναγνώριση λοβών

Στην παραπάνω παράγραφο, συμφωνήσαμε ότι ένας κόμβος Cassandra θα ισούται με ένα pod στο Kubernetes. Αλλά οι διευθύνσεις IP των pods θα είναι διαφορετικές κάθε φορά. Και η αναγνώριση ενός κόμβου στην Cassandra βασίζεται στη διεύθυνση IP... Αποδεικνύεται ότι μετά από κάθε αφαίρεση ενός pod, το σύμπλεγμα Cassandra θα προσθέτει έναν νέο κόμβο.

Υπάρχει διέξοδος και όχι μόνο μία:

  1. Μπορούμε να κρατάμε αρχεία με αναγνωριστικά κεντρικού υπολογιστή (UUID που προσδιορίζουν μοναδικά τις περιπτώσεις Cassandra) ή με διευθύνσεις IP και να τα αποθηκεύσουμε όλα σε ορισμένες δομές/πίνακες. Η μέθοδος έχει δύο βασικά μειονεκτήματα:
    • Ο κίνδυνος να εμφανιστεί μια κατάσταση αγώνα εάν δύο κόμβοι πέσουν ταυτόχρονα. Μετά την άνοδο, οι κόμβοι Cassandra θα ζητήσουν ταυτόχρονα μια διεύθυνση IP από τον πίνακα και θα ανταγωνίζονται για τον ίδιο πόρο.
    • Εάν ένας κόμβος Κασσάνδρας έχει χάσει τα δεδομένα του, δεν θα μπορούμε πλέον να τον αναγνωρίσουμε.
  2. Η δεύτερη λύση φαίνεται σαν ένα μικρό hack, αλλά παρόλα αυτά: μπορούμε να δημιουργήσουμε μια Υπηρεσία με ClusterIP για κάθε κόμβο Cassandra. Προβλήματα με αυτήν την υλοποίηση:
    • Εάν υπάρχουν πολλοί κόμβοι σε ένα σύμπλεγμα Cassandra, θα πρέπει να δημιουργήσουμε πολλές Υπηρεσίες.
    • Η δυνατότητα ClusterIP υλοποιείται μέσω iptables. Αυτό μπορεί να γίνει πρόβλημα εάν το σύμπλεγμα Cassandra έχει πολλούς (1000... ή ακόμα και 100;) κόμβους. Αν και εξισορρόπηση με βάση το IPVS μπορεί να λύσει αυτό το πρόβλημα.
  3. Η τρίτη λύση είναι να χρησιμοποιήσετε ένα δίκτυο κόμβων για κόμβους Cassandra αντί για ένα αποκλειστικό δίκτυο λοβών ενεργοποιώντας τη ρύθμιση hostNetwork: true. Αυτή η μέθοδος επιβάλλει ορισμένους περιορισμούς:
    • Για αντικατάσταση μονάδων. Είναι απαραίτητο ο νέος κόμβος να έχει την ίδια διεύθυνση IP με τον προηγούμενο (σε cloud όπως το AWS, GCP αυτό είναι σχεδόν αδύνατο να γίνει).
    • Χρησιμοποιώντας ένα δίκτυο κόμβων συμπλέγματος, αρχίζουμε να ανταγωνιζόμαστε για πόρους δικτύου. Επομένως, η τοποθέτηση περισσότερων του ενός pod με την Cassandra σε έναν κόμβο συμπλέγματος θα είναι προβληματική.

5. Αντίγραφα ασφαλείας

Θέλουμε να αποθηκεύσουμε μια πλήρη έκδοση των δεδομένων ενός κόμβου Κασσάνδρας σε ένα χρονοδιάγραμμα. Το Kubernetes παρέχει μια βολική δυνατότητα χρήσης CronJob, αλλά εδώ η ίδια η Κασσάνδρα μας βάζει μια ακτίνα στους τροχούς.

Να σας υπενθυμίσω ότι η Cassandra αποθηκεύει μερικά από τα δεδομένα στη μνήμη. Για να δημιουργήσετε ένα πλήρες αντίγραφο ασφαλείας, χρειάζεστε δεδομένα από τη μνήμη (Memtables) μετακίνηση στο δίσκο (SSTables). Σε αυτό το σημείο, ο κόμβος Κασσάνδρας σταματά να δέχεται συνδέσεις, κλείνοντας εντελώς από το σύμπλεγμα.

Μετά από αυτό, το αντίγραφο ασφαλείας αφαιρείται (στιγμιότυπο) και το σχήμα αποθηκεύεται (keyspace). Και τότε αποδεικνύεται ότι μόνο ένα αντίγραφο ασφαλείας δεν μας δίνει τίποτα: πρέπει να αποθηκεύσουμε τα αναγνωριστικά δεδομένων για τα οποία ήταν υπεύθυνος ο κόμβος Cassandra - αυτά είναι ειδικά διακριτικά.

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις
Κατανομή διακριτικών για τον προσδιορισμό των δεδομένων για τα οποία είναι υπεύθυνοι οι κόμβοι Cassandra

Ένα παράδειγμα σεναρίου για τη λήψη αντιγράφων ασφαλείας Cassandra από την Google στο Kubernetes μπορείτε να βρείτε στη διεύθυνση αυτό το σύνδεσμο. Το μόνο σημείο που δεν λαμβάνει υπόψη το σενάριο είναι η επαναφορά δεδομένων στον κόμβο πριν από τη λήψη του στιγμιότυπου. Δηλαδή, το backup δεν εκτελείται για την τρέχουσα κατάσταση, αλλά για μια κατάσταση λίγο νωρίτερα. Αυτό όμως βοηθά να μην βγει ο κόμβος εκτός λειτουργίας, κάτι που φαίνεται πολύ λογικό.

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

Ένα παράδειγμα σεναρίου bash για λήψη αντιγράφου ασφαλείας από έναν κόμβο Cassandra

Έτοιμες λύσεις για την Κασσάνδρα στο Kubernetes

Τι χρησιμοποιείται αυτήν τη στιγμή για την ανάπτυξη του Cassandra στο Kubernetes και ποιο από αυτά ταιριάζει καλύτερα στις δεδομένες απαιτήσεις;

1. Λύσεις που βασίζονται σε διαγράμματα StatefulSet ή Helm

Η χρήση των βασικών συναρτήσεων StatefulSets για την εκτέλεση ενός συμπλέγματος Cassandra είναι μια καλή επιλογή. Χρησιμοποιώντας τα πρότυπα Helm chart και Go, μπορείτε να παρέχετε στον χρήστη μια ευέλικτη διεπαφή για την ανάπτυξη της Cassandra.

Αυτό συνήθως λειτουργεί καλά... μέχρι να συμβεί κάτι απροσδόκητο, όπως αποτυχία κόμβου. Τα τυπικά εργαλεία Kubernetes απλά δεν μπορούν να λάβουν υπόψη όλα τα χαρακτηριστικά που περιγράφονται παραπάνω. Επιπλέον, αυτή η προσέγγιση είναι πολύ περιορισμένη στο πόσο μπορεί να επεκταθεί για πιο σύνθετες χρήσεις: αντικατάσταση κόμβου, δημιουργία αντιγράφων ασφαλείας, ανάκτηση, παρακολούθηση κ.λπ.

Εκπρόσωποι:

Και τα δύο διαγράμματα είναι εξίσου καλά, αλλά υπόκεινται στα προβλήματα που περιγράφονται παραπάνω.

2. Λύσεις βασισμένες στον χειριστή Kubernetes

Τέτοιες επιλογές είναι πιο ενδιαφέρουσες επειδή παρέχουν άφθονες ευκαιρίες για τη διαχείριση του συμπλέγματος. Για το σχεδιασμό ενός τελεστή Cassandra, όπως κάθε άλλη βάση δεδομένων, ένα καλό μοτίβο μοιάζει με Sidecar <-> Controller <-> CRD:

Μετανάστευση της Κασσάνδρας στο Kubernetes: χαρακτηριστικά και λύσεις
Σχέδιο διαχείρισης κόμβων σε έναν καλά σχεδιασμένο χειριστή Cassandra

Ας δούμε τους υπάρχοντες χειριστές.

1. Cassandra-operator από το instaclustr

  • GitHub
  • Ετοιμότητα: Άλφα
  • Άδεια χρήσης: Apache 2.0
  • Υλοποιήθηκε σε: Java

Αυτό είναι πράγματι ένα πολλά υποσχόμενο και ενεργά αναπτυσσόμενο έργο από μια εταιρεία που προσφέρει διαχειριζόμενες αναπτύξεις Cassandra. Όπως περιγράφεται παραπάνω, χρησιμοποιεί ένα κοντέινερ sidecar που δέχεται εντολές μέσω HTTP. Γραπτό σε Java, μερικές φορές δεν διαθέτει την πιο προηγμένη λειτουργικότητα της βιβλιοθήκης-πελάτη. Επίσης, ο χειριστής δεν υποστηρίζει διαφορετικά Racks για ένα Datacenter.

Αλλά ο χειριστής έχει τέτοια πλεονεκτήματα όπως υποστήριξη για παρακολούθηση, διαχείριση συμπλέγματος υψηλού επιπέδου με χρήση CRD, ακόμη και τεκμηρίωση για τη δημιουργία αντιγράφων ασφαλείας.

2. Navigator από το Jetstack

  • GitHub
  • Ετοιμότητα: Άλφα
  • Άδεια χρήσης: Apache 2.0
  • Υλοποιήθηκε σε: Golang

Μια δήλωση που έχει σχεδιαστεί για την ανάπτυξη του DB-as-a-Service. Αυτήν τη στιγμή υποστηρίζονται δύο βάσεις δεδομένων: Elasticsearch και Cassandra. Έχει τόσο ενδιαφέρουσες λύσεις όπως ο έλεγχος πρόσβασης στη βάση δεδομένων μέσω RBAC (για αυτό έχει τον δικό του ξεχωριστό πλοηγό-apiserver). Ένα ενδιαφέρον έργο που θα άξιζε να ρίξουμε μια πιο προσεκτική ματιά, αλλά το τελευταίο commit έγινε πριν από ενάμιση χρόνο, γεγονός που μειώνει σαφώς τις δυνατότητές του.

3. Cassandra-operator του vgkowski

  • GitHub
  • Ετοιμότητα: Άλφα
  • Άδεια χρήσης: Apache 2.0
  • Υλοποιήθηκε σε: Golang

Δεν το θεώρησαν «σοβαρά», αφού η τελευταία δέσμευση στο αποθετήριο ήταν πριν από περισσότερο από ένα χρόνο. Η ανάπτυξη χειριστή εγκαταλείπεται: η τελευταία έκδοση του Kubernetes που αναφέρεται ως υποστηριζόμενη είναι η 1.9.

4. Κασσάνδρα-χειριστής του Ρουκ

  • GitHub
  • Ετοιμότητα: Άλφα
  • Άδεια χρήσης: Apache 2.0
  • Υλοποιήθηκε σε: Golang

Ένας χειριστής του οποίου η ανάπτυξη δεν προχωρά τόσο γρήγορα όσο θα θέλαμε. Έχει μια καλά μελετημένη δομή CRD για τη διαχείριση συμπλέγματος, λύνει το πρόβλημα της αναγνώρισης κόμβων χρησιμοποιώντας Service with ClusterIP (το ίδιο "hack")... αλλά αυτό είναι όλο προς το παρόν. Δεν υπάρχει επί του παρόντος καμία παρακολούθηση ή αντίγραφα ασφαλείας εκτός συσκευασίας (παρεμπιπτόντως, είμαστε για παρακολούθηση το πήραμε μόνοι μας). Ένα ενδιαφέρον σημείο είναι ότι μπορείτε επίσης να αναπτύξετε το ScyllaDB χρησιμοποιώντας αυτόν τον τελεστή.

Σημείωση: Χρησιμοποιήσαμε αυτόν τον τελεστή με μικρές τροποποιήσεις σε ένα από τα έργα μας. Δεν παρατηρήθηκαν προβλήματα στην εργασία του χειριστή καθ' όλη την περίοδο λειτουργίας (~4 μήνες λειτουργίας).

5. CassKop από την Orange

  • GitHub
  • Ετοιμότητα: Άλφα
  • Άδεια χρήσης: Apache 2.0
  • Υλοποιήθηκε σε: Golang

Ο νεότερος χειριστής στη λίστα: η πρώτη δέσμευση έγινε στις 23 Μαΐου 2019. Ήδη τώρα έχει στο οπλοστάσιό της έναν μεγάλο αριθμό λειτουργιών από τη λίστα μας, περισσότερες λεπτομέρειες για τις οποίες μπορείτε να βρείτε στο αποθετήριο του έργου. Ο τελεστής είναι χτισμένος με βάση το δημοφιλές operator-sdk. Υποστηρίζει παρακολούθηση εκτός συσκευασίας. Η κύρια διαφορά από άλλους χειριστές είναι η χρήση Πρόσθετο CassKop, υλοποιείται στην Python και χρησιμοποιείται για επικοινωνία μεταξύ κόμβων Cassandra.

Ευρήματα

Ο αριθμός των προσεγγίσεων και οι πιθανές επιλογές για τη μεταφορά της Κασσάνδρας στο Kubernetes μιλάει από μόνος του: το θέμα είναι σε ζήτηση.

Σε αυτό το στάδιο, μπορείτε να δοκιμάσετε οποιοδήποτε από τα παραπάνω με δικό σας κίνδυνο και κίνδυνο: κανένας από τους προγραμματιστές δεν εγγυάται 100% τη λειτουργία της λύσης του σε περιβάλλον παραγωγής. Αλλά ήδη, πολλά προϊόντα φαίνονται πολλά υποσχόμενα για χρήση σε πάγκους ανάπτυξης.

Νομίζω ότι στο μέλλον αυτή η γυναίκα στο πλοίο θα είναι χρήσιμη!

PS

Διαβάστε επίσης στο blog μας:

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο