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?

16voto

Leo Gallucci Punkte 15714

Ok, dies wird jetzt unter docker issue #7198 verfolgt

Im Moment gehe ich damit um, indem ich Ihre zweite Option verwende:

Die Benutzer aus dem Host in den Container mappen

Dockerfile

#=======
# Benutzer
#=======
# TODO: Ich weiß nicht, wie man das Hardcodieren von uid & gid beheben kann, spezifisch für die Docker-Host-Maschine
RUN (adduser --system --uid=1000 --gid=1000 \
        --home /home/myguestuser --shell /bin/bash myguestuser)

CLI

# DIR_HOST und DIR_GUEST gehören zu uid:gid 1000:1000
docker run -d -v ${DIR_HOST}:${DIR_GUEST} elgalu/myservice:latest

UPDATE Ich neige derzeit mehr zu Hamy Antwort

7voto

Anton Krug Punkte 1345

Mein Ansatz besteht darin, die aktuelle UID/GID zu erkennen, dann solch einen Benutzer/Gruppe innerhalb des Containers zu erstellen und das Skript unter ihm auszuführen. Dadurch werden alle von ihm erstellten Dateien dem Benutzer auf dem Host entsprechen:

# Ermitteln Sie den Speicherort dieses Skripts, unabhhängig davon, in welchem Ordner Sie sich befinden, dies kann zwischen Shell-Umgebungen unterschiedlich sein. Stellen Sie also sicher, dass Sie bash ausführen
LOCAL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Aktuelle IDs abrufen
USER_ID=$(id -u)
GROUP_ID=$(id -g)

echo "Mounte $LOCAL_DIR in Docker und passe die Host-IDs ($USER_ID:$GROUP_ID) im Container an."

docker run -v $LOCAL_DIR:/host_mount -i debian:9.4-slim bash -c "set -euo pipefail && groupadd -r -g $GROUP_ID lowprivgroup && useradd -u $USER_ID lowprivuser -g $GROUP_ID && cd /host_mount && su -c ./runMyScriptAsRegularUser.sh lowprivuser"

5voto

umount Punkte 121

Für eine sichere und Wechsel-Wurzel für Docker-Container und Docker-Host versuchen Sie die Optionen --uidmap und --private-uids zu verwenden

https://github.com/docker/docker/pull/4572#issuecomment-38400893

Sie können auch mehrere Fähigkeiten (--cap-drop) im Docker-Container aus Sicherheitsgründen entfernen

http://opensource.com/business/14/9/security-for-docker

UPDATE Die Unterstützung sollte in docker > 1.7.0 kommen

UPDATE Version 1.10.0 (2016-02-04) fügt das Flag --userns-remap hinzu https://github.com/docker/docker/blob/master/CHANGELOG.md#security-2

5voto

Ethan Punkte 1057

Hier ist ein Ansatz, der immer noch einen reinen Datencontainer verwendet, aber nicht erfordert, dass er mit dem Anwendungscontainer synchronisiert wird (hinsichtlich der gleichen uid/gid).

Vermutlich möchten Sie eine App im Container als Nicht-Root-$USER ohne Login-Shell ausführen.

Im Dockerfile:

RUN useradd -s /bin/false meinbenutzer

# Setze Umgebungsvariablen
ENV VOLUME_ROOT /data
ENV USER meinbenutzer

...

ENTRYPOINT ["./entrypoint.sh"]

Dann in der entrypoint.sh:

chown -R $USER:$USER $VOLUME_ROOT
su -s /bin/bash - $USER -c "cd $repo/build; $@"

3voto

Eduardo Cuomo Punkte 15791

Basenbild

Verwenden Sie dieses Bild: https://hub.docker.com/r/reduardo7/docker-host-user

oder

Wichtig: dies zerstört die Container-Portabilität über Hosts hinweg.

1) init.sh

#!/bin/bash

if ! getent passwd $DOCKDEV_USER_NAME > /dev/null
  then
    echo "Benutzer $DOCKDEV_USER_NAME:$DOCKDEV_GROUP_NAME wird erstellt"
    groupadd --gid $DOCKDEV_GROUP_ID -r $DOCKDEV_GROUP_NAME
    useradd --system --uid=$DOCKDEV_USER_ID --gid=$DOCKDEV_GROUP_ID \
        --home-dir /home --password $DOCKDEV_USER_NAME $DOCKDEV_USER_NAME
    usermod -a -G sudo $DOCKDEV_USER_NAME
    chown -R $DOCKDEV_USER_NAME:$DOCKDEV_GROUP_NAME /home
  fi

sudo -u $DOCKDEV_USER_NAME bash

2) Dockerfile

FROM ubuntu:latest
# Volumes
    VOLUME ["/home/data"]
# Dateien kopieren
    COPY /home/data/init.sh /home
# Init
    RUN chmod a+x /home/init.sh

3) run.sh

#!/bin/bash

DOCKDEV_VARIABLES=(\
  DOCKDEV_USER_NAME=$USERNAME\
  DOCKDEV_USER_ID=$UID\
  DOCKDEV_GROUP_NAME=$(id -g -n $USERNAME)\
  DOCKDEV_GROUP_ID=$(id -g $USERNAME)\
)

cmd="docker run"

if [ ! -z "${DOCKDEV_VARIABLES}" ]; then
  for v in ${DOCKDEV_VARIABLES[@]}; do
    cmd="${cmd} -e ${v}"
  done
fi

# /home/usr/data enthält init.sh
$cmd -v /home/usr/data:/home/data -i -t my-image /home/init.sh

4) Erstellen mit docker

4) Los geht's!

sh run.sh

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