ACTUALIZACIÓN 2016-03-02 : A partir de Docker 1.9.0, Docker ha nombrado volúmenes que reemplazan los contenedores de solo datos . La respuesta a continuación, así como mi publicación de blog vinculada, todavía tiene valor en el sentido de cómo pensar sobre los datos dentro de la ventana acoplable, pero considere usar volúmenes con nombre para implementar el patrón que se describe a continuación en lugar de los contenedores de datos.
Creo que la forma canónica de resolver esto es mediante el uso de contenedores solo de datos . Con este enfoque, todo el acceso a los datos del volumen es a través de contenedores que usan -volumes-from
el contenedor de datos, por lo que el host uid / gid no importa.
Por ejemplo, un caso de uso dado en la documentación es hacer una copia de seguridad de un volumen de datos. Para hacer esto, se usa otro contenedor para hacer la copia de seguridad a través tar
, y también se usa -volumes-from
para montar el volumen. Entonces, creo que el punto clave para asimilar es: en lugar de pensar en cómo obtener acceso a los datos en el host con los permisos adecuados, piense en cómo hacer lo que necesite: copias de seguridad, navegación, etc., a través de otro contenedor . Los contenedores en sí mismos necesitan usar uid / gids consistentes, pero no necesitan mapearse a nada en el host, por lo que permanecen portátiles.
Esto también es relativamente nuevo para mí, pero si tiene un caso de uso en particular, no dude en comentar y trataré de ampliar la respuesta.
ACTUALIZACIÓN : para el caso de uso dado en los comentarios, es posible que tenga una imagen some/graphite
para ejecutar grafito y una imagen some/graphitedata
como contenedor de datos. Entonces, ignorando los puertos y demás, la Dockerfile
imagen some/graphitedata
es algo así como:
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"]
Construye y crea el contenedor de datos:
docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata
El some/graphite
Dockerfile también debería obtener los mismos uid / gids, por lo tanto, podría verse así:
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"]
Y se ejecutaría de la siguiente manera:
docker run --volumes-from=graphitedata some/graphite
Ok, ahora eso nos da nuestro contenedor de grafito y el contenedor de solo datos asociados con el usuario / grupo correcto (tenga en cuenta que también puede reutilizar el some/graphite
contenedor para el contenedor de datos, anulando el entradapoing / cmd cuando lo ejecute, pero tenerlos como imágenes separadas IMO es más claro).
Ahora, supongamos que desea editar algo en la carpeta de datos. Entonces, en lugar de vincular el montaje del volumen al host y editarlo allí, cree un nuevo contenedor para hacer ese trabajo. Vamos a llamarlo some/graphitetools
. También creemos el usuario / grupo apropiado, al igual que la some/graphite
imagen.
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"]
Puede hacer esto SECO heredando de some/graphite
o some/graphitedata
en el Dockerfile, o en lugar de crear una nueva imagen, simplemente reutilice una de las existentes (anulando el punto de entrada / cmd según sea necesario).
Ahora, simplemente ejecutas:
docker run -ti --rm --volumes-from=graphitedata some/graphitetools
y luego vi /data/graphite/whatever.txt
. Esto funciona perfectamente porque todos los contenedores tienen el mismo usuario de grafito con uid / gid coincidentes.
Como nunca monta /data/graphite
desde el host, no le importa cómo el uid / gid del host se asigna al uid / gid definido dentro de los contenedores graphite
y graphitetools
. Esos contenedores ahora se pueden implementar en cualquier host y continuarán funcionando perfectamente.
Lo bueno de esto es que graphitetools
podría tener todo tipo de utilidades y scripts útiles, que ahora también puede implementar de manera portátil.
ACTUALIZACIÓN 2 : Después de escribir esta respuesta, decidí escribir una publicación de blog más completa sobre este enfoque. Espero que ayude.
ACTUALIZACIÓN 3 : Corrigí esta respuesta y agregué más detalles. Anteriormente contenía algunas suposiciones incorrectas sobre la propiedad y los permisos: la propiedad generalmente se asigna en el momento de la creación del volumen, es decir, en el contenedor de datos, porque es cuando se crea el volumen. Ver este blog . Sin embargo, esto no es un requisito: puede usar el contenedor de datos como "referencia / identificador" y establecer la propiedad / permisos en otro contenedor a través de chown en un punto de entrada, que termina con gosu para ejecutar el comando como el usuario correcto. Si alguien está interesado en este enfoque, comente y puedo proporcionar enlaces a una muestra utilizando este enfoque.