Tornando uma montagem NFS no host visível e de leitura e gravação dentro do contêiner Docker

Tornando uma montagem NFS no host visível e de leitura e gravação dentro do contêiner Docker

Sou novo no Docker e quero usá-lo para obter um ambiente de compilação controlado para meu código.

Já tenho uma imagem Docker com todas as ferramentas que preciso. Meu problema no momento é o seguinte:

  • Eu tenho meu código na máquina host, dentro da minha pasta pessoal montada a partir de um servidor NFS
  • Quero tornar esta pasta visível dentro do contêiner Docker com permissões r+w

Aqui está o que tentei primeiro (executar o contêiner com a pasta de origem como volume) e o erro que recebo:

[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á tentando criar o diretório no lado do host, mas já está lá)

Curiosamente, quando tento executar o contêiner com toda a pasta inicial como volume, ele funciona, mas gera um erro diferente (sem permissão de gravação na pasta):

[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

Eu estou fazendo a coisa certa? o que estou perdendo?

Informações adicionais:

  • SO: CentOS Linux 7.6
  • Versão do Docker: 1.13.1

ATUALIZAÇÃO (1):

Aparentemente, definir um ID de usuário durante a execução docker runcorrige o problema, mas essa é a maneira correta de fazer isso? Executá-lo dessa maneira consertou as coisas, mas parece estranho (obtenho "Não tenho nome!" como nome de usuário):

[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$

Responder1

Como você observou em sua atualização, o UID nos arquivos não é mapeado nas montagens de ligação; é assim que o Linux vincula as montagens. Você pode iniciar o contêiner com um UID diferente, mas isso resultará no /etc/passwd dentro do contêiner mapeado para um usuário diferente ou até mesmo nenhum (no seu caso). Existem várias opções, mas minha preferência é modificar o UID do contêiner com um comando usermod que é executado dentro de um ponto de entrada para a imagem com meuscript de permissão de correção. Isso precisa ser executado como root, mas você pode usá-lo gosupara retornar ao usuário ao executar seus comandos. Já falei sobre isso no meuapresentações dockercon.


Observe que, em vez de uma montagem vinculada ao diretório NFS do host, você também pode fazer uma montagem de volume diretamente no servidor NFS. Aqui estão vários exemplos de como fazer isso:

  # 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"
  ...

Responder2

Caso você esteja executando seu contêiner como root, você pode encontrar a error while creating mount source path ... permission deniedmensagem porque o host NFS está remapeando todos os UIDs de raiz remota (também conhecido como root-squash).

https://en.wikipedia.org/wiki/Unix_security#Root_squash

Este é um recurso voltado para a segurança que evita que um malfeitor monte seu compartilhamento como seu próprio rootusuário e, em seguida, faça coisas ruins com os dados. Como tal, as montagens NFS normalmente têm a root_squashopção definida por padrão, para evitar esses tipos de problemas. Caso você precise que seu contêiner seja executado como root, você pode substituir isso usando a no_root_squashopção no arquivo do seu 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/

Responder3

Isso funcionou para mim - declarou o caminho do host nfs como volume para o contêiner. E o caminho do host nfs é um caminho de diretório não inicial, não é um diretório inicial.

Meu ponto de montagem do host nfs:/mnt/abc

Meu trecho de arquivo docker-compose.yml.

   ...
   volumes:
  - /mnt/abc/:/abc
   ...

informação relacionada