it-swarm.com.de

Grundlegendes zum Besitz von Benutzerdateien in Docker: So vermeiden Sie das Ändern der Berechtigungen für verknüpfte Volumes

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 anschließend ein Bash-Skript für den Container aus und verknüpfen Sie das Arbeitsverzeichnis mit einem neuen Unterverzeichnis im Home-Verzeichnis von Bob:

docker run --rm -it -v $(pwd):/home/bob/subdir test 

Wem gehört der Inhalt von subdir auf dem Container? 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 Hostcomputer außerhalb des Containers sehen wir, dass unser ursprünglicher Benutzer immer noch den Dockerfile besitzt. Versuchen wir, den Besitz des Ausgangsverzeichnisses von bob zu reparieren. 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 führen wir nun ls -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 jedes Basisverzeichnis zu erstellen, das dem ersten Nicht-Root-Benutzer gehört (auch wenn dieser Benutzer bei einem früheren Benutzer deklariert wurde) Bild). Ebenso ist dieser erste Benutzer derjenige, der den gleichen Eigentumsrechten entspricht wie mein Privatbenutzer.

Frage 1 Ist das richtig? Kann mich jemand auf eine Dokumentation dazu hinweisen, ich vermute nur aufgrund des obigen Experiments.

Frage 2: Vielleicht liegt das nur daran, dass beide den gleichen numerischen Wert im Kernel haben und wenn ich auf einem System teste, auf dem mein Heimanwender nicht die ID 1000 Hat, werden Berechtigungen erteilt in jedem Fall geändert?

Frage: Die eigentliche Frage ist natürlich: 'Was mache ich dagegen?' Wenn bob auf dem angegebenen Hostcomputer als bob angemeldet ist, sollte er den Container als bob ausführen können und unter seinem Hostkonto keine geänderten Dateiberechtigungen haben. So wie es aussieht, muss er den Container tatsächlich als Benutzer docker ausführen, um zu vermeiden, dass sein Konto geändert wird.

Ich höre dich fragen Warum habe ich überhaupt so eine seltsame Dockerfile? . Ich frage mich auch manchmal. Ich schreibe einen Container für eine Webanwendung (RStudio-Server), der es verschiedenen Benutzern ermöglicht, sich anzumelden. Dabei werden einfach die Benutzernamen und Anmeldeinformationen des Linux-Computers als gültige Benutzernamen verwendet. Dies bringt mir die vielleicht ungewöhnliche Motivation, mehrere Benutzer anlegen zu wollen. Ich kann das umgehen, indem ich den Benutzer nur zur Laufzeit erstelle und alles in Ordnung ist. Ich verwende jedoch ein Basis-Image, das einen einzelnen Benutzer docker hinzugefügt hat, damit es interaktiv verwendet werden kann, ohne als Root ausgeführt zu werden (gemäß der bewährten Methode). Dies ruiniert alles, da dieser Benutzer der erste Benutzer wird und letztendlich alles besitzt, sodass versucht wird, sich anzumelden, da andere Benutzer fehlschlagen (die App kann aufgrund dessen nicht gestartet werden) Schreibrechte fehlen). Nachdem das Startskript chown ausgeführt wurde, wird dieses Problem zuerst behoben, jedoch auf Kosten verknüpfter Volumes, die Berechtigungen ändern (offensichtlich nur ein Problem, wenn wir Volumes verknüpfen).

63
cboettig

Ist das korrekt? Kann mich jemand auf eine Dokumentation dazu hinweisen, ich vermute nur aufgrund des obigen Experiments.

Vielleicht liegt das nur daran, dass beide den gleichen numerischen Wert im Kernel haben und wenn ich auf einem System teste, auf dem mein Heimanwender nicht die ID 1000 hat, werden die Berechtigungen in jedem Fall geändert?

Lesen Sie info coreutils 'chown invocation', Um eine bessere Vorstellung davon zu erhalten, wie Dateiberechtigungen/-besitz funktionieren.

Grundsätzlich ist jedoch an jede Datei auf Ihrem Computer eine Reihe von Bits angeheftet, mit denen die Berechtigungen und der Besitz definiert werden. Wenn Sie eine Datei chown, setzen Sie nur diese Bits.

Wenn Sie eine Datei mit dem Benutzernamen oder Gruppennamen chown an einen bestimmten Benutzer/eine bestimmte Gruppe senden, sucht chown in /etc/passwd Nach dem Benutzernamen und /etc/group Nach dem Gruppe, um zu versuchen, den Namen einer ID zuzuordnen. Wenn der Benutzername/Gruppenname in diesen Dateien nicht vorhanden ist, schlägt chown fehl.

[email protected]:/test# touch test
[email protected]:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
[email protected]:/test# chown test:test test
chown: invalid user: 'test:test'

Sie können jedoch eine Datei mit beliebigen IDs chown erstellen (natürlich innerhalb einiger positiver ganzzahliger Obergrenzen), unabhängig davon, ob ein Benutzer/eine Gruppe mit diesen IDs auf Ihrem Computer vorhanden ist oder nicht.

[email protected]:/test# chown 5000:5000 test
[email protected]:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

Die UID- und GID-Bits werden für die Datei selbst festgelegt. Wenn Sie diese Dateien in Ihren Docker-Container einbinden, hat die Datei dieselbe Eigentümer-/Gruppen-UID wie auf dem Host, wird jedoch jetzt /etc/passwd Zugeordnet. im Container, der wahrscheinlich ein anderer Benutzer sein wird, es sei denn, er gehört root (UID 0).

Die eigentliche Frage ist natürlich: Was mache ich dagegen? Wenn Bob auf dem angegebenen Host-Computer als Bob angemeldet ist, sollte er den Container als Bob ausführen können und unter seinem Host-Konto keine geänderten Dateiberechtigungen haben. So wie es aussieht, muss er den Container tatsächlich als Benutzerdock ausführen, um zu vermeiden, dass sein Konto geändert wird.

Anscheinend müssen Sie bei Ihrer aktuellen Konfiguration sicherstellen, dass Ihre UIDs> Benutzernamen in /etc/passwd Auf Ihrem Host mit Ihren UIDs> Benutzernamen in Ihren Containern /etc/passwd Übereinstimmen, wenn Sie dies tun möchten mit Ihrem gemounteten Benutzerverzeichnis als derselbe Benutzer interagieren, der auf dem Host angemeldet ist.

Mit useradd -u xxxx Können Sie einen Benutzer mit einer bestimmten Benutzer-ID anlegen. Buuuut, das scheint eine unordentliche Lösung zu sein ...

Möglicherweise müssen Sie eine Lösung finden, die das Basisverzeichnis eines Host-Benutzers nicht bereitstellt.

25
Chris McKinnel

Zwei Möglichkeiten habe ich gefunden:

CHOWN all die Dinge (nach deiner Arbeit)

Ich habe docker run -v `pwd`/shared:/shared image Erstellt, und der Container hat Dateien in pwd/shared Erstellt, deren Eigentümer der Docker-Prozess ist. /shared Ist jedoch immer noch mein Eigentum. Also mache ich das im Docker-Prozess

chown -R `stat -c "%u:%g" /shared` /shared

stat -c "%u:%g" /shared Gibt in meinem Fall 1000:1000 Als uid:gid Meines Benutzers zurück. Obwohl sich im Docker-Container kein Benutzer 1000 Befindet, ist die ID vorhanden (und stat /shared Sagt nur "unbekannt", wenn Sie nach dem Benutzernamen fragen).

Wie auch immer, chown überträgt gehorsam das Eigentum an den Inhalten von /shared Auf 1000:1000 (Was, soweit es betrifft, nicht existiert, aber außerhalb des Containers, ich bin es ). Also besitze ich jetzt alle Dateien. Der Container kann weiterhin Änderungen vornehmen, wenn er dies wünscht, da es sich aus seiner Sicht um root handelt.

Und alles ist gut mit der Welt.

docker run -u, Damit alle erstellten Dateien automatisch den richtigen Eigentümer haben

Eine andere Möglichkeit, dies zu tun, ist das Flag -u Beim Ausführen des Dockers.

docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash

Auf diese Weise lautet der Docker-Benutzer im Container youruid:yourgid.

Allerdings: Dies bedeutet, dass Sie Ihre Root-Berechtigung innerhalb des Containers aufgeben müssen (apt-get install Usw.). Es sei denn, Sie erstellen einen Benutzer mit dieser neuen Benutzer-ID und fügen ihn der Gruppe root hinzu.

54
Jared Forsyth

So kam ich in diesem Beitrag auf die Frage, wie ich den Besitz aller Dateien (die root gehören), 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 zu laufen, daher kann ich -u nicht für Docker-Run verwenden.

Ich bin nicht stolz auf das, was ich getan habe, aber am Ende meines Bash-Skripts habe ich Folgendes hinzugefügt:

docker run --rm -it \
    --entrypoint /bin/sh \
    -e Host_UID=`id -u` \
    -v ${Host_FOLDER_OWNED_BY_ROOT}:/tmp \
    Alpine:latest \
    -c 'chown -R ${Host_UID}:${Host_UID} /tmp/'

Lassen Sie uns einige der Zeilen aufschlüsseln:

  • Führen Sie/bin/sh im Container aus:

--Eingabepunkt/bin/sh

  • Übergeben Sie die UID des aktuellen Benutzers als Umgebungsvariable an den Container:

-e Host_UID = `id -u`

  • Mounten Sie den Ordner, den Sie wieder besitzen möchten, an Ihren Benutzer (, der mit Dateien gefüllt ist, die root gehören und die vom vorherigen Container ausgegeben wurden, der als root ausgeführt wurde . ), unter dem /tmp:

-v $ {Host_FOLDER_OWNED_BY_ROOT}:/tmp

  • Führen Sie chown rekursiv mit der UID des Host-Benutzers über das Zielverzeichnis aus (eingehängt in den Container in /tmp):

-c 'chown -R $ {Host_UID}: $ {Host_UID}/tmp /'

Auf diese Weise habe ich die Dateien meinem 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.

2
BBerastegui