Подтвердить что ты не робот

Докер с использованием gosu vs USER

Docker всегда существовала команда USER для запуска процесса как конкретного пользователя, но в целом многое должно было выполняться как ROOT.

Я видел много изображений, которые используют ENTRYPOINT с gosu для отмены процесса для запуска.

Я все еще немного запутался в необходимости gosu. Должно ли ПОЛЬЗОВАТЕЛЯ быть достаточно?

Я знаю, что с точки зрения безопасности с Docker 1.10 я немного изменился, но я до сих пор не совсем понимаю, как использовать этот процесс в контейнере докеров.

Может кто-нибудь объяснить, когда я буду использовать gosu vs. USER?

Спасибо

EDIT:

Руководство Docker не очень понятно: в нем говорится, что если процесс может работать без привилегий, используйте USER, если вам нужно sudo, вы можете использовать gosu. Это сбивает с толку, потому что можно установить всевозможные вещи как ROOT в Dockerfile, затем создать пользователя и предоставить ему соответствующие привилегии, а затем, наконец, переключиться на этого пользователя и запустить CMD в качестве этого пользователя. Итак, зачем нам sudo или gosu тогда?

4b9b3361

Ответ 1

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

После создания изображения что-то вроде gosu позволяет отбрасывать права root в конце вашей точки входа внутри контейнера. Первоначально вам может потребоваться доступ root для выполнения некоторых этапов инициализации (исправление разрешений на использование uid, хоста и т.д.). Затем после инициализации вы запускаете окончательную службу без привилегий root и как pid 1 обрабатываете сигналы чисто.


Изменить: Вот простой пример использования gosu в изображении для докеров и дженкинсов: https://github.com/bmitch3020/jenkins-docker

Entrypoint.sh просматривает gid файла /var/lib/docker.sock и обновляет подсказку пользователя докера в контейнере, чтобы он соответствовал. Это позволяет переносить изображение на другие хосты докеров, где gid на хосте может отличаться. Для изменения группы требуется корневой доступ внутри контейнера. Если бы я использовал USER jenkins в файле dockerfile, я бы застрял в god группы докеров, как это определено в изображении, которое не сработало бы, если оно не соответствует тому, на котором он работает. Но root-доступ можно отбросить при запуске приложения, в которое входит gosu.

В конце script вызов exec запрещает оболочке открывать gosu, и вместо этого он заменяет pid 1 этим процессом. Gosu, в свою очередь, делает то же самое, переключая uid, а затем выполняет процесс jenkins так, чтобы он принимался за pid 1. Это позволяет правильно обрабатывать сигналы, которые в противном случае игнорировались бы оболочкой как pid 1.

Ответ 2

Я использую gosu и entrypoint.sh, потому что я хочу, чтобы пользователь в контейнере имел тот же UID, что и пользователь, создавший контейнер.

Объемы и разрешения Docker.

Целью контейнера, который я создаю, является разработка. Мне нужно собрать для Linux, но я все еще хочу все возможности локального (OS X) редактирования, инструментов и т.д. Мое сохранение идентификаторов UID внутри и снаружи контейнера делает владение файлом намного более разумным и предотвращает некоторые ошибки ( пользователь контейнера не может редактировать файлы в подключенном томе и т.д.)

Ответ 3

Преимуществом использования gosu является также обработка сигналов. Вы можете trap, например, SIGHUP для перезагрузки процесса, как обычно достигаете с помощью systemctl reload <process> или такого.

Ответ 4

Я пытался решить проблему с разрешениями в Docker-контейнере без GOSU-зависимости. Совсем. Мой подход заключается в том, чтобы изменить идентификатор пользователя контейнера на лету, перестроив контейнер в задании jenkins (или там, где мне нужно развернуть мои приложения).

Здесь ниже я приведу пример, как я это сделал.

Образец Dockerfile:

FROM imageWhereIWantToSetSameUidAsOnMyHostMachine

USER root

RUN usermod -u {{UID}} www-data

USER www-data

Перед созданием контейнера (скажем, в задании jenkins) с использованием этого Dockerfile я использую команду sed, чтобы заменить заполнитель идентификатора пользователя {{UID}}:

CURRENT_UID=id -u $(whoami)
sed -i -e "s/{{UID}}/$CURRENT_UID/g" Dockerfile

затем я строю контейнер:

docker build -t myImageWithFixedPermissions .

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

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

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

Заранее спасибо за ответ!