MISE À JOUR 2016-03-02 : Depuis Docker 1.9.0, Docker a nommé des volumes qui remplacent les conteneurs de données uniquement . La réponse ci-dessous, ainsi que mon article de blog lié, a toujours de la valeur dans le sens de penser aux données à l'intérieur de Docker, mais envisagez d'utiliser des volumes nommés pour implémenter le modèle décrit ci-dessous plutôt que des conteneurs de données.
Je pense que la manière canonique de résoudre ce problème consiste à utiliser des conteneurs de données uniquement . Avec cette approche, tous les accès aux données de volume se font via des conteneurs qui utilisent -volumes-from
le conteneur de données, donc l'hôte uid / gid n'a pas d'importance.
Par exemple, un cas d'utilisation donné dans la documentation est la sauvegarde d'un volume de données. Pour ce faire, un autre conteneur est utilisé pour effectuer la sauvegarde via tar
, et il l'utilise également -volumes-from
pour monter le volume. Je pense donc que le point clé de grok est: plutôt que de penser à comment accéder aux données sur l'hôte avec les autorisations appropriées, pensez à faire tout ce dont vous avez besoin - sauvegardes, navigation, etc. - via un autre conteneur . Les conteneurs eux-mêmes doivent utiliser des uid / gids cohérents, mais ils n'ont pas besoin d'être mappés à quoi que ce soit sur l'hôte, restant ainsi portables.
C'est relativement nouveau pour moi aussi, mais si vous avez un cas d'utilisation particulier, n'hésitez pas à commenter et j'essaierai de développer la réponse.
MISE À JOUR : Pour le cas d'utilisation donné dans les commentaires, vous pourriez avoir une imagesome/graphite
pour exécuter le graphite et une image some/graphitedata
comme conteneur de données. Donc, en ignorant les ports et autres, l' Dockerfile
image some/graphitedata
est quelque chose comme:
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"]
Générez et créez le conteneur de données:
docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata
le some/graphite
Dockerfile devrait également obtenir le même uid / gids, il pourrait donc ressembler à ceci:
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"]
Et il serait exécuté comme suit:
docker run --volumes-from=graphitedata some/graphite
Ok, maintenant cela nous donne notre conteneur de graphite et le conteneur de données uniquement associé avec le bon utilisateur / groupe (notez que vous pouvez également réutiliser le some/graphite
conteneur pour le conteneur de données, en remplaçant l'entrée / cmd lors de son exécution, mais en les ayant comme images distinctes IMO est plus clair).
Maintenant, disons que vous souhaitez modifier quelque chose dans le dossier de données. Donc, plutôt que de lier le montage du volume à l'hôte et de le modifier, créez un nouveau conteneur pour faire ce travail. Permet de l'appeler some/graphitetools
. Permet également de créer l'utilisateur / groupe approprié, tout comme l' some/graphite
image.
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"]
Vous pouvez rendre ce SEC en héritant de some/graphite
ousome/graphitedata
dans le Dockerfile, ou au lieu de créer une nouvelle image, réutilisez simplement l'une des images existantes (en remplaçant le point d'entrée / cmd si nécessaire).
Maintenant, vous exécutez simplement:
docker run -ti --rm --volumes-from=graphitedata some/graphitetools
et alors vi /data/graphite/whatever.txt
. Cela fonctionne parfaitement car tous les conteneurs ont le même utilisateur de graphite avec uid / gid correspondant.
Comme vous ne montez jamais à /data/graphite
partir de l'hôte, vous ne vous souciez pas de la façon dont l'hôte uid / gid est mappé à l'uid / gid défini à l'intérieur des conteneurs graphite
et graphitetools
. Ces conteneurs peuvent désormais être déployés sur n'importe quel hôte et continueront de fonctionner parfaitement.
La chose graphitetools
intéressante à ce sujet est qu'il pourrait avoir toutes sortes d'utilitaires et de scripts utiles, que vous pouvez désormais également déployer de manière portable.
MISE À JOUR 2 : Après avoir écrit cette réponse, j'ai décidé d'écrire un article de blog plus complet sur cette approche. J'espère que ça aide.
MISE À JOUR 3 : J'ai corrigé cette réponse et ajouté plus de détails. Il contenait auparavant des hypothèses incorrectes sur la propriété et les perms - la propriété est généralement attribuée au moment de la création du volume, c'est-à-dire dans le conteneur de données, car c'est à ce moment que le volume est créé. Voir ce blog . Ce n'est pas une exigence cependant - vous pouvez simplement utiliser le conteneur de données comme "référence / handle" et définir la propriété / les autorisations dans un autre conteneur via chown dans un point d'entrée, qui se termine par gosu pour exécuter la commande en tant qu'utilisateur correct. Si quelqu'un est intéressé par cette approche, veuillez commenter et je peux fournir des liens vers un exemple utilisant cette approche.