438 Stimmen

Was ist der (beste) Weg, Berechtigungen für gemeinsam genutzte Docker-Volumes zu verwalten?

Ich habe eine Weile mit Docker experimentiert und stoße immer wieder auf das gleiche Problem im Umgang mit persistenten Daten.

Ich erstelle mein Dockerfile und exponiere ein Volume oder verwende --volumes-from, um einen Host-Ordner in meinem Container einzubinden.

Welche Berechtigungen soll ich dem gemeinsam genutzten Volume auf dem Host zuweisen?

Ich kann mir zwei Optionen vorstellen:

  • Bisher habe ich allen Lese- und Schreibzugriff gewährt, damit ich vom Docker-Container aus in den Ordner schreiben kann.

  • Die Benutzer vom Host in den Container mappen, um genauere Berechtigungen zu vergeben. Ich bin mir jedoch nicht sicher, ob dies möglich ist und habe dazu nicht viel gefunden. Bisher kann ich nur den Container als bestimmten Benutzer ausführen: docker run -i -t -user="meinbenutzer" postgres, aber dieser Benutzer hat eine andere UID als mein Host-meinbenutzer, sodass die Berechtigungen nicht funktionieren. Außerdem bin ich mir unsicher, ob das Zuordnen der Benutzer Sicherheitsrisiken birgt.

Gibt es andere Alternativen?

Wie geht ihr mit diesem Problem um?

1voto

Varun Garg Punkte 2156

Letztendlich habe ich ein Skript geschrieben, das ausgewählte Benutzer-IDs und Gruppen-IDs von Host zu Container synchronisiert, indem usermod und groupmod verwendet werden.

Docker Compose:

volumes:
    - /etc/passwd:/etc/passwd.src:ro
    - /etc/group:/etc/group.src:ro
environment:
    - host_users=www-data,mysql
    - host_groups=www-data,mysql,staff

Skript:

#!/bin/bash

for user in ${host_users//,/ }; do
    echo "Benutzer $user synchronisieren" 
    uid=$(grep "^$user:" /etc/passwd.src | awk -F: '{print $3}')
    if [ ! -z "$uid" ]; then
        RET=1
        while [[ RET -ne 0 ]]; do
            usermod -u $uid $user
            RET=$?
            if [[ RET -eq 4 ]]; then
                existing_user=$(id $uid -u)
                existing_user_new_id=$(shuf -i 101-498 -n 1)
                usermod -u $existing_user_new_id $existing_user
                sleep 1
            elif [[ RET -ne 0 ]]; then
                sleep 5
            fi
        done
    else
        echo "Benutzer $user synchronisieren, nicht im Host gefunden" 
    fi
done

for group in ${host_groups//,/ }; do
    echo "Gruppe $group synchronisieren" 
    gid=$(grep "^$group:" /etc/group.src | awk -F: '{print $3}')
    if [ ! -z "$gid" ]; then
        RET=1
        while [[ RET -ne 0 ]]; do
            groupmod -g $gid $group
            RET=$?
            if [[ RET -eq 4 ]]; then
                existing_group=$(getent group $gid | awk -F: '{print $1}')
                existing_group_new_id=$(shuf -i 1-32766 -n 1)
                groupmod -g $existing_group_new_id $existing_group
                sleep 1
            elif [[ RET -ne 0 ]]; then
                sleep 5
            fi
        done
    else
        echo "Gruppe $group synchronisieren, nicht im Host gefunden" 
    fi

Auch hier verfügbar: https://github.com/Varun-garg/docker-sync-ids

0voto

Praveen Muthusamy Punkte 174

Um den Ordner zwischen dem Docker-Host und dem Docker-Container zu teilen, versuchen Sie den folgenden Befehl

$ docker run -v "$(pwd):$(pwd)" -i -t ubuntu

Der -v Flag bindet das aktuelle Arbeitsverzeichnis in den Container ein. Wenn das Host-Verzeichnis eines bindgebundenen Volumes nicht existiert, wird Docker dieses Verzeichnis automatisch auf dem Host für Sie erstellen,

Allerdings gibt es hier 2 Probleme:

  1. Sie können nicht in das eingebundene Volume schreiben, wenn Sie ein nicht-root Benutzer sind, da die freigegebene Datei von einem anderen Benutzer im Host stammt,
  2. Sie sollten den Prozess innerhalb Ihrer Container nicht als root ausführen, aber selbst wenn Sie als einen fest codierten Benutzer ausführen, wird dieser immer noch nicht dem Benutzer auf Ihrem Laptop/Jenkins entsprechen,

Lösung:

Container: Erstellen Sie einen Benutzer namens 'testuser', standardmäßig wird die Benutzer-ID von 1000 beginnen,

Host: Erstellen Sie eine Gruppe namens 'testgroup' mit der Gruppen-ID 1000 und ändern Sie den Besitzer des Verzeichnisses auf die neue Gruppe (testgroup)

0voto

johnklawlor Punkte 1496

In meinem speziellen Fall habe ich versucht, mein Node-Paket mit dem Node-Docker-Image zu erstellen, damit ich npm nicht auf dem Bereitstellungsserver installieren müsste. Es hat gut funktioniert, bis ich außerhalb des Containers und auf dem Host-Rechner versuchte, eine Datei in das von dem Node-Docker-Image erstellte node_modules-Verzeichnis zu verschieben, wozu mir die Berechtigungen verweigert wurden, da es im Besitz von root war. Mir wurde klar, dass ich dies umgehen konnte, indem ich das Verzeichnis aus dem Container auf den Host-Rechner kopiere. Über Docker-Dokumente...

Dateien, die auf den lokalen Rechner kopiert werden, werden mit der UID:GID des Benutzers erstellt, der den docker cp-Befehl aufgerufen hat.

Dies ist der Bash-Code, den ich verwendet habe, um den Besitz des vom und im Docker-Container erstellten Verzeichnisses zu ändern.

NODE_IMAGE=node_builder
docker run -v $(pwd)/build:/build -w="/build" --name $NODE_IMAGE node:6-slim npm i --production
# node_modules wird von root besessen, also müssen wir es kopieren
docker cp $NODE_IMAGE:/build/node_modules build/lambda
# Sie könnten Probleme haben, das Verzeichnis "node_modules" innerhalb des gemeinsam genutzten Volumens "build" zu entfernen, da es von root besessen ist, also entfernen Sie das Image und seine Volumes
docker rm -vf $NODE_IMAGE || true

Bei Bedarf können Sie das Verzeichnis mit einem zweiten Docker-Container entfernen.

docker run -v $(pwd)/build:/build -w="/build" --name $RMR_IMAGE node:6-slim rm -r node_modules

0voto

Nishant Punkte 18752

Wenn Sie dies für Entwicklung machen, ist eine gute Lösung, bindfs zu verwenden:

  1. Halten Sie den Quellcode im Besitz des Container-Benutzers. (Lassen Sie, wenn möglich, den Container den Quellcode klonen.)
  2. Verwenden Sie bindfs und map den Ordner für den Host-Benutzer.

So sieht meine Docker-Compose-Konfiguration jetzt aus:

project:
  web/src # Der Container kloniert es mit Hilfe von Init-Skripten.
  web/log
  __web__/src # Der Host-Benutzer verwendet dies. Es ist nur ein Bindfs-Spiegel.
  __web__/log

Ich habe über ein Jahr über dieses Problem nachgedacht, und bindfs ist die einfachste Option, auf die ich gestoßen bin. Es entstehen keine Laufzeitkosten abgesehen vom Klonen.

-5voto

Renato Alencar Punkte 93

Wenn Sie Docker Compose verwenden, starten Sie den Container im privilegierten Modus:

wordpress:
    image: wordpress:4.5.3
    restart: always
    ports:
      - 8084:80
    privileged: true

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X