Зазвичай проблеми з правами на кріплення тома хоста виникають через те, що uid / gid всередині контейнера не має доступу до файлу відповідно до дозволів uid / gid для файлу на хості. Однак цей конкретний випадок інший.
Крапка в кінці рядка дозволу drwxr-xr-x.
, вказує, що SELinux налаштований. Використовуючи кріплення хоста з SELinux, вам потрібно пройти додаткову опцію до кінця визначення гучності:
- The
z
Параметр вказує на те, що зміст прив'язка змонтованого розподіляється між декількома контейнерами.
Z
Параметр вказує на те, що зміст прив'язка змонтованого є приватним і нерозділене.
Тоді ваша команда встановлення гучності виглядатиме так:
sudo docker run -i -v /data1/Downloads:/Downloads:z ubuntu bash
Докладніше про кріплення хостів із SELinux за посиланням: https://docs.docker.com/storage/#configure-the-selinux-label
Для інших, хто бачить цю проблему з контейнерами, які працюють як інший користувач, вам потрібно переконатися, що uid / gid користувача всередині контейнера має дозволи на файл на хості. На виробничих серверах це часто робиться шляхом керування uid / gid у процесі збирання зображення, щоб відповідати uid / gid на хості, який має доступ до файлів (а ще краще, не використовуйте кріплення хостів у виробництві).
Іменований том часто віддають перевагу хост-версій, оскільки він ініціалізує каталог томів із каталогу зображень, включаючи будь-які права власності на файли та дозволи. Це відбувається, коли обсяг порожній і контейнер створюється з названим томом.
Зараз користувачі MacOS мають OSXFS, який автоматично обробляє uid / gid між хостом Mac та контейнерами. Одне місце, якому воно не допомагає, - це файли з всередині вбудованої VM, яка встановлюється в контейнер, як-от /var/lib/docker.sock.
Для середовищ розробки, де uid / gid хоста може змінюватись на кожного розробника, моїм кращим рішенням є запуск контейнера з точкою входу, що працює як корінь, виправлення uid / gid користувача всередині контейнера, щоб відповідати обсягу ходу uid / gid, і потім скористайтесь gosu
для переходу з кореня на користувача контейнера, щоб запустити програму всередині контейнера. Важливий сценарій для цього - fix-perms
у моїх сценаріях базового зображення, які можна знайти за посиланням: https://github.com/sudo-bmitch/docker-base
Важливий біт fix-perms
сценарію:
# update the uid
if [ -n "$opt_u" ]; then
OLD_UID=$(getent passwd "${opt_u}" | cut -f3 -d:)
NEW_UID=$(stat -c "%u" "$1")
if [ "$OLD_UID" != "$NEW_UID" ]; then
echo "Changing UID of $opt_u from $OLD_UID to $NEW_UID"
usermod -u "$NEW_UID" -o "$opt_u"
if [ -n "$opt_r" ]; then
find / -xdev -user "$OLD_UID" -exec chown -h "$opt_u" {} \;
fi
fi
fi
Це отримує uid користувача всередині контейнера, а uid файлу, і якщо вони не відповідають, викликає usermod
коригування uid. Нарешті, це рекурсивна знахідка, щоб виправити будь-які файли, які не змінили uid's. Мені це подобається краще, ніж запускати контейнер з -u $(id -u):$(id -g)
прапором, оскільки вищевказаний код точки введення не вимагає, щоб кожен розробник запустив скрипт для запуску контейнера, і будь-які файли поза томом, які належать користувачеві, будуть виправлені їх дозволи.
Ви також можете мати докер ініціалізувати каталог хостів із зображення, використовуючи названий том, який виконує кріплення прив’язки. Цей каталог повинен існувати заздалегідь, і вам потрібно надати абсолютний шлях до каталогу хостів, на відміну від томів хостів у складеному файлі, який може бути відносним шляхом. Каталог також повинен бути порожнім, щоб докер ініціалізував його. Три різні варіанти визначення названого гучності для прив’язки кріплення виглядають так:
# create the volume in advance
$ docker volume create --driver local \
--opt type=none \
--opt device=/home/user/test \
--opt o=bind \
test_vol
# create on the fly with --mount
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
foo
# inside a docker-compose file
...
volumes:
bind-test:
driver: local
driver_opts:
type: none
o: bind
device: /home/user/test
...
Нарешті, якщо ви спробуєте скористатись просторами імен користувачів, ви побачите, що в томах хостів є проблеми з дозволом, оскільки uid / gid контейнерів зміщуються. У такому сценарії, мабуть, найпростіше уникнути томів хосту і використовувати лише названі томи.