Понимание владения файлами пользователя в 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
группы.