Einführung
Docker ist eine leistungsstarke Containerisierungsplattform, die es Entwicklern ermöglicht, Anwendungen einfach zu verpacken und bereitzustellen. Ein häufiges Problem, auf das Benutzer stoßen, ist der Fehler 'permission denied' (Zugriff verweigert) beim Mounten von Volumes in Docker. Dieser Fehler tritt auf, wenn der Container nicht über die erforderlichen Berechtigungen verfügt, um auf Dateien oder Verzeichnisse auf dem Host-Rechner zuzugreifen.
In diesem Lab lernen Sie, wie Sie Fehler vom Typ 'permission denied' (Zugriff verweigert) beim Arbeiten mit Docker-Volumes identifizieren, beheben und lösen können. Am Ende dieses Tutorials werden Sie verstehen, wie Docker-Volumes funktionieren, wie sich Berechtigungen auf sie auswirken und welche Best Practices für die Einrichtung von Volumes mit den korrekten Berechtigungen gelten.
Docker-Volumes verstehen
Docker-Volumes sind ein Mechanismus zum Persistieren von Daten, die von Docker-Containern generiert und verwendet werden. Sie ermöglichen es Ihnen, Daten unabhängig vom Lebenszyklus des Containers zu speichern, was das Sichern, Teilen und Verwalten Ihrer Anwendungsdaten erleichtert.
Beginnen wir damit, Docker-Volumes zu erkunden und ein einfaches Volume zu erstellen, um zu verstehen, wie sie funktionieren.
Was sind Docker-Volumes?
Docker-Volumes dienen mehreren wichtigen Zwecken:
- Sie persistieren Daten auch dann, wenn Container entfernt werden
- Sie ermöglichen die gemeinsame Nutzung von Daten zwischen Containern
- Sie trennen die Speicherverwaltung von der Containerverwaltung
- Sie bieten eine bessere Leistung als das Schreiben in die beschreibbare Schicht des Containers
Erstellen und Verwalten von Docker-Volumes
Zuerst erstellen wir ein einfaches Docker-Volume:
docker volume create my_volume
Um alle Volumes aufzulisten:
docker volume ls
Sie sollten eine Ausgabe ähnlich der folgenden sehen:
DRIVER VOLUME NAME
local my_volume
Untersuchen wir unser neu erstelltes Volume, um zu sehen, wo es auf dem Host-Rechner gespeichert ist:
docker volume inspect my_volume
Die Ausgabe zeigt Details über das Volume:
[
{
"CreatedAt": "2023-XX-XX....",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my_volume/_data",
"Name": "my_volume",
"Options": {},
"Scope": "local"
}
]
Der Mountpoint (Einhängepunkt) ist der Ort, an dem Docker die Volumedaten auf dem Host-System speichert.
Testen des Volume-Mountings
Lassen Sie uns einen Container ausführen, der unser Volume mountet und einige Daten darin schreibt:
docker run --rm -v my_volume:/data alpine sh -c "echo 'Hello from Docker!' > /data/test.txt"
Dieser Befehl:
- Erstellt einen temporären Alpine Linux-Container mit dem Flag
--rm(er wird entfernt, wenn er beendet wird) - Mountet unser
my_volumein das Verzeichnis/datainnerhalb des Containers - Schreibt "Hello from Docker!" in eine Datei namens
test.txtim Volume
Nun wollen wir überprüfen, ob die Daten erhalten bleiben, indem wir sie von einem anderen Container lesen:
docker run --rm -v my_volume:/data alpine cat /data/test.txt
Sie sollten sehen:
Hello from Docker!
Dies demonstriert, wie Docker-Volumes Daten über verschiedene Container hinweg persistieren.
Erstellen eines Szenarios mit Zugriff verweigert
Nachdem wir die grundlegende Verwendung von Docker-Volumes verstanden haben, erstellen wir nun ein Szenario, das den Fehler 'permission denied' (Zugriff verweigert) erzeugt. Dies wird uns helfen zu verstehen, was das Problem verursacht und wie man es löst.
Einrichten eines Testverzeichnisses
Zuerst erstellen wir ein Verzeichnis auf dem Host-Rechner und eine Datei mit bestimmten Berechtigungen:
mkdir -p ~/project/docker-test
echo "This is a test file." > ~/project/docker-test/testfile.txt
chmod 700 ~/project/docker-test/testfile.txt
Diese Befehle:
- Erstellen ein Verzeichnis namens
docker-testin Ihrem Projektordner - Erstellen eine Testdatei mit Inhalt
- Setzen Berechtigungen für die Datei, so dass sie nur vom Eigentümer (Ihnen) gelesen, geschrieben und ausgeführt werden kann
Überprüfen wir die Berechtigungen der Datei:
ls -la ~/project/docker-test/
Sie sollten eine Ausgabe ähnlich der folgenden sehen:
total 12
drwxr-xr-x 2 labex labex 4096 XXX XX XX:XX .
drwxr-xr-x X labex labex 4096 XXX XX XX:XX ..
-rwx------ 1 labex labex 19 XXX XX XX:XX testfile.txt
Beachten Sie, dass die Dateiberechtigungen auf 700 (-rwx------) gesetzt sind, was bedeutet, dass nur der Eigentümer (Sie) die Datei lesen, schreiben oder ausführen kann.
Auftreten des Fehlers 'Zugriff verweigert'
Versuchen wir nun, auf diese Datei von innerhalb eines Docker-Containers zuzugreifen:
docker run --rm -v ~/project/docker-test:/app ubuntu cat /app/testfile.txt
Sie sollten eine Fehlermeldung ähnlich der folgenden sehen:
cat: /app/testfile.txt: Permission denied
Dies liegt daran, dass Docker-Container standardmäßig als Root-Benutzer innerhalb des Containers ausgeführt werden, aber dieser Root-Benutzer nicht derselben Benutzer-ID wie Ihr Host-Benutzer zugeordnet ist. Wenn Docker ein Host-Verzeichnis mountet, werden die Berechtigungsprüfungen weiterhin basierend auf den ursprünglichen Dateiberechtigungen und Benutzer-IDs angewendet.
Das Problem verstehen
Der Fehler 'permission denied' (Zugriff verweigert) tritt auf, weil:
- Die Datei auf Ihrem Host Ihrem Benutzer (labex) gehört
- Die Datei Berechtigungen auf 700 gesetzt hat (nur der Eigentümer kann darauf zugreifen)
- Der Docker-Container als eine andere Benutzer-ID (normalerweise root, also UID 0) ausgeführt wird
- Obwohl der Container-Benutzer "root" ist, hat er nicht die gleichen Privilegien wie der Host-Root-Benutzer beim Zugriff auf gemountete Volumes
Überprüfen wir die Benutzer-IDs, um dies besser zu verstehen:
echo "Host user ID: $(id -u)"
docker run --rm ubuntu bash -c "echo Container user ID: \$(id -u)"
Dies zeigt, dass Sie zwar mit Ihrer Benutzer-ID auf dem Host (wahrscheinlich 1000) arbeiten, der Container aber mit der Benutzer-ID 0 (root) ausgeführt wird. Trotz der Tatsache, dass er innerhalb des Containers "root" ist, unterliegt der Root-Benutzer des Containers beim Zugriff auf Host-gemountete Dateien weiterhin den Berechtigungsprüfungen des Hosts.
Beheben von 'Zugriff verweigert'-Fehlern
Nachdem wir die Ursache des Fehlers 'permission denied' (Zugriff verweigert) verstanden haben, wollen wir uns verschiedene Methoden zur Behebung ansehen.
Methode 1: Ändern der Dateiberechtigungen auf dem Host
Der einfachste Ansatz ist, die Berechtigungen der Dateien auf Ihrem Host zu ändern, um anderen Benutzern den Zugriff zu ermöglichen:
chmod 755 ~/project/docker-test/testfile.txt
Dies ändert die Berechtigungen auf 755 (-rwxr-xr-x), wodurch jeder die Datei lesen und ausführen kann, aber nur der Eigentümer sie ändern kann.
Versuchen wir erneut, auf die Datei von einem Container aus zuzugreifen:
docker run --rm -v ~/project/docker-test:/app ubuntu cat /app/testfile.txt
Nun sollten Sie den Inhalt der Datei sehen:
This is a test file.
Dies funktioniert, weil die Datei jetzt von "anderen" auf Ihrem Host-System lesbar ist, was den Benutzer des Containers einschließt.
Methode 2: Verwenden des Flags --user
Ein weiterer Ansatz ist, Docker anzuweisen, den Container mit derselben Benutzer-ID wie Ihr Host-Benutzer auszuführen:
## Setzen Sie die Dateiberechtigungen auf restriktiv zurück
chmod 700 ~/project/docker-test/testfile.txt
## Ermitteln Sie Ihre Benutzer-ID und Gruppen-ID
USER_ID=$(id -u)
GROUP_ID=$(id -g)
## Führen Sie den Container mit Ihrer Benutzer-ID aus
docker run --rm --user $USER_ID:$GROUP_ID -v ~/project/docker-test:/app ubuntu cat /app/testfile.txt
Sie sollten jetzt in der Lage sein, den Dateiinhalt trotz seiner restriktiven Berechtigungen zu lesen:
This is a test file.
Dies funktioniert, weil:
- Wir den Container mit derselben Benutzer-ID wie Ihr Host-Benutzer ausführen
- Die Berechtigungen für die Datei den Zugriff auf diese Benutzer-ID erlauben
- Docker die Benutzer-ID an die Prozesse des Containers weitergibt
Das Flag --user ist besonders nützlich, wenn Sie restriktive Berechtigungen für Ihre Host-Dateien beibehalten müssen.
Methode 3: Anpassen der Eigentümer- und Gruppen-IDs
Erstellen wir eine neue Datei, die einem anderen Benutzer gehört, um diese Methode zu demonstrieren:
## Erstellen Sie eine Datei als Root
sudo bash -c 'echo "This is a root-owned file." > ~/project/docker-test/rootfile.txt'
sudo chown root:root ~/project/docker-test/rootfile.txt
sudo chmod 600 ~/project/docker-test/rootfile.txt
## Sehen wir uns an, was wir haben
ls -la ~/project/docker-test/
Die Ausgabe sollte Folgendes zeigen:
total 16
drwxr-xr-x 2 labex labex 4096 XXX XX XX:XX .
drwxr-xr-x X labex labex 4096 XXX XX XX:XX ..
-rw------- 1 root root 25 XXX XX XX:XX rootfile.txt
-rwx------ 1 labex labex 19 XXX XX XX:XX testfile.txt
Versuchen Sie nun, auf die Root-eigene Datei von einem Container aus zuzugreifen, der als Root ausgeführt wird:
docker run --rm -v ~/project/docker-test:/app ubuntu cat /app/rootfile.txt
Sie sollten den Inhalt sehen:
This is a root-owned file.
Dies funktioniert, weil:
- Der Container standardmäßig als Root (UID 0) ausgeführt wird
- Die Datei auf dem Host Root (UID 0) gehört
- Die Berechtigungen (600) dem Eigentümer das Lesen der Datei erlauben
Dies zeigt, dass die tatsächlichen Benutzer-IDs wichtig sind, nicht nur die Namen. Wenn die Benutzer-ID des Containers mit der Eigentümer-ID der Datei übereinstimmt, werden die Berechtigungsprüfungen erfolgreich sein, wenn der Eigentümer die erforderlichen Berechtigungen hat.
Best Practices für Docker Volume-Berechtigungen
Nachdem wir verstanden haben, wie man Berechtigungsprobleme löst, wollen wir einige Best Practices für das Einrichten von Docker-Volumes mit den richtigen Berechtigungen besprechen.
Verwendung von benannten Volumes
Benannte Volumes werden von Docker verwaltet und haben in der Regel ein besseres Berechtigungsmanagement als Bind-Mounts. Erstellen wir ein benanntes Volume und sehen wir, wie es sich verhält:
## Erstellen Sie ein benanntes Volume
docker volume create data_volume
## Schreiben Sie als Root in das Volume in einem Container
docker run --rm -v data_volume:/data ubuntu bash -c "echo 'Created by root user' > /data/rootfile.txt && ls -la /data"
## Lesen Sie aus dem Volume als Nicht-Root-Benutzer
docker run --rm --user 1000:1000 -v data_volume:/data ubuntu cat /data/rootfile.txt
Sie werden feststellen, dass beide Operationen ohne Berechtigungsprobleme funktionieren. Dies liegt daran, dass Docker die Berechtigungen für benannte Volumes anders handhabt als für Bind-Mounts.
Erstellen einer konsistenten Entwicklungsumgebung
Für Entwicklungsumgebungen ist es oft nützlich, eine konsistente Benutzer-ID zwischen Ihrem Host und dem Container einzurichten:
## Erstellen Sie ein Dockerfile für einen Entwicklungscontainer
mkdir -p ~/project/dev-container
cat > ~/project/dev-container/Dockerfile << EOF
FROM ubuntu:22.04
ARG USER_ID=1000
ARG GROUP_ID=1000
RUN apt-get update && apt-get install -y sudo
## Erstellen Sie einen Nicht-Root-Benutzer mit derselben ID wie der Host-Benutzer
RUN groupadd -g \${GROUP_ID} developer && \\
useradd -u \${USER_ID} -g \${GROUP_ID} -m -s /bin/bash developer && \\
echo "developer ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/developer
USER developer
WORKDIR /home/developer
CMD ["bash"]
EOF
## Erstellen Sie den Entwicklungscontainer
cd ~/project/dev-container
docker build -t dev-container .
Jetzt können Sie diesen Container mit Ihrem Host-Verzeichnis gemountet ausführen:
docker run --rm -it -v ~/project/docker-test:/home/developer/project dev-container bash
Versuchen Sie innerhalb des Containers, auf die Dateien zuzugreifen:
ls -la ~/project
cat ~/project/testfile.txt
Dies funktioniert, weil:
- Der Container-Benutzer dieselbe UID wie Ihr Host-Benutzer hat
- Die Dateiberechtigungen den Zugriff auf diese UID erlauben
- Das gemountete Verzeichnis behält denselben Besitz und dieselben Berechtigungen bei
Verwenden von Docker Compose für konsistente Volume-Setups
Für komplexere Anwendungen kann Docker Compose helfen, konsistente Volume-Konfigurationen beizubehalten. Erstellen wir eine einfache Docker Compose-Datei:
mkdir -p ~/project/compose-test
cat > ~/project/compose-test/docker-compose.yml << EOF
version: '3'
services:
app:
image: ubuntu
user: "\${UID}:\${GID}"
volumes:
- ./data:/app/data
command: ["bash", "-c", "echo 'Running as user \$(id -u):\$(id -g)' > /app/data/output.txt && cat /app/data/output.txt"]
volumes:
app_data:
EOF
## Erstellen Sie das Datenverzeichnis
mkdir -p ~/project/compose-test/data
## Führen Sie es mit Ihrer Benutzer-ID aus
cd ~/project/compose-test
UID=$(id -u) GID=$(id -g) docker compose up
Dieser Ansatz:
- Verwendet Umgebungsvariablen, um Ihre Benutzer-ID und Gruppen-ID an Docker Compose zu übergeben
- Legt den Container so fest, dass er mit Ihrer Benutzer-ID ausgeführt wird
- Mountet ein lokales Verzeichnis, auf das Ihr Benutzer zugreifen kann
Überprüfen Sie nach dem Ausführen die Ausgabedatei:
cat ~/project/compose-test/data/output.txt
Sie sollten Folgendes sehen:
Running as user 1000:1000
Dies bestätigt, dass der Container mit Ihrer Benutzer-ID ausgeführt wurde und die entsprechenden Berechtigungen hatte, um in das gemountete Volume zu schreiben.
Zusammenfassung
In diesem Lab haben Sie gelernt, wie man den Fehler 'permission denied' (Zugriff verweigert) beim Mounten von Volumes in Docker identifiziert, behebt und löst. Die wichtigsten behandelten Punkte sind:
- Verstehen, wie Docker-Volumes funktionieren und welche Vorteile sie für die Datenpersistenz bieten
- Identifizieren von Berechtigungsproblemen beim Mounten von Host-Verzeichnissen als Volumes
- Beheben von Berechtigungsfehlern mit mehreren Techniken:
- Anpassen der Dateiberechtigungen auf dem Host
- Ausführen von Containern mit bestimmten Benutzer-IDs
- Verwalten des Eigentums von Dateien und Verzeichnissen
- Best Practices für das Einrichten von Docker-Volumes mit den richtigen Berechtigungen:
- Verwenden von benannten Volumes für ein besseres Berechtigungsmanagement
- Erstellen konsistenter Entwicklungsumgebungen mit übereinstimmenden Benutzer-IDs
- Verwenden von Docker Compose für komplexe Volume-Setups
Diese Fähigkeiten sind unerlässlich für die Arbeit mit Docker in realen Szenarien, in denen Datenpersistenz und ein ordnungsgemäßes Berechtigungsmanagement von entscheidender Bedeutung sind. Indem Sie verstehen, wie Docker Berechtigungen für gemountete Volumes handhabt, können Sie häufige Probleme vermeiden und robustere containerisierte Anwendungen erstellen.



