
Irgendwie hat sich historisch herausgestellt, dass die IT-Branche aus irgendeinem Grund in zwei bedingte Lager unterteilt ist: welche für und welche dagegen sind. Darüber hinaus kann das Thema der Kontroverse absolut willkürlich sein. Welches Betriebssystem ist besser: Win oder Linux? Auf einem Android- oder iOS-Smartphone? Alles in den Clouds aufbewahren oder in einen kalten RAID-Speicher hochladen und Schrauben in einen Safe stecken? Haben PHP-Schnicks das Recht, Programmierer genannt zu werden? Diese Streitigkeiten sind zeitweise ausschließlich existenzieller Natur und haben außer dem sportlichen Interesse keine andere Grundlage.
Es ist einfach so passiert, dass mit dem Aufkommen von Containern und all dieser geliebten Küche mit Docker und bedingten K8s die Streitigkeiten für und wider neue Möglichkeiten in verschiedenen Bereichen des Backends nutzten. (Wir werden im Voraus reservieren, dass, obwohl Kubernetes in dieser Diskussion meistens als Orchestrator angegeben wird, die Wahl dieses Instruments keine Rolle spielt. Stattdessen können Sie jedes andere Instrument ersetzen, das Ihnen am bequemsten und vertrautesten erscheint.)
Und es scheint, es wäre ein einfaches Argument über die beiden Seiten derselben Medaille. So sinnlos und gnadenlos wie die ewige Konfrontation Win vs Linux, in der irgendwo dazwischen adäquate Menschen für sich existieren. Das ist nur im Fall der Containerisierung nicht so einfach. Normalerweise gibt es bei solchen Streitigkeiten keine rechte Seite, aber im Fall von "Anwenden" - oder "Nicht-Anwenden" -Containern zum Speichern der Datenbank wird alles auf den Kopf gestellt. Denn in gewissem Sinne haben sowohl Befürworter als auch Gegner eines solchen Ansatzes Recht.
Helle Seite
Sie können die Argumente der hellen Seite kurz mit einem Satz beschreiben: "Hallo, 2k19 außerhalb des Fensters!" Es klingt natürlich nach Populismus, aber wenn Sie sich eingehend mit der Situation befassen, hat dies seine Vorteile. Wir werden sie jetzt analysieren.
Angenommen, Sie haben ein großes Webprojekt. Es könnte zunächst auf der Grundlage eines Microservice-Ansatzes aufgebaut werden oder irgendwann auf evolutionäre Weise dazu kommen - dies ist in der Tat nicht sehr wichtig. Sie haben unser Projekt auf separate Microservices verteilt, Orchestrierung, Lastausgleich und Skalierung eingerichtet. Und jetzt trinke mit gutem Gewissen Mojito in einer Hängematte während eines Habr-Effekts, anstatt die gefallenen Kellner zu heben. Aber alle Aktionen müssen konsistent sein. Sehr oft wird nur die Anwendung selbst containerisiert - der Code. Was haben wir außer dem Code noch?
Richtig, Daten. Das Herzstück eines jeden Projekts sind seine Daten: Es kann sich entweder um ein typisches DBMS handeln - MySQL, Postgre, MongoDB oder um einen für die Suche verwendeten Speicher (ElasticSearch), einen Schlüsselwertspeicher für das Caching - zum Beispiel um Redis usw. Jetzt tun wir dies nicht Wir werden über krumme Backend-Implementierungsoptionen sprechen, wenn die Datenbank aufgrund schlecht geschriebener Abfragen abstürzt, und stattdessen über die Bereitstellung von Fehlertoleranz für genau diese Datenbank unter Clientlast. Wenn wir unsere Anwendung containerisieren und sie frei skalieren lassen, um eine beliebige Anzahl eingehender Anforderungen zu verarbeiten, erhöht dies natürlich die Belastung der Datenbank.
Tatsächlich wird der Kanal für den Zugriff auf die Datenbank und den Server, auf dem sie rotiert, zum Nadelöhr in unserem schönen Container-Backend. Gleichzeitig ist das Hauptmotiv für die Containervirtualisierung die Mobilität und Plastizität der Struktur, die es ermöglicht, die Verteilung der Spitzenlast auf die gesamte uns zur Verfügung stehende Infrastruktur so effizient wie möglich zu organisieren. Das heißt, wenn wir nicht alle verfügbaren Elemente des Systems containerisieren und in einem Cluster zusammenfassen, machen wir einen sehr schwerwiegenden Fehler.
Es ist viel logischer, nicht nur die Anwendung selbst, sondern auch die für die Datenspeicherung verantwortlichen Dienste zu gruppieren. Beim Clustering und Bereitstellen unabhängig arbeitender und verteilter Webserver in k8s lösen wir bereits das Problem der Datensynchronisierung - dieselben Kommentare für Beiträge, wenn Sie eine Medien- oder Blogplattform als Beispiel nehmen. In jedem Fall starten wir eine sogar virtuelle Intracluster-Darstellung der Datenbank als ExternalService. Die Frage ist, dass die Datenbank selbst noch nicht geclustert wurde. Die im Cube bereitgestellten Webserver nehmen Informationen über die Änderungen von unserer statischen Kampfbasis entgegen, die separat rotiert.
Fühlen Sie den Haken? Wir verwenden k8s oder Swarm, um die Last zu verteilen und den Ausfall des Hauptwebservers zu vermeiden, aber wir tun dies nicht für die Datenbank. Aber wenn die Datenbank abstürzt, macht es in unserer gesamten Cluster-Infrastruktur keinen Sinn - was nützen leere Webseiten, die einen Datenbankzugriffsfehler zurückgeben?
Aus diesem Grund müssen nicht nur Webserver wie gewohnt geclustert werden, sondern auch die Datenbankinfrastruktur. Nur so können wir sicherstellen, dass Elemente derselben Struktur, die in einem Team voll funktionsfähig sind, aber gleichzeitig unabhängig voneinander sind. Selbst wenn die Hälfte unseres Backends unter Last "zusammenbricht", bleibt der Rest erhalten, und das Datenbanksynchronisationssystem innerhalb des Clusters und die Möglichkeit der unendlichen Skalierung und Bereitstellung neuer Cluster werden dazu beitragen, die erforderlichen Kapazitäten schnell zu erreichen - es würden Racks im Rechenzentrum vorhanden sein .
Darüber hinaus können Sie mit dem in Clustern verteilten Datenbankmodell dieselbe Datenbank dorthin bringen, wo sie benötigt wird. Wenn es sich um einen globalen Dienst handelt, ist es ziemlich unlogisch, einen Webcluster irgendwo in der Region San Francisco zu verdrehen und gleichzeitig Pakete zu betreiben, wenn auf die Datenbank in der Region Moskau zugegriffen wird, und umgekehrt.
Durch die Datenbankcontainerisierung können Sie außerdem alle Elemente des Systems auf derselben Abstraktionsebene erstellen. Dies ermöglicht es wiederum, dieses System von Entwicklern direkt aus dem Code heraus zu verwalten, ohne dass Administratoren aktiv beteiligt sind. Die Entwickler dachten, sie bräuchten ein separates DBMS für ein neues Teilprojekt - einfach! hat eine yaml-Datei geschrieben, in den Cluster hochgeladen und fertig.
Natürlich ist die interne Bedienung stark vereinfacht. Sagen Sie mir, wie oft haben Sie in den Augenblicken geschielt, in denen ein neues Mitglied des Teams seine Hände zur Arbeit in die Kampfdatenbank geschoben hat? Welches dreht sich gerade? Natürlich sind wir alle hier Erwachsene, und irgendwo haben wir ein neues Backup und noch weiter - hinter einem Regal mit Gurken der Großmutter und alten Skiern - ein weiteres Backup, möglicherweise sogar in einem Kühlhaus, weil Ihr Büro einmal in Flammen stand. Dennoch ist jede Einführung eines neuen Teammitglieds mit Zugriff auf die Kampfinfrastruktur und natürlich auf die Kampfdatenbank ein Eimer mit Validol für alle Beteiligten. Nun, wer, ein Neuling, weiß, vielleicht blinzelt er? Beängstigend, stimme zu.
Die Containerisierung und in der Tat die verteilte physische Datenbanktopologie Ihres Projekts tragen dazu bei, solche gültigen Momente zu vermeiden. Traue dem Neuling nicht? Okay Wir werden unseren eigenen Cluster dafür erstellen und ihn vom Rest der Datenbankcluster trennen - Synchronisation nur durch manuelles Drücken und gleichzeitiges Drehen von zwei Schlüsseln (ein Teamleiter, der zweite Administrator). Und alle sind glücklich.
Und jetzt ist es an der Zeit, die Gegner der Datenbankcontainerisierung zu wechseln.
Die dunkle Seite
Wenn wir argumentieren, warum es nicht notwendig ist, die Datenbank zu containerisieren und sie weiterhin auf einem zentralen Server zu drehen, werden wir uns nicht an die Rhetorik der Orthodoxie und Aussagen wie "Großväter haben die Datenbank auf Hardware umgestellt, und wir werden!" Versuchen wir stattdessen, eine Situation zu finden, in der die Containerisierung wirklich greifbare Dividenden bringen würde.
Sie müssen zugeben, dass Projekte, die wirklich eine Basis im Container benötigen, an den Fingern einer Hand als nicht der beste Fräsmaschinenbediener gezählt werden können. Zum größten Teil ist sogar die Verwendung von k8s oder Docker Swarm überflüssig - häufig greifen sie aufgrund des allgemeinen Hype der Technologie auf diese Tools zurück, und die „mächtigsten“ in der Person der Geschlechter, um alles in Wolken und Container zu treiben. Nun, denn jetzt ist es in Mode und jeder tut es.
Zumindest in der Hälfte der Fälle ist die Verwendung von Kubernetis oder nur eines Dockers in einem Projekt überflüssig. Die Frage ist, dass nicht alle Teams oder Outsourcing-Unternehmen, die für die Wartung der Kundeninfrastruktur eingestellt wurden, sich dessen bewusst sind. Schlimmer noch - wenn Container auferlegt werden, weil sie dem Kunden in einer bestimmten Menge Münzen aufsteigen.
Im Allgemeinen gibt es eine Meinung, dass der Docker / Mafia-Würfel Kunden, die diese Infrastrukturprobleme auslagern, dumm vernichtet. Um mit Clustern arbeiten zu können, benötigen Sie Ingenieure, die dazu in der Lage sind und die Architektur der implementierten Lösung im Allgemeinen verstehen. Irgendwie haben wir unseren Fall bereits mit der Republic Edition beschrieben - dort haben wir das Kundenteam geschult, um in den Realitäten von Kubernetis zu arbeiten, und alle waren zufrieden. Und es war anständig. Oft nehmen die „Implementierer“ von k8 die Infrastruktur des Kunden als Geisel - jetzt verstehen sie nur noch, wie dort alles funktioniert, es gibt keine Spezialisten auf der Client-Seite.
Stellen Sie sich nun vor, dass wir auf diese Weise nicht nur den Webserverteil an das Outsourcing übergeben, sondern auch die Datenbankwartung. Wir sagten, dass eine DB ein Herz ist und Herzverlust für jeden lebenden Organismus tödlich ist. Kurz gesagt, die Aussichten sind nicht die besten. Anstelle von Hype Kubernetis sollten viele Projekte einfach nicht verrückt nach dem normalen AWS-Tarif werden, der alle Probleme mit der Auslastung ihrer Website / ihres Projekts löst. Aber AWS ist nicht mehr in Mode und Show-Offs sind teurer als Geld - leider auch in der IT-Umgebung.
Okay Vielleicht muss das Projekt wirklich geclustert werden, aber wenn bei zustandslosen Anwendungen alles klar ist, wie können wir dann eine angemessene Bereitstellung der Netzwerkkonnektivität für die geclusterte Datenbank organisieren?
Wenn es sich um eine nahtlose Engineering-Lösung handelt, bei der es sich anscheinend um den Übergang zu k8s handelt, besteht unser Hauptproblem in der Datenreplikation in einer Clusterdatenbank. Einige DBMS sind anfangs der Verteilung von Daten zwischen ihren einzelnen Instanzen ziemlich treu. Viele andere sind nicht so einladend. Und häufig ist das Hauptargument bei der Auswahl eines DBMS für unser Projekt nicht die Fähigkeit, mit minimalen Ressourcen- und Engineeringkosten zu replizieren. Vor allem, wenn das Projekt ursprünglich nicht als Microservice geplant war, sondern sich einfach in diese Richtung entwickelt hat.
Wir müssen nicht über die Geschwindigkeit von Netzwerklaufwerken sprechen - sie sind langsam. Das heißt, Wir haben immer noch keine echte Möglichkeit. In diesem Fall können wir eine DBMS-Instanz irgendwo aktualisieren, wo beispielsweise mehr Prozessorkapazitäten oder freier RAM vorhanden sind. Wir stoßen sehr schnell auf die Leistung eines virtualisierten Festplattensubsystems. Dementsprechend muss das DBMS in unmittelbarer Nähe an seine eigenen Maschinen genagelt werden. Oder es ist notwendig, die ausreichend schnelle Synchronisation der Datensynchronisation irgendwie von den geschätzten Reserven zu trennen.
Fortsetzung des Themas der virtuellen FS: Docker-Volumes sind leider nicht problemlos. Im Allgemeinen möchte ich in einem Fall wie einer langfristig zuverlässigen Datenspeicherung mit den einfachsten technischen Schemata arbeiten. Das Hinzufügen einer neuen Abstraktionsschicht aus dem FS-Container zum übergeordneten Host-FS ist an sich schon ein Risiko. Wenn es jedoch auch Schwierigkeiten gibt, Daten zwischen diesen Schichten beim Betrieb des Containerisierungs-Support-Systems zu übertragen, ist dies wirklich eine Katastrophe. Im Moment scheinen die meisten Probleme, die der fortschrittlichen Menschheit bekannt sind, beseitigt zu sein. Aber Sie selbst verstehen, je komplexer der Mechanismus ist, desto leichter bricht er.
Angesichts all dieser "Abenteuer" ist es viel rentabler und einfacher, die Datenbank an einem Ort zu halten. Selbst wenn Sie eine Containerisierung der Anwendung benötigen, lassen Sie sie sich von selbst drehen und erhalten über das Distributions-Gateway eine gleichzeitige Kommunikation mit der Datenbank, die nur einmal gelesen und geschrieben wird an einem Ort. Dieser Ansatz reduziert die Wahrscheinlichkeit von Fehlern und Fehlersynchronisation auf minimale Werte.
Wohin führen wir? Darüber hinaus ist eine Containerisierung der Datenbank angebracht, wenn ein wirklicher Bedarf besteht. Sie können die Basis der vollständigen App nicht überfüllen und drehen, als hätten Sie zwei Dutzend Microservices - dies funktioniert nicht. Und das muss klar verstanden werden.
Anstelle von Ausgabe
Wenn Sie auf die verständliche Schlussfolgerung „Virtualisieren oder nicht die Datenbank“ warten, sind wir enttäuscht: Sie wird nicht hier sein. Denn bei der Erstellung einer Infrastrukturlösung sollte man sich nicht von Mode und Fortschritt leiten lassen, sondern vor allem vom gesunden Menschenverstand.
Es gibt Projekte, bei denen die Prinzipien und Werkzeuge von kubernetis perfekt passen, und bei solchen Projekten kommt Frieden zumindest im Backend-Bereich. Und es gibt Projekte, die keine Containerisierung benötigen, sondern eine normale Serverinfrastruktur, da sie grundsätzlich nicht auf ein Microservice-Cluster-Modell skaliert werden können, da sie fallen werden.