En la ventana acoplable, los archivos creados dentro de los contenedores tienden a tener una propiedad impredecible al inspeccionarlos desde el host. El propietario de los archivos en un volumen es root (uid 0) por defecto, pero tan pronto como las cuentas de usuario no root están involucradas en el contenedor y escriben en el sistema de archivos, los propietarios se vuelven más o menos aleatorios desde la perspectiva del host.
Es un problema cuando necesita acceder a los datos de volumen desde el host utilizando la misma cuenta de usuario que llama a los comandos de la ventana acoplable.
Las soluciones típicas son
- forzar los UID de los usuarios en el momento de la creación en Dockerfiles (no portátil)
- pasar el UID del usuario del host al
docker run
comando como una variable de entorno y luego ejecutar algunoschown
comandos en los volúmenes en un script de punto de entrada.
Ambas soluciones pueden dar cierto control sobre los permisos reales fuera del contenedor.
Esperaba que los espacios de nombres de usuario fueran la solución final a este problema. He ejecutado algunas pruebas con la versión 1.10 publicada recientemente y --userns-remap configurado en mi cuenta de escritorio. Sin embargo, no estoy seguro de que pueda hacer que la propiedad de archivos en volúmenes montados sea más fácil de manejar, me temo que en realidad podría ser lo contrario.
Supongamos que comienzo este contenedor básico
docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit
Y luego inspecciona el contenido del host:
ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/
-rw-r--r-- 1 100000 100000 6 Feb 8 19:43 test.txt
Este número '100000' es un sub-UID de mi usuario de host, pero como no se corresponde con el UID de mi usuario, todavía no puedo editar test.txt sin privilegios. Este subusuario no parece tener ninguna afinidad con mi usuario habitual real fuera de Docker. No está mapeado.
Las soluciones alternativas mencionadas anteriormente en esta publicación, que consistían en alinear los UID entre el host y el contenedor, ya no funcionan debido a la UID->sub-UID
asignación que se produce en el espacio de nombres.
Entonces, ¿hay alguna manera de ejecutar la ventana acoplable con el espacio de nombres de usuario habilitado (para mejorar la seguridad), y al mismo tiempo hacer posible que el usuario host que ejecuta la ventana acoplable posea los archivos generados en los volúmenes?
Respuestas:
Si puede preorganizar usuarios y grupos con anticipación, entonces es posible asignar UID y GID de una manera tan específica para que los usuarios del host se correspondan con los usuarios con espacios de nombres dentro de los contenedores.
Aquí hay un ejemplo (Ubuntu 14.04, Docker 1.10):
Cree algunos usuarios con ID numéricos fijos:
Edite manualmente los rangos de ID subordinados generados automáticamente en archivos
/etc/subuid
y/etc/subgid
:(tenga en cuenta que no hay registros para
ns1-root
yns1-user1
debidoMAX_UID
yMAX_GID
límites en/etc/login.defs
)Habilite los espacios de nombres de usuario en
/etc/default/docker
:Reinicie el demonio
service docker restart
, asegúrese de que/var/lib/docker/500000.500000
se crea el directorio.Ahora, dentro de los contenedores tiene
root
yuser1
, y en el host,ns1-root
yns1-user1
, con ID coincidentesACTUALIZACIÓN: para garantizar que los usuarios no root tengan ID fijos en los contenedores (por ejemplo, user1 1000: 1000), créelos explícitamente durante la creación de la imagen.
Prueba de conducción:
Prepare un directorio de volumen
Pruébalo en un recipiente
Prueba del anfitrión
No es portátil y parece un truco, pero funciona.
fuente
subUID lower bound + UID in image
si estamos ejecutando muchas imágenes diferentes con un usuario que tiene el ID configurado en 1000?Una solución es asignar dinámicamente el uid del usuario en el tiempo de compilación para que coincida con el host.
Ejemplo
Dockerfile
:Luego construye como:
y ejecutar como:
Si tiene un contenedor existente, cree un contenedor de envoltura con lo siguiente
Dockerfile
:Esto se puede envolver
docker-compose.yml
como:Luego compile y ejecute como:
fuente
Puede evitar problemas de permisos utilizando el
docker cp
comando .Aquí está su ejemplo cambiado para usar
docker cp
:Sin embargo, si solo desea leer archivos de un contenedor, no necesita el volumen con nombre. Este ejemplo usa un contenedor con nombre en lugar de un volumen con nombre:
Encuentro que los volúmenes con nombre son útiles cuando quiero copiar archivos en un contenedor, como se describe en esta pregunta .
fuente
docker cp
implica la duplicación de datos. Además, según el documento, al copiar datos en un contenedor, establece los ID de propiedad según el usuario raíz, que a menudo no es la cuenta que ejecuta la aplicación en contenedor. No veo cómo resuelve nuestro problema.docker cp
le brinda control total sobre la propiedad de los archivos cuando transmite un archivo tar dentro o fuera de un contenedor. Puede ajustar la propiedad y los permisos de cada entrada en el archivo tar a medida que lo transmite, por lo que no está limitado al usuario raíz.