Понимание владения файлами пользователя в docker: как избежать изменения разрешений связанных томов
рассмотрим следующий тривиальный Dockerfile:
FROM debian:testing
RUN adduser --disabled-password --gecos '' docker
RUN adduser --disabled-password --gecos '' bob
в рабочем каталоге ни с чем другим. Создайте изображение docker:
docker build -t test .
и затем запустить bash-скрипт на контейнер, связывающий рабочую директорию в новый подкаталог домашнего каталога на Боба:
docker run --rm -it -v $(pwd):/home/bob/subdir test
кому принадлежит содержимое subdir на контейнере? На контейнере запустите:
cd /home/bob/subdir
ls -l
объявление мы видим:
-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile
Святые угодники! docker владеет содержание! Вернувшись на главную машину вне контейнера, мы видим, что наш исходный пользователь все еще владеет Dockerfile. Давайте попробуем исправить право собственности на bobдомашний каталог. На контейнере запустите:
chown -R bob:bob /home/bob
ls -l
и видим:
-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile
но подождите! вне контейнера, мы теперь бежим ls -l
-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile
у нас больше нет собственного файла. Ужасные новости!
если бы мы добавили только одного пользователя в приведенном выше примере, все прошло бы более гладко. По какой-то причине Docker, похоже, делает любой домашний каталог, принадлежащий первый некорневой пользователь, с которым он сталкивается (даже если этот пользователь объявлен на более раннем изображении). Аналогично, это первый пользователь-это тот, который соответствует тем же разрешениям владения, что и мой домашний пользователь.
Вопрос 1 это правильно? Может ли кто-нибудь указать мне на документацию об этом, я просто предполагаю, основываясь на выше эксперимента.
Вопрос 2: возможно, это просто потому, что они оба имеют одинаковое числовое значение на ядре, и если бы я тестировал на системе, где мой домашний пользователь не был id 1000 тогда разрешения будут изменены в каждом случае?
Вопрос 3: вопрос, конечно, что мне делать по этому поводу?- Если bob вошел в bob на данном хост-компьютере он должен иметь возможность запускать контейнер как bob и не имеют прав доступа к файлам, измененных под его учетной записью хоста. Как бы то ни было, он на самом деле должен запустить контейнер как пользователь docker чтобы избежать изменения его учетной записи.
2 ответа:
это правильно? Может ли кто-нибудь указать мне на документацию об этом, я просто предполагаю, основываясь на приведенном выше эксперименте.
возможно, это просто потому, что они оба имеют одинаковое числовое значение на ядре, и если бы я тестировал в системе, где мой домашний пользователь не был id 1000, то разрешения менялись бы в каждом случае?
прочитать
info coreutils 'chown invocation', это может дать вам лучшее представление о том, как права доступа к файлам / владение завод.в основном, однако, каждый файл на вашем компьютере имеет набор битов, прикрепленных к нему, который определяет его разрешения и права собственности. Когда ты
chownфайл, вы просто устанавливаете эти биты.когда вы
chownфайл для конкретного пользователя/группы, используя имя пользователя или имя группы,chownбудет выглядеть в/etc/passwdимя пользователя и/etc/groupдля группы, чтобы попытаться сопоставить имя с идентификатором. Если имя пользователя / группы не существует в этих файлах,chownбудет неудача.root@dc3070f25a13:/test# touch test root@dc3070f25a13:/test# ll total 8 drwxr-xr-x 2 root root 4096 Oct 22 18:15 ./ drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../ -rw-r--r-- 1 root root 0 Oct 22 18:15 test root@dc3070f25a13:/test# chown test:test test chown: invalid user: 'test:test'однако, вы можете
chownфайл, использующий идентификаторы для всего, что вы хотите (в пределах некоторых верхних положительных целочисленных границ, конечно), есть ли пользователь / группа, которая существует с этими идентификаторами на вашем компьютере или нет.root@dc3070f25a13:/test# chown 5000:5000 test root@dc3070f25a13:/test# ll total 8 drwxr-xr-x 2 root root 4096 Oct 22 18:15 ./ drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../ -rw-r--r-- 1 5000 5000 0 Oct 22 18:15 testбиты UID и GID устанавливаются в самом файле, поэтому при монтировании этих файлов внутри контейнера docker файл имеет тот же идентификатор владельца / группы, что и на хосте, но теперь сопоставляется с
/etc/passwdв контейнере, который вероятно, будет другой пользователь, если он не принадлежит root (UID 0).реальный вопрос, конечно, что мне делать по этому поводу?"Если Боб вошел в систему как боб на данном хост-компьютере, он должен иметь возможность запускать контейнер как Боб и не иметь прав доступа к файлам, измененных под его учетной записью хоста. Как бы то ни было, ему действительно нужно запустить контейнер в качестве пользователя docker, чтобы избежать изменения его учетной записи.
похоже, с вашим нынешним настройка, вам нужно будет убедиться, что ваши UIDs > имена пользователей в
/etc/passwdна вашем хосте совпадают с вашими UIDs > имена пользователей в ваших контейнерах/etc/passwdесли вы хотите взаимодействовать с подключенным каталогом пользователя как тот же пользователь, который вошел в систему на хосте.вы можете создать пользователя с определенным идентификатором пользователя с
useradd -u xxxx. Buuuut, это действительно похоже на грязное решение...возможно, вам придется придумать решение, которое не монтирует домашний каталог пользователей хоста.
два варианта я нашел:
CHOWN все вещи (после выполнения вашей работы)
Я сделал
docker run -v `pwd`/shared:/shared image, и контейнер создал файлы в пределахpwd/shared, которые, как владельцем процесса докер. Однако,/sharedвсе еще принадлежит мне. Поэтому в процессе докера я делаю
chown -R `stat -c "%u:%g" /shared` /shared
stat -c "%u:%g" /sharedвозвращает1000:1000в моем случае, являясьuid:gidмоего пользователя. Даже если нет пользователя1000в докере conatainer, идентификатор есть ли (иstat /sharedпросто говорит "неизвестно", если вы спросите имя пользователя).во всяком случае,
chownпослушно передает право собственности на содержание/sharedдо1000:1000(который, насколько это касается, не существует, но вне контейнера, это я). Так что теперь у меня есть все файлы. Контейнер все еще может изменять вещи, если захочет, потому что с его точки зрения этоroot.и все хорошо с миром.
docker run -uитак, все файлы созданы автоматически будет иметь право владельцадругой способ сделать это
-uфлаг при запуске докера.
docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bashтаким образом, пользователь docker внутри контейнера является
youruid:yourgid.: это означает отказ от ваших корневых полномочий в контейнере (
apt-get installи т. д.). Если вы не создадите пользователя с этим новым uid и не добавите его вrootгруппы.