Benutzer-Werkzeuge

Webseiten-Werkzeuge


docker

Docker ist eine Open-Source-Plattform zur Containerisierung von Anwendungen. Es ermöglicht die Erstellung, Bereitstellung und Ausführung von Anwendungen in isolierten Containern, die unabhängig von der zugrunde liegenden Infrastruktur sind. Docker bietet eine standardisierte Methode zum Verpacken von Software und allen damit verbundenen Abhängigkeiten in ein einzelnes Paket, das als Docker-Image bezeichnet wird. Diese Images können dann auf jedem System ausgeführt werden, das Docker unterstützt.

Docker basiert auf der Linux-Containertechnologie (LXC) und nutzt die Funktionen des Linux-Kernels, um isolierte Umgebungen, sogenannte Container, zu erstellen. Jeder Container enthält eine eigenständige und isolierte Umgebung, in der eine Anwendung und ihre Abhängigkeiten ausgeführt werden können. Die Isolation sorgt dafür, dass eine Anwendung und ihre Abhängigkeiten unabhängig von anderen Containern und dem Hostsystem ausgeführt werden können, was zu einer besseren Portabilität und Skalierbarkeit führt.

Siehe auch Kubernetes.

Hauptkomponenten

  • Docker-Image: Ein Docker-Image ist ein leichtgewichtiges, ausführbares Paket, das alles enthält, was zur Ausführung einer Anwendung benötigt wird, einschließlich des Betriebssystems, der Laufzeitumgebung, der Bibliotheken und der Anwendungsdateien selbst. Images werden durch sogenannte Dockerfiles definiert, die eine Reihe von Anweisungen enthalten, um die Konfiguration und Installation der Anwendungsschichten zu beschreiben.
  • Docker-Container: Ein Docker-Container ist eine Instanz eines Docker-Images. Er kann gestartet, gestoppt, verschoben und gelöscht werden. Container bieten eine isolierte Umgebung für die Ausführung einer Anwendung, wodurch Konflikte mit anderen Containern oder dem Hostsystem vermieden werden. Container können schnell erstellt und bereitgestellt werden, was eine effiziente Skalierung und Verteilung von Anwendungen ermöglicht.
  • Docker-Daemon: Der Docker-Daemon ist der Hintergrundprozess, der auf dem Hostsystem läuft und Docker-Befehle entgegennimmt. Er ist für die Erstellung, Ausführung und Verwaltung von Docker-Containern verantwortlich. Der Daemon kommuniziert mit dem Docker-Client, der über eine Befehlszeilenschnittstelle oder eine grafische Benutzeroberfläche verfügbar ist und dem Benutzer die Interaktion mit Docker ermöglicht.

Dockerfile

Ein Dockerfile ist eine Textdatei, die eine automatisierte Build-Anweisung für das Erstellen eines Docker-Images enthält. Dockerfiles werden verwendet, um Container-Images zu erstellen.

Ein Dockerfile besteht aus einer Reihe von Anweisungen, die Docker verwendet, um ein Docker-Image zu erstellen. Jede Anweisung in einem Dockerfile führt eine bestimmte Aktion aus, z. B. das Hinzufügen von Dateien, das Ausführen von Befehlen oder das Festlegen von Umgebungsvariablen. Dockerfiles verwenden eine einfache Syntax und können mit grundlegenden Texteditoren erstellt und bearbeitet werden.

Hier sind einige der gängigsten Anweisungen, die in einem Dockerfile verwendet werden:

  • FROM: Die FROM-Anweisung definiert das Basisimage, auf dem das neue Image basieren soll. Es kann sich um ein offizielles Docker-Image handeln, z. B. ein Betriebssystem wie Ubuntu oder Alpine, oder um ein benutzerdefiniertes Image, das von einem anderen Dockerfile abgeleitet wurde.
  • RUN: Die RUN-Anweisung führt Befehle innerhalb des Containers aus und erzeugt einen neuen Layer mit den Änderungen. Dies können Installationsbefehle, Kompilierungsschritte oder andere Befehle sein, die zur Einrichtung der Anwendungsumgebung erforderlich sind.
  • COPY: Die COPY-Anweisung kopiert Dateien oder Verzeichnisse vom Host in den Container. Dies wird häufig verwendet, um Anwendungsquellcode, Konfigurationsdateien oder andere Ressourcen in den Container zu übertragen.
  • WORKDIR: Die WORKDIR-Anweisung legt das Arbeitsverzeichnis innerhalb des Containers fest, in dem alle nachfolgenden Befehle ausgeführt werden. Dadurch können relative Dateipfade in den folgenden Anweisungen verwendet werden.
  • EXPOSE: Die EXPOSE-Anweisung gibt an, welche Ports der Container zur Kommunikation mit der Außenwelt öffnen soll. Diese Anweisung hat keine Auswirkung auf die tatsächliche Portöffnung, sondern dient als Dokumentation für den Entwickler.
  • CMD: Die CMD-Anweisung gibt die Standardbefehle an, die beim Starten eines Containers ausgeführt werden sollen. Es kann nur eine CMD-Anweisung in einem Dockerfile vorhanden sein. Wenn beim Starten des Containers zusätzliche Befehle angegeben werden, überschreiben sie die in der CMD-Anweisung angegebenen Befehle.
  • ENV: Die ENV-Anweisung in einem Dockerfile wird verwendet, um Umgebungsvariablen im Container zu definieren. Umgebungsvariablen sind Schlüssel-Wert-Paare, die in der Containerumgebung verfügbar sind und von der Anwendung oder dem System innerhalb des Containers genutzt werden können.
  • ENTRYPOINT: Die ENTRYPOINT-Anweisung in einem Dockerfile definiert den Standardbefehl oder das Skript, das beim Starten eines Containers ausgeführt wird. Der Befehl oder das Skript wird als ausführbare Datei innerhalb des Containers behandelt.
  • VOLUME: Die VOLUME-Anweisung in einem Dockerfile wird verwendet, um ein oder mehrere Volumes im Container zu definieren. Ein Volume ist ein Speicherbereich, der von einem Container genutzt wird, um Daten persistent zu speichern, auch wenn der Container beendet oder neu gestartet wird.
# Verwenden des Python-Basisimages
FROM python:3.9

# Setzen des Arbeitsverzeichnisses innerhalb des Containers
WORKDIR /app

# Kopieren der Anforderungen (requirements.txt) in den Container
COPY requirements.txt .

# Installation der Abhängigkeiten
RUN pip install --no-cache-dir -r requirements.txt

# Kopieren des Anwendungsquellcodes in den Container
COPY . .

# Exponieren des Ports, auf dem die Anwendung lauscht
EXPOSE 8000

# Festlegen des Standardbefehls beim Starten des Containers
CMD ["python", "app.py"]

Den Container erstellen.

docker build -t <containername> .
docker run -dit -p 80:80 <containername>

Docker-Compose

Im Gegensatz zu einem einzelnen Dockerfile, das ein einzelnes Image definiert, ermöglicht Docker Compose die Definition und Konfiguration von Diensten, Netzwerken und Volumes für eine vollständige Anwendungsumgebung. Es verwendet eine einfache YAML-Datei, um die Konfiguration zu beschreiben.

version: '3'
services:
  webserver:
    image: httpd:latest
    networks:
      - my-network
    ports:
      - 80:80
    volumes:
      - ./html:/usr/local/apache2/htdocs/
    depends_on:
      - database
  database:
    image: mariadb:latest
    networks:
      - my-network
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_DATABASE=mydatabase
      - MYSQL_USER=myuser
      - MYSQL_PASSWORD=mypassword
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:
networks:
  my-network: 

Deployments

Um einen Load-Balanced Cluster mit mehreren Instanzen einer Anwendung zu erstellen, kannst du die Deploymentfunktion von Docker Compose verwenden. Somit laufen 3 Instanzen der Anwendung. Fällt eine aus, wird automatisch ein neuer Container gestartet.

version: '3'
services:
  app:
    image: myapp:latest
    ports:
      - 80:80
    deploy:
      mode: replicated
      replicas: 3
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: any

Deployment starten/stoppen

// Im Verzeichnis wo die docker-compose.yaml Datei liegt
sudo docker compose [-f <yml-filename>] up -d

sudo docker compose down <deployment-name>

Volumes

Docker Volumes werden verwendet, um Daten zwischen Containern und dem Host-Betriebssystem auszutauschen und um sicherzustellen, dass Daten auch dann erhalten bleiben, wenn Container neu erstellt oder aktualisiert werden. Es sind sozusagen virtuelle Festplatten für Container.

  • Named Volumes: Named Volumes sind Volumes, die einen Namen haben und vom Docker-Daemon verwaltet werden. Sie sind einfach zu verwenden und können leicht zwischen Containern geteilt werden.
  • Host-mounted Volumes: Host-mounted Volumes ermöglichen es, einen Pfad auf dem Host-Betriebssystem als Volume-Mountpunkt zu verwenden. Dies ermöglicht eine direkte Verbindung zwischen dem Host und dem Container, wodurch Daten schnell ausgetauscht werden können. Allerdings sind Host-mounted Volumes weniger portabel, da sie von der spezifischen Konfiguration des Hosts abhängig sind.
  • Anonymous Volumes: Anonymous Volumes sind temporäre Volumes, die während der Laufzeit des Containers erstellt werden und keinen expliziten Namen haben. Sie werden automatisch von Docker erstellt und sind für einzelne Container reserviert.

Ein Volume erstellen kann man mit

docker volume create myvolume

Mit dem Parameter –mount kann man ein Volume in einen Container mounten. Mit dem Parameter -v kann man einen Pfad am Host in einen Mountpoint am Container mounten.

docker run -dit --mount source=<docker-volume>,target=<container-mountpoint> ubuntu
docker run -dit -v <host-path>:<container-path> ubuntu

LVM

Vor der Installation bzw Inbbetriebnahme von Docker das LVM anlegen.

sudo mount /dev/docker_vg_lv0 /var/lib/docker

In der fstab

/dev/docker-vg/lv0 /var/lib/docker ext4 defaults 0 2

Netzwerke

Docker Networking unterstützt verschiedene Netzwerkmodelle, um den unterschiedlichen Anforderungen von Anwendungen gerecht zu werden.

NameBeschreibung
nonetodo
HostDas Host-Netzwerkmodell verwendet das Netzwerk des Docker-Hosts direkt für die Container. Container, die das Host-Netzwerk verwenden, haben Zugriff auf alle Netzwerkressourcen des Hosts, einschließlich der Netzwerkschnittstellen und Ports. Dieses Modell bietet eine maximale Leistung, kann aber die Isolation zwischen Containern beeinträchtigen.
BridgeEin Bridge-Netzwerk ist das Standardnetzwerkmodell von Docker. Es erstellt ein isoliertes Netzwerk für Container auf dem Docker-Host und ermöglicht die Kommunikation zwischen Containern über einen gemeinsamen Bridge-Dienst. Bridge-Netzwerke sind standardmäßig in Docker aktiviert und bieten eine einfache Möglichkeit, Container zu verbinden.
OverlayOverlay-Netzwerke werden verwendet, um Container über mehrere Docker-Hosts hinweg zu verbinden. Sie ermöglichen es Containern, über Host-Grenzen hinweg zu kommunizieren und eine skalierbare, verteilte Anwendung zu erstellen. Overlay-Netzwerke verwenden spezielle Protokolle wie VXLAN oder IPSec, um Container über das gesamte Cluster hinweg zu vernetzen.
MacVlanDas macvlan Netzwerkmodell ermöglicht es Containern, eine eigene MAC-Adresse zu haben und direkt mit dem physikalischen Netzwerk zu kommunizieren. Jeder Container erhält eine eindeutige MAC-Adresse, die von der des Hosts abweichen kann. Dies ermöglicht es Containern, direkt auf das physische Netzwerk zuzugreifen und mit anderen Geräten zu kommunizieren, als ob sie direkt an das physische Netzwerk angeschlossen wären.
IpVlanDas ipvlan Netzwerkmodell ist ähnlich wie das macvlan Modell, jedoch auf IP-Ebene. Es ermöglicht es Containern, eigene IP-Adressen zu haben und direkt mit dem physikalischen Netzwerk zu kommunizieren. Jeder Container erhält eine eindeutige IP-Adresse, die von der des Hosts abweichen kann.

Mit

docker network create -d <driver> <network-name>
docker network inspect <network-name>
docker network rm <network-name>

kann man ein neues erstellen. Ein Container Interface an ein Netzwerk binden kann man mit dem Parameter –network.

docker run -dit --name test --network mynetwork ubuntu

Ein Netzwerk von einem Container entfernen oder ändern kann man mit

docker network disconnect <network-name> <container-name>
docker network connect <network-name> <container-name>

Traefik

Traefik ist ein Reverse Proxy um Container über das Internet erreichbar zu machen.

Installation

Docker Installation.

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

Ubuntu

# update packages
sudo apt-get update

# add pgp key for signed docker repository
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# update again
sudo apt-get update

# install docker
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

WSL2

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

sudo usermod -aG docker $USER

# Install Docker Compose v2
sudo apt-get update && sudo apt-get install docker-compose-plugin

# Sanity check that both tools were installed successfully
docker --version
docker compose version

# Using Ubuntu 22.04 or Debian 10 / 11? You need to do 1 extra step for iptables
# compatibility, you'll want to choose option (1) from the prompt to use iptables-legacy.
sudo update-alternatives --config iptables

Docker Daemon

nano /etc/docker/daemon.json
{
  "bip": "172.17.1.1/24",
  "ipv6": false,
  "storage-driver": "devicemapper",
  "storage-opts": 
     [
       "dm.basesize = 41G",
       "dm.thinpooldev=/dev/mapper/docker--vg-thinpool",
       "dm.use_deferred_removal=true"
     ]
}

Usage

docker pull <image>
docker images
docker rmi -f <image-id>
docker image prune

docker inspect <container>
docker container diff <container> // see changes from base image

// see https://docs.docker.com/engine/reference/commandline/run/
docker run -dit --name <container-name> --hostname <hostname> -p <ext-port>:<int-port> --mount source=<vol>,target=<mountpoint>,readonly -v <volume>:<mountpoint> <image> <commands>
 --> -it - interactive, root terminal
 --> -p - port mapping ext:int
 --> -d - detach console
 --> --name - set container name
 --> --mount mount a docker-volume
 --> -v - mount a host folder <folder>:<mountpoint>
 --> --network - connect to a specific docker-network
 --> --cpus=0.1 - use 1 % of cpu
 --> -m 512m - use max 512 bytes of memory
 --> --cpu-shares=2000 - operations per cycle?
 --> -e VAR=1 - set environment variable

// change a running container using a snapshot
docker commit <container> <new-image-name>
docker run -dit <new-image-name> 

// start with same settings as setup
docker start <container>

// befehl auf laufendem host ausführen
docker exec <container> <commands>

docker attach <container>
sudo docker exec -it <container> /bin/bash
# ctrl + p - ctrl q ==> detach (nur mit -ti)?

docker start <container>
docker stop <container>
docker restart <container>

docker rename <oldname> <newname>

docker container ls
docker ps -a
docker rm <container>
docker container prune // remove all "status=exited" containers

// volumes
docker volume create --name testvol
docker volume inspect test-vol
docker volume rm test-vol
docker run -dit --mount source=test-vol,target=/mount/test,readonly <image>
docker run -dit -v test-vol:/mount/test <image>

// networking
docker network create -d bridge MyBridgedNetwork
docker network connect <options> <network> <container>
docker network inspect

docker network connect <network> <container>
docker network disconnect <network> <container>

Docker Swarm Cluster

Als erstes erstellt man mit dem Befehl

docker swarm init --advertise-addr <manager-ip>

ein Kontrollnode. Am Ende wird ein Token angezeigt, diesem gut merken! Möchte man weitere Nodes zu dem Cluster hinzufügen, führt man auf den jeweiligen Nodes den Befehl

docker swarm join --token <swarm-token> <manager-node-ip>

aus. Mit dem Befehl

docker node ls

werden alle Nodes eines Clusters angezeigt.

docker.txt · Zuletzt geändert: 2025/03/04 17:33 von jango