Stor IT Back - Ihr Speicherspezialist
Docker Basis V1.3 (c) Stor IT Back 2024
Das folgende Beispiel basiert auf einem Debian System, Docker wird dort über die Paketverwaltung installiert. Eine grundlegende Erklärung zu Docker und
der Container-Virtualisierung mit den Unterschieden zu virtuellen Maschinen und LXC finden Sie in unserer
Container-Einführung zu diesem Thema.
Wichtiger Hinweis:
Dies soll keine
vollständige Anleitung für die Installation und den Betrieb von Docker sein, sondern nur einen Eindruck über die Funktion vermitteln.
Installation zusätzlich benötigte Software:
sudo apt-get install ca-certificates curl
Einzufügen der Installationsquellen für die Paketverwaltung:
sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Installation von Docker:
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Damit ist die Docker-Software auf dem Debian System (Bookworm 12 oder Bullseye 11) installiert und der Daemon gestartet. Für eine einfachere Verwaltung der Images und Container kann ein normaler User
der Gruppe docker hinzugefügt werden, damit wird sudo beim Aufruf der Docker-Kommandos nicht mehr benötigt.
Die Überprüfung der Installation ist sehr einfach, es wird ein Container gestartet.
docker run hello-world
admin@debian:~$ docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
Aber woher kommt jetzt dieser Container? Docker versucht als erstes das Image auf der lokalen Platte zu finden, da wir Docker aber gerade erst installiert haben, haben wir noch
keine Images. Also sucht Docker als nächstes im Docker Repository und lädt das Image dann auf die lokale Platte herunter und startet den Container. Im Docker Repository sind
sehr viele Images vorhanden, einige zum Testen, aber viele auch mit kompletten Anwendungen und Applikationen. Diese Images können direkt genutzt werden, aber auch den eigenen
Anforderungen angepasst werden. Es ist sogar möglich, das eigene Image, zum Beispiel mit einer eigenen Anwendung, auf das Docker Repository hochzuladen. Andere können dann dieses
Image selbst nutzen.
Sicherheitshinweis:
Wie schon oben beschrieben, "jeder" kann eigene Anwendungen in das Repository hochladen. Und jeder andere kann diese wieder nutzen. Und genau da liegt die Gefahr. Mitte 2024 wurden
in ca. 20% aller Container (bzw. deren Image) Schadsoftware entdeckt. Da waren aber meist keine richtigen Images, sondern eigentlich leere Images mit Meta-Daten in Form von HTML Dokumente
mit schädlichen Links. Aber es ist natürlich sehr einfach, in ein Image Schadsoftware zu integrieren. So könnte man dann ein "Betriebssystem" Image mit einem Keylogger hochladen.
Wird dieser Container dann genutzt, zum Beispiel mit einem Browser ergänzt, kann man sehr einfach Daten abgreifen.
Images sollten also immer mit Vorsicht genutzt und ausführlich getestet werden.
Nehmen wir ein anderes Beispiel:
docker run -it ubuntu bash
admin@debian:~$ docker run -it ubuntu bash root@f6255860bef0:/# id uid=0(root) gid=0(root) groups=0(root) root@f6255860bef0:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@f6255860bef0:/# ps -efa UID PID PPID C STIME TTY TIME CMD root 1 0 0 10:52 pts/0 00:00:00 bash root 12 1 0 10:53 pts/0 00:00:00 ps -efa root@f6255860bef0:/# exit exit
Jetzt wird wieder ein Image heruntergeladen und ein Container mit Ubuntu gestartet mit der Anwendung bash. Durch die Parameter -it befinden wir uns dann direkt im Container
auf der bash Shell. Dort können wir jetzt zum Beispiel den Ubuntu Container durch weitere Software erweitern.
Ergebnis:
Auf einem installierten Linux System kann innerhalb von weniger als 5 Minuten der erste Container gestartet werden.
Container mit Docker - Installation auf Debian
Einen wichtigen Befehl von Docker haben wir ja schon kennengelernt, es ist run, er startet einen Container (und lädt das Image, wenn es nicht schon vorhanden ist,
auch gleich runter). Dem run Befehl können auch weitere Parameter mitgegeben werden. Auch da haben wir schon -it gesehen. Dies ruft den Container interaktiv auf und nutzt eine
virtuelle TTY Schnittstelle. Damit wird man direkt auf dem Container angemeldet.
Sie können aber auch ein Image einfach nur herunterladen, das geht mit docker pull nginx. Dieser Befehl lädt das Image nginx (ein einfacher Webserver) herunter. Damit ist das
Image auf der lokalen Festplatte, wird aber nicht gestartet. Durch docker run -d --name test-nginx -p 80:80 nginx wird das Image als Container mit dem Namen test-nginx gestartet.
Der Parameter -p gibt den Port auf dem Host-Betriebssystem bzw. dem Container an. Der Webserver wird also auf dem Port 80 des Hosts hören. Ein Browser auf die IP des Hosts zeigt dann
die Test-Seite von nginx an. Der Parameter -d startet den Container im Hintergrund und zeigt die ID an. Die ID wird später für das Beenden des Containers benötigt.
admin@debian:~$ docker run -d --name test-nginx -p 80:80 nginx 432689b0af02f0cada32d76c185423f97422c6652c1e6b6dade86caacf232c18 docker: Error response from daemon: driver failed programming external connectivity on endpoint test-nginx (203ecee9df85dfae49658453037c8bb6e789e2c30306c7236d1e2d1f825feae5): Error starting userland proxy: listen tcp 0.0.0.0:80: listen: address already in use. admin@debian:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Also das war jetzt nicht erfolgreich. Was ist passiert? Ganz einfach, der Port 80 wird schon auf dem Host genutzt, dort läuft ein Apache Webserver. Also wurde der Container nicht gestartet. Mit dem Kommando docker ps können wir uns die laufenden Container anzeigen lassen. Es läuft kein Container also war der Start nicht erfolgreich. Korrigieren wir unsere Fehler und nutzen den Port 8080:
admin@debian:~$ docker run -d --name test-nginx -p 8080:80 nginx docker: Error response from daemon: Conflict. The container name "/test-nginx" is already in use by container "432689b0af02f0cada32d76c185423f97422c6652c1e6b6dade86caacf232c18". You have to remove (or rename) that container to be able to reuse that name. See 'docker run --help'. admin@debian:~$ docker rm test-nginx test-nginx admin@debian:~$ docker run -d --name test-nginx -p 8080:80 nginx 5d75bc4aaa730689ad9854b1be57bf4b16c9466a244b2006639b01234de69268 admin@debian:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5d75bc4aaa73 nginx "nginx -g 'daemon of" 18 seconds ago Up 16 seconds 0.0.0.0:8080->80/tcp test-nginx
Schon wieder ein Fehler beim Aufruf des run Kommandos. Wenn der Container mit unserem Namen schon existiert (auch wenn er nicht läuft), dann müsste er entweder einen
anderen Namen bekommen oder wir löschen den ersten Versuch. Und genau das haben wir mit dem Kommando docker rm gemacht. Danach konnte der Container gestartet werden. Mit
dem Kommando docker ps kann man sich die laufenden Container anschauen. Jetzt klappt natürlich auch der Browser-Aufruf und es wird die "Welcome" Seite angezeigt.
Jetzt kommt der große Vorteil der Container: Wenn ich den Webserver jetzt auch noch auf Port 8081 und 8082 benötige, dann starte ich den Container mit neuem Namen und dem
entsprechenden Port einfach noch zwei Mal.
Werden die Container nicht mehr benötigt, so lassen sie sich einfach stoppen und bei Bedarf wieder starten.
admin@debian:~$ docker run -d --name test-nginx1 -p 8081:80 nginx 606b541324e53b5ff8f4909c5bd4b7e86c7e46f81b9f40930991116fd232d55f admin@debian:~$ docker run -d --name test-nginx2 -p 8082:80 nginx 7793025d7cd86b190ea94c8490d9416901ac8abe4cef4b4c51299696ed86637c admin@debian:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7793025d7cd8 nginx "nginx -g 'daemon of" 6 seconds ago Up 4 seconds 0.0.0.0:8082->80/tcp test-nginx2 606b541324e5 nginx "nginx -g 'daemon of" 14 seconds ago Up 12 seconds 0.0.0.0:8081->80/tcp test-nginx1 5d75bc4aaa73 nginx "nginx -g 'daemon of" 8 minutes ago Up 8 minutes 0.0.0.0:8080->80/tcp test-nginx admin@debian:~$ docker stop test-nginx test-nginx1 test-nginx2 test-nginx test-nginx1 test-nginx2 admin@debian:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Die Container können natürlich auch verändert und die Veränderungen dann wieder in neue Images geschrieben werden. Bei docker ist die Hilfefunktion gleich mit eingebaut. Ein docker --help zeigt alle Kommandos an und ein docker Kommando --help zeigt dann alle Parameter zu dem Kommando an.
Wichtig ist die Unterscheidung zwischen Image und Container in Docker. Das Image enthält alle Programme, Libraries, Tools, Config-Dateien für den zu startenden Container.
Neben dem Image, welches im Normalfalle aus verschiedenen Layern besteht, wird auch noch eine Beschreibungsdatei, das sogenannte Dockerfile benötigt. In diesem Dockerfile stehen Informationen
zu dem Aufbau der Layer der Images und auch Anweisung zum Beispiel für die Netzwerkkonfiguration.
Schauen wir uns erst mal das Images an: Wie würde man einen Container bauen, der die Applikation apache (also den Webserver) nutzt? Nehmen wir einmal an, ein fertiges Image auf dem Docker Hub
würde es nicht geben. Dann starten wir mit einem Basis-Image zum Beispiel einer CentOS Basisinstallation. Auf diesem Image sind grundlegende Programme und Libraries enthalten und die bash als Shell.
Dieses Image könnte man dann als Container starten und meldet sich mit dem -it Paramter auf der bash an. Jetzt kann man wie üblich den apache Webserver installieren, also so, als wäre
man auf einem richtigen Server. Läuft der Container jetzt wie gewünscht, dann sind die Änderungen nur im Container, nicht aber im Basis-Image.
Danach kann aus diesem Container
ein neues Image gebaut werden. Es wird dann zum Basis-Image ein neuer Layer für den Apache. Aus diesem neuen Image (Basis Image und Apache Image) können Sie jetzt wieder einen neuer Container
startet. Möchten Sie jetzt eine Webseite oder Anwendung hinzufügen (Container starten und Webseite hinein kopieren), so können Sie auch dann wieder ein neues Image
(Basis Image und Apache Image und Webseite Image) daraus erstellen. Möchten Sie eine andere Webseite in einem Container erstellen, so starten Sie einfach das Basis und Apache Image neu und
fügen die neue Webseite hinzu. Sie können also Images und Container immer wieder verwenden.
Damit sind die Images immer Read Only, bis auf den obersten Layer, der ist immer Read Write. Dieser oberste Layer (oberstes Image) gehört zur Laufzeit des Containers nicht zum eigentlichen Image,
sondern zum laufenden Container. Wenn Sie also den Container stoppen und dann löschen, so sind alle Änderungen am Image verschwunden. Sie waren im obersten Image Read Write enthalten. Damit können
Container immer wieder frische aus einem Image gestartet werden. Ein Container besteht aus als dem Image und dem beschreibbaren obersten Layer.
Eine Besonderheit bei Docker ist, dass ein Volume in mehrere Container hinein gemountet werden kann. Bei den Images ist es quasi immer so, wenn ein Layer schon im Cache ist, also in einem
Container läuft, dann wird es bei einem anderen Container mit dem gleichen Layer einfach wiederverwendet. Ein Ansatz um Speicherplatz im RAM und Filesystem zu sparen.
Eine Anwendung wäre zum Beispiel der Webbrowser im Container für privates Surfen im Büro. Sie möchten Ihren Mitarbeitern das private Surfen erlauben, aber nicht direkt auf dem Firmenrechner? Auch das könnte im Container laufen. Was sind Probleme beim privaten Surfen in der Firma? Eine Forderung, gerade von der Geschäftsführung, ist häufig die zeitliche Begrenzung der Nutzung, also nur in den Pausen und nach der Arbeit. Aber auch ein Security Problem taucht auf, die Verbindungen sind ja alle verschlüsselt, also kann der Firmenproxy den Datenverkehr nicht kontrollieren, er findet keine Viren und sonstige Bedrohungen. Wenn der Mitarbeiter zum privaten Surfen aber einen Container nutzt, dann laufen evtl. Programme (und auch die Viren) in dem Container. Wenn der Download von Dateien aus dem Container nicht möglich ist und der Container regelmäßig neu gestartet wird ist dies eine recht sichere Möglichkeit.
Container mit Docker - Sicherer Browser im Container