Docker Tutorial [Teil 6 - Storage (Grundlagen)]

Datum

Ein Container ist flüchtig und beinhaltet somit keine persistenten Daten.

Um Daten, welche in einem Container erzeugt oder verarbeitet werden persistent zu haben gibt es den docker volume Befehl.
Damit erstellt und steuert man docker Volumes. Diese haben gegenüber bind-mounts diverse Vorteile, welche man in der docker Dokumentation nachlesen kann.

Ich werde hier sowohl Volumes als auch die Verwendung von bind mounts aufzeigen.

Volumes

Der docker volume Befehl kennt folgende Kommandos:

$ Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes
ls

Direkt nach der Installation hat docker noch keine Volumes:

$ docker volume ls
DRIVER              VOLUME NAME
create

Um Volumes zu erstellen verwendet man docker volume create <Volumename>.

docker volume create test_vol01

$ docker volume ls
DRIVER              VOLUME NAME
local               test_vol01

create selbst kennt noch folgende Optionen:

Options:
  -d, --driver string   Specify volume driver name (default "local")
      --label list      Set metadata for a volume
  -o, --opt map         Set driver specific options (default map[])
inspect

Alle Einzelheiten über das entsprechende Volume kann man sich mit dem Befehl docker volume inspect <Volumename> anzeigen lassen.

$ docker volume inspect test_vol01
[
    {
        "CreatedAt": "2019-06-14T20:38:12Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test_vol01/_data",
        "Name": "test_vol01",
        "Options": {},
        "Scope": "local"
    }
]
rm

Um gezielt ein bestimmtes Volume zu löschen verwendet man docker volume rm <Volumename>

$ docker volume ls
DRIVER              VOLUME NAME
local               test_vol01
local               test_vol02
local               test_vol03

docker volume rm test_vol01

$ docker volume ls
DRIVER              VOLUME NAME
local               test_vol02
local               test_vol03
prune

Mit docker volume prune werden alle Volumes entfernt, welche keinem Contianer zugeordnet sind.

$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
test_vol03
test_vol02
Volume mounten

Hierbei gibt es 2 Methoden:
1.)
mit der --mount Option lässt sich ein erstelltes Volumen im Container mounten:

docker container run -d --name nginx_mount_test --mount type=volume,source=test_vol01,target=/usr/share/nginx/html/ nginx
  • -d —> starte detached
  • --name —> der Name des neuen Containers
  • --mount —> gibt an das ein Mount aus dem Dateisystem hinzugefügt werden soll
    • type=volume —> gibt an das ein bestehendes Volume verwendet werden soll
    • source=... —> gibt den Namen des einzubindenden Volumes an
    • target=... —> gibt den Mountpunkt innerhalb des Containers an

Hierbei gilt es besonders zu beachten, dass die einzelnen Parameter der --mount Option per Komma , getrennt sind.

Da sich zum Zeitpunkt des Einbindens des Volumes bereits Dateien innerhalb des entsprechenden Mountpunktes innerhalb des Containers befanden, befinden sich diese nun bereits automatisch im Volume.

Zuerst prüfen wir wo sich die Dateien des entsprechenden Volumes befinden:

$ docker volume inspect test_vol01 | grep Mountpoint
        "Mountpoint": "/var/lib/docker/volumes/test_vol01/_data",
$ ll /var/lib/docker/volumes/test_vol01/_data
total 8
-rw-r--r--. 1 root root 494 May 21 14:23 50x.html
-rw-r--r--. 1 root root 612 May 21 14:23 index.html

des weiteren kann man noch zusätzlich die Option readonly setzen wenn es sich um Dateien handelt, welche vom Container nicht verändert werden sollen.

docker container run -d --name nginx_mount_test --mount type=volume,source=test_vol01,target=/usr/share/nginx/html/,readonly nginx

2.) per bind-mount

Nun verwenden wir das --volume bzw. -v Flag.

docker container run -d --name nginx_mount_test2 -v test_vol01:/usr/share/nginx/html/ nginx

Zu beachten ist hierbei die Syntax:
-v <Volumenname>:<Mountpunkt im Container>

bind mounts

Die offizielle Dokumentation dazu findet man hier: Use bind mounts

Man sollte auch beachten, dass bind mounts nicht per docker volume Befehl gesteuert werden.

Dazu erstellen wir uns in unserem aktuellen Verzeichnis ein Ordner, welchen wir dann per bind mount in den Container einbinden:
mkdir zielordner

Anschließend erstellen wir einen Container, welcher unseren eben angelegten zielordner unter /mnt gemountet hat:

1.) per --mount Option
docker container run -d --name nginx_bind_mount_test --mount type=bind,source="$(pwd)"/zielordner,target=/mnt nginx

Der einzige Unterschied zur --mount Option mit Volumes ist die Angabe des type=bind.

Wenn nun auf dem Hostsystem eine Datei im zielordner per touch zielordner/testfile erstellt wird, können wir im Container direkt darauf zugreifen:

$ docker exec -it nginx_bind_mount_test ls /mnt
testfile

Dies natürlich auch anders herum möglich und eine im Container angelegte Datei ist im entsprechenden Ordner auf dem Hostsystem verfügbar.

$ docker container inspect nginx_bind_mount_test
                ...
                "Mounts": [                     
                {                             
                    "Type": "bind",   
                    "Source": "/tmp/zielordner",
                    "Target": "/mnt"            
                }  
                ...

2.) per -v Option

docker container run -d --name nginx_bind_mount_test2 -v "$(pwd)"/zielordner:/mnt nginx

$ docker exec -it nginx_bind_mount_test2 ls /mnt
testfile  

bind mounts eignen sich gut um Configs in einen Container einzubinden.
Hier mal ein Beispiel, wie man eine auf dem Hostsystem liegende Konfigurationsdatei in einen Container einbindet:

docker container run -d --name nginx-bind-mount3 -v "$(pwd)"/nginx/nginx.conf:/etc/nginx/nginx.conf nginx

tmpfs mounts

docker bietet noch die Option für tmpfs mounts an.

Im Gegensatz zu Volumes und bind mounts kann ein tmpfs mount nicht zwischen Containern geteilt werden und befindet sich nur im Speicher des Hostsystemes.

Für die Erstellung gibt es wieder zwei Möglichkeiten:

1.) --tmpfs
Bei der --tmpfs Option braucht man nur den Namen des tmpfs angeben:
docker run -d -it --tmpfs /mnt2 --name centos01 centos bash

$ docker exec -it centos01 df -Th /mnt2
Filesystem     Type   Size  Used Avail Use% Mounted on
tmpfs          tmpfs  1.9G     0  1.9G   0% /mnt2

2.) --mount

docker run -d -it --name centos02 --mount type=tmpfs,destination=/mnt2 centos bash

$ docker exec -it centos02 df -Th /mnt2
Filesystem     Type   Size  Used Avail Use% Mounted on
tmpfs          tmpfs  1.9G     0  1.9G   0% /mnt2
Des weiteren unterstützt die --mount Option zwei weitere Parameter, welche die --tmpfs Option nicht unterstützt.
  • tmpfs-size —> gibt die Größe des tmpfs in Bytes an
  • tmpfs-mode —> Legt die Dateiberechtigung in octal fest (Standard ist 1777)

Als Beispiel erstelle ich einen Container, welche ein zusätzliches ca. 500MB großes tmpfs besitzt:

docker run -d -it --name centos03 --mount type=tmpfs,destination=/mnt2,tmpfs-size=500000000 centos bash

$ docker exec -it centos03 df -Th /mnt2
Filesystem     Type   Size  Used Avail Use% Mounted on
tmpfs          tmpfs  477M     0  477M   0% /mnt2

—-
Hinweis: es gibt mit bestimmten Plugins auch die Möglichkeit z.B. Verzeichnisse direkt per nfs in einen Container zu mounten, aber ich wollte hier nur die eigens von docker mitgebrachten Befehle und Module verwenden.

Autor
Kategorien container, docker

PRTG Map