Ist Docker ein Spielzeug oder nicht? Oder doch?

Hallo zusammen!

Ich würde sehr gerne sofort mit dem Thema beginnen, aber es ist besser, ein wenig über meine Geschichte zu erzählen:

Einleitung

Ich bin Programmierer mit Erfahrung in der Entwicklung von Frontend-Einzelanwendungen, Scala/Java und Node.js auf dem Server.

Lange Zeit (schon mindestens zwei bis drei Jahre) war ich der Meinung, dass Docker ein Geschenk des Himmels ist und insgesamt ein cooles Tool, das jeder Entwickler beherrschen sollte. Daraus folgt, dass jeder Entwickler Docker auf seinem lokalen Rechner installiert haben sollte. Und wenn Sie mein Urteil anzweifeln, schauen Sie sich einfach die Jobangebote auf derselben Plattform an. In jedem zweiten gibt es eine Erwähnung von Docker, und wenn Sie damit vertraut sind, wird das Ihr Wettbewerbsvorteil sein 😉.

Auf meinem Weg habe ich viele Menschen getroffen, die unterschiedliche Einstellungen zu Docker und seinem Ökosystem hatten. Einige sagten, dass es ein nützliches Werkzeug ist, das Plattformunabhängigkeit garantiert. Andere verstanden nicht, warum sie in Containern arbeiten sollten und welchen Nutzen das hat, während es Dritte völlig egal war – sie schrieben einfach ihren Code und gingen nach Hause – ich beneide sie übrigens ein bisschen 🙂.

Gründe für die Nutzung

Warum habe ich Docker verwendet? Wahrscheinlich aus den folgenden Gründen:

  • Datenbankstart, 99 % der Anwendungen nutzen sie.
  • Nginx-Start für die Bereitstellung des Frontends und das Proxying zum Backend.
  • Ich kann meine Anwendung in ein Docker-Image verpacken, sodass meine Anwendung überall dort funktioniert, wo Docker vorhanden ist. Das Verteilungsproblem ist somit bereits gelöst.
  • Service-Discovery direkt integriert, ich kann Mikrodienste erstellen; jeder Container (verbunden mit einem gemeinsamen Netzwerk) kann leicht über einen Alias auf einen anderen zugreifen, sehr praktisch.
  • Es macht Spaß, einen Container zu erstellen und darin "zu experimentieren".

Was mir an Docker immer NICHT gefallen hat:

  • Damit meine Anwendung funktioniert, muss Docker auf dem Server vorhanden sein. Aber warum brauche ich das, wenn meine Anwendungen bereits auf JRE oder Node.js basieren und die Umgebung dafür bereits auf dem Server vorhanden ist?
  • Wenn ich mein (privates) lokal erstelltes Image auf einem entfernten Server starten möchte, benötige ich ein eigenes Docker-Repository, da irgendwo ein Registry laufen muss, und ich muss außerdem HTTPS einrichten, da die Docker-CLI nur über HTTPS funktioniert. Oh verdammtes Chao... es gibt zwar Alternativen, wie das Bild lokal zu speichern über docker save und dann via SCP einfach das Image zu übertragen... Aber das ist so viel Aufwand. Außerdem sieht es wie eine "Notlösung" aus, bis ich ein eigenes Repository habe.
  • docker-compose. Es wird nur zum Starten von Containern benötigt. Und das war's. Mehr kann es nicht. Docker-compose hat eine Menge Versionen seiner Dateien, seine eigene Syntax. So deklarativ es auch sein mag, ich möchte deren Dokumentation nicht lesen. Ich werde sie sonst nirgendwo benötigen.
  • In der Teamarbeit schreiben die meisten Menschen Dockerfiles sehr schlecht, verstehen nicht, wie es gecached wird, fügen alle notwendigen und unnötigen Inhalte in das Image ein, erben von Images, die nicht in Docker Hub oder im privaten Repository vorhanden sind, und kreieren irgendwelche docker-compose Dateien mit Datenbanken und persistieren nichts. Trotzdem erklären die Entwickler stolz, dass Docker großartig ist, alles lokal funktioniert und HR in den Stellenanzeigen wichtig schreibt: „Wir verwenden Docker und brauchen einen Kandidaten mit dieser Erfahrung“
  • verfolgen ständig die Gedanken, alles in Docker hochzufahren: Postgresql, Kafka, Redis. Schade, dass nicht alles in Containern funktioniert, nicht alles leicht konfiguriert und gestartet werden kann. Die Unterstützung dafür kommt von Drittanbietern und nicht von den Anbietern selbst. Und übrigens stellt sich gleich die Frage, warum sich die Anbieter nicht um die Unterstützung ihrer Produkte in Docker kümmern, vielleicht wissen sie etwas?
  • Es gibt immer wieder Fragen zur Persistenz der Containerdaten. Und hier überlege ich, ob ich einfach ein Verzeichnis des Hosts einbinden oder ein Docker-Volume erstellen oder einen Data-Container erstellen soll, der nun deprecated? Если я монтирую директорию то мне нужно убедиться что uid и gid пользователя в контейнере соответствует id пользователя запустившего контейнер, иначе файлы созданные контейнером будут созданы с правами владельца root. Если использую Volume die Daten einfach in irgendeinem /usr/* und es wird die gleiche Geschichte mit uid und gid wie im ersten Fall sein. Wenn du eine Drittanbieter-Komponente startest, musst du dich in die Dokumentation vertiefen und die Antwort auf die Frage suchen: „In welche Verzeichnisse schreibt die Komponente Dateien im Container?“

Ich mochte es schon immer nicht, dass man zu lange mit Docker herumspielen muss. In der Anfangsphase: Ich überlegte, wie ich Container starten, von welchen Images ich ausgehen sollte, und erstellte Makefiles, die Aliase für lange Docker-Befehle enthielten. Ich konnte Docker-compose nicht ausstehen, weil ich kein weiteres Tool des Docker-Ökosystems lernen wollte. Und docker-compose up es nervte mich, besonders wenn dort auch noch build Konstruktionen vorkamen und nicht bereits gebaute Images. Alles, was ich wirklich wollte, war, das Produkt effizient und schnell zu erstellen. Aber ich konnte die Nutzung von Docker einfach nicht vernünftig aufschlüsseln.

Bekanntschaft mit Ansible

Vor kurzem (vor etwa drei Monaten) arbeitete ich mit einem DevOps-Team zusammen, dessen fast jedes Mitglied eine negative Einstellung zu Docker hatte. Aus folgenden Gründen:

  • Docker verwaltet iptables (obwohl man es in daemon.json deaktivieren kann)
  • Docker ist instabil und wir werden ihn in der Produktion nicht einsetzen
  • Wenn der Docker Daemon abstürzt, fallen entsprechend alle Container mit Infrastruktur aus
  • In Docker ist keine Notwendigkeit vorhanden
  • Warum Docker, wenn es Ansible und virtuelle Maschinen gibt?

Bei der gleichen Arbeit habe ich ein weiteres Tool kennengelernt – Ansible. Früher hatte ich schon davon gehört, aber nie versucht, meine eigenen Playbooks zu schreiben. Jetzt habe ich angefangen, meine Aufgaben zu schreiben, und mein Blick hat sich endgültig geändert! Denn ich erkannte: Ansible hat Module zum Starten von Docker-Containern, zum Erstellen von Images, Netzwerken usw., und Container können nicht nur lokal, sondern auch auf entfernten Servern gestartet werden! Meine Begeisterung kannte keine Grenzen – ich habe ein vernünftiges Tool gefunden und meine Makefile- und Docker-Compose-Dateien entsorgt, sie wurden durch YAML-Aufgaben ersetzt. Der Code wurde durch die Verwendung von Konstruktionen wie loop, when, usw. reduziert.

Docker zum Starten von Drittanbieter-Komponenten wie Datenbanken

Kürzlich habe ich SSH-Tunnel kennengelernt. Es stellte sich heraus, dass man sehr einfach den Port eines entfernten Servers auf einen lokalen Port weiterleiten kann. Der entfernte Server kann sowohl ein Cloud-Rechner als auch eine virtuelle Maschine sein, die in VirtualBox läuft. Wenn ich oder mein Kollege eine Datenbank (oder ein anderes externes Element) brauchen, können wir einfach den Server mit diesem Element starten und herunterfahren, wenn der Server nicht mehr benötigt wird. Die Portweiterleitung hat denselben Effekt wie eine Datenbank, die in einem Docker-Container läuft.

Dieser Befehl leitet meinen lokalen Port an den entfernten Server mit PostgreSQL weiter:

ssh -L 9000:localhost:5432 user@example.com

Die Verwendung eines Remote-Servers löst das Problem mit der Zusammenarbeit im Team. Dieser Server kann gleichzeitig von mehreren Entwicklern genutzt werden, die sich nicht mit der Einrichtung von PostgreSQL, dem Umgang mit Docker und anderen Feinheiten auseinandersetzen müssen. Auf dem Remote-Server kann dieselbe Datenbank in Docker installiert werden, wenn es schwierig ist, eine spezielle Version zu installieren. Alles, was die Entwickler brauchen, ist SSH-Zugriff!

Kürzlich las ich, dass SSH-Tunnel eine eingeschränkte Funktionalität eines normalen VPNs sind! Man kann einfach OpenVPN oder andere VPN-Implementierungen einrichten, die Infrastruktur konfigurieren und den Entwicklern zur Verfügung stellen. Das ist doch großartig!

Glücklicherweise bieten AWS, GoogleCloud und andere ein Jahr kostenlose Nutzung an, also nutzen Sie sie! Sie sind günstig, wenn man sie abschaltet, wenn sie nicht in Gebrauch sind. Ich habe immer darüber nachgedacht, wofür ich einen Remote-Server wie gcloud benötigen könnte, und ich glaube, ich habe es gefunden.

Als virtuelle Maschine auf der lokalen Maschine kann man das gleiche Alpine verwenden, das aktiv in Docker-Containern genutzt wird. Oder andere leichte Distributionen, damit die Maschine schneller hochfährt.

Fazit: Datenbanken und andere infrastrukturelle Extras können und sollten auf Remote-Servern oder in VirtualBox betrieben werden. Ich brauche Docker nicht für diese Zwecke.

Einige Informationen zu Docker-Images und Distribution

Ich habe bereits geschrieben einen Artikel darüber, dass die Nutzung von Docker-Images keine Garantie bietet. Docker-Images sind nur dazu da, um Docker-Container zu erstellen. Wenn Sie auf ein Docker-Image angewiesen sind, sind Sie auf die Nutzung von Docker-Containern angewiesen und werden nur mit ihnen arbeiten.

Haben Sie schon irgendwo gesehen, dass Softwareentwickler ihre Produkte nur als Docker-Image portiert haben?
Das Ergebnis der meisten Produkte sind Binärdateien für eine bestimmte Plattform, die einfach in ein Docker-Image hinzugefügt werden, das von der benötigten Plattform abgeleitet ist. Haben Sie sich schon mal gefragt, warum es so viele ähnliche Images auf Docker Hub gibt? Geben Sie zum Beispiel nginx ein, und Sie werden unzählige Images von verschiedenen Personen sehen. Diese Leute haben Nginx nicht selbst entwickelt, sie haben einfach Nginx in ihr Docker-Image hinzugefügt und es mit ihren Konfigurationen für die bequeme Ausführung von Containern angereichert.

Im Allgemeinen kann man es einfach in tgz aufbewahren. Wenn jemand es in Docker starten möchte, kann er es im Dockerfile hinzufügen, von der benötigten Umgebung erben und zusätzliche Extras erstellen, die die Anwendung im tgz nicht verändern. Derjenige, der ein Docker-Image erstellt, wird wissen, was dieses tgz ist und was er für die Arbeit benötigt. So nutze ich Docker. hier

Fazit: Ich brauche kein Docker-Registry, ich werde irgendeinen S3 oder einfach ein Dateispeicher wie Google Drive/Dropbox verwenden.

Docker in CI

Alle Unternehmen, in denen ich gearbeitet habe, ähneln sich. Sie sind in der Regel produktorientiert. Das heißt, sie haben eine bestimmte Anwendung, einen Technologiestack (vielleicht ein bis drei Programmiersprachen).

Diese Unternehmen verwenden Docker auf ihren Servern, wo der CI-Prozess läuft. Die Frage ist: Warum sollten Projekte in einem Docker-Container auf den eigenen Servern gebaut werden? Warum nicht einfach eine Umgebung für den Build vorbereiten, zum Beispiel ein Ansible-Playbook schreiben, das die benötigten Versionen von Node.js, PHP, JDK installiert, SSH-Schlüssel usw. auf den Server kopiert, auf dem der Build stattfindet?

Jetzt verstehe ich, dass das sich selbst ins Bein schießen bedeutet, weil Docker durch seine Isolation keinen Nutzen bringt. Die Probleme mit CI in Docker, mit denen ich konfrontiert war:

  • Wieder wird ein Docker-Image für den Build benötigt. Man muss ein Image suchen oder eine eigene Dockerfile schreiben.
  • Es gibt eine 90%ige Wahrscheinlichkeit, dass man irgendwelche SSH-Schlüssel, geheime Daten weitergeben muss, die man nicht im Docker-Image speichern möchte.
  • Der Container wird erstellt und stirbt, alle Caches gehen mit ihm verloren. Der nächste Build muss alle Abhängigkeiten des Projekts neu herunterladen, und das ist langsam und ineffizient; Zeit ist Geld.

Entwickler bauen Projekte nicht in Docker-Containern (ich war einmal ein solcher Fan, es tut mir leid um mein früheres Ich xD). In Java hat man die Möglichkeit, mehrere Versionen zu haben und kann mit einem Befehl auf die benötigte Version wechseln. Bei Node.js ist es dasselbe, es gibt nvm.

Ausgabe

Ich halte Docker für ein sehr mächtiges und flexibles Werkzeug, was gleichzeitig sein Nachteil ist (klingt seltsam, oder?). Mit ihm „gewöhnen“ sich Unternehmen daran, es dort zu verwenden, wo es nötig und wo nicht nötig ist. Entwickler starten ihre eigenen Container, ihre eigene Umgebung, und das fließt dann sanft in CI und Produktion über. Das DevOps-Team schreibt irgendwelche Fahrräder, um diese Container zu starten.

Verwenden Sie Docker nur im allerletzten Schritt Ihres Arbeitsprozesses, ziehen Sie es nicht zu Beginn ins Projekt. Es wird Ihre Geschäftsprobleme nicht lösen. Es wird die Probleme nur auf eine ANDERE Ebene verschieben und eigene Lösungsvorschläge anbieten, wodurch Sie doppelte Arbeit leisten müssen.

Wenn Docker benötigt wird: bin ich zu dem Schluss gekommen, dass Docker sehr gut zur Optimierung des festgelegten Prozesses geeignet ist, aber nicht beim Aufbau der grundlegenden Funktionalität.

Wenn Sie sich dennoch entschieden haben, Docker zu verwenden, dann:

  • Seien Sie äußerst vorsichtig
  • Drängen Sie die Verwendung von Docker nicht den Entwicklern auf
  • Lokalisieren Sie dessen Verwendung an einem Ort, verbreiten Sie es nicht über alle Repositories mit Dockerfile und docker-compose.

PS:

Vielen Dank fürs Lesen! Ich wünsche Ihnen transparente Lösungen in Ihren Geschäften und produktive Arbeitstage!

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