
Soy nuevo en Docker y quiero usarlo para obtener un entorno de compilación controlado para mi código.
Ya tengo una imagen de Docker con todas las herramientas que necesito. Mi problema en este momento es el siguiente:
- Tengo mi código en la máquina host, dentro de mi carpeta de inicio que está montada desde un servidor NFS.
- Quiero que esta carpeta sea visible dentro del contenedor Docker con permisos r+w
Esto es lo que intenté primero (ejecutar el contenedor con la carpeta de origen como un volumen) y aparece el error:
[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/src:/usr/local/src/" mbrandalero/my-image bash
/usr/bin/docker-current: Error response from daemon: error while creating mount source path '/homes/mbrandalero/src': mkdir /homes/mbrandalero/src: permission denied.
(aparentemente está intentando crear el directorio en el lado del host, pero ya está allí)
Curiosamente, cuando intento ejecutar el contenedor con toda la carpeta de inicio como volumen, funciona pero arroja un error diferente (sin permiso de escritura en la carpeta):
[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/:/usr/local/src/home" mbrandalero/my_image bash
root@46712ad936f2:/usr/local/src# cd home/
bash: cd: home/: Permission denied
root@46712ad936f2:/usr/local/src# ls -lah | grep "\(\.\|home\)"
total 4.0K
drwxr-xr-x 1 root root 18 May 20 14:50 .
drwxr-xr-x 1 root root 17 May 15 14:06 ..
drwxr-x--- 30 10031 10031 4.0K May 20 15:03 home
¿Lo estoy haciendo bien? ¿Qué me estoy perdiendo?
Información adicional:
- Sistema operativo: CentOS Linux 7.6
- Versión de Docker: 1.13.1
ACTUALIZACIÓN (1):
Aparentemente, configurar una identificación de usuario durante la ejecución docker run
soluciona el problema, pero ¿es esta la forma correcta de hacerlo? Ejecutarlo de esta manera solucionó las cosas, pero parece extraño (me sale "¡No tengo nombre!" como nombre de usuario):
[mbrandalero@machine ~]$ docker run -it --cap-add sys_admin -v "/homes/mbrandalero/:/usr/local/src/home" --user $(id -u) mbrandalero/my_image bash
I have no name!@2efec822e572:/usr/local/src$ cd home/
I have no name!@2efec822e572:/usr/local/src/home$
Respuesta1
Como observó en su actualización, el UID de los archivos no está asignado en los montajes vinculados; así es como Linux vincula los montajes. Puede iniciar el contenedor con un UID diferente, pero esto dará como resultado que /etc/passwd dentro del contenedor se asigne a un usuario diferente, o incluso a ningún usuario (en su caso). Hay varias opciones, pero mi preferencia es modificar el UID del contenedor con un comando usermod que se ejecuta dentro de un punto de entrada para la imagen con misecuencia de comandos de arreglo permanente. Esto debe ejecutarse como root, pero luego puede usarlo gosu
para volver al usuario cuando ejecute sus comandos. He hablado de esto en mipresentaciones dockercon.
Tenga en cuenta que, en lugar de realizar un montaje vinculado al directorio NFS del host, también puede realizar un montaje de volumen directamente en el servidor NFS. A continuación se muestran varios ejemplos de cómo hacerlo:
# create a reusable volume
$ docker volume create --driver local \
--opt type=nfs \
--opt o=nfsvers=4,addr=nfs.example.com,rw \
--opt device=:/path/to/dir \
foo
# or from the docker run command
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=nfs.example.com\",volume-opt=device=:/host/path \
foo
# or to create a service
$ docker service create \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=nfs.example.com\",volume-opt=device=:/host/path \
foo
# inside a docker-compose file
...
volumes:
nfs-data:
driver: local
driver_opts:
type: nfs
o: nfsvers=4,addr=nfs.example.com,rw
device: ":/path/to/dir"
...
Respuesta2
En caso de que esté ejecutando su contenedor como root
, es posible que encuentre el error while creating mount source path ... permission denied
mensaje porque el host NFS está reasignando todos los UID raíz remotos (también conocido como root-squash).
https://en.wikipedia.org/wiki/Unix_security#Root_squash
Esta es una característica orientada a la seguridad que evita que un mal actor monte su recurso compartido como su propio root
usuario y luego haga cosas malas con los datos. Como tal, los montajes NFS suelen tener la root_squash
opción configurada de forma predeterminada para evitar este tipo de problemas. En caso de que necesite que su contenedor se ejecute como root
, puede anular esto usando la no_root_squash
opción en el archivo de su host NFS /etc/exports
.
/srv/nfs/shared_folder <hostname>(rw,sync,no_subtree_check,no_root_squash)
http://nfs.sourceforge.net/nfs-howto/ar01s03.html
https://www.thegeekdiary.com/understanding-the-etc-exports-file/
Respuesta3
Esto funcionó para mí: declaró la ruta nfs del host como volumen al contenedor. Y la ruta nfs del host es una ruta de directorio que no es de inicio, no es un directorio de inicio.
Punto de montaje de mi host nfs:/mnt/abc
Mi fragmento de archivo docker-compose.yml.
...
volumes:
- /mnt/abc/:/abc
...