
Bonjour, Habr! Je m'appelle Dmitry, je suis développeur chez ISPsystem. Récemment, nous avons publié en version bêta une nouvelle version du panneau de configuration de la machine virtuelle. Aujourd'hui, je vais vous dire comment nous avons décidé quoi prendre d'un ancien produit et quoi de mieux à refuser. Je vais passer en revue les problèmes les plus importants pour nous: une bibliothèque pour travailler avec libvirt, la prise en charge de divers systèmes d'exploitation lors de l'installation du produit, la transition du monolithique aux microservices et le déploiement de machines virtuelles.
L'article concerne
VMmanager . Il s'agit d'un système de gestion, de déploiement et de surveillance des machines virtuelles basé sur la virtualisation KVM et OVZ. La cinquième génération est sortie en 2012. Depuis lors, l'interface est très dépassée et l'architecture centralisée a empêché le développement du produit. Il est temps de faire une nouvelle version.
La première histoire. Nous utilisons le travail des elfes de maison
Travailler avec libvirt: considérer les options, sélectionner les bibliothèques
En tant qu'outil de gestion de la virtualisation KVM, notre produit utilise libvirt. En 2012, une bibliothèque écrite en C a été choisie pour travailler avec, donc c'était plus pratique pour cette équipe de développement. En conséquence - une grande quantité de code écrit en C ++, appelant la bibliothèque C, qui implémente le travail direct avec libvirt.
Et maintenant, au seuil d'un nouveau projet, nous regardons en arrière et examinons notre produit, évaluons s'il vaut la peine de prendre une solution / technologie particulière; ce qui a fait ses preuves et ce qui doit être rappelé et jamais répété.
Nous nous asseyons et faisons une rétrospective de nombreuses années de travail sur la version précédente du produit. Nous sommes patients, prenons des autocollants et écrivons trois types de feuilles de papier:
- Qu'est-ce qui a réussi dans le produit? Qu'est-ce que les utilisateurs ont loué? Qu'est-ce qui n'a jamais entendu de plaintes? Qu'est-ce qui vous a plu?
- Qu'est-ce qui a échoué? Quels étaient les problèmes constamment? Qu'est-ce qui a gêné le travail et pourquoi ont-ils ouvert une nouvelle succursale?
- Que peut-on changer? Que demandent les utilisateurs? Qu'est-ce que les membres de l'équipe veulent changer?
Le groupe de personnes qui gâtent le papier avec zèle devrait inclure à la fois ceux qui ont été en contact étroit avec le produit pendant des siècles et ceux qui peuvent avoir un regard neuf sur le produit. N'oubliez pas Feature Request et Product Manager. Des autocollants prêts à l'emploi sont collés sur la planche, ils nous aideront certainement.

Revenons à l'histoire. Nous examinons un morceau de code où la norme C ++ 98 coexiste pacifiquement avec les appels de la bibliothèque C. Nous rappelons que 2018 est l'année et décidons de le laisser tranquille. Mais comment répéter la fonctionnalité de travailler avec des machines virtuelles (VM), rendant le code plus compact et plus pratique pour le travail?
Nous étudions le problème, comprenons que quelle que soit la solution et la langue que nous choisissons, ce sera un wrapper sur la bibliothèque C. Comme option intéressante, il convient de noter la
bibliothèque sur Go de DigitalOcean , elle utilise le protocole RPC pour communiquer directement avec libvirt, mais elle a ses inconvénients. Nous nous sommes installés sur la
bibliothèque Python .
En conséquence, nous avons obtenu la vitesse d'écriture du code, la facilité d'utilisation et la lecture. Il vaut la peine d'expliquer ces belles paroles.
- La vitesse . Maintenant, nous pouvons rapidement prototyper une certaine partie du travail avec le domaine directement à partir de la console sur le serveur de débogage, sans reconstruire l'application principale.
- Simplicité . Au lieu d'appeler de nombreuses méthodes C ++ dans un certain gestionnaire, nous avons un appel de script Python avec passage de paramètres.
- Le débogage est également aussi rapide et indolore que possible. À mon avis, à long terme, cela peut entraîner une expérience utilisateur intéressante. Imaginez, l'administrateur système, mécontent que ses machines virtuelles attendent un arrêt avant de les détruire, va redéfinir le script de la méthode host_stop.
Puis-je également écrire un panneau pour vous?
En conséquence, nous avons obtenu un outil simple et pratique pour travailler avec des machines virtuelles au niveau du serveur.
La deuxième histoire. Un produit bien emballé n'a pas besoin de caresses supplémentaires
Distribution de produits: nous refusons de nombreux colis et nous passons à Docker

VMmanager 5 est distribué comme un ensemble de packages Linux. CentOS 6/7 et, jusqu'à récemment, Debian 7 sont pris en charge. Qu'est-ce que cela signifie? Cela signifie plus de serveurs de build pour CI / CD, plus de tests, plus d'attention au code. Nous devons nous rappeler que lorsque dans le référentiel officiel de CentOS 7 qemu version 1.5.3, dans CentOS 6, c'est 0.12.1. Dans le même temps, l'utilisateur peut utiliser des référentiels dans lesquels la version de ce package est beaucoup plus élevée. Cela signifie que vous devez prendre en charge différentes versions d'api lorsque vous travaillez avec des machines virtuelles, en particulier lors de la migration. Nous devons nous rappeler la différence entre les initialiseurs (init, systemd), prendre en compte la différence dans les noms des packages et des utilitaires. Les utilitaires qui fonctionnent sur CentOS ne fonctionneront pas sur Debian, ou leurs versions dans les dépôts officiels varient considérablement. Pour chaque push, vous devez collecter des packages pour toutes les versions, et il est conseillé de ne pas oublier de les tester également.
Tout cela dans le nouveau produit ne nous convient pas. Afin de ne pas supporter une logique différente, nous abandonnons plusieurs systèmes et ne laissons que CentOS 7. Le problème est-il résolu? Pas vraiment.
Nous ne voulons pas non plus vérifier la version du système d'exploitation avant l'installation, si les utilitaires nécessaires sont disponibles, quelles règles sont installées dans SELinux et nous ne voulons pas reconfigurer les listes de pare-feu et de référentiel. Je voudrais une fois - et c'est tout, en cliquant pour
détruire chaque seconde pour déployer tout l'environnement et le produit lui-même. Il est dit - fait, le projet est emballé dans un conteneur docker.
Il suffit maintenant de faire:
Le panneau est opérationnel.
Bien sûr, j'exagère, l'utilisateur doit installer Docker pour lui-même, et nous avons plus d'un conteneur, et actuellement VMmanager fonctionne en mode essaim en tant que service SaaS. À propos de ce que nous avons rencontré lors du choix de Docker et de la façon de le résoudre, vous pouvez écrire un article séparé.
Le fait lui-même est combien il est important de simplifier le développement, et surtout, le déploiement de votre produit, install.sh, qui occupait autrefois
2097 lignes .
En conséquence:
- Un environnement d'installation de produit homogène simplifie le code du programme et réduit les coûts d'assemblage et de test.
- La distribution de l'application en tant que conteneur Docker rend le déploiement simple et prévisible.
La troisième histoire. Première relation avec les microservices
Architecture: on abandonne le monolithe au profit des microservices, ou pas

La cinquième version du produit est un grand système monolithique avec la norme C ++ obsolète. En conséquence, la mise en œuvre problématique des nouvelles technologies et la difficulté de refactoriser le code hérité, une mauvaise mise à l'échelle horizontale. Dans la nouvelle branche, ils ont décidé d'utiliser l'approche du microservice comme l'un des moyens d'éviter de tels problèmes.
Les microservices sont une tendance moderne qui a à la fois des avantages et des inconvénients. J'essaierai de présenter ma vision des points forts de cette architecture et de parler de la résolution des problèmes qu'elle apporte au projet. Il convient de noter que ce sera le premier aperçu de l'architecture des microservices en pratique du côté d'un développeur ordinaire. Les aspects que je ne mentionnerai probablement pas sont traités dans un
bon article de synthèse .
Côté positif
Le petit service offre de nombreuses opportunités.En plus de la commodité de l'écriture, des tests et du débogage, les microservices ont introduit un nouveau langage de programmation dans le projet. Lorsque votre projet est un monolithe, il est difficile d'imaginer qu'un jour vous essayerez d'en réécrire une partie dans une autre langue qui vous intéresse. Dans l'architecture de microservices - s'il vous plaît. En plus du langage de programmation, vous pouvez également essayer de nouvelles technologies, avec la seule mise en garde que tout cela sera justifié pour l'entreprise. Par exemple, nous avons écrit certains des microservices à Golang, tout en économisant pas mal de temps.
Mise à l'échelle de l'équipeNous pouvons diviser de nombreuses personnes qui avaient l'habitude de s'engager dans un seul référentiel et ont essayé de garder la structure du monolithe dans leur tête en plusieurs équipes. Chaque équipe sera engagée dans son service. De plus, l'entrée d'une nouvelle personne dans le travail est beaucoup plus simple et plus rapide, en raison du contexte limité dans lequel elle travaillera. D'un autre côté, il y a moins de personnes-agrégateurs de connaissances mondiales, qui peuvent toujours être découvertes sur n'importe quel aspect d'un énorme système. Peut-être qu'avec le temps, je reconsidérerai mon attitude sur ce point.
Dégradation indépendanteJ'attribuerais la dégradation indépendante aux côtés positifs et négatifs des microservices, car qui a besoin de votre application si, par exemple, se trouve un service d'autorisation? Cependant, c'est toujours un côté positif. Auparavant, la collecte de statistiques à partir de plusieurs centaines de machines virtuelles faisait travailler dur notre monolithe, au moment de la charge de pointe, l'attente d'une demande des utilisateurs augmentait considérablement. Un service de collecte de statistiques distinct peut le collecter sans affecter d'autres services, tandis qu'il peut toujours être mis à l'échelle en ajoutant du nouveau matériel ou en augmentant le nombre de collecteurs des mêmes statistiques. Et nous pouvons même sélectionner un serveur distinct pour Graphite, où ce service enregistre des statistiques. Avec un monolithe, où il y a une base, c'est impossible.
Côté négatif
Contexte de la demandeTout mon débogage dans le monolithe se résumait à deux requêtes dans la console:
C'est fait! Je peux suivre l'intégralité de la demande, de sa réception au système jusqu'à ce qu'une erreur se produise.
Mais qu'en est-il maintenant, lorsque la demande passe du microservice au microservice, accompagnée d'appels supplémentaires aux services voisins et d'enregistrements dans diverses bases de données? Pour ce faire, nous avons implémenté les informations de demande, qui contiennent l'identifiant de la demande et des informations sur l'utilisateur ou le service qui les a produites. Il devient donc plus facile de suivre toute la chaîne des événements, mais le désir vient d'écrire un service d'agrégation de journaux, car nous avons, après tout, une architecture de microservices. Vous pouvez également regarder vers Elasticsearch, ce problème est ouvert et sera bientôt résolu.
Incohérence des donnéesLes données des microservices sont décentralisées, il n'y a pas de base de données unique dans laquelle toutes les informations sont stockées. En réfléchissant à cet article, je suis passé en revue les principales interactions entre les microservices dans mon esprit - où nous pouvons obtenir des doublons, où nous utilisons des transactions interréseaux - et j'ai réalisé que nous avons résolu le problème de l'incohérence avec un monolithe.
Nous avons vraiment construit un monolithe avec une base principale, englobant la plupart des actions transactionnelles. Et autour du monolithe, tous les microservices ont été collectés sans affecter la cohérence des données principales. L'exception est un tas d'autorisation de service + monolith. Le problème dans ce cas est que la base de données d'application de base ne contient pas d'utilisateurs en tant que tels, leurs rôles et paramètres supplémentaires, tout cela est dans le service d'autorisation.
L'utilisateur du système peut travailler avec des machines virtuelles dans un monolithe, tandis que dans le service d'autorisation, ses droits peuvent changer, ou il sera complètement bloqué. Le système doit y répondre en temps opportun. Dans cette situation, la cohérence des données est obtenue en vérifiant les paramètres utilisateur avant d'exécuter une demande.
Comme pour les microservices restants, l'impossibilité de s'enregistrer dans le service de statistiques n'affecte pas le fonctionnement de la machine virtuelle et cette action peut toujours être répétée. Eh bien, nous faisons un microservice de collecte de statistiques. Mais le service de définition de domaine (création d'une machine virtuelle à l'aide de libvirt) ne verra jamais le jour, car qui a besoin d'un blanc de la machine sans son existence réelle.
La quatrième histoire. Le frais est l'ennemi du bien
Déploiement de VM: installation à partir d'images au lieu d'installer sur un réseau
Dans la cinquième version du produit, le déploiement d'une machine virtuelle prend assez de temps selon de vrais standards. La raison en est l'installation du système d'exploitation sur le réseau.
Pour Centos, Fedora, RedHat est la
méthode de démarrage :
1. Créez un fichier kickstart.
2. Spécifiez le lien vers le fichier de réponses dans les paramètres du noyau linux inst.ks = <lien vers le fichier kickstart>.
3. Exécutez l'installation de kickstart.
Le fichier Kickstart est assez flexible, vous pouvez y décrire toutes les étapes d'installation, en commençant par sa méthode et en définissant le fuseau horaire, en terminant par le partitionnement du disque et les paramètres réseau. Le paramètre url dans nos modèles indique que l'installation provient d'un serveur distant.
Pour Debian et Ubuntu, la méthode
préconfigurée :
Elle est similaire à la précédente, cette méthode est également construite autour du fichier de configuration et de son contenu. Dans ce document, nous avons également configuré l'installation sur le réseau.
L'installation de FreeBSD est similaire, mais au lieu d'un fichier kickstart, il y a un script shell de notre propre production.
Aspects positifs de l'approche
Cette option d'installation vous permet d'utiliser un modèle dans nos deux produits: VMmanager et
DCImanager (gestion de serveurs dédiés).
Le déploiement des machines virtuelles est assez flexible, l'administrateur du panel peut simplement copier le modèle de système d'exploitation et modifier le fichier de configuration comme bon lui semble.
Tous les utilisateurs disposent toujours de versions à jour des systèmes d'exploitation s'ils sont mis à jour en temps opportun sur un serveur distant.

Côté négatif
Comme le montre la pratique, la flexibilité d'installation n'était pas requise par les utilisateurs de VMmanager: en comparaison avec les serveurs dédiés, peu de gens s'inquiétaient des paramètres de fichier kickstart spécifiques pour les machines virtuelles. Mais attendre l'installation de l'OS était vraiment un luxe inadmissible. L'inconvénient de la pertinence des systèmes d'exploitation est qu'une partie du programme d'installation est sur le réseau, et une partie est locale à
initrd . Et leurs versions doivent correspondre.
Ce sont des problèmes résolubles. Vous pouvez créer un pool de machines installées et créer votre propre référentiel pour les systèmes d'exploitation, mais cela entraîne des coûts supplémentaires.
Comment résoudre ces problèmes sans créer de référentiels et de pools? Nous avons sélectionné les fichiers image du système d'exploitation. Maintenant, le processus d'installation ressemble à ceci:
1. Copie de l'image du système d'exploitation sur le disque de la machine virtuelle.
2. Augmentez la section principale de l'image de la taille de l'espace libre après la copie.
3. Configuration de base (définition d'un mot de passe, d'un fuseau horaire, etc.).
Tout ce qui est nouveau est bien oublié. Nous avons utilisé des images de système d'exploitation dans VDSmanager-Linux, l'ancêtre de VMmanager.
Mais qu'en est-il de la flexibilité d'installation? La pratique a montré que la plupart des utilisateurs ne sont pas intéressés par les paramètres réseau spécifiques et le mappage de disque sur les machines virtuelles.
Et la pertinence des données? Cela peut être réalisé par la présence d'images avec les dernières versions du système d'exploitation dans le référentiel, et des mises à jour mineures peuvent être installées dans le script de configuration initial. Ainsi, la machine virtuelle sera déjà créée et en cours d'exécution, et pour y accéder, vous trouverez la mise à jour conditionnelle yum en cours d'exécution.
En retour, nous obtenons une machine virtuelle prête à l'emploi, dont le déploiement ne dépend que de la copie du disque, de l'augmentation de la partition du disque et du démarrage du système d'exploitation. La mise en œuvre de cette approche du travail avec les machines nous donne l'opportunité de créer nos propres images et de les partager. L'utilisateur peut installer un bundle
LAMP ou un environnement complexe sur la machine virtuelle, puis créer une image de cette machine. Désormais, d'autres personnes n'auront pas à perdre de temps à installer les utilitaires nécessaires.
Nous avons implémenté la configuration et la modification des partitions en utilisant les utilitaires de la
suite libguestfs . Par exemple, changer un mot de passe sur une machine Linux est passé de 40 lignes de code, comprenant mount, chroot et usermod, en une seule ligne:
command = "/usr/bin/virt-customize --root-password password:{password} --domain '{domain_name}'".format(password=args.password, domain_name=args.domain_name)
En conséquence, nous avons fait en sorte que la machine virtuelle finie soit aussi rapide que possible. Il convient de noter qu'avec la configuration du réseau et l'installation de scripts internes, le temps de déploiement a légèrement augmenté. Nous avons résolu ce problème en affichant les étapes d'installation sur la face avant, comblant ainsi la pause formée entre la création et l'état de préparation complet de la machine.
Nous avons également obtenu une approche plus flexible du déploiement de machines virtuelles, sur la base de laquelle il est pratique de créer vos propres images avec l'environnement nécessaire.
Qu'avez-vous réussi à faire
Dans la sixième version du produit, nous avons essayé de prendre en compte le principal inconvénient de la cinquième: la complexité de l'interaction de l'utilisateur avec le produit. Nous avons réduit le délai d'exécution des actions clés. Associé à une interface non bloquante, cela permet de travailler avec le panneau sans attente forcée. La conteneurisation a rendu le processus d'installation du produit plus facile et plus pratique. L'utilisation de technologies modernes et de divers langages de programmation a simplifié le support et la maintenance pour les programmeurs et les spécialistes du support technique. Le passage aux microservices a permis d'ajouter de nouvelles fonctionnalités rapidement et avec des restrictions mineures.
En conclusion, je veux dire que le nouveau produit est une bonne occasion d'essayer d'autres approches de développement, de nouvelles technologies. Il convient de se rappeler pourquoi vous faites cela, quelles nouvelles choses cela vous apportera, ainsi qu'à vos utilisateurs. Allez-y!
Nous invitons la communauté Habr à voir la version bêta de VMmanager 6 et à laisser vos commentaires. Pour ce faire, accédez à my.saasvm.com , connectez-vous et connectez un serveur dédié (CentOS 7 x64, accès Internet, adresse IP publique).
Si vous n'avez pas de serveur, écrivez-nous à help@ispsystem.com ou discutez sur le site , nous vous fournirons des équipements de test de notre partenaire Selectel.
En savoir plus dans les actualités sur le site Web d'ISPsystem .