Proxmox / Docker – persistenten Storage in Container einbinden
Docker Container sind flüchtig, die Container besitzen bei einem Neustart immer denselben Stand. Wenn Anwendungsdaten und Konfigurationen auch nach dem Neustart eines Containers erhalten bleiben sollen, müssen Sie persistenten Storage in den Container einbinden.
Wo kann der persistente Storage angelegt werden?
Je nach vorhandener Docker-Installation gibt es verschiedene Möglichkeiten, wo und wie der Storage grundsätzlich in das Docker-System eingebunden werden kann.
- In einem Verzeichnis auf dem Docker-Server selbst. Diese Variante kann in jeder Art von Docker-Installation genutzt werden. Hierbei handelt es sich quasi um „lokalen“ bzw. „internen“ Speicher auf dem Dockersystem selbst.
- In einem „Docker-Volume“ auf dem Docker-Server.
- Im Fall von Proxmox, als Virtualisierungshost für Docker, im Filesystem des Proxmox-Hosts. Dieses Verzeichnis auf dem Host wird dann als Mountpoint im Docker-LXC eingebunden. In diesem Fall wäre von „externem“ Speicher zu sprechen, der den Vorteil bietet, dass Sie zum Beispiel große Datenmengen auslagern und nicht den Dockerserver selbst vorhalten (müssen).
Auf 2. wird in diesem Artikel nicht separat eingegangen, da sich ein Docker-Volume wie ein Verzeichnis aus 1. verhält, es liegt nur an einer fest definierten Stelle auf dem Docker-Server, nämlich unter
/var/lib/docker/volumes
Dass persistenter Storage benötigt wird ist unabdingbar für die meisten Docker-Container, wo dieser verwendete Speicher liegen soll, müssen Sie selbst entscheiden bzw. hängt von Ihren speziellen Gegebenheiten ab.
Organisation des Storage
Unabhängig von der Art, wie Sie den Speicher einbinden, empfehle ich aber diesen grundsätzlich zu organisieren. Eine organisierte Ablage führt dazu, dass Sie die Daten leicht finden bzw. zuordnen und zum Beispiel auch gezielt sichern können.
Da es beim persistenten Speicher für Docker-Container meistens um „Daten“ und / oder „Konfigurationen“ geht, sollte der Speicherbereich auch analog organisiert sein. Ich verwende dabei immer folgende Struktur:
data
+-CONTAINER/ANWENDUNG 1
+-CONTAINER/ANWENDUNG 2
+-CONTAINER/ANWENDUNG n
config
+-CONTAINER/ANWENDUNG 1
+-CONTAINER/ANWENDUNG 2
+-CONTAINER/ANWENDUNG n
Hier ein praktisches Beispiel vom Proxmox Host für die Daten von Datenbanksystemen (DBMS), die als Docker Container laufen:
root@proxmox:/mnt/zfsstorage/docker/data# ls -la
total 61
drwxrwxrwx 9 root root 9 Dec 13 23:59 .
drwxrwxrwx 8 root root 8 Dec 6 20:27 ..
drwxrwxr-x 5 100000 100000 6 Oct 13 21:51 grafana
drwxrwxr-x 5 100000 100000 5 Oct 13 19:30 influxdb
drwxr-xr-x 6 100000 100000 6 Aug 31 23:41 mssql
drwxrwxr-x 6 100000 100000 6 Aug 31 23:32 mssql2019
drwxrwxr-x 7 100999 100000 16 Dec 15 22:15 mysql
drwx------ 19 100999 100000 25 Sep 5 13:26 psql
drwxrwxr-x 7 100000 100000 8 Dec 14 00:22 seqdata
Nutzung von lokalem Speicher auf dem Docker-Server
Diese Methode ist die einfachste und auf jeder Docker-Installation nutzbar. Bedenken Sie dabei aber folgendes: Wenn Ihr Docker-Server, warum auch immer stirbt und Sie kein Backup haben, dann können Sie zwar Ihre Docker-Container (auf einer neuen Maschine) einfach wiederherstellen – die persistierten Anwendungs- und Konfigurationsdaten sind dann allerdings verloren.
Erstellen Sie auf dem Dockerserver dazu ganz einfach ein neues Verzeichnis auf oberster Ebene, zum Beispiel „dockerdata“:
root@Docker:/# mkdir dockerdata
Wechseln Sie in das erstellte Verzeichnis und legen Sie die beiden Unterverzeichnisse an
root@Docker:/# cd dockerdata/
root@Docker:/dockerdata# mkdir data
root@Docker:/dockerdata# mkdir config
Da die Docker-Container Lese-und Schreibzugriff auf diese Verzeichnisse benötigen, müssen diese mit entsprechenden Rechten versehen werden:
root@Docker:/# chmod -R 775 dockerdata/
Dies sollte dann so aussehen:
root@Docker:/dockerdata# ls -la
total 16
drwxrwxr-x 4 root root 4096 Dec 22 15:35 .
drwxr-xr-x 26 root root 4096 Dec 22 15:34 ..
drwxrwxr-x 2 root root 4096 Dec 22 15:35 config
drwxrwxr-x 2 root root 4096 Dec 22 15:35 data
Wie schon in der Einleitung unter 2. gesagt, können Sie natürlich auch ein Docker-Volume anlegen, die Nachteile sind aber identisch mit denen eines lokalen Verzeichnisses. Ein Docker-Volume können Sie über folgenden Befehl einrichten:
docker volume create NAME_DES_VOLUMES
Nutzung von externem Speicher auf dem Docker-Server
In diesem Beispiel läuft ein Docker-LXC auf einem Proxmox Host. Unter Proxmox wird Storage mit dem Dateisystem ZFS verwendet. Zusätzlich wird dieser Storage im Rahmen eines Backups gesichert.
Für die Dockerdaten wird dazu ein eigenes Dataset mit dem Namen „dockerdata“ im ZFS-Pool angelegt:
root@proxmox:~# zfs create zfspool/dockerdata
Üblicherweise wird automatisch ein entsprechender Mountpoint auf dem Proxmox Host eingerichtet. Beispielsweise
/mnt/IRGENDEINNAME/dockerdata
in unserem Fall
mnt/zfsstorage/dockerdata
Diesem Mountpoint müssen Sie natürlich volle Lese- und Schreibrechte geben, wenn der Docker Host und dessen Container mit dieser Freigabe arbeiten soll. Ob chmod 775
oder chmod 777
für Sie benötigt wird, kommt auf Ihre Anwendungsfälle an, zum Beispiel:
chmod 775 /mnt/zfsstorage/dockerdata
Bearbeiten Sie anschließend die Container-Konfigurationsdatei auf dem Proxmox Host unter
nano /etc/pve/lxc/CONTAINER-ID.conf
und fügen Sie folgende Zeile hinzu (der Mountpoint des ZFS-Pools auf dem Proxmox-Host ist entsprechend Ihrer Konfiguration anzupassen, hier /mnt/zfsstorage
):
mp0: /mnt/zfsstorage/dockerdata,mp=/dockerdata
Die Konfigrationsdatei des Docker-Containers sollte dann ähnlich wie dieses Beispiel aussehen:
arch: amd64
cores: 2
features: keyctl=1,nesting=1
hostname: Docker
memory: 4096
mp0: /mnt/zfsstorage/dockerdata,mp=/dockerdata
net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=F2:4A:4E:D2:B2:15,ip=dhcp,ip6=auto,type=veth
onboot: 1
ostype: debian
rootfs: local-lvm:vm-103-disk-1,size=100G
swap: 512
unprivileged: 1
In dem Docker-Container erstellen Sie noch den zugehörigen Mountpoint im Hauptverzeichnis:
root@Docker:/# mkdir dockerdata
Erstellen Sie die beiden Verzeichnisse data
und config
(siehe oben „Organisation des Speicherbereichs“)
root@Docker:/# cd dockerdata/
root@Docker:/dockerdata# mkdir data
root@Docker:/dockerdata# mkdir config
und vergeben diesen Verzeichnissen anschließend die notwendigen Rechte:
root@Docker:/# chmod -R 775 dockerdata/
Starten Sie anschließend den Container neu. Sie sollten in der Proxmox-Oberfläche den neuen Mountpoint für den Container unter „Ressourcen“ sehen.
Den persistenten Storage in Container einbinden
Die Nutzung des persistenten Speichers erfolgt immer gleich. Hier am Beispiel von „dokuwiki“ und einer Docker YAML Datei:
version: "2.1"
services:
dokuwiki:
image: ghcr.io/linuxserver/dokuwiki
container_name: dokuwiki
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
volumes:
- /dockerdata/data/dokuwiki/config:/config
ports:
- 5080:80
- 5443:443 #optional
restart: unless-stopped
Hier dasselbe Beispiel mit einem Docker-CLI Kommando:
docker run -d \
--name=dokuwiki \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Europe/Berlin \
-p 80:80 \
-p 443:443 `#optional` \
-v /dockerdata/data/dokuwiki/config:/config \
--restart unless-stopped \
ghcr.io/linuxserver/dokuwiki
Wir sehen, dass wir ein Mapping in den Container nach /config
benötigen. Da DokuWiki seine gesamten Daten (Konfiguration und Daten) in einem Verzeichnis vorhält, wählen wir als Speicherort den data
Ordner unseres dockerdata
Verzeichnisses und legen dort ein Verzeichnis dokuwiki
mit dem Unterverzeichnis config
an.
Hinweis: Das Verzeichnis dokuwiki
alleine hätte auch gereicht, wusste der Autor zum damaligen Zeitpunkt aber nicht 😉
Anschließend noch die Rechte setzen
root@Docker:/dockerdata/data# chmod -R 775 dokuwiki/
und den Container starten.
Fazit
Die Nutzung von persistentem Storage für Docker-Container ist in der Regel zwingend und wie Sie den Storage in Container einbinden auch recht einfach. Ein externer Storage bietet neben einem lokalen Verzeichnis oder einem Docker-Volume verbesserte Datensicherheit, zumal sich durch das „Outsourcing“ der Daten auch der Docker-Server überschaubar schlank und wartbar halten lässt.
Ist der externe Storage einmal eingerichtet, kann dieser komfortabel zum Beispiel über Portainer bei der Erstellung und Verwaltung von containerisierten Anwendungen verwendet werden.
Hallo,
grundsätzlich eine gute Anleitung. Leider funktioniert sie nicht wenn ich Ihr Folge.
Das Einhängen des persistenten Speichers in den LXC Container funktioniert zwar, aber er ist nicht nutzbar da ich keine Schreibrechte auf das Dataset habe.
Nach meinen Recherchen liegt es wohl daran das der LXC Container als unpreviligierter Container erstellt wurde. Wenn es so ist, dann müsste die Anleitung entsprechend angepasst werden.
Hallo Sven,
>> Nach meinen Recherchen liegt es wohl daran das der LXC Container als unpreviligierter Container erstellt wurde.
Nein, denn hier funktioniert es mit einem unpreviligierten Container.
Evtl. den letzten Schritt aus der Anleitung übersehen?
root@Docker:/# chmod -R 775 dockerdata/
Insgesamt muss das so aussehen:
Eingebundenes Dataset „zfspool/dockerdata“:
rwxrwx 8 nobody nogroup 8 Feb 13 14:06 dockerdata
Berechtigungen innerhalb von „dockerdata“ (die Verzeichnisse müssen aus dem lxc heraus angelegt werden:
root@Docker:/dockerdata# ls -la
total 48
drwxrwxrwx 8 nobody nogroup 8 Feb 13 14:06 .
drwxr-xr-x 25 root root 4096 Mar 18 09:58 ..
drwxr-xr-x 2 nobody nogroup 2 Dec 11 2020 config
drwxrwxrwx 9 nobody nogroup 9 Dec 13 22:59 data
drwxr-xr-x 3 root root 3 Feb 10 2021 dokuwiki
drwxr-xr-x 4 root root 5 Mar 18 09:58 gotify
drwxr-xr-x 6 root root 7 Feb 12 2021 webdevstack
drwxrwxr-x 4 root root 4 Dec 6 19:28 wordpress
EDIT: Was noch sein könnte, aber das sehe ich als selbstverständlich an. Natürlich müssen auf dem gemounteten Dataset im Proxmox alle Lese- und Schreibrechte haben. Denn wenn das bereits eingeschränkt ist, macht ja das Weiterreichen keinen Sinn:
drwxrwxrwx 7 root root 7 Dec 22 17:44 zfsstorage
Viele Grüße
Servus,
Danke für die Anleitung.
Ein nicht unerhebliches Detail ist eben, ob man mit 775 oder 777 auf dem PVE-Host arbeitet. (Sicherheitsaspekte lassen wir hier mal bewusst aussen vor).
Aber wenn die Container im Verzeichnis „was“ machen möchten, ne DB anlegen o.ä., kommst du mit 775 eben nicht weit.
Folgt man jetzt der Anleitung mit 775 – hat aber wie von dir auch erwähnt, einen „Anwendungsfall für 777 – bleibt die Küche kalt. Den Anwendungsfall kann man aber erst bestimmen, wenn man weiss, was Kollege Container im Verzeichnis alles treibt…
Grüße
Olli
Hallo Olli,
ja, sehe ich grundsätzlich wie Du. Ich verfahre aber immer nach dem Motto, nur das freigeben, was tatsächlich benötigt wird und erst wenn das nicht ausreicht, denn weiter freigeben.
Viele Grüße
Kay
Pingback: Kostenlose Teamviewer Alternative - RustDesk - kayomo GmbH
Hallo, danke für die tolle Anleitung.
Du schreibst, „In diesem Beispiel läuft ein Docker-LXC auf einem Proxmox Host. Unter Proxmox wird Storage mit dem Dateisystem ZFS verwendet. Zusätzlich wird dieser Storage im Rahmen eines Backups gesichert.“
Kannst du bitte kurz erklären wie man den Storage im Rahmen eines Backups sichert. Ich hab leider bei google nichts gefunden.
Sorry für die verspätete Rückmeldung. Ich habe in der Zwischenzeit einen neuen Proxmox-Homeserver aufgesetzt und die Datensicherung dort dokumentiert.
Der Artikel ist hier zu finden: https://kayomo.de/blog/borgbackup-datensicherung-unter-proxmox/
Danke für die Anleitung. Wäre auch mein Ansatz für den persistenten Speicher der Docker Container.
Was mich allerdings interessieren würde und ich mangels Proxmox Server noch nicht testen kann ist, wie ich anschließend die lokalen Daten unter Proxmox sichern kann. Es wird hier ja auch von einem Backup gesprochen.
Ich lese immer, dass Proxmox nur ganze virtuelle Maschinen bzw. Linux Container sichern kann, nicht aber einzelne Dateien.
Eine kurze Erklärung wäre super 🙂
Danke!
Sorry für die verspätete Rückmeldung. Ich habe in der Zwischenzeit einen neuen Proxmox-Homeserver aufgesetzt und die Datensicherung dort dokumentiert.
Der Artikel ist hier zu finden: https://kayomo.de/blog/borgbackup-datensicherung-unter-proxmox/
Pingback: BorgBackup - Datensicherung unter Proxmox - kayomo GmbH