Каков механизм докер-контейнера для управления сопоставленным томом?

У меня есть каталог с разрешениями для пользователя user1:

$ ls -la owned-by-u1
drwxr-xr-x 19 u1 u1 4096 Sep  4 16:22 owned-by-u1

$ ls -nla
drwx------ 19 1001 1001 4096 Sep  4 16:22 owned-by-u1

когда я сопоставляю этот каталог как том с контейнером postgres, он меняет владельца каталога на идентификатор пользователя 999, который может сопоставляться с разными именами пользователей.

$ ls -la owned-by-u1
drwx------ 19 gitlab-runner u1 4096 Sep  4 16:22 owned-by-u1

$ ls -nla
drwx------ 19  999 1001 4096 Sep  4 16:22 owned-by-u1

Я запускаю контейнер вот так

docker run -d \
    --name aaa-postgres \
    -e POSTGRES_PASSWORD=mysecretpassword \
    -e PGDATA=/var/lib/postgresql/pgdata \
    -v /home/u1/tt/owned-by-u1:/var/lib/postgresql/pgdata \
    postgres

Может кто-нибудь объяснить механизм, пожалуйста?

Dockerd работает от имени пользователя root (не без root), и переназначение UID не заблокировано.

Если я включу переназначение uid, контейнер выйдет из строя:

chmod: changing permissions of '/var/lib/postgresql/pgdata': Operation not permitted
find: ‘/var/lib/postgresql/pgdata’: Permission denied
chown: changing ownership of '/var/lib/postgresql/pgdata': Operation not permitted

Это ожидаемо, поскольку корень внутри не является настоящим корнем:

$ docker run \
    --name aaa-postgres \
    --entrypoint "" \
    -e POSTGRES_PASSWORD=mysecretpassword \
    -e PGDATA=/var/lib/postgresql/pgdata \
    -v /home/max/tt/owned-by-u1:/var/lib/postgresql/pgdata \
    postgres cat /proc/self/uid_map

дает это

0     296608      65536

что соответствует /etc/subuid:

$ cat /etc/subuid
dockremap:296608:65536

Вот немного информации о докере:

$ docker context ls
NAME            DESCRIPTION                               DOCKER ENDPOINT                             ERROR
default *       Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
desktop-linux   Docker Desktop                            npipe:////./pipe/dockerDesktopLinuxEngine

$ docker version
Client: Docker Engine - Community
Server: Docker Engine - Community

По умолчанию uid будут просто одинаковыми (хотя в некоторых настройках, таких как докер без root-прав, происходит некоторое сопоставление): uid, который вы видите в контейнере, такой же, как uid снаружи. Поскольку хост и контейнер не используют общую базу данных пользователей (т. е. /etc/passwd или что-то еще, настроенное), которая может сопоставляться с разными (или нет) пользователями.

Joachim Sauer 04.09.2024 16:30

Какова ваша среда Docker (обычный Docker в родном Linux, Docker Desktop или что-то еще)? Используете ли вы режим без рута и включили ли вы переназначение uid?

David Maze 04.09.2024 16:57

@ДэвидМейз. спасибо за ваши разъяснения, я добавил эти детали в вопрос

Max Koretskyi 04.09.2024 18:59

@JoachimSauer, да, но они разные, и это меня смущает. Я вижу, что постгресс-изображение создаёт пользователя 999, может это как-то влияет на результат?

Max Koretskyi 04.09.2024 19:00

Просто чтобы прояснить: «uid» — это числовой идентификатор пользователя, а не имя пользователя. Попробуйте перечислить файлы, используя ls -nla.

Joachim Sauer 04.09.2024 20:18

@JoachimSauer, да, верно, я обновил вопрос выводом ls -nla

Max Koretskyi 04.09.2024 20:24

Я включил переназначение uid, и контейнер разбился, потому что не смог chown. Думаю, до переназначения он работал как root

Max Koretskyi 04.09.2024 22:29
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
1
7
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

UID при монтировании томов между контейнером докера и хостом не сопоставляется. Но имена пользователей на обоих контролируются файлами /etc/passwd и /etc/group, которые специфичны для хоста и контейнера (поэтому имя пользователя на хосте не будет совпадать с именем пользователя для того же uid внутри контейнера).

В режиме без root-доступа и пространствах имен пользователей контейнеры могут сопоставлять идентификаторы пользователей и групп (после сопоставлений /etc/subuid и /etc/subgid и указанного пользователя с механизмом Docker). Когда контейнеры uid и gid сдвинуты, эти сдвинутые uid и gid появятся в процессах на хосте и у пользователя, пытающегося получить доступ к любым привязкам. В этом сценарии root в контейнере не является rootом на хосте, поэтому операции файловой системы, пытающиеся изменить владельца файла на хосте, завершатся неудачей так же, как если бы вы попытались запустить их от имени случайного пользователя с большим номером вне контейнера. . Если файл на хосте принадлежит uid и gid за пределами сопоставленных диапазонов, я считаю, что в контейнере он отображается как никто, и любая попытка изменить файл потерпит неудачу, поскольку пользователь контейнера не имеет доступа.

В примере postgres он настроен на запуск от имени пользователя root и изменение прав доступа к файлам как часть точки входа. Вам следует избегать монтирования хоста/привязки и вместо этого использовать именованный том для этого сценария. Вы можете увидеть команды chown для пользователя postgres в /usr/local/bin/docker-entrypoint.sh, а также текущего пользователя и пользователя postgres внутри контейнера с помощью:

# id                                                                                                                                                                                                               
uid=0(root) gid=0(root) groups=0(root)                                                                                                                                                                             
# id postgres                                                                                                                                                                                                      
uid=999(postgres) gid=999(postgres) groups=999(postgres),101(ssl-cert)  

Обратите внимание, что в Docker Desktop есть виртуальная машина, внутри которой работает механизм Docker, и эта виртуальная машина имеет драйвер файловой системы, монтирующий файловые системы хоста в виртуальную машину таким образом, что автоматически сопоставляет uid и gid пользователю хоста при записи файлов, чтобы избежать проблемы с разрешениями.

Спасибо! Обратите внимание: в Docker Desktop есть виртуальная машина — возможно, вы знаете, похожа ли она на виртуальную машину фейерверка?

Max Koretskyi 05.09.2024 07:38

и, возможно, вы знаете, почему переназначение uid по умолчанию не включено в демоне Docker?

Max Koretskyi 05.09.2024 08:01

Docker Desktop основан на linuxkit, но сам код Desktop не является открытым исходным кодом (никогда не был). Включение пространств имен пользователей нарушает монтирование хостов, поэтому изменение этого значения по умолчанию приведет к нарушению существующих рабочих процессов пользователей.

BMitch 05.09.2024 10:40

ты занимаешься консалтингом? нам может понадобиться помощь эксперта

Max Koretskyi 05.09.2024 11:22

Другие вопросы по теме