Docker für Anfänger: Verabschiede dich von Deployment-Alpträumen!

Docker für Anfänger: Verabschiede dich von Deployment-Alpträumen!

Einsteiger-Entwickler haben oft mit Schmerzpunkten wie ineffizienten Code-Updates, Releases und Deployments zu kämpfen, sowie mit Herausforderungen bei der Aufrechterhaltung der Umgebungskonsistenz. Code, der in der Entwicklungsumgebung reibungslos läuft, könnte auf einer anderen Maschine auf Fehler stoßen. In der Ära des Cloud Computings wirkt das Bereitstellen von Code mit traditionellen Methoden veraltet. Dieser Blogbeitrag stellt Ihnen Docker vor.

Docker, basierend auf der Go-Sprache und unter der Apache-2.0-Lizenz als Open Source veröffentlicht, ist eine Anwendungscontainer-Engine. Diese Containerisierungstechnologie ermöglicht es Entwicklern, ihre Anwendungen und Abhängigkeiten in leichtgewichtige, portable Container zu packen. Diese Container können auf jeder gängigen Linux-Maschine bereitgestellt werden, ohne sich Gedanken über Umgebungsunterschiede machen zu müssen.

Docker vs. Virtuelle Maschinen (VMs)

Wie erwähnt, nutzt Docker Virtualisierung. Bei der Diskussion über Virtualisierung kommen zwangsläufig Virtuelle Maschinen (VMs) ins Spiel. Da beide auf Virtualisierung basieren, fragt man sich natürlich, worin ihre Unterschiede bestehen. Lassen Sie uns darauf eingehen.

Betrachten wir zunächst eine typische VM-Architektur. Oberhalb der Infrastruktur (die zugrunde liegende Hardware) befindet sich ein Hypervisor. Er fungiert als Vermittler zwischen dem physischen Server und den Betriebssystemen und ermöglicht mehreren Betriebssystemen und Anwendungen, die zugrunde liegende Hardware gemeinsam zu nutzen. Virtuelle Maschinen führen mehrere unterschiedliche Betriebssysteme auf dem Host-Betriebssystem aus und nutzen den Hypervisor, um auf die zugrunde liegende Hardware zuzugreifen. Wenn Sie drei isolierte Anwendungen ausführen müssten, würden Sie drei virtuelle Maschinen erstellen. Das bedeutet, dass drei Betriebssysteme auf dem Hypervisor laufen, was zu einem erheblichen Ressourcen-Overhead führt.

Eine typische VM-Architektur

(Hinweis: Das Diagramm sollte idealerweise ein Host-Betriebssystem oberhalb des Hypervisors zeigen)

Docker hingegen ist bemerkenswert leichtgewichtig. Sein Daemon (Docker Daemon) ersetzt den Hypervisor und läuft direkt auf dem Betriebssystem. Der Quellcode der Anwendung und ihre Abhängigkeiten werden in ein Docker-Image verpackt. Die Docker-Engine verwendet dann dieses Image, um einen Container zu erstellen. Unterschiedliche Anwendungen laufen in isolierten Containern.

Darüber hinaus kommuniziert der Docker-Daemon direkt mit dem Betriebssystem, um Docker-Containern Ressourcen zuzuweisen. Ohne den Overhead eines vollständigen Betriebssystems reduziert sich die Startzeit eines Containers von Minuten bei virtuellen Maschinen auf Millisekunden bei Docker-Containern, was die Effizienz erheblich steigert und wertvollen Festplattenspeicher sowie andere Systemressourcen spart.

Obwohl Docker überzeugende Vorteile bietet, ersetzt es virtuelle Maschinen nicht vollständig. Jede Technologie hat ihre Stärken. Virtuelle Maschinen eignen sich hervorragend zum Isolieren der gesamten Laufzeitumgebung und werden von Cloud-Anbietern häufig verwendet, um Benutzer durch VMs zu trennen. Docker hingegen isoliert typischerweise verschiedene Anwendungen.

Wie man Docker verwendet

Docker-Installation (CentOS 7 Beispiel)

  1. Installieren Sie wichtige Systemtools:
yum install -y yum-utils device-mapper-persistent-data lvm2 
  1. Aktualisieren Sie den Systemkernel und den yum-Cache:
yum update
yum makecache fast
  1. Installieren Sie Docker und starten Sie es:
yum -y install docker-ce
systemctl start docker 
  1. Testen Sie, ob Docker erfolgreich installiert wurde:
docker run hello-world 

Wenn Sie „Hello from Docker" auf Ihrem Bildschirm sehen, herzlichen Glückwunsch! Die Installation ist abgeschlossen.

Konzepte

Bevor wir tiefer in Docker einsteigen, behandeln wir einige Schlüsselkonzepte, um das Verständnis zu erleichtern.

  1. Docker-Images: Ein Docker-Image ist eine Vorlage zur Erstellung von Docker-Containern.
  2. Docker-Container: Docker erstellt aus Images Container, um eine Reihe unabhängiger Anwendungen auszuführen.
  3. Docker-Registry: Ein Code-Repository zum Speichern von Images.

Normalerweise laden wir das passende Image aus einer Docker-Registry herunter und verwenden es, um Container für unsere Anwendungen zu erstellen.

Beispiele

Verknüpfen wir diese Konzepte anhand von zwei gängigen Beispielen, um zu veranschaulichen, wie Docker verwendet wird.

Python mit Docker installieren

Wie erwähnt, besteht der erste Schritt zur Verwendung eines Docker-Containers darin, das entsprechende Image aus einem Repository herunterzuladen. Damit kommen wir zum ersten Befehl unseres Tutorials:

  • Zweck: Ein bestimmtes Image im Image-Repository suchen.
  • Syntax: docker search [OPTIONS] TERM
  • Beispiel: docker search python
  • Erklärung: Suche nach Python-bezogenen Images im Repository.
[root@novita ~]# docker search pythonINDEX       NAME                                       DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/python                           Python is an interpreted, interactive, obj...   4356      [OK]
docker.io   docker.io/django                           Django is a free web application framework...   856       [OK]
docker.io   docker.io/pypy                             PyPy is a fast, compliant alternative impl...   196       [OK]
docker.io   docker.io/kaggle/python                    Docker image for Python scripts run on Kaggle   125                  [OK]
docker.io   docker.io/arm32v7/python                   Python is an interpreted, interactive, obj...   38
docker.io   docker.io/centos/python-35-centos7         Platform for building and running Python 3...   36

Wir wählen das offizielle Image mit dem Tag (Version) 3.7.

docker pull

  • Zweck: Ein bestimmtes Image aus dem Image-Repository ziehen oder aktualisieren.
  • Syntax: docker pull [OPTIONS] NAME:TAG
  • Beispiel: docker pull python:3.7
  • Erklärung: Lade das Python-Image mit Tag 3.7 aus dem Repository herunter.
[root@novita ~]# docker pull python:3.7
Trying to pull repository docker.io/library/python ...3.7: Pulling from docker.io/library/python
5ae19949497e: Downloading [=============>                                     ] 13.72 MB/50.38 MB
ed3d96a2798e: Download complete
f12136850781: Downloading [============================================>      ] 8.789 MB/9.978 MB
1a9ad5d5550b: Downloading [==>                                                ] 2.628 MB/51.77 MB
6f18049a0455: Waiting
ce39fa9d79d1: Waiting
Digest: sha256:d8718f4c8f28360c88d2d8b53681edb3c95e6a7bacedabd32eb5b1d120a75dc5
Status: Downloaded newer image for docker.io/python:3.7

Docker hat nun das angegebene Image heruntergeladen. Um vorhandene Docker-Images anzuzeigen:

docker images

  • Zweck: Lokale Images auflisten.
  • Syntax: docker images [OPTIONS] [REPOSITORY[:TAG]]
  • Beispiel: docker images
  • Erklärung: Alle lokalen Docker-Images anzeigen.
[root@novita ~]# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
docker.io/python        3.7                 42d620af35be        6 days ago          918 MB
docker.io/rabbitmq      3-management        7aae48fa6ef6        7 days ago          179 MB
docker.io/golang        latest              f50db16df5da        9 days ago          774 MB

Das Python-3.7-Image ist vorhanden. Erstellen wir einen Container daraus.

docker run

Bevor wir den Container erstellen, gehen wir kurz auf IDs ein. In Docker identifizieren IDs eindeutig Images oder Container. Wir interagieren mit ihnen über „Befehl + ID." Beispielsweise hat Python 3.7 im vorherigen Code die Image-ID 42d620af35be.

  • Zweck: Einen neuen Container erstellen.
  • Syntax: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Um die Python-Umgebung zu testen, erstellen wir lokal eine Datei hello.py:

#!/usr/bin/python 
import sys 

print("Hello, Docker!") 
print(sys.version)  # Ausgabe der Python-Versionsnummer 

Angenommen, dieser Code ist unter /root/code/python gespeichert:

[root@novita python]# docker run  -v $PWD:/usr/src/code  -w /usr/src/code python:3.7 python hello.py 
Hello, Docker! 
3.7.4 (default, Jul 13 2019, 14:04:11) [GCC 8.3.0] 

Lassen Sie uns diesen Befehl aufschlüsseln:

  • docker run: Erstellt einen Container.
  • -v $PWD:/usr/src/code: Hängt das lokale Verzeichnis in den Docker-Container ein. Hier wird das Verzeichnis, in dem der Befehl ausgeführt wird, nach /usr/src/code im Container eingehängt. Der Doppelpunkt trennt den lokalen Pfad vom Container-Pfad. Sie können anstelle von $PWD auch absolute Pfade verwenden.
  • -w /usr/src/code: Legt das Arbeitsverzeichnis für den Container fest. Da das Python-Codeverzeichnis nach /usr/src/code eingehängt ist, setzen wir es als Arbeitsverzeichnis.
  • python:3.7: Gibt das Image an. Sie können auch die Image-ID verwenden.
  • python hello.py: Führt diesen Befehl innerhalb des Containers aus.

Denkaufgabe: Wenn Sie eine Datei hello.go in /root/data/ haben und diese mit einem Golang-Container mit der Image-ID f50db16df5da ausführen möchten, wie lautet der Befehl? (Hinweis: Der Befehl zum Ausführen von Go-Code ist go run DATEINAME)

MariaDB mit Docker installieren

Angenommen, Sie können jetzt ein MariaDB-Image suchen und herunterladen – konzentrieren wir uns auf das Starten.

Dienste wie Datenbanken benötigen entsprechende Ports auf dem Host. Wie erreichen wir das mit Docker? Wir verwenden Portweiterleitung, ähnlich wie beim Einhängen von Verzeichnissen.

[root@novita python]# docker run -d -v /data/mysql/:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456  --restart unless-stopped 3a2ef06682ac 
  • -d: Container im Hintergrund ausführen.
  • -p 3306:3306: Bildet Port 3306 im Container auf Port 3306 des Hosts ab.
  • -e MYSQL_ROOT_PASSWORD=123456: Setzt das Root-Passwort für MariaDB auf 123456.
  • --restart unless-stopped: Startet den Container automatisch neu, wenn er unerwartet stoppt.
  • 3a2ef06682ac: Die Image-ID für die Containererstellung.

Überprüfen wir nun, ob der Datenbankdienst läuft:

docker ps

  • Zweck: Container auflisten.
  • Syntax: docker ps [OPTIONS]
[root@novita ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                                        NAMES
107b52416c13        3a2ef06682ac        "docker-entrypoint..."   5 minutes ago       Up 5 minutes        0.0.0.0:3306->3306/tcp                                                                       quizzical_mcnulty 

Als Nächstes greifen wir auf die interne Umgebung des Containers zu.

docker exec

  • Zweck: Einen Befehl in einem laufenden Container ausführen.
  • Syntax: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
  • Beispiel: docker exec -it 107b52416c13 bash
  • Erklärung: Greife auf den Container mit der ID 107b52416c13 zu und führe den Befehl bash aus.

Innerhalb des Containers können Sie wie in einer normalen Linux-Umgebung interagieren. Mit den zuvor gesetzten Anmeldedaten können Sie auf MariaDB zugreifen.

[root@novita ~]# docker exec -it 107b52416c13 bash 
root@107b52416c13:/# mysql -u root -p123456 
Welcome to the MariaDB monitor.  Commands end with ; or \g. 
Your MariaDB connection id is 11 
Server version: 10.4.6-MariaDB-1:10.4.6+maria~bionic mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 
MariaDB [(none)]> 

Bisher haben Sie die Grundlagen von Docker gelernt. Versuchen Sie, mehr zu erkunden.

Novita AI ist die All-in-One-Cloud-Plattform, die Ihre KI-Ambitionen unterstützt. Mit nahtlos integrierten APIs, serverlosem Computing und GPU-Beschleunigung bieten wir die kostengünstigen Tools, die Sie benötigen, um Ihr KI-gesteuertes Geschäft schnell aufzubauen und zu skalieren. Beseitigen Sie Infrastruktur-Herausforderungen und starten Sie kostenlos – Novita AI macht Ihre KI-Träume wahr.