Hallo zusammen!
Ich möchte sofort zum Thema kommen, aber es ist besser, ein wenig über meine Geschichte zu erzählen:
Einleitung
Ich bin Programmierer mit Erfahrung in der Entwicklung von Frontend-Einzelseitenanwendungen, Scala/Java und Node.js auf dem Server.
Lange Zeit (schon bestimmt zwei bis drei Jahre) war ich der Meinung, dass Docker ein wahres Geschenk des Himmels ist, ein beeindruckendes Tool, das jeder Entwickler beherrschen sollte. Daraus folgt, dass Docker auf jedem Entwickler-PC installiert sein sollte. Aber was sage ich da über meine Meinung? Schaut euch einfach die Stellenanzeigen auf Plattformen wie hh an. In jeder zweiten wird Docker erwähnt, und wenn ihr damit vertraut seid, ist das euer Wettbewerbsvorteil 😉
Auf meinem Weg habe ich vielen Menschen begegnet, die unterschiedliche Ansichten zu Docker und seiner Ökosystem hatten. Einige sagten, es sei eine praktische Sache, die Plattformunabhängigkeit garantiert. Andere verstanden nicht, warum sie in Containern arbeiten sollten und welchen Vorteil es bringt. Dritte war es völlig egal; sie schrieben einfach ihren Code und gingen nach Hause – ich beneide sie übrigens 🙂
Gründe für die Nutzung
Warum habe ich Docker verwendet? Wahrscheinlich aus folgenden Gründen:
- Datenbank starten, 99 % der Anwendungen nutzen sie.
- Nginx für die Bereitstellung von Frontend und Proxierung auf Backend starten.
- Es ist möglich, die Anwendung in ein Docker-Image zu packen, somit läuft meine Anwendung überall, wo Docker vorhanden ist, das Problem der Verteilung ist damit bereits gelöst.
- Service Discovery ist standardmäßig integriert, es können Mikrodienste erstellt werden, jeder Container (der mit dem gemeinsamen Netzwerk verbunden ist) kann leicht über einen Alias auf einen anderen zugreifen, sehr praktisch.
- Es ist spannend, einen Container zu erstellen und darin "zu experimentieren".
Was mir an Docker immer NICHT gefallen hat:
- Damit meine Anwendung funktioniert, benötige ich Docker auf dem Server. Warum sollte ich das tun, wenn meine Anwendungen bereits auf JRE oder Node.js basieren und die Umgebung dafür schon auf dem Server vorhanden ist?
- Wenn ich mein (privates) lokal erstelltes Image auf einem Remote-Server starten möchte, benötige ich mein eigenes Docker-Repository, ich muss dafür sorgen, dass irgendwo ein Registry läuft, und ich muss HTTPS konfigurieren, denn Docker CLI funktioniert nur über HTTPS. Oh Mann… natürlich gibt es Optionen, das Image lokal zu speichern über
docker saveund sicher über SCP einfach zu übertragen… aber das sind so viele Schritte. Außerdem sieht es nach einer "Flickwerk"-Lösung aus, bis ein eigenes Repository verfügbar ist. version: '1' services: simplesample-sonar: image: sonarqube:lts ports: - 9001:9000 - 9092:9092 network_mode: bridge. Es ist nur für das Starten von Containern notwendig. Das war's. Es kann nichts anderes.Docker-composehat eine Menge Versionen seiner Dateien, seine eigene Syntax. So deklarativ es auch sein mag, ich möchte deren Dokumentation nicht lesen. Ich brauche sie sonst nirgends.- Wenn man im Team arbeitet, schreiben die meisten Leute Dockerfiles sehr schlecht, verstehen nicht, wie Caching funktioniert, fügen alles Notwendige und Unnötige zum Image hinzu, leiten von Images ab, die nicht auf Docker Hub oder in privaten Repositories vorhanden sind, und erstellen irgendwelche
version: '1' services: simplesample-sonar: image: sonarqube:lts ports: - 9001:9000 - 9092:9092 network_mode: bridgeDatenbankdateien, aber nichts wird persistent gespeichert. Dabei behaupten die Entwickler stolz, dass Docker großartig ist, alles lokal funktioniert und HR in den Stellenanzeigen wichtig schreibt: „Wir verwenden Docker und suchen einen Kandidaten mit dieser Erfahrung“. - Sie sind ständig besessen von der Idee, alles und jeden in Docker hochzufahren: PostgreSQL, Kafka, Redis. Schade, dass nicht alles in Containern läuft und nicht alles leicht konfiguriert und gestartet werden kann. Dies wird von externen Entwicklern unterstützt und nicht von den Anbietern selbst. Und übrigens stellt sich sofort die Frage, warum sich die Anbieter nicht um die Unterstützung ihrer Produkte in Docker kümmern. Wissen sie vielleicht etwas, das wir nicht wissen?
- Immer wieder stellt sich die Frage nach der Persistenz der Container-Daten. Und dann überlegt man, ob ich einfach das Host-Verzeichnis einbinden, ein Docker-Volume erstellen oder einen Data-Container nutzen sollte, der jetzt...
deprecated? Если я монтирую директорию то мне нужно убедиться что uid и gid пользователя в контейнере соответствует id пользователя запустившего контейнер, иначе файлы созданные контейнером будут созданы с правами владельца root. Если используюvolumedie Daten einfach in irgendeinem.../usr/*Und es wird die gleiche Geschichte mit UID und GID wie im ersten Fall. Wenn man eine externe Komponente startet, muss man sich in die Dokumentation einlesen und die Antwort auf die Frage suchen: "In welche Verzeichnisse schreibt die Komponente Dateien in den Container?"
Ich mochte es schon immer nicht, dass ich zu lange mit Docker herumhantieren musste. In der Anfangsphase: habe ich darüber nachgedacht, wie ich Container starte, aus welchen Images ich starten soll, und habe Makefiles erstellt, die Aliase für lange Docker-Befehle enthielten. Ich konnte Docker-Compose nicht ausstehen, weil ich nicht ein weiteres Werkzeug im Docker-Ökosystem lernen wollte. Und... docker-compose up es hat mich gestresst, besonders wenn dort auch noch... build Konstrukte vorkamen und nicht bereits gebaute Images. Alles, was ich wirklich wollte, war, das Produkt effizient und schnell zu erstellen. Doch ich konnte Docker einfach nicht klar strukturieren.
Die Bekanntschaft mit Ansible
Vor etwa drei Monaten arbeitete ich mit einem DevOps-Team, dessen fast jedes Mitglied eine negative Einstellung zu Docker hatte. Gründe dafür waren:
- Docker verändert die iptables (wobei man das in daemon.json deaktivieren kann)
- Docker ist instabil und wir möchten es nicht in der Produktion einsetzen
- Wenn der Docker-Daemon abstürzt, fallen dementsprechend alle Container der Infrastruktur aus
- Docker ist nicht notwendig
- Warum Docker, wenn es Ansible und virtuelle Maschinen gibt?
Bei der gleichen Arbeit lernte ich ein weiteres Tool kennen — Ansible. Früher hatte ich schon davon gehört, aber nie eigene Playbooks geschrieben. Jetzt begann ich mit meinen Tasks zu experimentieren und meine Sichtweise änderte sich vollständig! Denn ich erkannte: Ansible hat Module, um die gleichen Docker-Container, Image-Bauten, Netzwerke usw. zu starten, und die Container können nicht nur lokal, sondern auch auf entfernten Servern gestartet werden! Meine Begeisterung kannte keine Grenzen — ich fand ein WERKZEUG, das wirklich funktioniert, und verworfen meine Makefile- und Docker-Compose-Dateien, die durch YAML-Tasks ersetzt wurden. Der Code wurde durch die Verwendung von Konstruktionen wie loop, when, usw.
Docker zum Starten von externen Komponenten wie Datenbanken
Kürzlich habe ich mich mit SSH-Tunneln vertraut gemacht. Es stellte sich heraus, dass es sehr einfach ist, einen Port von einem Remote-Server auf einen lokalen Port weiterzuleiten. Der Remote-Server kann entweder ein Cloud-Server oder eine virtuelle Maschine sein, die in VirtualBox läuft. Wenn ich oder einer meiner Kollegen eine Datenbank (oder eine andere externe Komponente) benötigen, kann einfach ein Server mit diesem Bestandteil gestartet und abgeschaltet werden, wenn der Server nicht mehr benötigt wird. Die Portweiterleitung hat den gleichen Effekt wie eine in einem Docker-Container laufende Datenbank.
Dieser Befehl leitet meinen lokalen Port an den Remote-Server mit PostgreSQL weiter:
ssh -L 9000:localhost:5432 user@example.com
Die Verwendung eines Remote-Servers löst das Problem der Teamarbeit in der Entwicklung. An diesem Server können mehrere Entwickler gleichzeitig arbeiten, ohne PostgreSQL konfigurieren oder sich mit Docker und anderen Feinheiten auseinandersetzen zu müssen. Auf dem Remote-Server kann dieselbe Datenbank in Docker installiert werden, falls eine spezielle Version erforderlich ist. Alles, was die Entwickler benötigen, ist SSH-Zugang!
Neulich habe ich gelesen, dass SSH-Tunnel eine eingeschränkte Funktionalität im Vergleich zu einem herkömmlichen VPN bieten! Man kann einfach OpenVPN oder andere VPN-Implementierungen einrichten, die Infrastruktur konfigurieren und diese den Entwicklern zur Verfügung stellen. Das ist doch großartig!
Zum Glück bieten AWS, Google Cloud und andere einen kostenlosen Jahrgang, nutzen Sie sie also! Sie sind kostengünstig, wenn man sie nur dann nutzt, wenn man sie benötigt. Ich habe mich immer gefragt, wofür ich einen Remote-Server wie GCloud brauchen könnte – es scheint, als hätte ich die Antwort gefunden.
Als virtuelle Maschine vor Ort kann man dasselbe Alpine verwenden, das aktiv in Docker-Containern genutzt wird. Oder man nimmt andere leichtgewichtige Distributionen, um die Maschine schneller zu starten.
Fazit: Datenbanken und andere infrastrukturelle Tools sollten auf entfernten Servern oder in VirtualBox gestartet werden. Docker benötige ich für diese Zwecke nicht.
Ein bisschen über Docker-Images und Distribution
Ich habe bereits geschrieben Ich wollte vermitteln, dass die Verwendung von Docker-Images keine Garantie bietet. Docker-Images sind lediglich dazu da, um einen Docker-Container zu erstellen. Wenn Sie mit einem Docker-Image arbeiten, arbeiten Sie mit Docker-Containern, und Sie werden nur damit arbeiten.
Haben Sie jemals gesehen, dass Softwareentwickler ihre Produkte ausschließlich in einem Docker-Image portiert haben?
Das Ergebnis der meisten Produkte sind Binärdateien für eine bestimmte Plattform, die einfach in ein Docker-Image integriert werden, das von der entsprechenden Plattform erbt. Haben Sie sich niemals gefragt, warum es so viele ähnliche Images auf Docker Hub gibt? Geben Sie zum Beispiel nginx ein, und Sie werden tausende von Images von verschiedenen Leuten sehen. Diese Personen haben nicht selbst nginx entwickelt; sie haben einfach das offizielle nginx in ihr Docker-Image integriert und ihre Konfigurationen hinzugefügt, um die Containerbereitstellung zu erleichtern.
Im Allgemeinen kann man einfach in tgz speichern. Wenn jemand das in Docker ausführen möchte, sollte er tgz in das Dockerfile hinzufügen, das passende Umfeld erben und zusätzliche Funktionen erstellen, die die Anwendung in tgz nicht ändern. Derjenige, der das Docker-Image erstellt, wird wissen, was dieses tgz ist und was er für die Arbeit benötigt. So nutze ich Docker.
Fazit: Ich brauche kein Docker-Registry, sondern verwende irgendeinen S3-Dienst oder einfach einen Dateispeicher wie Google Drive/Dropbox.
Docker in CI
Alle Unternehmen, in denen ich gearbeitet habe, sind einander ähnlich. Sie sind in der Regel produktorientiert, das heißt, sie haben eine bestimmte Anwendung und einen Technologie-Stack (vielleicht ein paar Programmiersprachen).
Diese Unternehmen nutzen Docker auf ihren Servern, wo der CI-Prozess läuft. Die Frage ist: Warum sollte man Projekte in einem Docker-Container auf seinen Servern bauen? Warum nicht einfach die Umgebung für den Build vorbereiten, zum Beispiel ein Ansible-Playbook schreiben, das die erforderlichen 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 schädlich ist, weil Docker mit seiner Isolation keinen Gewinn bringt. Hier sind die Probleme mit CI in Docker, mit denen ich konfrontiert war:
- Ich benötige erneut ein Docker-Image für den Build. Ich muss nach einem Image suchen oder mein eigenes Dockerfile schreiben.
- Es besteht eine 90%ige Wahrscheinlichkeit, dass ich SSH-Schlüssel oder geheime Daten weitergeben muss, die ich nicht im Docker-Image hinterlegen möchte.
- Der Container wird erstellt und stirbt, wodurch alle Caches verloren gehen. Der nächste Build wird alle Projektabhängigkeiten erneut herunterladen, was lange dauert und ineffizient ist. Zeit ist schließlich Geld.
Entwickler bauen Projekte nicht in Docker-Containern. Ich war früher auch einmal ein Fan davon, aber ich bedaure mein früheres Ich. In Java gibt es die Möglichkeit, mehrere Versionen zu haben und mit einem Befehl auf die benötigte Version umzuschalten. In Node.js funktioniert es genauso, da gibt es nvm.
Fazit
Ich halte Docker für ein äußerst leistungsfähiges und flexibles Tool, was gleichzeitig auch sein Nachteil ist (klingt merkwürdig, oder?). Unternehmen kommen leicht darauf, nutzen es dort, wo es sinnvoll ist, und auch wo nicht. Entwickler starten ihre Container und ihre spezifische Umgebung, die dann nahtlos in CI und Produktion übergeht. Das DevOps-Team entwickelt irgendwelche Lösungen, um diese Container zu betreiben.
Verwenden Sie Docker nur in der letzten Phase Ihres Arbeitsprozesses, bringen Sie es nicht zu Beginn ins Projekt ein. Es wird Ihre Geschäftsprobleme nicht lösen. Es verschiebt die Probleme lediglich auf eine ANDERE Ebene und bietet Ihnen eigene Lösungsvorschläge an, während Sie doppelte Arbeit leisten.
Wann Docker nötig ist: Ich bin zu dem Schluss gekommen, dass Docker hervorragend darin ist, den etablierten Prozess zu optimieren, jedoch nicht beim Aufbau grundlegender Funktionalitäten.
Falls Sie sich dennoch für die Nutzung von Docker entscheiden:
- Seien Sie äußerst vorsichtig.
- Zwingen Sie den Entwicklern nicht auf, Docker zu verwenden.
- Lokalisieren Sie seinen Einsatz an einem Ort, verteilen Sie nicht die Dockefile und docker-compose über alle Repositories.
PS:
- Kürzlich stieß ich auf Und er sagt, dass es sehr gut mit Ansible funktioniert und den Prozess der Erstellung von Images (einschließlich Docker-Images) vereinheitlicht.
Danke, dass Sie bis hierher gelesen haben. Ich wünsche Ihnen transparente Lösungen in Ihren Geschäften und produktive Arbeitstage!
Quelle: habr.com
