
Hallo Habr! Mein Name ist Dmitry, ich bin Entwickler bei ISPsystem. Kürzlich haben wir im Beta-Test eine neue Version des Virtual Machine Control Panels veröffentlicht. Heute werde ich Ihnen erzählen, wie wir entschieden haben, was wir von einem alten Produkt nehmen und was besser abzulehnen ist. Ich werde die wichtigsten Themen für uns durchgehen: eine Bibliothek für die Arbeit mit libvirt, Unterstützung für verschiedene Betriebssysteme während der Produktinstallation, Übergang von Monolith zu Microservices, Bereitstellung virtueller Maschinen.
Der Artikel handelt von
VMmanager . Dies ist ein System zum Verwalten, Bereitstellen und Überwachen von virtuellen Maschinen basierend auf KVM- und OVZ-Virtualisierung. Die fünfte Generation kam 2012 heraus. Seitdem ist die Schnittstelle sehr veraltet und die zentralisierte Architektur hat die Entwicklung des Produkts verhindert. Es ist Zeit, eine neue Version zu erstellen.
Die erste Geschichte. Wir benutzen die Arbeit von Hauselfen
Mit libvirt arbeiten: Optionen berücksichtigen, Bibliotheken auswählen
Als Tool zur Verwaltung der KVM-Virtualisierung verwendet unser Produkt libvirt. Im Jahr 2012 wurde eine in C geschriebene Bibliothek ausgewählt, um damit zu arbeiten, was für dieses Entwicklungsteam bequemer war. Infolgedessen - eine große Menge an Code, der in C ++ geschrieben wurde und die C-Bibliothek aufruft, die die direkte Arbeit mit libvirt implementiert.
Und jetzt, an der Schwelle eines neuen Projekts, schauen wir zurück und untersuchen unser Produkt, um zu prüfen, ob es sich lohnt, eine bestimmte Lösung / Technologie zu wählen. was sich bewährt hat und woran man sich erinnern und nie wiederholen muss.
Wir setzen uns und machen eine Retrospektive langjähriger Arbeit an der vorherigen Version des Produkts. Wir sind geduldig, nehmen Aufkleber und schreiben drei Arten von Papier:
- Was ist mit dem Produkt gelungen? Was haben Benutzer gelobt? Was hat noch nie Beschwerden gehört? Was hat dir gefallen?
- Was ist fehlgeschlagen? Was waren die Probleme ständig? Was hat die Arbeit behindert und warum haben sie eine neue Niederlassung gegründet?
- Was kann geändert werden? Was verlangen Benutzer? Was möchten Teammitglieder ändern?
Zu der Gruppe von Menschen, die das Papier eifrig verderben, sollten sowohl diejenigen gehören, die seit Jahrhunderten in engem Kontakt mit dem Produkt stehen, als auch diejenigen, die das Produkt neu betrachten können. Vergessen Sie nicht Feature Request und Produktmanager. Vorgefertigte Aufkleber werden auf die Tafel geklebt, sie werden uns definitiv helfen.

Zurück zur Geschichte. Wir untersuchen einen Code, in dem der C ++ 98-Standard friedlich mit C-Bibliotheksaufrufen koexistiert. Wir erinnern uns, dass 2018 das Jahr ist und beschließen, ihn in Ruhe zu lassen. Aber wie kann man die Funktionalität der Arbeit mit virtuellen Maschinen (VMs) wiederholen, um den Code kompakter und bequemer für die Arbeit zu machen?
Wir untersuchen das Problem und verstehen, dass es unabhängig von der gewählten Lösung und Sprache ein Wrapper über die C-Bibliothek sein wird. Als interessante Option ist es erwähnenswert, dass die
Bibliothek von DigitalOcean auf Go verwendet wird. Sie verwendet das RPC-Protokoll, um direkt mit libvirt zu kommunizieren, hat jedoch ihre Nachteile. Wir haben uns für die
Python-Bibliothek entschieden .
Als Ergebnis haben wir die Geschwindigkeit des Schreibens von Code, die Benutzerfreundlichkeit und das Lesen erhalten. Es lohnt sich, diese schönen Worte zu erklären.
- Geschwindigkeit . Jetzt können wir schnell einen bestimmten Teil der Arbeit mit der Domäne direkt von der Konsole auf dem Debug-Server aus prototypisieren, ohne die Hauptanwendung neu erstellen zu müssen.
- Einfachheit . Anstatt viele C ++ - Methoden in einem bestimmten Handler aufzurufen, haben wir einen Python-Skriptaufruf mit Parameterübergabe.
- Das Debuggen ist auch so schnell und schmerzlos wie möglich. Meiner Meinung nach kann dies auf lange Sicht eine interessante Benutzererfahrung mit sich bringen. Stellen Sie sich vor, der Systemadministrator, der unglücklich darüber ist, dass seine virtuellen Maschinen vor dem Zerstören auf ein Herunterfahren warten, definiert das Skript für die Methode host_stop neu.
Kann ich auch ein Panel für Sie schreiben?
Als Ergebnis haben wir ein einfaches und praktisches Tool für die Arbeit mit virtuellen Maschinen auf Serverebene erhalten.
Die zweite Geschichte. Ein gut verpacktes Produkt benötigt keine zusätzlichen Liebkosungen
Produktverteilung: Wir lehnen viele Pakete ab und gehen zu Docker über

VMmanager 5 wird als eine Reihe von Linux-Paketen verteilt. CentOS 6/7 und bis vor kurzem Debian 7 werden unterstützt. Was bedeutet das? Dies bedeutet mehr Build-Server für CI / CD, mehr Tests und mehr Aufmerksamkeit für Code. Wir müssen uns daran erinnern, dass im offiziellen Repository von CentOS 7 qemu Version 1.5.3 in CentOS 6 0.12.1 ist. Gleichzeitig kann der Benutzer Repositorys verwenden, in denen die Version dieses Pakets viel höher ist. Dies bedeutet, dass Sie verschiedene API-Versionen unterstützen müssen, wenn Sie mit VMs arbeiten, insbesondere während der Migration. Wir müssen uns an den Unterschied zwischen Initialisierern (init, systemd) erinnern und den Unterschied in den Namen von Paketen und Dienstprogrammen berücksichtigen. Die Dienstprogramme, die unter CentOS funktionieren, funktionieren unter Debian nicht, oder ihre Versionen in den offiziellen Repositorys variieren stark. Für jeden Push müssen Sie Pakete für alle Versionen sammeln, und es ist ratsam, nicht zu vergessen, sie auch zu testen.
All dies in dem neuen Produkt passt nicht zu uns. Um unterschiedliche Logik nicht zu unterstützen, geben wir mehrere Systeme auf und belassen nur CentOS 7. Ist das Problem behoben? Nicht wirklich.
Wir möchten auch nicht die Version des Betriebssystems vor der Installation überprüfen, ob die erforderlichen Dienstprogramme verfügbar sind, welche Regeln in SELinux installiert sind, und wir möchten die Firewall- und Repository-Listen nicht neu konfigurieren. Ich würde es gerne einmal tun - und das ist alles, indem Sie klicken,
um jede Sekunde zu zerstören und die gesamte Umgebung und das Produkt selbst bereitzustellen. Es heißt - fertig, das Projekt wird in einen Docker-Container verpackt.
Jetzt reicht es zu tun:
Das Panel ist betriebsbereit.
Ich übertreibe natürlich, der Benutzer muss Docker für sich selbst installieren, und wir haben mehr als einen Container, und derzeit wird VMmanager im Schwarmmodus als SaaS-Dienst ausgeführt. Über das, was uns bei der Auswahl von Docker begegnet ist und wie es gelöst werden kann, können Sie in einem separaten Artikel schreiben.
Tatsache ist, wie wichtig es ist, die Entwicklung und vor allem die Bereitstellung Ihres Produkts install.sh zu vereinfachen, das einst
2097 Zeilen belegte .
Als Ergebnis:
- Eine homogene Produktinstallationsumgebung vereinfacht den Programmcode und reduziert die Montage- und Testkosten.
- Durch die Verteilung der Anwendung als Docker-Container wird die Bereitstellung einfach und vorhersehbar.
Die dritte Geschichte. Erste Beziehung zu Microservices
Architektur: Wir geben den Monolithen zugunsten von Microservices auf oder nicht

Die fünfte Version des Produkts ist ein großes monolithisches System mit dem veralteten C ++ - Standard. Die problematische Implementierung neuer Technologien und die Schwierigkeit, Legacy-Code umzugestalten, führen zu einer schlechten horizontalen Skalierung. In der neuen Niederlassung entschieden sie sich, den Microservice-Ansatz als eine Möglichkeit zu verwenden, um solche Probleme zu vermeiden.
Microservices sind ein moderner Trend, der sowohl Vor- als auch Nachteile hat. Ich werde versuchen, meine Vision der Stärken dieser Architektur vorzustellen und über die Lösung der Probleme zu sprechen, die sie mit dem Projekt bringt. Es ist erwähnenswert, dass dies der erste Blick auf die Mikroservice-Architektur in der Praxis von Seiten eines normalen Entwicklers sein wird. Aspekte, die ich wahrscheinlich nicht erwähnen werde, werden in einem
guten Übersichtsartikel behandelt .
Positive Seite
Kleiner Service bietet viele Möglichkeiten.Zusätzlich zum bequemen Schreiben, Testen und Debuggen haben Microservices eine neue Programmiersprache in das Projekt eingeführt. Wenn Ihr Projekt ein Monolith ist, ist es schwer vorstellbar, dass Sie eines Tages versuchen werden, einen Teil davon in einer anderen Sprache umzuschreiben, die Sie interessiert. In der Microservice-Architektur - bitte. Neben der Programmiersprache können Sie auch neue Technologien ausprobieren, mit der einzigen Einschränkung, dass all dies für das Unternehmen gerechtfertigt ist. Zum Beispiel haben wir einige der Mikrodienste in Golang geschrieben und dabei ziemlich viel Zeit gespart.
Team-SkalierungWir können viele Leute, die sich früher auf ein Repository festgelegt haben und versucht haben, die Struktur des Monolithen im Kopf zu behalten, in mehrere Teams aufteilen. Jedes Team wird mit seinem Dienst beschäftigt sein. Darüber hinaus ist der Einstieg einer neuen Person in die Arbeit aufgrund des begrenzten Kontextes, in dem sie arbeiten wird, viel einfacher und schneller. Auf der anderen Seite gibt es weniger Menschen-Aggregatoren von Weltwissen, die immer über jeden Aspekt eines riesigen Systems informiert werden können. Vielleicht werde ich mit der Zeit meine Einstellung zu diesem Punkt überdenken.
Unabhängige DegradationIch würde die unabhängige Verschlechterung sowohl der positiven als auch der negativen Seite von Microservices zuschreiben, denn wer braucht Ihre Bewerbung, wenn beispielsweise ein Autorisierungsdienst liegt? Dies ist jedoch immer noch eine positive Seite. Zuvor hat unser Monolith durch das Sammeln von Statistiken von mehreren hundert virtuellen Maschinen hart gearbeitet. Zum Zeitpunkt der Spitzenlast nahm die Wartezeit auf eine Benutzeranforderung erheblich zu. Ein separater Statistiksammlungsdienst kann es erfassen, ohne andere Dienste zu beeinträchtigen, während es dennoch skaliert werden kann, indem neue Hardware hinzugefügt oder die Anzahl der Sammler derselben Statistik erhöht wird. Wir können sogar einen separaten Server für Graphite auswählen, auf dem dieser Dienst Statistiken aufzeichnet. Bei einem Monolithen, bei dem es eine Basis gibt, ist dies unmöglich.
Negative Seite
Kontext anfordernMein gesamtes Debuggen im Monolithen ergab zwei Abfragen in der Konsole:
Fertig! Ich kann die gesamte Anfrage vom Eingang bis zum System verfolgen, bis ein Fehler auftritt.
Aber wie sieht es jetzt aus, wenn die Anfrage vom Mikrodienst zum Mikrodienst wechselt, begleitet von zusätzlichen Aufrufen benachbarter Dienste und Aufzeichnungen in verschiedenen Datenbanken? Zu diesem Zweck haben wir Anforderungsinformationen implementiert, die die Anforderungskennung und Informationen zu dem Benutzer oder Dienst enthalten, der sie erstellt hat. So wird es einfacher, die gesamte Ereigniskette zu verfolgen, aber es besteht der Wunsch, einen Protokollaggregationsdienst zu schreiben, da wir schließlich über eine Mikroservice-Architektur verfügen. Sie können auch auf Elasticsearch schauen. Dieses Problem ist offen und wird bald behoben.
DateninkonsistenzDaten in Microservices sind dezentralisiert, es gibt keine einzige Datenbank, in der alle Informationen gespeichert sind. Als ich über diesen Artikel nachdachte, ging ich die wichtigsten Wechselwirkungen zwischen Mikrodiensten in meinem Kopf durch - wo wir Duplikate erhalten können, wo wir Internetwork-Transaktionen verwenden - und stellte fest, dass wir das Problem der Inkonsistenz mit einem Monolithen gelöst haben.
Wir haben wirklich einen Monolithen mit einer Hauptbasis gebaut, in den die meisten Transaktionsaktionen eingeschlossen sind. Um den Monolithen herum wurden alle Mikrodienste gesammelt, die die Konsistenz der Hauptdaten nicht beeinflussen. Die Ausnahme ist eine Reihe von Serviceberechtigungen + Monolithen. Das Problem in diesem Fall ist, dass die Basisanwendungsdatenbank keine Benutzer als solche, ihre Rollen und zusätzlichen Parameter enthält. Dies alles befindet sich im Autorisierungsdienst.
Der Systembenutzer kann mit virtuellen Maschinen in einem Monolithen arbeiten, während sich im Autorisierungsdienst seine Rechte ändern können oder er vollständig blockiert wird. Das System muss rechtzeitig darauf reagieren. In dieser Situation wird die Datenkonsistenz erreicht, indem Benutzerparameter überprüft werden, bevor eine Anforderung ausgeführt wird.
Bei den verbleibenden Mikrodiensten wirkt sich die Unfähigkeit, sich im Statistikdienst zu registrieren, nicht auf den Betrieb der virtuellen Maschine aus, und diese Aktion kann immer wiederholt werden. Nun, wir machen einen Statistik-Microservice. Der Definitionsdomänendienst (Erstellen einer virtuellen Maschine mit libvirt) wird jedoch niemals das Licht der Welt erblicken, da wer einen leeren Bereich der Maschine ohne deren tatsächliche Existenz benötigt.
Die vierte Geschichte. Frisch ist der Feind des Guten
VM-Bereitstellung: Installation von Images anstelle der Installation über ein Netzwerk
In der fünften Version des Produkts dauert die Bereitstellung einer virtuellen Maschine im Vergleich zu realen Standards ziemlich lange. Der Grund dafür ist die Installation des Betriebssystems über das Netzwerk.
Für Centos, Fedora ist RedHat die
Kickstart-Methode :
1. Erstellen Sie eine Kickstart-Datei.
2. Geben Sie den Link zur Antwortdatei in den Kernelparametern an. Linux inst.ks = <Link zur Kickstart-Datei>.
3. Führen Sie die Kickstart-Installation aus.
Kickstart-Datei ist sehr flexibel, darin können Sie alle Schritte der Installation beschreiben, angefangen von der Methode über die Zeitzone bis hin zur Partitionierung der Festplatte und Einrichtung des Netzwerks. Der URL-Parameter in unseren Vorlagen gibt an, dass die Installation von einem Remote-Server stammt.
Für Debian und Ubuntu gilt die
vordefinierte Methode:
Es ähnelt der vorherigen, diese Methode basiert auch auf der Konfigurationsdatei und ihrem Inhalt. Darin haben wir auch die Installation über das Netzwerk konfiguriert.
Die Installation für FreeBSD ist ähnlich, aber anstelle einer Kickstart-Datei gibt es ein Shell-Skript unserer eigenen Produktion.
Positive Aspekte des Ansatzes
Mit dieser Installationsoption können Sie eine Vorlage in unseren beiden Produkten verwenden: VMmanager und
DCImanager (Verwaltung dedizierter Server).
Die Bereitstellung virtueller Maschinen ist sehr flexibel. Der Panel-Administrator kann einfach die Betriebssystemvorlage kopieren und die Konfigurationsdatei nach eigenem Ermessen ändern.
Alle Benutzer haben immer aktuelle Versionen von Betriebssystemen, wenn sie auf einem Remote-Server rechtzeitig aktualisiert werden.

Negative Seite
Wie die Praxis gezeigt hat, benötigten VMmanager-Benutzer keine Installationsflexibilität: Im Vergleich zu dedizierten Servern machten sich nur wenige Leute Sorgen über bestimmte Kickstart-Dateieinstellungen für virtuelle Maschinen. Das Warten auf die Installation des Betriebssystems war jedoch ein unzulässiger Luxus. Die Kehrseite der Relevanz von Betriebssystemen ist, dass sich ein Teil des Installationsprogramms im Netzwerk befindet und ein Teil lokal für
initrd ist . Und ihre Versionen müssen übereinstimmen.
Dies sind lösbare Probleme. Sie können einen Pool installierter Computer erstellen und ein eigenes Repository für Betriebssysteme erstellen. Dies ist jedoch mit zusätzlichen Kosten verbunden.
Wie können diese Probleme gelöst werden, ohne Repositorys und Pools zu erstellen? Wir haben Betriebssystem-Image-Dateien ausgewählt. Jetzt sieht der Installationsprozess folgendermaßen aus:
1. Kopieren des Betriebssystemabbilds auf die Festplatte der virtuellen Maschine.
2. Vergrößern Sie den Hauptbereich des Bildes nach dem Kopieren um die Größe des freien Speicherplatzes.
3. Grundeinstellung (Festlegen eines Passworts, einer Zeitzone usw.).
Alles Neue ist alt vergessen. Wir haben Betriebssystem-Images in VDSmanager-Linux, dem Vorläufer von VMmanager, verwendet.
Aber was ist mit der Flexibilität bei der Installation? Die Praxis hat gezeigt, dass die meisten Benutzer nicht an bestimmten Netzwerkeinstellungen und der Festplattenzuordnung auf virtuellen Maschinen interessiert sind.
Und die Relevanz der Daten? Dies kann durch das Vorhandensein von Images mit den neuesten Betriebssystemversionen im Repository erreicht werden, und kleinere Updates können im Erstkonfigurationsskript installiert werden. Somit wird die virtuelle Maschine bereits erstellt und ausgeführt, und wenn Sie sie aufrufen, wird das bedingte yum-Update ausgeführt.
Im Gegenzug erhalten wir eine vorgefertigte virtuelle Maschine, deren Bereitstellung nur vom Kopieren der Festplatte, Erhöhen der Festplattenpartition und Starten des Betriebssystems abhängt. Die Implementierung dieses Ansatzes für die Arbeit mit Maschinen gibt uns die Möglichkeit, eigene Bilder zu erstellen und diese zu teilen. Der Benutzer kann ein
LAMP- Bundle oder eine komplexe Umgebung auf der virtuellen Maschine installieren und dann ein Image dieser Maschine erstellen. Jetzt müssen andere Benutzer keine Zeit damit verschwenden, die erforderlichen Dienstprogramme zu installieren.
Wir haben die Konfiguration und Änderung von Partitionen mithilfe der Dienstprogramme aus der
libguestfs-Suite implementiert . Wenn Sie beispielsweise ein Kennwort auf einem Linux-Computer ändern, werden aus 40 Codezeilen, bestehend aus mount, chroot und usermod, eine Zeile:
command = "/usr/bin/virt-customize --root-password password:{password} --domain '{domain_name}'".format(password=args.password, domain_name=args.domain_name)
Infolgedessen haben wir die Fertigstellung der fertigen virtuellen Maschine so schnell wie möglich gemacht. Es ist erwähnenswert, dass sich die Bereitstellungszeit mit der Netzwerkeinrichtung und der Installation interner Skripte leicht verlängert hat. Wir haben dieses Problem gelöst, indem wir die Installationsschritte am Frontend angezeigt haben und so die Pause zwischen der Erstellung und der vollständigen Bereitschaft der Maschine ausgefüllt haben.
Wir haben auch einen flexibleren Ansatz für die Bereitstellung virtueller Maschinen, auf dessen Grundlage Sie bequem Ihre eigenen Images mit der erforderlichen Umgebung erstellen können.
Was hast du geschafft?
In der sechsten Version des Produkts haben wir versucht, den Hauptnachteil der fünften zu berücksichtigen: die Komplexität der Benutzerinteraktion mit dem Produkt. Wir haben die Vorlaufzeit für Schlüsselaktionen verkürzt. Zusammen mit einer nicht blockierenden Schnittstelle ermöglicht dies die Arbeit mit dem Panel ohne erzwungenes Warten. Die Containerisierung hat den Produktinstallationsprozess einfacher und bequemer gemacht. Der Einsatz moderner Technologien und verschiedener Programmiersprachen hat den Support und die Wartung sowohl für Programmierer als auch für Spezialisten des technischen Supports vereinfacht. Durch den Wechsel zu Microservices konnten neue Funktionen schnell und mit geringfügigen Einschränkungen hinzugefügt werden.
Abschließend möchte ich sagen, dass das neue Produkt eine gute Gelegenheit ist, andere Entwicklungsansätze und neue Technologien auszuprobieren. Denken Sie daran, warum Sie dies tun und welche neuen Dinge es Ihnen und Ihren Benutzern bringen wird. Mach es!
Wir laden die Habr-Community ein, die Beta-Version von VMmanager 6 zu sehen und Ihr Feedback zu hinterlassen. Gehen Sie dazu zu my.saasvm.com , melden Sie sich an und verbinden Sie einen dedizierten Server (CentOS 7 x64, Internetzugang, öffentliche IP-Adresse).
Wenn Sie keinen Server haben, schreiben Sie uns an help@ispsystem.com oder chatten Sie auf der Website . Wir stellen Testgeräte von unserem Partner Selectel zur Verfügung.
Lesen Sie mehr in den Nachrichten auf der ISPsystem-Website .