
D'une manière ou d'une autre, il est arrivé historiquement que l'industrie informatique soit divisée pour une raison quelconque en deux camps conditionnels: ceux qui sont pour et ceux qui sont contre. De plus, le sujet de controverse peut être absolument arbitraire. Quel système d'exploitation est le meilleur: Win ou Linux? Sur un smartphone Android ou iOS? Gardez tout dans les nuages ou téléchargez vers un stockage RAID froid et mettez les vis dans un coffre-fort? Les schnicks PHP ont-ils le droit d'être appelés programmeurs? Ces différends sont parfois de nature exclusivement existentielle et n'ont pas d'autre fondement que l'intérêt sportif.
Il se trouve que, avec l'avènement des conteneurs et de toute cette cuisine bien-aimée avec docker et k8 conditionnels, les différends pour et contre ont commencé à utiliser de nouvelles opportunités dans divers domaines du backend. (Nous ferons une réserve à l'avance que bien que le plus souvent Kubernetes soit indiqué comme orchestrateur dans cette discussion, le choix de cet instrument n'a pas d'importance. Au lieu de cela, vous pouvez remplacer tout autre qui vous semble le plus pratique et familier.)
Et, semble-t-il, ce serait un simple argument sur les deux faces d'une même pièce. Aussi insensé et impitoyable que l'éternelle confrontation Win vs Linux, dans laquelle des personnes adéquates existent pour elles-mêmes quelque part entre les deux. C'est juste dans le cas de la conteneurisation n'est pas si simple. Habituellement, dans de tels litiges, il n'y a pas de côté droit, mais dans le cas des conteneurs «appliquer» ou «ne pas appliquer» pour stocker la base de données, tout est renversé. Parce que dans un certain sens, les partisans et les opposants à une telle approche ont raison.
Côté lumineux
Vous pouvez décrire brièvement les arguments du Bright Side avec une phrase: "Bonjour, 2k19 en dehors de la fenêtre!" Cela ressemble à du populisme, bien sûr, mais si vous approfondissez la situation, cela a ses avantages. Nous allons les analyser maintenant.
Supposons que vous ayez un grand projet Web. Il pourrait initialement être construit sur la base d'une approche de microservice, ou à un moment donné, il est venu de manière évolutive - ce n'est pas très important, en fait. Vous avez dispersé notre projet sur des microservices distincts, mis en place l'orchestration, l'équilibrage de charge, la mise à l'échelle. Et maintenant, en toute conscience, buvez du mojito dans un hamac lors d'un effet habr, au lieu d'élever les serveurs tombés. Mais toutes les actions doivent être cohérentes. Très souvent, seule l'application elle-même est conteneurisée - le code. Qu'avons-nous d'autre que le code?
À droite, les données. Le cœur de tout projet est ses données: il peut s'agir d'un SGBD typique - MySQL, Postgre, MongoDB ou d'un stockage utilisé pour la recherche (ElasticSearch), d'un stockage de valeurs-clés pour la mise en cache - par exemple, redis, etc. nous parlerons des options d'implémentation de backend tordu lorsque la base de données se bloquera en raison de requêtes mal écrites, et nous parlerons plutôt de la garantie de la tolérance aux pannes de cette base de données même sous la charge du client. En effet, lorsque nous conteneurisons notre application et lui permettons d'évoluer librement pour gérer n'importe quel nombre de demandes entrantes, cela augmente naturellement la charge sur la base de données.
En fait, le canal d'accès à la base de données et le serveur sur lequel il tourne deviennent l'œil de l'aiguille dans notre beau backend conteneurisé. Dans le même temps, le principal motif de la virtualisation des conteneurs est la mobilité et la plasticité de la structure, qui permettent d'organiser le plus efficacement possible la répartition des pics de charge sur l'ensemble de l'infrastructure à notre disposition. Autrement dit, si nous ne conteneurisons pas et ne roulons pas tous les éléments disponibles du système dans un cluster, nous commettons une erreur très grave.
Il est beaucoup plus logique de regrouper non seulement l'application elle-même, mais également les services chargés du stockage des données. Lors du clustering et du déploiement de manière indépendante et de la distribution de la charge des serveurs Web dans k8s, nous résolvons déjà le problème de la synchronisation des données - les mêmes commentaires pour les publications, si vous prenez une sorte de plate-forme multimédia ou de blog comme exemple. Dans tous les cas, nous démarrons une représentation intracluster, même virtuelle, de la base de données en tant que ExternalService. La question est que la base de données elle-même n'a pas encore été mise en cluster - les serveurs Web déployés dans le cube prennent des informations sur les changements de notre base de combat statique, qui tourne séparément.
Sentez-vous le hic? Nous utilisons k8s ou Swarm pour répartir la charge et éviter la chute du serveur web principal, mais nous ne le faisons pas pour la base de données. Mais après tout, si la base de données tombe en panne, alors dans toute notre infrastructure en cluster, cela ne sert à rien - à quoi servent les pages Web vides qui renvoient une erreur d'accès à la base de données?
C'est pourquoi non seulement les serveurs Web doivent être mis en cluster, comme c'est généralement le cas, mais également l'infrastructure de base de données. Ce n'est que de cette manière que nous pourrons garantir que les éléments d'une même structure qui sont pleinement opérationnels dans une même équipe, mais en même temps, sont indépendants les uns des autres. Dans le même temps, même si la moitié de notre backend sous charge s'effondre, le reste survivra et le système de synchronisation de la base de données les uns avec les autres au sein du cluster et la possibilité de mise à l'échelle infinie et de déploiement de nouveaux clusters aideront à atteindre rapidement les capacités requises - il y aurait des racks dans le centre de données .
De plus, le modèle de base de données distribué en clusters vous permet d'emmener cette même base de données là où elle est nécessaire; si nous parlons d'un service global, il est plutôt illogique de tordre un cluster Web quelque part dans la région de San Francisco et en même temps de générer des packages lors de l'accès à la base de données dans la région de Moscou et vice versa.
De plus, la conteneurisation de base de données vous permet de construire tous les éléments du système au même niveau d'abstraction. Ce qui, à son tour, permet de gérer ce système directement à partir du code, par les développeurs, sans la participation active des administrateurs. Les développeurs ont pensé qu'ils avaient besoin d'un SGBD séparé pour un nouveau sous-projet - c'est facile! a écrit un fichier yaml, téléchargé sur le cluster et vous avez terminé.
Eh bien, bien sûr, le fonctionnement interne est grandement simplifié. Dites-moi, combien de fois avez-vous louché au moment où un nouveau membre de l'équipe a mis ses mains dans la base de données de combat pour travailler? Laquelle, en fait, tourne actuellement? Bien sûr, nous sommes tous ici des adultes, et quelque part, nous avons une nouvelle sauvegarde, et encore plus loin - derrière une étagère avec des concombres de grand-mère et de vieux skis - une autre sauvegarde, peut-être même dans une chambre froide, car une fois que votre bureau était en feu. Mais toujours, chaque introduction d'un nouveau membre de l'équipe avec accès à l'infrastructure de combat et, bien sûr, à la base de données de combat est un seau de validol pour tout le monde. Eh bien, qui, un novice, sait, peut-être qu'il plisse les yeux? Effrayant, d'accord.
La conteneurisation et, en fait, la topologie de base de données physique distribuée de votre projet permettent d'éviter de tels moments valides. Ne faites pas confiance au débutant? Ok Nous allons créer notre propre cluster pour cela et le déconnecter du reste des clusters de base de données - synchronisation uniquement par poussée manuelle et rotation simultanée de deux clés (un chef d'équipe, le deuxième administrateur). Et tout le monde est content.
Et maintenant, il est temps de changer de camp chez les opposants à la conteneurisation des bases de données.
Côté obscur
Arguant pourquoi il n'est pas nécessaire de conteneuriser la base de données et de continuer à la faire tourner sur un serveur central, nous ne nous pencherons pas sur la rhétorique de l'orthodoxie et des déclarations comme «les grands-pères ont transformé la base de données en matériel, et nous le ferons!» Essayons plutôt de trouver une situation dans laquelle la conteneurisation apporterait vraiment des dividendes tangibles.
Vous devez admettre que les projets qui ont vraiment besoin d'une base dans le conteneur peuvent être comptés sur les doigts d'une main comme n'étant pas le meilleur opérateur de fraiseuse. Pour la plupart, même l'utilisation même de k8 ou de Docker Swarm est redondante - assez souvent, ils recourent à ces outils en raison de la nature hype générale de la technologie et des plus «puissants», dans la personne des genres, pour tout conduire dans des nuages et des conteneurs. Eh bien, parce que maintenant c'est à la mode et tout le monde le fait.
Au moins dans la moitié des cas, utiliser kubernetis ou simplement un docker sur un projet est redondant. La question est que toutes les équipes ou sociétés d’impartition embauchées pour entretenir l’infrastructure du client ne le savent pas. Pire - lorsque des conteneurs sont imposés, car ils augmentent dans une certaine quantité de pièces pour le client.
En général, il y a une opinion que le cube docker / mafia écrase bêtement les clients qui externalisent ces problèmes d'infrastructure. En effet, pour travailler avec des clusters, vous avez besoin d'ingénieurs qui en soient capables et qui comprennent l'architecture de la solution implémentée en général. D'une manière ou d'une autre, nous avons déjà décrit notre cas avec l'édition République - nous avons formé l'équipe cliente à travailler dans les réalités de kubernetis, et tout le monde était satisfait. Et c'était décent. Souvent, les «exécutants» de k8 prennent en otage l'infrastructure du client - maintenant ils ne comprennent que comment tout fonctionne là-bas, il n'y a pas de spécialistes du côté client.
Imaginez maintenant que de cette façon, nous donnons non seulement la partie serveur Web à l'externalisation, mais aussi la maintenance de la base de données. Nous avons dit qu'une DB est un cœur et que la perte cardiaque est mortelle pour tout organisme vivant. Bref, les perspectives ne sont pas les meilleures. Ainsi, au lieu du battage médiatique kubernetis, de nombreux projets ne devraient tout simplement pas devenir fous au tarif AWS normal, ce qui résoudra tous les problèmes de charge sur leur site Web / projet. Mais AWS n'est plus à la mode, et les démonstrations sont plus chères que l'argent - malheureusement, dans l'environnement informatique aussi.
Ok Peut-être que le projet a vraiment besoin d'un clustering, mais si tout est clair avec les applications sans état, comment pouvons-nous organiser une fourniture décente de la connectivité réseau pour la base de données en cluster?
Si nous parlons d'une solution d'ingénierie transparente, qui semble être la transition vers k8s, alors notre principal casse-tête est la réplication des données dans une base de données en cluster. Certains SGBD sont initialement assez fidèles à la distribution des données entre leurs instances individuelles. Beaucoup d'autres ne sont pas aussi accueillants. Et bien souvent, l'argument principal dans le choix d'un SGBD pour notre projet n'est pas la capacité de se répliquer avec un minimum de ressources et de coûts d'ingénierie. Surtout si le projet n'était pas initialement prévu comme un microservice, mais a simplement évolué dans ce sens.
Nous n'avons pas besoin de parler de la vitesse des lecteurs réseau - ils sont lents. C'est-à-dire nous n'avons toujours pas vraiment la possibilité, dans ce cas, de mettre à niveau une instance de SGBD quelque part, où il y a plus, par exemple, des capacités de processeur ou de RAM libre. Nous rencontrons très rapidement les performances d'un sous-système de disque virtualisé. En conséquence, le SGBD doit être cloué sur son propre ensemble personnel de machines à proximité. Ou bien, il est nécessaire de séparer d'une manière ou d'une autre la synchronisation suffisamment rapide de la synchronisation des données avec les réserves estimées.
Poursuivant le thème de FS virtuels: les volumes Docker, malheureusement, ne sont pas sans tracas. En général, dans un cas comme le stockage de données fiable à long terme, je voudrais gérer avec les schémas techniques les plus simples. Et l'ajout d'une nouvelle couche d'abstraction du conteneur FS à l'hôte parent FS est un risque en soi. Mais quand il y a aussi des difficultés à transmettre des données entre ces couches dans le fonctionnement du système de support de conteneurisation, alors c'est vraiment un désastre. À l'heure actuelle, la plupart des problèmes connus de l'humanité progressiste semblent être éliminés. Mais vous comprenez vous-même, plus le mécanisme est complexe, plus il se brise facilement.
À la lumière de toutes ces «aventures», il est beaucoup plus rentable et plus facile de conserver la base de données en un seul endroit, et même si vous avez besoin de conteneuriser l'application, laissez-la tourner d'elle-même et, via la passerelle de distribution, recevez une communication simultanée avec la base de données, qui ne sera lue et écrite qu'une seule fois et en un seul endroit. Cette approche réduit la probabilité d'erreurs et de mauvaise synchronisation à des valeurs minimales.
À quoi allons-nous? De plus, la conteneurisation de la base de données est appropriée là où elle est réellement nécessaire. Vous ne pouvez pas entasser la base de l'application complète et la tourner comme si vous disposiez de deux douzaines de microservices - cela ne fonctionne pas. Et cela doit être clairement compris.
Au lieu de la sortie
Si vous attendez la conclusion intelligible «virtualiser ou non la base de données», alors nous sommes déçus: elle ne sera pas là. Car lors de la création d'une solution d'infrastructure, il ne faut pas être guidé par la mode et le progrès, mais d'abord par le bon sens.
Il y a des projets sur lesquels les principes et les outils qui accompagnent kubernetis s'intègrent parfaitement, et dans de tels projets, la paix vient au moins dans le domaine du backend. Et il y a des projets qui n'ont pas besoin de conteneurisation, mais d'une infrastructure de serveur normale, car ils ne peuvent pas être redimensionnés en un modèle de cluster de microservices, car ils tomberont.