Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen.

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen.

Irgendwie beschloss ich eines Tages, einen Artikel über die Bereitstellung in Form von Docker-Containern und deb-Paketen zu schreiben. Doch als ich anfing, brachte es mich irgendwie zurück zu den frühen Zeiten der ersten Personal Computer und sogar Taschenrechner. Statt trockener Vergleiche zwischen Docker und deb entstanden so Gedanken zur Evolution, die ich Ihnen zur Verfügung stelle.

Jedes Produkt, egal was es ist, muss irgendwie zu den Produktservern gelangen, muss konfiguriert und in Betrieb genommen werden. Dieser Artikel wird sich genau mit diesem Thema befassen.

Ich werde im historischen Kontext nachdenken: "Was ich sehe, darüber singe ich". Was ich gesehen habe, als ich anfing, Code zu schreiben, und was ich jetzt beobachte, und was wir derzeit selbst nutzen und warum. Der Artikel erhebt keinen Anspruch auf eine umfassende Untersuchung, einige Punkte wurden ausgelassen. Dies ist mein persönlicher Blick auf das, was war und was es heute ist.

Nun, in den guten alten Zeiten… der früheste Bereitstellungsweg, den ich erlebt habe, waren Kassetten von Kassettenrecordern. Ich hatte einen BK-0010.01 Computer…

Das Zeitalter der Taschenrechner

Nein, es gab einen noch früheren Moment, da gab es einen Taschenrechner MK-61 und MK-52.

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen. Jedenfalls, als ich hatte MK-61, war die Methode, ein Programm zu übertragen, ein gewöhnliches kariertes Blatt Papier, auf dem das Programm aufgeschrieben war, das, wenn man es starten wollte, manuell in den Taschenrechner eingegeben wurde. Willst du spielen (ja, ja, sogar auf diesem uralten Taschenrechner gab es Spiele) — setzt du dich hin und schreibst das Programm in den Taschenrechner. Natürlich verschwand das Programm beim Ausschalten des Taschenrechners ins Nichts. Neben den handgeschriebenen Codes auf Papier wurden Programme auch in den Zeitschriften "Radio" und "Technik der Jugend" veröffentlicht und in Büchern dieser Zeit abgedruckt.

Die nächste Modifikation war der Taschenrechner MK-52, der nun eine Art von nichtflüchtigem Datenspeicher hatte. Jetzt musste das Spiel oder Programm nicht mehr manuell eingegeben werden; durch einige magische Tastenkombinationen wurde es automatisch geladen.

Das Volumen des größten Programms im Taschenrechner betrug 105 Schritte, während der Speicher im MK-52 512 Schritte betrug.

Übrigens, falls es Fans dieser Taschenrechner gibt, die diesen Artikel lesen: Während ich den Artikel schrieb, fand ich auch einen Emulator für den Taschenrechner für Android sowie Programme dafür. Auf geht's in die Vergangenheit!

Eine kleine Abzweigung zum MK-52 (aus Wikipedia)

Der MK-52 flog ins All mit dem Raumschiff „Sojus TM-7“. Er sollte zur Berechnung der Lande Bahn im Falle eines Ausfalls des Bordcomputers verwendet werden.

Der MK-52 mit dem Speichererweiterungsblock „Elektronika-Astro“ wurde seit 1988 an die Schiffe der Marine im Rahmen des navigatorischen Berechnungskomplexes geliefert.

Die ersten Personal Computer

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen. Lass uns zu den Zeiten zurückkehren BK-0010. Es ist klar, dass der Speicher größer wurde und es schon ganz unmöglich war, den Code von einem Zettel einzugeben (auch wenn ich das anfangs tat, weil es einfach kein anderes Speichermedium gab). Hauptspeichermedium für die Speicherung und Lieferung von Software wurden Audiokassetten für Kassettenrekorder.





Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen.Die Speicherung auf Kassette war normalerweise in Form einer oder zweier Binärdateien, alles andere befand sich im Inneren. Die Zuverlässigkeit war sehr gering, sodass man 2-3 Kopien des Programms aufbewahren musste. Auch die Ladezeiten waren nicht erfreulich, und Enthusiasten experimentierten mit unterschiedlichen Frequenzkodierungen, um diese Mängel zu überwinden. Zu dieser Zeit beschäftigte ich mich noch nicht professionell mit Softwareentwicklung (abgesehen von einfachen Programmen in BASIC), deshalb kann ich leider nicht im Detail erzählen, wie alles intern strukturiert war. Die Tatsache, dass der Computer hauptsächlich nur über RAM verfügte, bestimmte größtenteils die Einfachheit des Datenspeicherschemas.

Das Erscheinen zuverlässiger und großer Speichermedien

Später tauchen Disketten auf, der Kopiervorgang wird einfacher, die Zuverlässigkeit steigt.
Aber die Situation verändert sich grundlegend, erst als ausreichend große lokale Speicher in Form von HDD verfügbar werden.

Der Typ der Lieferung ändert sich grundlegend: Programme-Installer erscheinen, die den Prozess der Systemkonfiguration sowie der Bereinigung nach der Deinstallation steuern, da Programme nicht einfach in den Speicher geladen werden, sondern bereits in den lokalen Speicher kopiert werden, aus dem man bei Bedarf unerwünschte Daten auch löschen können muss.

Parallel dazu steigt die Komplexität der gelieferten Software.
Die Anzahl der Dateien in der Lieferung steigt von wenigen auf Hunderte und Tausende, es beginnen Konflikte zwischen verschiedenen Versionen von Bibliotheken und andere Herausforderungen, wenn verschiedene Programme dieselben Daten verwenden.

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen. In jener Zeit war mir die Existenz von Linux noch nicht bekannt, ich lebte in der Welt von MS DOS und später von Windows und schrieb in Borland Pascal und Delphi, während ich manchmal in Richtung C++ schaute. Für die Bereitstellung von Produkten verwendeten damals viele InstallShield, ru.wikipedia.org/wiki/InstallShield, das alle gestellten Aufgaben der Bereitstellung und Konfiguration von Software sehr erfolgreich löste.




Das Internetzeitalter

Allmählich wird die Komplexität der Softwaresysteme noch komplizierter, der Übergang vom Monolithen und Desktop-Anwendungen erfolgt zu verteilten Systemen, schlanken Clients und Mikrodiensten. Jetzt muss man nicht mehr nur ein Programm konfigurieren, sondern deren Sammlung, und zwar so, dass sie alle zusammenarbeiten.

Das Konzept änderte sich grundlegend, das Internet kam auf, das Zeitalter der Cloud-Dienste begann. Zunächst war es nur in der Anfangsphase in Form von Webseiten, und wirklich Dienste hatte noch niemand im Blick. Aber das war ein Wendepunkt in der Industrie sowohl in der Entwicklung als auch in der Bereitstellung von Anwendungen.

Für mich wurde in diesem Moment deutlich, dass ein Generationenwechsel unter den Entwicklern stattfand (oder war das nur in meiner Umgebung so?), und es entstand das Gefühl, dass all die alten, bewährten Methoden der Bereitstellung plötzlich vergessen waren und alles neu begann: die gesamte Bereitstellung wurde mit Bastelskripten durchgeführt und stolz als „Continuous Delivery“ bezeichnet. Tatsächlich begann eine Art chaotische Phase, in der das Alte vergessen war und nicht mehr benutzt wurde, während es einfach nichts Neues gab.

Ich erinnere mich an Zeiten, als in unserem Unternehmen, wo ich damals arbeitete (ich möchte es nicht nennen), anstatt eine Compilation über Ant zu machen (Maven war damals noch nicht populär oder gab es gar nicht), die Leute einfach JARs in der IDE erstellten und sorglos in SVN committed haben. Folglich bestand die Bereitstellung darin, die Datei aus SVN zu holen und über SSH auf die entsprechende Maschine zu kopieren. So einfach und grob.

Zur gleichen Zeit wurde die Bereitstellung einfacher Webseiten in PHP auf äußerst primitive Weise durchgeführt, indem die geänderte Datei einfach über FTP auf das Zielgerät kopiert wurde. Manchmal war nicht einmal das der Fall – der Code wurde direkt auf dem produktiven Server bearbeitet, und es war besonders schick, wenn irgendwo Backups vorhanden waren.


RPM- und DEB-Pakete

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen.Andererseits gewannen mit der Entwicklung des Internets UNIX-ähnliche Systeme zunehmend an Popularität. Insbesondere entdeckte ich damals RedHat Linux 6, ca. 2000. Natürlich gab es auch dort bestimmte Mittel zur Bereitstellung von Software; laut Wikipedia erschien RPM als Hauptpaketmanager bereits 1995 in der Version RedHat Linux 2.0. Seitdem wird das System bis heute in Form von RPM-Paketen geliefert und entwickelt sich durchaus erfolgreich weiter.

Distributionen der Debian-Familie gingen einen ähnlichen Weg und implementierten die Bereitstellung in Form von deb-Paketen, was bis heute unverändert bleibt.

Paketmanager ermöglichen die Bereitstellung der Softwareprodukte selbst, konfigurieren diese während der Installation, verwalten Abhängigkeiten zwischen verschiedenen Paketen und führen die Deinstallation von Produkten durch sowie das Entfernen überflüssiger Dateien im Deinstallationsprozess. Das heißt, größtenteils ist das alles, was man braucht, genau deshalb haben sie sich über mehrere Jahrzehnte nahezu ohne Veränderungen gehalten.

Cloud-Lösungen haben in Paketmanager die Installation nicht nur von physischen Trägern, sondern auch aus Cloud-Repositorys hinzugefügt, aber prinzipiell hat sich am Grundsatz wenig geändert.

Es ist bemerkenswert, dass es derzeit einige Bestrebungen gibt, von deb abzurücken und auf Snap-Pakete umzusteigen, aber dazu später mehr.

So wuchs diese neue Generation von Cloud-Entwicklern, die weder DEB noch RPM kannten, langsam heran, sammelte Erfahrungen, die Produkte wurden komplexer, und es wurden intelligenteren Bereitstellungsmethoden benötigt als FTP, bash-Skripte und ähnliche studentische Bastelarbeiten.
Und hier tritt Docker auf, eine Art Mischung aus Virtualisierung, Ressourcenteilung und Bereitstellungsmethode. Es ist jetzt modern, jugendlich, aber wird es überall benötigt? Ist es ein Allheilmittel?

Nach meinen Beobachtungen wird Docker oft nicht als vernünftige Wahl angeboten, sondern schlichtweg, weil es in der Gemeinschaft besprochen wird und diejenigen, die es anbieten, nur dies kennen. Auf der anderen Seite wird über die guten alten Verpackungssysteme größtenteils geschwiegen — sie sind vorhanden und leisten still und unauffällig ihre Arbeit. In dieser Situation gibt es nicht viel Auswahl — die Wahl ist offensichtlich — Docker.

Ich werde versuchen, meine Erfahrungen zu teilen, wie bei uns die Einführung von Docker ablief und was dabei herausgekommen ist.


Selbstgeschriebene Skripte

Ursprünglich gab es Bash-Skripte, die Jar-Archive auf die benötigten Maschinen deployten. Jenkins steuerte diesen Prozess. Das funktionierte erfolgreich, da das Jar-Archiv selbst bereits eine Sammlung ist, die Klassen, Ressourcen und sogar Konfigurationen enthält. Wenn man alles maximiert, ist es nicht die schwierigste Aufgabe, es mit einem Skript zu entpacken.

Aber Skripte haben mehrere Nachteile:

  • Skripte werden normalerweise hastig geschrieben und sind daher so primitiv, dass sie nur ein einziges, am erfolgreichsten getestetes Szenario beinhalten. Das wird durch das Interesse des Entwicklers an einer schnellen Auslieferung begünstigt, während ein ordentliches Skript eine beträchtliche Menge an Ressourcen erfordert.
  • Infolge des vorherigen Punktes enthalten Skripte keine Deinstallationsprozeduren.
  • Es gibt kein festgelegtes Upgrade-Verfahren.
  • Bei der Einführung eines neuen Produkts muss ein neues Skript geschrieben werden.
  • Es gibt keine Unterstützung für Abhängigkeiten.

Natürlich könnte man ein ausgefeiltes Skript schreiben, aber wie ich bereits erwähnt habe, ist das eine erhebliche Entwicklungszeit, und Zeit ist bekanntlich immer knapp.

All dies schränkt den Einsatz einer solchen Bereitstellungsmethode auf die einfachsten Systeme ein. Es ist an der Zeit, dies zu ändern.


Docker

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen.Irgendwann kamen frischgebackene Mid-Level-Entwickler zu uns, sprühend vor Ideen und begeistert von Docker. Na gut, lassen Sie uns das angehen! Es gab zwei Versuche. Beide waren erfolglos – sagen wir, wegen großer Ambitionen, aber fehlender praktischer Erfahrung. Hätte man das nicht forciert und mit aller Kraft zu Ende bringen sollen? Wahrscheinlich nicht – das Team muss evolutionär auf das nötige Niveau wachsen, bevor es in der Lage ist, die entsprechenden Werkzeuge zu nutzen. Zudem hatten wir oft Schwierigkeiten mit Docker-Images, bei denen das Netzwerk nicht richtig funktionierte (was möglicherweise mit der Unreife von Docker selbst zusammenhing) oder es schwierig war, fremde Container zu erweitern.

Mit welchen Unannehmlichkeiten sind wir konfrontiert worden?

  • Netzwerkprobleme im Bridge-Modus.
  • Es ist unpraktisch, die Logs im Container zu betrachten (wenn sie nicht getrennt im Dateisystem der Hostmaschine gespeichert sind).
  • Gelegentlich kam es zu seltsamen Hängern von ElasticSearch im Container, die Ursache wurde nie ermittelt, der Container ist offiziell.
  • Die Nutzung der Shell im Container ist unpraktisch – alles ist stark eingeschränkt, die gewohnten Werkzeuge fehlen.
  • Die große Größe der gesammelten Container ist teuer zu lagern.
  • Aufgrund der großen Größe der Container ist es schwierig, mehrere Versionen zu verwalten.
  • Längere Aufbauzeit im Vergleich zu anderen Methoden (Skripte oder deb-Pakete).

Warum lässt sich ein Spring-Service als jar-Archiv nicht ebenso gut über ein deb deployen? Ist Ressourcensicherung wirklich notwendig? Sollten wir auf nützliche Werkzeuge des Betriebssystems verzichten, indem wir den Service in einen stark reduzierten Container packen?

Wie die Erfahrung zeigt, ist das in der Realität nicht nötig; mit deb-Paketen kommt man in 90 % der Fälle aus.

Wann funktioniert der gute alte deb nicht mehr und wann war Docker tatsächlich erforderlich?

Für uns ging es um das Deployment von Services in Python. Viele Bibliotheken, die für maschinelles Lernen notwendig sind und in der Standardausstattung des Betriebssystems fehlen (und die vorhandenen sind nicht die richtigen Versionen), Hacks mit Konfigurationen und die Notwendigkeit, verschiedene Versionen für verschiedene Services zu haben, die auf demselben Host-System laufen, führten dazu, dass Docker die einzige logische Methode zur Bereitstellung dieser Mischung war. Der Aufwand für den Aufbau eines Docker-Containers erwies sich als geringer als die Idee, all dies in separate deb-Pakete mit Abhängigkeiten zu verpacken, und niemand mit vollem Verstand würde dies wagen.

Ein weiterer Punkt, an dem Docker genutzt werden soll, ist das Deployment von Services nach dem Schema Blue-Green Deploy. Hier möchten wir jedoch die Komplexität schrittweise erhöhen: Zuerst werden deb-Pakete erstellt, und dann wird daraus der Docker-Container gebaut.


Snap-Pakete.

Die Evolution von Liefermethoden, oder Überlegungen zu Docker, deb, jar und anderen. Kehren wir zu den Snap-Paketen zurück. Sie wurden zum ersten Mal offiziell in Ubuntu 16.04 eingeführt. Im Gegensatz zu den gewohnten deb- und rpm-Paketen bringen Snap-Pakete alle Abhängigkeiten mit. Einerseits verhindert dies Konflikte zwischen Bibliotheken, andererseits führt es zu größeren Paketgrößen. Darüber hinaus kann dies die Sicherheit des Systems beeinflussen: Bei der Bereitstellung von Snap-Paketen muss der Entwickler, der das Paket erstellt, alle Änderungen der enthaltenen Bibliotheken überwachen. Insgesamt ist das nicht so eindeutig und das allgemeine Glück über deren Nutzung tritt nicht ein. Dennoch ist es eine durchaus vernünftige Alternative, wenn Docker lediglich als Mittel zum Verpacken und nicht zur Virtualisierung genutzt wird.



Insgesamt verwenden wir derzeit eine sinnvolle Kombination aus deb-Paketen und Docker-Containern, die wir in bestimmten Fällen möglicherweise durch Snap-Pakete ersetzen.

Nur registrierte Benutzer können an der Umfrage teilnehmen. Bitte einloggen.

Welche Methode verwenden Sie für die Bereitstellung?

  • Selbstgeschriebene Skripte

  • Wir kopieren manuell über FTP.

  • deb-Pakete

  • rpm-Pakete

  • snap-Pakete

  • Docker-Images

  • Virtuelle Maschinen-Images

  • Wir klonen die gesamte HDD.

  • Puppet

  • ansible

  • Sonstiges

109 Benutzer haben abgestimmt. 32 Benutzer haben sich enthalten.

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster