In Docker haben Dateien, die in Containern erstellt wurden, in der Regel einen unvorhersehbaren Besitz, während sie vom Host aus überprüft werden. Der Eigentümer der Dateien auf einem Volume ist standardmäßig root (UID 0). Sobald jedoch Nicht-Root-Benutzerkonten in den Container eingebunden sind und in das Dateisystem schreiben, werden die Eigentümer aus Host-Sicht mehr oder weniger zufällig.
Dies ist ein Problem, wenn Sie mit demselben Benutzerkonto, das die Docker-Befehle aufruft, auf Datenträgerdaten vom Host zugreifen müssen.
Typische Problemumgehungen sind
- Erzwingen von Benutzer-UIDs zur Erstellungszeit in Docker-Dateien (nicht portierbar)
- Übergeben der UID des Hostbenutzers an den
docker run
Befehl als Umgebungsvariable und Ausführen einigerchown
Befehle auf den Volumes in einem Einstiegspunktskript.
Beide Lösungen können eine gewisse Kontrolle über die tatsächlichen Berechtigungen außerhalb des Containers geben.
Ich habe erwartet, dass Benutzernamensräume die endgültige Lösung für dieses Problem darstellen. Ich habe einige Tests mit der kürzlich veröffentlichten Version 1.10 und --userns-remap durchgeführt, die auf mein Desktop-Konto eingestellt sind. Ich bin mir jedoch nicht sicher, ob es den Umgang mit Dateien auf bereitgestellten Volumes erleichtern kann. Ich befürchte, dass es tatsächlich das Gegenteil sein könnte.
Angenommen, ich starte diesen Basiscontainer
docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit
Überprüfen Sie anschließend den Inhalt des Hosts:
ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/
-rw-r--r-- 1 100000 100000 6 Feb 8 19:43 test.txt
Diese Nummer '100000' ist eine Unter-UID meines Hostbenutzers. Da sie jedoch nicht der UID meines Benutzers entspricht, kann ich test.txt immer noch nicht ohne Berechtigungen bearbeiten. Dieser Unterbenutzer scheint keine Affinität zu meinem tatsächlichen regulären Benutzer außerhalb von Docker zu haben. Es ist nicht zurück abgebildet.
Die zuvor in diesem Beitrag erwähnten Problemumgehungen, die darin bestanden, UIDs zwischen dem Host und dem Container auszurichten, funktionieren aufgrund der UID->sub-UID
im Namespace auftretenden Zuordnung nicht mehr .
Gibt es dann eine Möglichkeit, Docker mit aktiviertem Benutzernamensraum auszuführen (um die Sicherheit zu verbessern), während der Hostbenutzer, der Docker ausführt, weiterhin die auf Volumes generierten Dateien besitzen kann?
Antworten:
Wenn Sie Benutzer und Gruppen im Voraus vorab anordnen können, können Sie UIDs und GIDs so spezifisch zuweisen, dass Hostbenutzer Benutzern mit Namespace in Containern entsprechen.
Hier ist ein Beispiel (Ubuntu 14.04, Docker 1.10):
Erstellen Sie einige Benutzer mit festen numerischen IDs:
Bearbeiten Sie automatisch generierte untergeordnete ID-Bereiche in
/etc/subuid
und/etc/subgid
Dateien manuell :(Beachten Sie, dass es keine Aufzeichnungen für
ns1-root
undns1-user1
aufgrund vonMAX_UID
undMAX_GID
Grenzen in gibt./etc/login.defs
)Aktivieren Sie Benutzernamensräume in
/etc/default/docker
:Starten Sie den Daemon neu
service docker restart
und stellen Sie sicher, dass das/var/lib/docker/500000.500000
Verzeichnis erstellt wurde.Jetzt haben Sie in Containern
root
unduser1
und auf dem Host -ns1-root
undns1-user1
mit passenden IDsUPDATE: Um sicherzustellen, dass Nicht-Root-Benutzer feste IDs in Containern haben (z. B. Benutzer1 1000: 1000), erstellen Sie diese explizit während der Image-Erstellung.
Probefahrt:
Bereiten Sie ein Volume-Verzeichnis vor
Probieren Sie es aus einem Behälter
Versuchen Sie es vom Host
Nicht tragbar und sieht aus wie ein Hack, funktioniert aber.
quelle
subUID lower bound + UID in image
dann lautet, wenn wir viele verschiedene Bilder mit einem Benutzer ausführen, dessen ID auf 1000 gesetzt ist?Eine Problemumgehung besteht darin, die Benutzer-UID während der Erstellungszeit dynamisch dem Host zuzuweisen.
Beispiel
Dockerfile
:Dann bauen als:
und laufen als:
Wenn Sie bereits einen Container haben, erstellen Sie einen Wrapper-Container mit den folgenden Angaben
Dockerfile
:Dies kann wie folgt eingepackt werden
docker-compose.yml
:Dann erstellen und ausführen als:
quelle
Mit dem
docker cp
Befehl können Sie Berechtigungsprobleme vermeiden .Hier ist Ihr Beispiel umgeschaltet, um zu verwenden
docker cp
:Wenn Sie jedoch nur Dateien aus einem Container lesen möchten, benötigen Sie das angegebene Volume nicht. In diesem Beispiel wird ein benannter Container anstelle eines benannten Volumes verwendet:
Ich finde benannte Volumes nützlich, wenn ich Dateien in einen Container kopieren möchte, wie in dieser Frage beschrieben .
quelle
docker cp
beinhaltet das Duplizieren von Daten. Darüber hinaus werden laut Dokument beim Kopieren von Daten in einen Container Eigentümer-IDs entsprechend dem Root-Benutzer festgelegt, bei dem es sich häufig nicht um das Konto handelt, auf dem die containerisierte App ausgeführt wird. Ich verstehe nicht, wie es unser Problem löst.docker cp
Sie haben die volle Kontrolle über den Dateieigentum, wenn Sie ein Teerarchiv in einen Container oder aus einem Container streamen. Sie können den Besitz und die Berechtigungen jedes Eintrags in der TAR-Datei beim Streamen anpassen, sodass Sie nicht auf den Root-Benutzer beschränkt sind.