2016-02-09 7 views
48

Im Andockfenster haben Dateien, die in Containern erstellt werden, oft unberechenbare Eigenschaften, wenn sie vom Host aus untersucht werden. Der Besitzer der Dateien auf einem Volume ist standardmäßig root (uid 0). Sobald jedoch nicht root-Benutzerkonten in den Container eingebunden und in das Dateisystem geschrieben werden, werden die Besitzer aus der Hostperspektive mehr oder weniger zufällig.Docker und --userns-remap, wie Volume Berechtigungen verwalten, um Daten zwischen Host und Container zu teilen?

Es ist ein Problem, wenn Sie mit dem gleichen Benutzerkonto, das die docker-Befehle aufruft, auf Volumendaten vom Host zugreifen müssen.

Typische Abhilfen

  • zwingt Benutzer UIDs bei der Erstellung in Dockerfiles (nicht portabel)
  • die UID des Host-Benutzer an den docker run Befehl als eine Umgebungsvariable vorbei und dann einige chown Befehle ausführen zu werden die Volumes in einem Einstiegsskript.

Diese beiden Lösungen können einige Kontrolle über die tatsächlichen Berechtigungen außerhalb des Containers geben.

Ich erwartete User-Namespaces, um die endgültige Lösung für dieses Problem zu sein. Ich habe einige Tests mit der kürzlich veröffentlichten Version 1.10 und --userns-remap set auf meinem Desktop-Account durchgeführt. Ich bin mir jedoch nicht sicher, ob dies den Besitz von Dateien auf gemounteten Volumes erleichtern kann, ich befürchte, dass es tatsächlich das Gegenteil sein könnte.

Angenommen, fange ich an diesem Basiscontainer

docker run -ti -v /data debian:jessie /bin/bash 
echo 'hello' > /data/test.txt 
exit 

Und dann den Inhalt aus dem Host inspizieren:

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 Zahl '100000' ist eine Unter UID meines Host-Benutzer, aber seit Es entspricht nicht der UID meines Benutzers, ich kann die test.txt trotzdem nicht ohne Berechtigungen bearbeiten. Dieser Subbenutzer scheint keine Affinität zu meinem eigentlichen regulären Benutzer außerhalb von Docker zu haben. Es ist nicht zugeordnet.

Die zuvor erwähnten Problemumgehungen, die aus dem Ausrichten von UIDs zwischen dem Host und dem Container bestanden, funktionieren aufgrund der Zuordnung UID->sub-UID im Namespace nicht mehr.

Dann gibt es eine Möglichkeit zum Ausführen von docker mit Benutzer-Namespace aktiviert (für eine verbesserte Sicherheit), während es weiterhin für den Host-Benutzer Docker ermöglicht, die Dateien auf Volumes besitzen zu besitzen?

+0

Ich denke, dass, wenn Sie Volumes zwischen dem Host und dem Container freigeben, Benutzer Namespaces sind * nicht * wird Teil der Lösung sein. Ihre zweite Option ("Übergabe der UID des Host-Benutzers an den Befehl docker run als Umgebungsvariable und Ausführung einiger chown-Befehle auf den Volumes in einem Einstiegsskript") ist wahrscheinlich die beste Lösung. – larsks

+3

Docker selbst scheint nicht zu ermutigen, Host-mounted beschreibbare Volumes zu verwenden. Da ich keinen Cloud-Dienst betreibe und nur meine eigenen vertrauenswürdigen Bilder verwende, frage ich mich jetzt, ob der Sicherheitsvorteil von Benutzer NS es wert ist, so viel Bequemlichkeit zu opfern. –

+0

@ StéphaneC. Hast du vielleicht einen besseren Ansatz gefunden? – EightyEight

Antwort

31

Wenn Sie Benutzer und Gruppen im Voraus festlegen können, ist es möglich, UIDs und GIDs auf eine bestimmte Art und Weise zuzuweisen, sodass Host-Benutzer Namespace-Benutzern in Containern entsprechen.

Hier ist ein Beispiel (Ubuntu 14.04, Docker 1.10):

  1. Erstellen Sie einige Benutzer mit festen numerischen IDs:

    useradd -u 5000 ns1 
    
    groupadd -g 500000 ns1-root 
    groupadd -g 501000 ns1-user1 
    
    useradd -u 500000 -g ns1-root ns1-root 
    useradd -u 501000 -g ns1-user1 ns1-user1 -m 
    
  2. manuell bearbeiten automatisch generierte untergeordnete ID-Bereiche in /etc/subuid und /etc/subgid Dateien:

    ns1:500000:65536 
    

    (beachten Sie, dass sind keine Datensätze für ns1-root und ns1-user1 aufgrund MAX_UID und MAX_GID lim seine in /etc/login.defs)

  3. Benutzer Namespaces in /etc/default/docker Enable:

    DOCKER_OPTS="--userns-remap=ns1" 
    

    Restart-Daemon service docker restart sicher /var/lib/docker/500000.500000 Verzeichnis erstellt wird.

    nun in Container haben Sie root und user1, und auf die Host - ns1-root und ns1-user1, mit passender IDs

    UPDATE:, dass nicht-root zu gewährleisten Benutzer-IDs in Containern festgelegt hat (zB user1 1000: 1000), erstellen Sie diese explizit während der Image-Erstellung.

Probefahrt:

  1. Bereiten Sie ein Volumen Verzeichnis

    mkdir /vol1 
    chown ns1-root:ns1-root /vol1 
    
  2. Probieren Sie es aus einem Behälter

    docker run --rm -ti -v /vol1:/vol1 busybox sh 
    echo "Hello from container" > /vol1/file 
    exit 
    
  3. Versuchen vom Host

    passwd ns1-root 
    login ns1-root 
    cat /vol1/file 
    echo "can write" >> /vol1/file 
    

nicht tragbar und sieht aus wie ein Hack, aber funktioniert.

+2

Sehr interessant und verdient +1. Sie müssen jedoch sicherstellen, dass Benutzer1 in Ihrem Image die UID 1000 zugewiesen hat. Andernfalls können Sie nicht sicher sein, dass auf dem Host die UID 501000 empfangen wird. Btw sind wir absolut sicher, dass die Formel immer "subUID untere Grenze + UID im Bild" ist, wenn wir viele verschiedene Bilder mit einem Benutzer laufen lassen, dessen ID auf 1000 gesetzt ist? –

+0

@ StéphaneC. Guter Punkt! Es wurde eine Notiz zum Fixieren von IDs in Bildern hinzugefügt. Was die Formel betrifft, werde ich weiter mit meinen eigenen Bildern experimentieren und die Antwort aktualisieren, wenn Sie etwas finden. – amartynov

+0

Wenn Sie Benutzer und Gruppen manuell in Host und in Containern anordnen, brauchen Sie wirklich die Funktion "User Namespace"? – Tristan

2

Sie können Berechtigungsprobleme vermeiden, indem Sie die docker cp command verwenden.

Das Eigentumsrecht wird auf den Benutzer und die primäre Gruppe am Ziel festgelegt. Zum Beispiel werden Dateien, die in einen Container kopiert wurden, mit UID:GID des Root-Benutzers erstellt. Dateien, die auf den lokalen Computer kopiert wurden, werden mit der UID:GID des Benutzers erstellt, der den Befehl docker cp aufgerufen hat.

Hier ist dein Beispiel docker cp verwenden geschaltet:

$ docker run -ti -v /data debian:jessie /bin/bash 
[email protected]:/# echo 'hello' > /data/test.txt 
[email protected]:/# exit 
exit 
$ docker volume ls 
DRIVER    VOLUME NAME 
local    f073d0e001fb8a95ad8d919a5680e72b21a457f62a40d671b63c62ae0827bf93 
$ sudo ls -l /var/lib/docker/100000.100000/volumes/f073d0e001fb8a95ad8d919a5680e72b21a457f62a40d671b63c62ae0827bf93/_data 
total 4 
-rw-r--r-- 1 100000 100000 6 Oct 6 10:34 test.txt 
$ docker ps -a 
CONTAINER ID  IMAGE    COMMAND    CREATED    STATUS       PORTS    NAMES 
e33bb735a70f  debian:jessie  "/bin/bash"   About a minute ago Exited (0) About a minute ago      determined_hypatia 
$ docker cp determined_hypatia:/data/test.txt . 
$ ls -l test.txt 
-rw-r--r-- 1 don don 6 Oct 6 10:34 test.txt 
$ cat test.txt 
hello 
$ 

Wenn Sie jedoch nur Dateien aus einem Behälter lesen möchten, müssen Sie auf den genannten Datenträger nicht benötigen.In diesem Beispiel wird eine benannte Container anstelle eines benannten Volumen:

$ docker run -ti --name sandbox1 debian:jessie /bin/bash 
[email protected]:/# echo 'howdy' > /tmp/test.txt 
[email protected]:/# exit 
exit 
$ docker cp sandbox1:/tmp/test.txt . 
$ ls -l test.txt 
-rw-r--r-- 1 don don 6 Oct 6 10:52 test.txt 
$ cat test.txt 
howdy 
$ 

Ich nannte Mengen nützlich finden, wenn ich Dateien in einen Container zu kopieren, wie in this question beschrieben.

+0

Aber "Docker cp" beinhaltet das Duplizieren von Daten. Darüber hinaus legt das Dokument beim Kopieren von Daten in einen Container Ownership-IDs entsprechend dem Root-Benutzer fest, bei dem es sich häufig nicht um das Konto handelt, auf dem die containerisierte App ausgeführt wird. Ich sehe nicht, wie es unser Problem löst. –

+0

Sie haben Recht, @ Stéphane, es beinhaltet das Duplizieren von Daten. Wenn Sie jedoch Kopien der Dateien erstellen, können Sie auf dem Host und im Container unterschiedliche Eigentumsrechte und Berechtigungen zuweisen. 'docker cp' gibt Ihnen die volle Kontrolle über den Dateibesitz, wenn Sie ein tar-Archiv in oder aus einem Container streamen. Sie können die Eigentumsrechte und Berechtigungen für jeden Eintrag in der TAR-Datei beim Streamen anpassen, sodass Sie nicht auf den Benutzer root beschränkt sind. –

Verwandte Themen