Betrachten Sie die folgende triviale Docker-Datei:
FROM debian:testing
RUN adduser --disabled-password --gecos '' docker
RUN adduser --disabled-password --gecos '' bob
in einem Arbeitsverzeichnis mit nichts anderem. Erstellen Sie das Docker-Image:
docker build -t test .
Führen Sie dann ein Bash-Skript für den Container aus und verknüpfen Sie das Arbeitsverzeichnis mit einem neuen Unterverzeichnis im Basisverzeichnis von bob:
docker run --rm -it -v $(pwd):/home/bob/subdir test
Wem gehört der Inhalt des subdir
Containers? Führen Sie auf dem Container Folgendes aus:
cd /home/bob/subdir
ls -l
ad wir sehen:
-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile
Heiliger Rauch! docker
besitzt den Inhalt! Zurück auf dem Host-Computer außerhalb des Containers sehen wir, dass unser ursprünglicher Benutzer das noch besitzt Dockerfile
. Versuchen wir, den Besitz des bob
Home-Verzeichnisses zu beheben . Führen Sie auf dem Container Folgendes aus:
chown -R bob:bob /home/bob
ls -l
und wir sehen:
-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile
Aber warte! außerhalb des Containers rennen wir jetztls -l
-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile
Wir besitzen keine eigene Datei mehr. Schreckliche Nachrichten!
Wenn wir im obigen Beispiel nur einen Benutzer hinzugefügt hätten, wäre alles reibungsloser verlaufen. Aus irgendeinem Grund scheint Docker ein Home-Verzeichnis zu erstellen, das dem ersten Nicht-Root-Benutzer gehört, auf den es trifft (selbst wenn dieser Benutzer in einem früheren Image deklariert ist). Ebenso ist dieser erste Benutzer derjenige, der den gleichen Eigentumsrechten wie mein Privatbenutzer entspricht.
Frage 1 Ist das richtig? Kann mich jemand auf eine Dokumentation verweisen, ich vermute nur, basierend auf dem obigen Experiment.
Frage 2 : Vielleicht liegt dies nur daran, dass beide den gleichen numerischen Wert im Kernel haben. Wenn ich auf einem System testen würde, auf dem mein Heimbenutzer keine ID 1000
hatte, würden die Berechtigungen in jedem Fall geändert.
Frage 3 : Die eigentliche Frage lautet natürlich: Was mache ich dagegen? Wenn er auf dem angegebenen Hostcomputer bob
angemeldet ist bob
, sollte er in der Lage sein, den Container als auszuführen bob
und keine Dateiberechtigungen unter seinem Hostkonto zu ändern. Derzeit muss er den Container tatsächlich als Benutzer ausführen docker
, um zu vermeiden, dass sein Konto geändert wird.
Ich höre dich fragen, warum ich überhaupt so eine seltsame Docker-Datei habe. . Ich frage mich auch manchmal. Ich schreibe einen Container für eine Webanwendung (RStudio-Server), der es verschiedenen Benutzern ermöglicht, sich anzumelden, wobei einfach die Benutzernamen und Anmeldeinformationen des Linux-Computers als gültige Benutzernamen verwendet werden. Dies bringt mir die vielleicht ungewöhnliche Motivation, mehrere Benutzer erstellen zu wollen. Ich kann dies umgehen, indem ich den Benutzer nur zur Laufzeit erstelle und alles in Ordnung ist. Ich verwende jedoch ein Basis-Image, das einen einzelnen docker
Benutzer hinzugefügt hat, damit es interaktiv verwendet werden kann, ohne als Root ausgeführt zu werden (gemäß Best Practice). Dies ruiniert alles, da dieser Benutzer der erste wirdBenutzer und besitzt am Ende alles, so dass Versuche, sich anzumelden, wenn andere Benutzer fehlschlagen (die App kann nicht gestartet werden, da ihr Schreibberechtigungen fehlen). Das chown
erste Ausführen des Startskripts löst dieses Problem, jedoch auf Kosten verknüpfter Volumes, die Berechtigungen ändern (offensichtlich nur ein Problem, wenn Volumes verknüpft werden).
quelle
Antworten:
Lesen Sie
info coreutils 'chown invocation'
, was Ihnen möglicherweise eine bessere Vorstellung davon gibt, wie Dateiberechtigungen / -eigentum funktionieren.Grundsätzlich ist jedoch an jeder Datei auf Ihrem Computer eine Reihe von Bits angeheftet, die ihre Berechtigungen und ihren Besitz definieren. Wenn Sie
chown
eine Datei erstellen, setzen Sie nur diese Bits.Wenn Sie
chown
eine Datei an einen bestimmten Benutzer / eine bestimmte Gruppe mit dem Benutzernamen oder Gruppennamen senden,chown
suchen Sie/etc/passwd
nach dem Benutzernamen und/etc/group
nach der Gruppe, um zu versuchen, den Namen einer ID zuzuordnen. Wenn der Benutzername / Gruppenname in diesen Dateien nicht vorhanden ist, schlägt dieschown
fehl.Sie können jedoch
chown
eine Datei mit IDs nach Belieben erstellen (natürlich innerhalb einiger oberer positiver Ganzzahlgrenzen), unabhängig davon, ob auf Ihrem Computer ein Benutzer / eine Gruppe mit diesen IDs vorhanden ist oder nicht.Die UID- und GID-Bits werden in der Datei selbst festgelegt. Wenn Sie diese Dateien in Ihrem Docker-Container bereitstellen, hat die Datei dieselbe Eigentümer- / Gruppen-UID wie auf dem Host, wird jedoch jetzt
/etc/passwd
im Container zugeordnet wird wahrscheinlich ein anderer Benutzer sein, es sei denn, er gehört root (UID 0).Es scheint, als müssten Sie bei Ihrer aktuellen Einrichtung sicherstellen, dass Ihre UIDs> Benutzernamen
/etc/passwd
auf Ihrem Host mit Ihren UIDs> Benutzernamen in Ihren Containern übereinstimmen,/etc/passwd
wenn Sie mit Ihrem bereitgestellten Benutzerverzeichnis als demselben Benutzer interagieren möchten Das ist auf dem Host angemeldet.Sie können einen Benutzer mit einer bestimmten Benutzer-ID mit erstellen
useradd -u xxxx
. Buuuut, das scheint eine chaotische Lösung zu sein ...Möglicherweise müssen Sie eine Lösung finden, die das Home-Verzeichnis eines Hostbenutzers nicht bereitstellt.
quelle
userdel
obwohl freigeben . fwiw hier ist die Lösung, die ich in meiner aktuellen Docker-Zwei Optionen, die ich gefunden habe:
CHOWN alle Dinge (nach Ihrer Arbeit)
Ich habe es getan
docker run -v `pwd`/shared:/shared image
, und der Container hat Dateien erstelltpwd/shared
, die dem Docker-Prozess gehören. Ist/shared
jedoch immer noch im Besitz von mir. Also mache ich es innerhalb des Docker-Prozesseschown -R `stat -c "%u:%g" /shared` /shared
stat -c "%u:%g" /shared
kehrt1000:1000
in meinem Fall alsuid:gid
Benutzer zurück. Obwohl sich1000
im Docker-Conatainer kein Benutzer befindet, ist die ID vorhanden (undstat /shared
sagt nur "unbekannt", wenn Sie nach dem Benutzernamen fragen).Wie auch immer,
chown
gehorsam überträgt das Eigentum an den Inhalten von/shared
auf1000:1000
(was, soweit es betrifft, nicht existiert, aber außerhalb des Containers bin ich es). Also besitze ich jetzt alle Dateien. Der Container kann immer noch Dinge ändern, wenn er möchte, weil es aus seiner Sicht so istroot
.Und alles ist gut mit der Welt.
docker run -u
Alle erstellten Dateien haben automatisch den richtigen EigentümerEine andere Möglichkeit, dies zu tun, ist das
-u
Flag beim Andockenlauf.docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash
Auf diese Weise befindet sich der Docker-Benutzer im Container
youruid:yourgid
.Allerdings: Dies bedeutet, dass Sie Ihre Root-Berechtigung innerhalb des Containers (
apt-get install
usw.) aufgeben müssen . Es sei denn, Sie erstellen einen Benutzer mit dieser neuen UID und fügen sie derroot
Gruppe hinzu.quelle
chown
. Ich neige auch dazu, zu verwenden-u 1000
. Ich denke nicht, dass die Verwendung%u
so viel hilft, denn wenn Ihr Benutzer eine UID hat, die nicht auf dem Container vorhanden ist, wird es trotzdem nur einen Fehler geben.UID
undGID
durch die in Docker weitergegeben werden-u
Option muss innerhalb des Docker Container existieren selbst (dh die IDs, nicht die damit verbundenen Namen).In diesem Beitrag habe ich untersucht, wie ich den Besitz aller Dateien (im Besitz von root), die aus einem Docker-Container stammen, der als root ausgeführt wird , für meinen nicht privilegierten Benutzer auf dem Host wiederherstellen kann .
Ich brauchte den Prozess im Container, um als Root ausgeführt zu werden, daher kann ich -u beim Andocken nicht verwenden.
Ich bin nicht stolz auf das, was ich getan habe, aber am Ende meines Bash-Skripts habe ich Folgendes hinzugefügt:
Lassen Sie uns einige der Zeilen aufschlüsseln:
/tmp
:chown
rekursiv mit der UID des Hostbenutzers über das Zielverzeichnis aus (im Container eingebunden in/tmp
):Auf diese Weise habe ich die Dateien an meinen aktuellen Benutzer zurückgegeben, ohne die Berechtigungen für root oder sudo "eskalieren" zu müssen.
Es ist schmutzig, aber es hat funktioniert. Hoffe ich habe geholfen.
quelle