Каков (лучший) способ управления разрешениями для разделяемых томов Docker?



6 Answers

Очень элегантное решение можно увидеть на официальном изображении redis и вообще на всех официальных изображениях.

Описанный в пошаговом процессе:

  • Создавать пользователя / группу redis перед чем-либо еще

Как видно на комментариях Dockerfile:

сначала добавьте нашего пользователя и группу, чтобы убедиться, что их идентификаторы получаются последовательно, независимо от того, какие зависимости добавляются

  • Установите gosu с Dockerfile

gosu является альтернативой su / sudo для простого перехода от пользователя root. (Redis всегда запускается с пользователем redis )

  • Настроить /data объем /data и установить его как workdir

Конфигурируя том / data с помощью команды VOLUME /data теперь у нас есть отдельный том, который может быть либо докерером, либо привязанным к хосту.

Настройка его как workdir ( WORKDIR /data ) делает его каталогом по умолчанию, из которого выполняются команды.

  • Добавьте файл точки входа в докер и установите его как ENTRYPOINT с помощью redis-сервера CMD по умолчанию

Это означает, что все выполнение контейнера будет выполняться через сценарий точки входа в докер, и по умолчанию команда, которую нужно запустить, является redis-server.

docker-entrypoint - это скрипт, который выполняет простую функцию: изменение владельца текущего каталога (/ data) и redis от root к пользователю redis для запуска redis-server . (Если исполняемая команда не redis-server, она будет запускать команду напрямую.)

Это имеет следующий эффект:

Если каталог / data привязан к узлу хоста, точка входа в докер подготовит права пользователя перед запуском redis-сервера под пользователем redis .

Это дает вам легкость в том, что существует нулевая настройка для запуска контейнера при любой конфигурации тома.

Конечно, если вам нужно разделить объем между разными изображениями, вам нужно убедиться, что они используют один и тот же идентификатор пользователя / groupid, иначе последний контейнер удержит права пользователя от предыдущего.

docker

Я некоторое время играю с Docker и продолжаю находить ту же проблему при работе с постоянными данными.

Я создаю свой Dockerfile и выставляю тома или использую --volumes-from для монтирования папки хоста внутри моего контейнера .

Какие разрешения следует применять к общему тому на хосте?

Я могу представить два варианта:

  • До сих пор я предоставлял каждому доступ для чтения / записи, поэтому я могу писать в папку из контейнера Docker.

  • Сопоставьте пользователей из хоста в контейнер, поэтому я могу назначить более подробные разрешения. Не уверен, что это возможно, хотя и не нашли много об этом. Пока что все, что я могу сделать, это запустить контейнер как некоторый пользователь: docker run -i -t -user="myuser" postgres , но у этого пользователя есть другой UID, чем мой myuser хозяин, поэтому разрешения не работают. Кроме того, я не уверен, что сопоставление пользователей будет представлять собой некоторые угрозы безопасности.

Существуют ли другие альтернативы?

Как вы, ребята / девушки, занимаетесь этой проблемой?




Хорошо, теперь это отслеживается при выпуске докеров # 7198

На данный момент я имею дело с этим, используя ваш второй вариант:

Отображать пользователей из хоста в контейнер

Dockerfile

#=======
# Users
#=======
# TODO: Idk how to fix hardcoding uid & gid, specifics to docker host machine
RUN (adduser --system --uid=1000 --gid=1000 \
        --home /home/myguestuser --shell /bin/bash myguestuser)

CLI

# DIR_HOST and DIR_GUEST belongs to uid:gid 1000:1000
docker run -d -v ${DIR_HOST}:${DIR_GUEST} elgalu/myservice:latest

ОБНОВЛЕНИЕ В настоящее время я склонен к answer Хами




То же, что и вы, я искал способ сопоставления пользователей / групп с хостом на контейнеры докеров, и это самый короткий способ, который я нашел до сих пор:

  version: "3"
    services:
      my-service:
        .....
        volumes:
          # take uid/gid lists from host
          - /etc/passwd:/etc/passwd:ro
          - /etc/group:/etc/group:ro
          # mount config folder
          - path-to-my-configs/my-service:/etc/my-service:ro
        .....

Это выдержка из моего docker-compose.yml.

Идея состоит в том, чтобы монтировать (в режиме только для чтения) список пользователей / групп из хоста в контейнер, поэтому после запуска контейнера он будет иметь одинаковые совпадения uid-> username (а также для групп) с хостом. Теперь вы можете настроить параметры пользователя / группы для своей службы внутри контейнера, как если бы она работала на вашей хост-системе.

Когда вы решите переместить свой контейнер на другой хост, вам просто нужно изменить имя пользователя в файле конфигурации службы на то, что у вас есть на этом хосте.




Для обеспечения безопасности и изменения корневого --uidmap для докер-контейнера хост-докеры попробуйте использовать --uidmap и --private-uids

https://github.com/docker/docker/pull/4572#issuecomment-38400893

Также вы можете удалить несколько возможностей ( --cap-drop ) в контейнере --cap-drop для обеспечения безопасности

http://opensource.com/business/14/9/security-for-docker

Поддержка UPDATE должна появиться в docker > 1.7.0

UPDATE Версия 1.10.0 (2016-02-04) add --userns-remap flag https://github.com/docker/docker/blob/master/CHANGELOG.md#security-2




Мой подход заключается в обнаружении текущего идентификатора UID / GID, а затем создания такого пользователя / группы внутри контейнера и выполнения сценария под ним, поэтому все файлы, которые он создаст, будут соответствовать пользователю, выполняющему сценарий:

# get location of this script no matter what your current folder is, this might break between shells so make sure you run bash
LOCAL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# get current IDs
USER_ID=$(id -u)
GROUP_ID=$(id -g)

echo "Mount $LOCAL_DIR into docker, and match the host IDs ($USER_ID:$GROUP_ID) inside the container."

docker run -v $LOCAL_DIR:/host_mount -i debian:9.4-slim bash -c "set -euo pipefail && groupadd -r -g $GROUP_ID lowprivgroup && useradd -u $USER_ID lowprivuser -g $GROUP_ID && cd /host_mount && su -c ./runMyScriptAsRegularUser.sh lowprivuser"



Чтобы обмениваться папкой между докером-хостом и контейнером докеров, попробуйте выполнить команду ниже

$ docker run -v "$ (pwd): $ (pwd)" -i -t ubuntu

Флаг -v устанавливает текущий рабочий каталог в контейнер. Если каталог хоста подключенного тома не существует, Docker автоматически создаст этот каталог на хосте для вас,

Однако есть две проблемы, которые мы имеем здесь:

  1. Вы не можете писать на том, смонтированный, если вы не являетесь пользователем root, потому что общий файл будет принадлежать другому пользователю в хосте,
  2. Вы не должны запускать процесс внутри своих контейнеров как root, но даже если вы запускаете его как некорректного пользователя, он все равно не будет соответствовать пользователю на вашем ноутбуке / Jenkins,

Решение:

Контейнер: создайте пользователя «testuser», по умолчанию идентификатор пользователя будет начинаться с 1000,

Хост: создайте группу, скажем «testgroup» с идентификатором группы 1000, и запустите каталог в новую группу (тестовая группа






Related


Tags

docker