В докере файлы, созданные внутри контейнеров, имеют тенденцию иметь непредсказуемое владение при проверке их с хоста. Владельцем файлов на томе по умолчанию является root (uid 0), но как только учетные записи пользователей без полномочий root включаются в контейнер и записывают в файловую систему, владельцы становятся более или менее случайными с точки зрения хоста.
Это проблема, когда вам нужно получить доступ к данным тома с хоста, используя ту же учетную запись пользователя, которая вызывает команды докера.
Типичные обходные пути:
- принудительное использование uID пользователей во время создания в Dockerfiles (не переносится)
- передача UID пользователя хоста
docker run
команде в качестве переменной среды, а затем выполнение некоторыхchown
команд на томах в сценарии точки входа.
Оба эти решения могут дать некоторый контроль над фактическими разрешениями вне контейнера.
Я ожидал, что пространства имен пользователей станут окончательным решением этой проблемы. Я провел несколько тестов с недавно выпущенной версией 1.10 и параметром --userns-remap для моей учетной записи рабочего стола. Однако я не уверен, что это может упростить владение файлами на смонтированных томах, я боюсь, что на самом деле может быть наоборот.
Предположим, я запустил этот базовый контейнер
docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit
А затем проверьте содержимое хоста:
ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/
-rw-r--r-- 1 100000 100000 6 Feb 8 19:43 test.txt
Этот номер «100000» является суб-UID моего пользователя хоста, но поскольку он не соответствует UID моего пользователя, я все еще не могу редактировать test.txt без прав. Этот субпользователь, похоже, не имеет ничего общего с моим фактическим постоянным пользователем за пределами докера. Это не отображается на карте.
Обходные пути, упомянутые ранее в этом посте, которые заключались в выравнивании UID между хостом и контейнером, больше не работают из-за UID->sub-UID
сопоставления, которое происходит в пространстве имен.
Тогда есть ли способ запустить докер с включенным пространством имен пользователей (для повышения безопасности), при этом позволяя пользователю хоста, запускающему докер, владеть файлами, созданными на томах?
Ответы:
Если вы можете заранее упорядочить пользователей и группы, то можно назначить UID и GID таким особым образом, чтобы пользователи хоста соответствовали пользователям с пространством имен внутри контейнеров.
Вот пример (Ubuntu 14.04, Docker 1.10):
Создайте нескольких пользователей с фиксированными числовыми идентификаторами:
Ручное редактирование автоматически генерируемые подчиненные диапазонов ID в
/etc/subuid
и/etc/subgid
файлы:(примечание нет записей для
ns1-root
иns1-user1
из - заMAX_UID
иMAX_GID
ограничение в/etc/login.defs
)Включить пространства имен пользователей в
/etc/default/docker
:Перезапустите демон
service docker restart
, убедитесь, что/var/lib/docker/500000.500000
каталог создан.Теперь внутри контейнеров у вас есть
root
anduser1
, и на хосте -ns1-root
иns1-user1
с соответствующими идентификаторамиОБНОВЛЕНИЕ: чтобы гарантировать, что пользователи без полномочий root имеют фиксированные идентификаторы в контейнерах (например, user1 1000: 1000), создайте их явно во время сборки образа.
Тест-драйв:
Подготовить каталог тома
Попробуйте из контейнера
Попробуйте от хозяина
Не портативный и выглядит как хакерский, но работает.
источник
subUID lower bound + UID in image
если мы запускаем много разных изображений с пользователем, у которого установлен идентификатор 1000?Один из способов решения этой проблемы - динамически назначать uid пользователя во время сборки для соответствия хосту.
Пример
Dockerfile
:Затем создайте как:
и запустить как:
Если у вас есть контейнер, создайте контейнер-оболочку со следующим
Dockerfile
:Это можно обернуть
docker-compose.yml
так:Затем соберите и запустите как:
источник
Вы можете избежать проблем с разрешениями, используя
docker cp
команду .Вот ваш пример, переключенный на использование
docker cp
:Однако, если вы просто хотите читать файлы из контейнера, именованный том вам не нужен. В этом примере вместо именованного тома используется именованный контейнер:
Я считаю именованные тома полезными, когда я хочу скопировать файлы в контейнер, как описано в этом вопросе .
источник
docker cp
предполагает дублирование данных. Более того, согласно документу, при копировании данных в контейнер он устанавливает идентификаторы владения в соответствии с пользователем root, который часто не является учетной записью, на которой запущено контейнерное приложение. Я не понимаю, как это решает нашу проблему.docker cp
дает вам полный контроль над владением файлом при потоковой передаче tar-архива в контейнер или из него. Вы можете настроить права собственности и разрешения для каждой записи в tar-файле по мере его потоковой передачи, поэтому вы не ограничены пользователем root.