ОБНОВЛЕНИЕ 2016-03-02 : Начиная с Docker 1.9.0, Docker имеет именованные тома, которые заменяют контейнеры только для данных . Приведенный ниже ответ, как и мой пост в блоге, все еще имеет значение в том смысле, как думать о данных внутри докера, но подумайте об использовании именованных томов для реализации описанного ниже шаблона, а не контейнеров данных.
Я считаю, что канонический способ решить эту проблему - использовать контейнеры только для данных . При таком подходе весь доступ к данным тома осуществляется через контейнеры, которые используют -volumes-from
контейнер данных, поэтому хост uid / gid не имеет значения.
Например, один из вариантов использования, приведенный в документации, - резервное копирование тома данных. Для этого используется другой контейнер для резервного копирования через tar
, и он также использует -volumes-from
для монтирования тома. Поэтому я думаю, что ключевой момент в работе с Grok: вместо того, чтобы думать о том, как получить доступ к данным на хосте с соответствующими разрешениями, подумайте о том, как сделать все, что вам нужно - резервное копирование, просмотр и т. Д. - через другой контейнер. , Сами контейнеры должны использовать согласованные uid / gids, но им не нужно сопоставлять что-либо на хосте, тем самым оставаясь переносимым.
Для меня это тоже относительно новый вопрос, но если у вас есть конкретный вариант использования, не стесняйтесь комментировать, и я постараюсь расширить ответ.
ОБНОВЛЕНИЕ : Для данного варианта использования в комментариях у вас может быть изображение some/graphite
для запуска графита и изображение some/graphitedata
в качестве контейнера данных. Таким образом, игнорируя порты и тому подобное, Dockerfile
изображение some/graphitedata
выглядит примерно так:
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
RUN mkdir -p /data/graphite \
&& chown -R graphite:graphite /data/graphite
VOLUME /data/graphite
USER graphite
CMD ["echo", "Data container for graphite"]
Создайте и создайте контейнер данных:
docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata
some/graphite
Dockerfile также должен получить тот же UID / GID, поэтому она может выглядеть следующим образом :
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
# ... graphite installation ...
VOLUME /data/graphite
USER graphite
CMD ["/bin/graphite"]
И это будет работать следующим образом:
docker run --volumes-from=graphitedata some/graphite
Хорошо, теперь это дает нам наш графитовый контейнер и связанный контейнер только для данных с правильной пользователем / группой (обратите внимание, что вы также можете повторно использовать some/graphite
контейнер для контейнера данных, переопределяя entrypoing / cmd при его запуске, но имея их как отдельные изображения ИМО понятнее).
Теперь предположим, что вы хотите редактировать что-то в папке данных. Поэтому вместо того, чтобы привязывать монтирование тома к хосту и редактировать его там, создайте новый контейнер для этой работы. Давай называть это some/graphitetools
. Также давайте создадим соответствующего пользователя / группу, как some/graphite
изображение.
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
VOLUME /data/graphite
USER graphite
CMD ["/bin/bash"]
Вы можете сделать этот СУХОЙ, унаследовав от some/graphite
или some/graphitedata
в Dockerfile, или вместо создания нового образа просто повторно используйте один из существующих (при необходимости переопределяя точку входа / cmd).
Теперь вы просто запускаете:
docker run -ti --rm --volumes-from=graphitedata some/graphitetools
а потом vi /data/graphite/whatever.txt
. Это прекрасно работает, потому что все контейнеры имеют одного и того же пользователя графита с совпадающим uid / gid.
Поскольку вы никогда не установить /data/graphite
от хозяина, не все равно , как хозяин UID / GID карты к UID / GID определяется внутри graphite
и graphitetools
контейнеров. Эти контейнеры теперь могут быть развернуты на любом хосте, и они будут продолжать работать отлично.
Отличительной особенностью этого является то graphitetools
, что у вас могут быть всевозможные полезные утилиты и скрипты, которые теперь вы также можете развернуть в переносном режиме.
ОБНОВЛЕНИЕ 2 : После написания этого ответа я решил написать более полный блог об этом подходе. Я надеюсь, что это помогает.
ОБНОВЛЕНИЕ 3 : я исправил этот ответ и добавил больше деталей. Ранее в нем содержались некоторые неверные предположения о владении и привилегиях - владение обычно назначается во время создания тома, т. Е. В контейнере данных, поскольку именно тогда создается том. Смотрите этот блог . Это не является обязательным требованием - вы можете просто использовать контейнер данных в качестве «ссылки / дескриптора» и устанавливать владельца / права доступа в другом контейнере с помощью chown в точке входа, который заканчивается gosu для запуска команды от имени правильного пользователя. Если кто-то заинтересован в этом подходе, пожалуйста, прокомментируйте, и я могу предоставить ссылки на образец, используя этот подход.