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 solltype=volume
—> gibt an das ein bestehendes Volume verwendet werden sollsource=...
—> gibt den Namen des einzubindenden Volumes antarget=...
—> 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 destmpfs
in Bytes antmpfs-mode
—> Legt die Dateiberechtigung in octal fest (Standard ist1777
)
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.