Процесс контейнера докеров, запущенный от имени пользователя без полномочий root, не может записывать в том докера

TLDR

  • все рекомендуют процессы внутри контейнеров никогда не запускать от имени root
  • (за исключением kubernetes) похоже, что не существует хорошего подхода devops/configuration-as-code для получения правильного владельца/разрешений, установленных на томах докеров, поэтому пользователь (не root) не может записывать в том

Что является хорошей практикой при запуске процесса контейнера в качестве пользователя non-root, и я хочу записать в том докера (cloudstor, aws-ebs).


Длинная история

В док-контейнерах (и за их пределами) считается плохой практикой запускать процессы от имени пользователя root (см., например, ref1, ref2, ...). Это может иметь последствия для безопасности.

Но когда мы начинаем использовать тома докеров, и этот пользователь без полномочий root пытается записать в том, начинаются проблемы. Мне не удалось найти чистое решение, которое будет работать в облачной инфраструктуре без ручного вмешательства. Рабочие решения, которые я нашел, кажется, не соответствуют некоторым пунктам (безопасность, ремонтопригодность и т. д.).

В качестве примечания: мы развертываем на docker-swarm, используя cloudstor для предоставления aws-ebs томов. Мы надеемся когда-нибудь перейти на kubernetes, но у нас пока нет kubernetes, поэтому мы пытаемся найти альтернативное решение для нашей установки.

Рассмотренные решения / обходные пути

1. Предварительно создайте том в образе докера

Как предложено здесь, если docker-compose создает новый том, будут распространяться разрешения на каталог внутри образа.

минусы:

  • это не сработает, если том существовал раньше или если это папка на диске
  • если том подготовлен с помощью cloudstor, вероятно, это тоже не сработает, потому что это не будет docker-compose инициализация тома (не тестировалось)

2. Используйте Volumes-Provisioner

hasnat создал образ volumes-provisioner, который может установить правильные разрешения для папки непосредственно перед начинается настоящий контейнер.

минусы:

  • нужно добавить дополнительный сервис в стек докеров. Эта служба умирает почти мгновенно (после установки разрешений).
  • Настоящий контейнер должен зависить от Volumes_Provisioner. При повторном развертывании того же стека (после изменения конфигурации) порядок выполнения не гарантируется
  • ebs тома могут быть смонтированы только в одном док-контейнере, что вызвало множество проблем с развертыванием.

3. Используйте docker run для исправления прав доступа к файлам.

Как только реальный контейнер запускается с подключенным томом (но все еще с неправильными разрешениями), мы вызываем

docker run --rm -u root -v ${MOUNT}:${TARGET} { real_image } chown -R user:group ${TARGET}

минусы:

  • том ebs может быть смонтирован только в одном контейнере, поэтому это создаст конфликты
  • эту команду можно запустить только после развертывания стека докеров (в противном случае том еще не был подготовлен), поэтому между реальным запуском контейнера и правильными разрешениями будет задержка. Это означает, что при запуске реальный контейнер находит том с неправильными разрешениями, поэтому это будет работать только в том случае, если служба продолжает проверять, были ли исправлены разрешения.

4. Смена владельца при запуске контейнера

Из этого следует:

  • запуск процесса от имени пользователя root (иначе мы не имеем права менять владельца каталога/права доступа)
  • смена владельца/разрешений
  • переключение на non-root пользователя

минусы:

  • все еще есть (незначительный?) период времени, когда процесс контейнера работает как root (последствия безопасности?)
  • нужно взломать точки входа, переопределить пользователя,... официальных изображений, чтобы это заработало

5. Просто запустите как root

Это самое простое решение, но что тогда с безопасностью? И все рекомендуют не этого делать?

6. Используйте кубернет

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

минусы:

  • (к сожалению) мы пока не используем kubernetes.
  • (не испытано.)

7. создайте папки в файловой системе с правильными разрешениями

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

недостатки

  • это не облачное хранилище... а если контейнер переключится на другую ноду? или если сервер рухнет? (именно поэтому мы используем cloudstor, что позволяет нам даже переключать зоны доступности)
  • не похоже на конфигурацию как код

person Chris Maes    schedule 09.09.2020    source источник
comment
Запуск служб от имени пользователя root в k8s не рекомендуется. Для среды docker-compose мы создаем все без запуска служб (docker-compose up --no-start), затем устанавливаем разрешения (docker run --rm -it --volumes-from ... --entrypoint chown alpine:3 -R 1000:1000 /data), затем запускаем службы. Для обычной практики k8s afaik использует initContainers.   -  person masseyb    schedule 21.09.2020
comment
вы не можете добавить пользователя докера в группу пользователей, у которой есть доступ к тому?   -  person clogwog    schedule 23.09.2020
comment
@clogwog пользователь, запускающий процесс внутри контейнера, отличается для каждого контейнера и отличается от пользователя докера   -  person Chris Maes    schedule 23.09.2020


Ответы (1)


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

person Cyril G.    schedule 23.09.2020