Делаем монтирование NFS на хосте видимым и доступным для чтения и записи внутри контейнера Docker

Делаем монтирование NFS на хосте видимым и доступным для чтения и записи внутри контейнера Docker

Я новичок в Docker и хочу использовать его для получения контролируемой среды компиляции моего кода.

У меня уже есть образ Docker со всеми необходимыми мне инструментами. Моя проблема на данный момент заключается в следующем:

  • Мой код находится на хост-машине, внутри моей домашней папки, которая смонтирована с сервера NFS.
  • Я хочу сделать эту папку видимой внутри контейнера Docker с правами r+w.

Вот что я попробовал сделать в первую очередь (запустить контейнер с исходной папкой в ​​качестве тома) и какая ошибка у меня возникла:

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

(судя по всему, он пытается создать каталог на стороне хоста, но он уже там)

Любопытно, что когда я пытаюсь запустить контейнер со всей домашней папкой в ​​качестве тома, это работает, но выдает другую ошибку (нет разрешения на запись в папку):

[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

Правильно ли я делаю? Что я упускаю?

Дополнительная информация:

  • Операционная система: CentOS Linux 7.6
  • Версия докера: 1.13.1

ОБНОВЛЕНИЕ (1):

Видимо, установка идентификатора пользователя при запуске docker runрешает проблему, но правильный ли это способ? Запуск таким образом вроде как исправляет ситуацию, но выглядит странно (я получаю "I have no name!" в качестве имени пользователя):

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

решение1

Как вы отметили в своем обновлении, UID файлов не отображается в привязке монтирования, это то, как Linux делает привязку монтирования. Вы можете запустить контейнер с другим UID, но это приведет к тому, что /etc/passwd внутри контейнера будет отображаться на другого пользователя или даже на никакого (в вашем случае). Есть разные варианты, но я предпочитаю изменять UID контейнера с помощью команды usermod, которая запускается внутри точки входа для образа с моимскрипт исправления-перезагрузки. Это нужно запускать как root, но затем вы можете использовать gosuего, чтобы вернуться к пользователю при выполнении команд. Я говорил об этом в своемпрезентации dockercon.


Обратите внимание, что вместо привязки к каталогу NFS хоста вы также можете выполнить монтирование тома непосредственно на сервере NFS. Вот несколько примеров того, как это сделать:

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

решение2

В случае, если вы запускаете свой контейнер как root, вы можете столкнуться с этим error while creating mount source path ... permission deniedсообщением, поскольку хост NFS переназначает все удаленные корневые UID (т. н. root-squash).

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

Это функция, ориентированная на безопасность, которая не позволяет злоумышленнику смонтировать ваш ресурс как своего rootпользователя, а затем сделать что-то плохое с данными. Таким образом, монтирования NFS обычно имеют опцию, root_squashустановленную по умолчанию, чтобы предотвратить подобные проблемы. В случае, если вам нужно, чтобы ваш контейнер работал как root, вы можете переопределить это, используя опцию в файле no_root_squashвашего хоста 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/

решение3

Это сработало для меня - объявил путь хоста nfs как том к контейнеру. И путь хоста nfs - это путь не домашнего каталога, это не домашний каталог.

Точка монтирования nfs моего хоста:/mnt/abc

Фрагмент моего файла docker-compose.yml.

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

Связанный контент