Migration complexe de MongoDB vers Kubernetes.

Migration complexe de MongoDB vers Kubernetes.

Cet article poursuit notre dernier contenu sur la migration de RabbitMQ et est dédié à MongoDB. Étant donné que nous gérons plusieurs clusters Kubernetes et MongoDB, nous avons naturellement dû migrer des données d'une installation à une autre sans temps d'arrêt. Les principaux scénarios précédent : le transfert de MongoDB d'un serveur virtuel/matériel vers Kubernetes ou le transfert de MongoDB au sein d'un même cluster Kubernetes (d'un espace de noms à un autre).

Notre recette est destinée aux cas où un ancien cluster MongoDB fonctionne (par exemple, celui de 3 nœuds et étant soit déjà dans K8s, soit sur d'anciens serveurs), avec lequel l'application déployée dans Kubernetes interagit :

Migration complexe de MongoDB vers Kubernetes.

Comment allons-nous transférer ce cluster vers la nouvelle production dans Kubernetes ?

Théorie

L'algorithme général de migration est similaire à celui décrit dans le cas de RabbitMQ.

Il est important de noter que pour permettre le déménagement, il est nécessaire que les serveurs avec MongoDB et Kubernetes soient sur le même réseau. Les nœuds du cluster MongoDB communiqueront entre eux par IP des anciens serveurs (où se trouvent les anciennes installations MongoDB) et par les noms DNS des pods avec MongoDB dans K8s. Par conséquent, sur les anciens serveurs (avec les anciennes installations), il faudra rediriger les routes vers les pods, puis les configurer pour qu'ils utilisent le serveur DNS fonctionnant dans Kubernetes (ou inscrire les noms nécessaires là-bas, bien que, dans l'ensemble, il vaut mieux éviter cette possibilité). /etc/hosts, хотя в общем случае такой возможности лучше избегать).

La prochaine étape consiste à déployer le cluster MongoDB dans les pods Kubernetes. Dans notre cas, le cluster de base de données est composé de 3 nœuds et chaque nœud se trouve dans un pod K8s distinct — bien que leur nombre puisse être différent. Dans le ConfigMap, il faut spécifier l'adresse du maître MongoDB de la vieille installation : alors les nœuds MongoDB situés dans les pods K8s commenceront immédiatement à se synchroniser avec lui.

Après que tous les pods se soient lancés, un cluster MongoDB de 6 nœuds sera formé :

Migration complexe de MongoDB vers Kubernetes.

Notez que les pods mettront du temps à se lancer, car chaque pod se lance à tour de rôle, et au moment de leur lancement, ils synchronisent les données avec le maître.

Après cela, il est possible de basculer l'application pour utiliser les nouveaux serveurs MongoDB :

Migration complexe de MongoDB vers Kubernetes.

Il ne restera plus qu'à supprimer les anciens nœuds du cluster MongoDB, après quoi le déménagement pourra être considéré comme terminé :

Migration complexe de MongoDB vers Kubernetes.

Nous appliquons souvent ce schéma en production et pour en faciliter l'utilisation, nous l'avons implémenté dans le module de addon-operator (cet outil que nous avons récemment annoncé), ce qui permet de déployer des configurations standard de MongoDB sur de nombreux clusters. Nous prévoyons de publier nos modules sous peu, mais pour l'instant, nous présentons des instructions séparées avec lesquelles vous pouvez tester la solution proposée en action sans utiliser l'addon-operator.

Essayons en pratique

Exigences

Détails :

  • Un cluster Kubernetes (minikube conviendra aussi);
  • Cluster MongoDB (peut être déployé sur bare metal ou créé comme un cluster standard dans Kubernetes à partir du Helm chart officiel).

Dans l'exemple décrit ci-dessous, l'ancien cluster MongoDB sera nommé mongo-old et installé dans le même cluster Kubernetes où nous installerons par la suite le nouveau (mongo-new).

Préparation de l'ancien cluster

1. Pour illustrer le schéma décrit en action, créons un cluster MongoDB « ancien » (c'est-à-dire devant être migré) directement dans Kubernetes (en réalité, il peut se trouver sur des serveurs séparés en dehors de K8s). Pour cela, téléchargeons le Helm chart :

helm fetch --untar stable/mongodb-replicaset

… et modifions-le légèrement en configurant l'autorisation :

auth:
  enabled: true
  adminUser: mongo
  adminPassword: pa33w0rd
  # metricsUser: metrics
  # metricsPassword: password
  # key: keycontent
  # existingKeySecret:
  # existingAdminSecret:
  # existingMetricsSecret:

Vous pouvez également configurer des certificats et bien plus encore ici. values.yaml 2. Installons le chart :

helm install . --name mongo-old --namespace mongo-old

Après cela, une installation de test « ancienne » de MongoDB sera lancée :

kubectl --namespace=mongo-old get pods

Accédez au pod avec son maître et créons une base de données de test :

Migration complexe de MongoDB vers Kubernetes.

kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo use admin db.auth('mongo','password') use music db.artists.insert({ artistname: "The Tea Party" }) show dbs

En consultant différents pods, j'ai découvert que le maître est

Migration complexe de MongoDB vers Kubernetes.

mongo-old-mongodb-replicaset-0 . Cependant, pour une solution plus pratique à cette question, après l'installation du Helm chart, une commande est affichée pour déterminer leMASTER_POD . Dans mon cas (pour3 nœuds), cela ressemble à ceci : mongo-old for ((i = 0; i < 3; ++i)); do kubectl exec --namespace mongo-old mongo-old-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done

Ainsi, la préparation de l'ancienne installation de MongoDB, dont les données seront migrées, est prête.

Migration du cluster MongoDB

Nous allons maintenant déployer une nouvelle installation de MongoDB, qui sera située dans Kubernetes et utilisée par l'application en production.

: Je tiens à rappeler que la même version de MongoDB doit être utilisée que précédemment. Sinon, il y a un risque de problèmes de compatibilité.

NBPar analogie avec la section précédente (où nous avons simulé une ancienne installation de MongoDB), prenons le Helm chart déjà mentionné (avec la commande

helm fetch helm fetch) et configurer l'authentification, ainsi que d'autres paramètres, s'ils sont utilisés. Nous allons également corriger le fichier init/on-start.sh, en y ajoutant temporairement à la ligne 165 l'adresse du maître, obtenue à l'étape précédente (ou bien connue lors de l'installation de MongoDB sur des serveurs séparés) :

peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'

Nous sommes prêts à créer une nouvelle installation de MongoDB :

helm install . --name mongo-new --namespace mongo-new

Attendez que tous les pods démarrent (si les données sont nombreuses, leur lancement peut prendre des heures) :

Migration complexe de MongoDB vers Kubernetes.

Nous faisons maintenant exec dans le nouveau pod et consultons la liste des bases :

kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo

Migration complexe de MongoDB vers Kubernetes.

Deux clusters MongoDB sont combinés en un seul, composé de 6 nœuds.

À ce stade, il est déjà possible de basculer l'application vers le nouveau cluster, mais quelques étapes restent à accomplir pour finaliser la migration.

Du fichier init/on-start.sh dans la nouvelle installation, nous retirons la ligne que nous avons ajoutée :

peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'

Nous allons maintenant dans l'ancien maître du cluster et le « renverser » — ainsi, un nouveau maître sera désigné dans le cluster. Entrons dans le pod avec le maître MongoDB :

kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo
use admin
db.auth('mongo','password')

Après cela, nous changeons les priorités des nœuds et modifions le maître :

cfg = rs.conf()
cfg.members[5].priority = 2
rs.reconfig(cfg)
rs.stepDown(120)

Le nœud actuel n'est plus le maître — des élections pour un nouveau maître auront lieu. Puisque nous avons modifié les priorités, le nœud souhaité deviendra le maître.

NB: Par défaut, tous les nœuds MongoDB ont une priorité de 1. Nous l'élévons à 2 pour le nœud souhaité. De cette manière, un membre du nouveau cluster devient assurément le maître. Pour en savoir plus sur le fonctionnement de ces mécanismes dans MongoDB, vous pouvez lire dans documentation.

Désactivons l'ancienne installation de MongoDB, puis accédons au maître du nouveau et supprimons les anciens nœuds :

rs.remove("mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")
rs.remove("mongo-old-mongodb-replicaset-1.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")
rs.remove("mongo-old-mongodb-replicaset-2.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")

Après cela, la migration peut être considérée comme terminée : nous avons réussi à passer de l'ancien cluster MongoDB à un nouveau !

Résultats

Le schéma décrit convient pratiquement à tous les cas où il est nécessaire de déplacer MongoDB ou simplement de migrer vers un nouveau cluster.

Sans doute, le principal point à retenir lors du transfert est la nécessité de faire passer les adresses IP des nouveaux pods sur les serveurs de l'ancienne installation de MongoDB, si elle est en dehors de K8s, et de bien les nommer dans le DNS (ou /etc/hosts). Dans cet exemple, ces étapes n'étaient pas nécessaires, car la migration se faisait entre différents espaces de noms d'un même cluster Kubernetes.

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