Вкратце: я пытаюсь смонтировать каталог хоста в Docker, но затем я не могу получить к нему доступ из контейнера, даже если права доступа выглядят хорошо.
Детали:
я делаю
sudo docker run -i -v /data1/Downloads:/Downloads ubuntu bash
а потом
ls -al
Это дает мне:
total 8892
drwxr-xr-x. 23 root root 4096 Jun 18 14:34 .
drwxr-xr-x. 23 root root 4096 Jun 18 14:34 ..
-rwxr-xr-x. 1 root root 0 Jun 18 14:34 .dockerenv
-rwx------. 1 root root 9014486 Jun 17 22:09 .dockerinit
drwxrwxr-x. 18 1000 1000 12288 Jun 16 11:40 Downloads
drwxr-xr-x. 2 root root 4096 Jan 29 18:10 bin
drwxr-xr-x. 2 root root 4096 Apr 19 2012 boot
drwxr-xr-x. 4 root root 340 Jun 18 14:34 dev
drwxr-xr-x. 56 root root 4096 Jun 18 14:34 etc
drwxr-xr-x. 2 root root 4096 Apr 19 2012 home
и еще много подобных строк (я думаю, что это соответствующая часть).
Если я сделаю
cd /Downloads
ls
результат
ls: cannot open directory .: Permission denied
Хост - это Fedora 20 с Docker 1.0.0 и go1.2.2.
Что идет не так?
источник
-v $(pwd):/app:ro,Z
. Это должно быть помечено как правильный ответ.Это проблема SELinux .
Вы можете временно выдать
на хосте, чтобы получить доступ или добавить правило SELinux, запустив
источник
ВНИМАНИЕ: это решение имеет риски для безопасности.
Попробуйте запустить контейнер как привилегированный:
Другой вариант (который я не пробовал) - создать привилегированный контейнер, а затем создать внутри него непривилегированные контейнеры.
источник
--privileged=true
--privileged
риск для безопасностиКак правило, проблемы с разрешениями при монтировании тома хоста связаны с тем, что uid / gid внутри контейнера не имеет доступа к файлу в соответствии с разрешениями uid / gid файла на хосте. Однако этот конкретный случай отличается.
Точка в конце строки разрешения
drwxr-xr-x.
указывает, что SELinux настроен. При использовании монтирования хоста с SELinux вам необходимо передать дополнительную опцию в конец определения тома:Ваша команда монтирования тома будет выглядеть так:
Подробнее о монтировании хоста с помощью SELinux читайте по адресу: https://docs.docker.com/storage/#configure-the-selinux-label.
Для других, которые видят эту проблему с контейнерами, работающими как другой пользователь, вы должны убедиться, что uid / gid пользователя внутри контейнера имеют разрешения на файл на хосте. На производственных серверах это часто делается путем управления uid / gid в процессе построения образа, чтобы соответствовать uid / gid на хосте, который имеет доступ к файлам (или, что еще лучше, не использовать монтирование хоста в рабочей среде).
Именованный том часто предпочтительнее для хостов монтирования, потому что он инициализирует каталог тома из каталога образа, включая любое владение файлом и разрешения. Это происходит, когда том пуст и контейнер создается с указанным томом.
У пользователей MacOS теперь есть OSXFS которая автоматически обрабатывает uid / gid между хостом Mac и контейнерами. Единственное место, где это не помогает, это файлы из встроенной виртуальной машины, которые монтируются в контейнер, например /var/lib/docker.sock.
В средах разработки, где uid / gid хоста может меняться в зависимости от разработчика, мое предпочтительное решение состоит в том, чтобы запустить контейнер с точкой входа, работающей от имени пользователя root, исправить uid / gid пользователя внутри контейнера в соответствии с uid / gid тома хоста и затем используйте
gosu
для перехода от пользователя root к пользователю контейнера, чтобы запустить приложение внутри контейнера. Важный сценарий для этого естьfix-perms
в моих сценариях для базовых изображений, которые можно найти по адресу: https://github.com/sudo-bmitch/docker-baseВажный бит из
fix-perms
сценария:Это получает пользовательский идентификатор внутри контейнера и пользовательский идентификатор файла, и, если они не совпадают, вызывает
usermod
настройку пользовательского идентификатора. Наконец, он делает рекурсивный поиск, чтобы исправить любые файлы, которые не изменили uid. Мне это нравится больше, чем запуск контейнера с-u $(id -u):$(id -g)
флагом, потому что приведенный выше код точки входа не требует от каждого разработчика запуска сценария для запуска контейнера, и для любых файлов вне тома, принадлежащих пользователю, будут исправлены их разрешения.Вы также можете сделать так, чтобы docker инициализировал каталог хоста из образа, используя именованный том, который выполняет подключение. Этот каталог должен существовать заранее, и вам необходимо указать абсолютный путь к каталогу хоста, в отличие от томов хоста в файле составления, которые могут быть относительными путями. Каталог также должен быть пустым, чтобы докер мог его инициализировать. Три различных варианта определения именованного тома для монтирования привязки выглядят так:
Наконец, если вы попытаетесь использовать пользовательские пространства имен, то обнаружите, что у томов хоста есть проблемы с разрешениями, потому что значения uid / gid контейнеров смещены. В этом случае, вероятно, проще всего избежать томов хоста и использовать только именованные тома.
источник
От access.redhat.com:Sharing_Data_Across_Containers :
Кажется, это всего лишь обходной путь, но я попытался, и это работает.
источник
Я проверил, что
chcon -Rt svirt_sandbox_file_t /path/to/volume
это работает, и вам не нужно работать как привилегированный контейнер.Это на:
источник
Попробуй
docker volume create
.Взгляните на документ https://docs.docker.com/engine/reference/commandline/volume_create/
источник
У меня была похожая проблема, моя была вызвана несоответствием между UID хоста и UID пользователя контейнера. Исправление состояло в том, чтобы передать UID пользователя в качестве аргумента сборке Docker и создать пользователя контейнера с тем же UID.
В DockerFile:
На этапе сборки:
После этого выполнение контейнера и команд согласно OP дало мне ожидаемый результат.
источник
Я решил эту проблему с помощью контейнера данных, это также имеет преимущество в изоляции данных от прикладного уровня. Вы можете запустить его так:
Этот учебник дает хорошее объяснение по использованию контейнеров данных.
источник
В моей ситуации проблема была в другом. Я не знаю почему, но даже если на нем
chmod 777
запускался каталог на хосте , внутри докера это было видно как755
.Запуск внутри контейнера
sudo chmod 777 my_volume_dir
исправил это.источник
chmod 777
вряд ли что-нибудь исправит.sudo -s
сделал трюк для меня на MACисточник