ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Права доступа к томам: UID, GID и процесс контейнера

Автор: · Обновлено

Сообщение Permission denied после подключения папки обычно связано с тем, от чьего имени процесс обращается к файлам. В этом уроке вы воспроизведёте отказ записи, сравните числовые идентификаторы и исправите владельца только учебного тома. Не нужно делать все файлы доступными всем пользователям, чтобы понять причину.

Имя пользователя не является идентификатором

На обычном Linux Engine доступ проверяется по числовым UID/GID и режимам файлов. Пользователь app внутри образа и пользователь app на хосте могут иметь разные номера. У non-root процесса UID 10001 нет автоматического права записывать в каталог root с режимом 755. Каталог должен также разрешать проход по пути: одного права чтения конечного файла недостаточно.

Параметр --user 10001:10001 задаёт основной UID/GID процесса, но не переименовывает файлы на томе и не создаёт полноценную учётную запись с домашним каталогом. Условия запуска описаны в Docker run. В rootless/user-namespace режиме отображение идентификаторов дополнительно меняется; результаты следующего опыта относятся к обычному rootful Linux Engine.

Воспроизвести и увидеть разницу

Выберите свободное имя учебного тома:

docker volume create yk-permission-demo
docker run --rm --mount type=volume,src=yk-permission-demo,dst=/data alpine:3.22 sh -c 'chown 0:0 /data; chmod 755 /data; ls -ldn /data'
docker run --rm --user 10001:10001 --mount type=volume,src=yk-permission-demo,dst=/data alpine:3.22 sh -c 'id; touch /data/message.txt'

Последняя команда ожидаемо завершается с ненулевым кодом: процесс печатает свой UID, затем получает отказ. Первая команда внутри контейнера намеренно нормализует права лишь нового учебного тома. Так эксперимент не зависит от текущего umask и состояния образа.

Теперь назначьте каталог тому идентификатору, который действительно будет писать данные:

docker run --rm --mount type=volume,src=yk-permission-demo,dst=/data alpine:3.22 chown 10001:10001 /data
docker run --rm --user 10001:10001 --mount type=volume,src=yk-permission-demo,dst=/data alpine:3.22 sh -c 'printf "owned by app\n" > /data/message.txt; ls -ln /data/message.txt'

Ожидается файл с владельцем 10001. Это узкое исправление: другие пользователи не получили право записи, а всё дерево хоста не подверглось рекурсивному chown. Для реального приложения настройку выполняют при подготовке хранилища или предусмотренной инициализации; не запускают произвольный entrypoint базы под новым UID без проверки документации образа.

Разделить четыре причины

НаблюдениеЧто проверить
Write denied при mount roMounts[].RW, read_only и необходимость записи
Write denied при rwUID/GID процесса и каталога, mode, ACL
Числовые права выглядят подходящими, отказ остаётсяSELinux/AppArmor, rootless mapping, сетевой FS
Ошибка возникает только на DesktopДоступ к пути хоста и слой совместного использования файлов

docker inspect и id описывают разные стороны проверки. Сначала убедитесь, что это нужный mount, затем анализируйте доступ. Замена порта или перестройка сети не исправит права файловой системы.

В системах SELinux метки могут запрещать доступ даже при подходящем mode. Опции z и Z меняют разметку подключаемого пути и отличаются предполагаемым совместным использованием. Не применяйте их к системным каталогам вслепую: начните с журнала отказов и выделенной папки приложения. Официальные ограничения SELinux для bind mounts.

Что проверить самостоятельно

Подключите подготовленный том читателю с UID 10002 и попробуйте прочитать файл. Затем попробуйте создать новый: чтение и запись должны дать разные результаты при режиме каталога 755. Измените только группу каталога и сравните доступ процесса с нужным GID. Уберите учебный том после окончания эксперимента: docker volume rm yk-permission-demo.

Для rootless Docker повторно проверьте фактическое отображение идентификаторов по руководству rootless. Не исправляйте отказ через chmod 777 или открытие Docker socket всем: это меняет границу доступа значительно шире, чем требуется одному сервису.

Источники