docker: монтирование: создает промежуточные папки в качестве корневых вместо пользователя хоста

#docker

Вопрос:

СЛУЧАЙ 1:

Я пытаюсь смонтировать папку хоста dir1 /dir1 внутри docker

 docker run --rm -it 
    -v "$(pwd)/dir1":"/dir1" 
some_image /bin/bash
 

Я вижу разрешения внутри docker как

 drwxr-xr-x 3 hostuser users 4096 Apr 18 13:51 dir1
 

СЛУЧАЙ 2:

Где, как если бы я попытался смонтировать вложенную папку, я вижу, что родительские папки созданы пользователем root, и только последний каталог имеет разрешение пользователя хоста

 docker run --rm -it 
    -v "$(pwd)/dir1/dir2":"/dir1/dir2" 
some_image /bin/bash
 

здесь я вижу разрешение /dir1 внутри docker как

 drwxr-xr-x 3 root root 4096 Apr 18 13:51 dir1
 

и

здесь я вижу разрешение /dir1/dir2 внутри docker как

 drwxr-xr-x 3 hostuser users 4096 Apr 18 13:51 dir2
 

Я ожидаю, что и у dir1 и dir2 будут hostuser users разрешения

Как я могу этого достичь

решение

 docker run --rm -it 
  -v "$(pwd)/dir1":"/dir1" 
  -v "$(pwd)/dir1/dir2":"/dir1/dir2" 
someimage /bin/bash
 

Мне также нужно смонтировать родительскую папку, тогда я смогу увидеть ее разрешение в качестве пользователей хоста

Ответ №1:

dockerd Движок работает от имени root, он ничего не знает о пользователе, выполняющем docker процесс, точно так же, как веб-сервер не знает идентификатор пользователя, запускающего браузер.

Что управляет UID, так это то, настроены ли у вас пользовательские пространства имен (по умолчанию отключены из-за того, как они разрывают эти крепления привязки), и пользователь процесса, запущенного внутри контейнера. Если ваш контейнер работает от имени root, он будет создавать файлы от имени пользователя root, точно так же, как если бы вы запускали любой корневой процесс в Linux.

Чтобы переопределить пользователя по умолчанию, настроенного на изображении, вы можете передать -u флаг:

 docker run --rm -it 
  -u "$(id -u):$(id -g)" 
  -v "$(pwd)/dir1":"/dir1" 
  some_image /bin/bash
 

Однако имейте в виду, что создатели изображений ожидают, что их контейнер будет работать с настроенным uid, и в образе могут быть другие изменения, необходимые для поддержки запуска контейнера с другим UID. Я часто создавал изображения, которые обрабатывали это с fixperms помощью сценария из моего репозитория на базе докеров. Я вызываю этот сценарий как часть точки входа, чтобы изменить UID контейнера в соответствии с каталогом (монтирование тома). UID, а затем запустите gosu , чтобы переключиться с работы от имени пользователя root на работу от имени этого пользователя контейнера.

Также обратите внимание, что это dir1 должно уже существовать на хосте заранее. В противном случае механизм docker имеет функцию, в которой он создаст для вас отсутствующую исходную папку, но не знает, какие разрешения/права собственности ей предоставить, и просто использует корень по умолчанию:корневое владение. Если бы docker этого не сделал, монтирование привязки завершилось бы ошибкой, поскольку Linux требует, чтобы источник монтирования привязки уже существовал.

Исключение составляют случаи, когда файловая система проходит через какой-либо промежуточный уровень, например, NFS выполняет сквош или рабочий стол Docker синхронизирует каталоги хостов с каталогами встроенной виртуальной машины Linux.

Комментарии:

1. Предположим, что мой хост uid:gid 1000:100 , а также мой dockerimage имеют такого же пользователя, как 1000:100 . Теперь даже я использую -u "1000:100" его, чтобы создать dir1 as root:root и dir2 как 1000:100

2. @Santhosh вам нужно создать dir1 заранее. Механизм docker не знает, какой владелец каталога/разрешения для настройки для вас, и это немного особенность, которую каталог вообще создает docker, так как команда bind mount не выполняется, когда исходный каталог отсутствует в Linux.

3. добавил свое решение в вопрос.

4. Я думаю, что ваш комментарий отвечает на вопрос. Но настоящий ответ заключается не в том, чтобы шутить по этому поводу. можете ли вы заменить ответ этим. Чтобы я мог нажать в качестве ответа