Hacer visible un montaje NFS en el host y leer y escribir dentro del contenedor Docker

Hacer visible un montaje NFS en el host y leer y escribir dentro del contenedor Docker

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 runsoluciona 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 gosupara 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 deniedmensaje 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 rootusuario y luego haga cosas malas con los datos. Como tal, los montajes NFS suelen tener la root_squashopció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_squashopció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
   ...

información relacionada