UPDATE 2016-03-02 : Ab Docker 1.9.0 hat Docker Volumes benannt, die Nur-Daten-Container ersetzen . Die folgende Antwort sowie mein verlinkter Blog-Beitrag haben immer noch einen Wert in dem Sinne, wie man über Daten in Docker nachdenkt. Verwenden Sie jedoch benannte Volumes, um das unten beschriebene Muster anstelle von Datencontainern zu implementieren.
Ich glaube, der kanonische Weg, dies zu lösen, ist die Verwendung von Nur-Daten-Containern . Bei diesem Ansatz erfolgt der gesamte Zugriff auf die Volumendaten über Container, die -volumes-from
den Datencontainer verwenden, sodass die Host-UID / GID keine Rolle spielt.
Ein in der Dokumentation angegebener Anwendungsfall ist beispielsweise das Sichern eines Datenvolumens. Zu diesem Zweck wird ein anderer Container verwendet, um die Sicherung über durchzuführen tar
, und er wird auch verwendet -volumes-from
, um das Volume bereitzustellen. Ich denke, der entscheidende Punkt bei grok ist: Anstatt darüber nachzudenken, wie Sie mit den richtigen Berechtigungen auf die Daten auf dem Host zugreifen können, sollten Sie darüber nachdenken, wie Sie alles tun können, was Sie benötigen - Backups, Surfen usw. - über einen anderen Container . Die Container selbst müssen konsistente UID / GIDs verwenden, müssen jedoch nichts auf dem Host zuordnen und bleiben somit portabel.
Dies ist auch für mich relativ neu, aber wenn Sie einen bestimmten Anwendungsfall haben, können Sie dies gerne kommentieren, und ich werde versuchen, die Antwort zu erweitern.
UPDATE : Für den angegebenen Anwendungsfall in den Kommentaren haben Sie möglicherweise ein Bild some/graphite
zum Ausführen von Graphit und ein Bild some/graphitedata
als Datencontainer. Wenn man also Ports und dergleichen ignoriert, ist das Dockerfile
Bild some/graphitedata
so etwas wie:
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
RUN mkdir -p /data/graphite \
&& chown -R graphite:graphite /data/graphite
VOLUME /data/graphite
USER graphite
CMD ["echo", "Data container for graphite"]
Erstellen und erstellen Sie den Datencontainer:
docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata
Das some/graphite
Dockerfile sollte auch die gleiche UID / GID erhalten, daher könnte es ungefähr so aussehen:
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
# ... graphite installation ...
VOLUME /data/graphite
USER graphite
CMD ["/bin/graphite"]
Und es würde wie folgt laufen:
docker run --volumes-from=graphitedata some/graphite
Ok, jetzt erhalten wir unseren Graphitcontainer und den zugehörigen Nur-Daten-Container mit dem richtigen Benutzer / der richtigen Gruppe (beachten Sie, dass Sie den some/graphite
Container auch für den Datencontainer wiederverwenden können, indem Sie den Eintrag / cmd beim Ausführen überschreiben, ihn aber als haben separate Bilder IMO ist klarer).
Angenommen, Sie möchten etwas im Datenordner bearbeiten. Erstellen Sie einen neuen Container, um diese Aufgabe zu erledigen, anstatt das Mounten des Volumes an den Host zu binden und dort zu bearbeiten. Nennen wir es some/graphitetools
. Erstellen wir auch den entsprechenden Benutzer / die entsprechende Gruppe, genau wie das some/graphite
Bild.
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
VOLUME /data/graphite
USER graphite
CMD ["/bin/bash"]
Sie können diesen DRY erstellen, indem Sie von some/graphite
oder some/graphitedata
in der Docker-Datei erben oder anstatt ein neues Image zu erstellen, verwenden Sie einfach eines der vorhandenen (überschreiben Sie den Einstiegspunkt / cmd nach Bedarf).
Jetzt rennst du einfach:
docker run -ti --rm --volumes-from=graphitedata some/graphitetools
und dann vi /data/graphite/whatever.txt
. Dies funktioniert perfekt, da alle Behälter denselben Graphitbenutzer mit passender UID / GID haben.
Da Sie niemals /data/graphite
vom Host aus mounten , ist es Ihnen egal, wie die Host-UID / GID der UID / GID zugeordnet wird, die in den Containern graphite
und definiert ist graphitetools
. Diese Container können jetzt auf jedem Host bereitgestellt werden und funktionieren weiterhin einwandfrei.
Das Schöne daran ist, dass graphitetools
es alle möglichen nützlichen Dienstprogramme und Skripte geben kann, die Sie jetzt auch portabel bereitstellen können.
UPDATE 2 : Nachdem ich diese Antwort geschrieben hatte, beschloss ich, einen vollständigeren Blog-Beitrag über diesen Ansatz zu schreiben . Ich hoffe, es hilft.
UPDATE 3 : Ich habe diese Antwort korrigiert und weitere Details hinzugefügt. Zuvor enthielt es einige falsche Annahmen zu Besitz und Dauerwellen. Der Besitz wird normalerweise zum Zeitpunkt der Datenträgererstellung zugewiesen, dh im Datencontainer, da zu diesem Zeitpunkt der Datenträger erstellt wird. Siehe diesen Blog . Dies ist jedoch keine Voraussetzung - Sie können den Datencontainer einfach als "Referenz / Handle" verwenden und den Besitz / die Dauerwellen in einem anderen Container über chown in einem Einstiegspunkt festlegen, der mit gosu endet, um den Befehl als richtigen Benutzer auszuführen. Wenn sich jemand für diesen Ansatz interessiert, kommentieren Sie ihn bitte und ich kann mit diesem Ansatz Links zu einem Beispiel bereitstellen.