У меня вопрос к разрешениям томов докеров.
Теперь я установил докер на нескольких серверах, и для некоторых контейнеров я использовал точки монтирования привязки, а для других я использовал именованные тома, которые для меня кажутся одинаковыми - единственное различие, которое я вижу, это каталог (/var/lib/docker/volumes/...
или выбрал сам).
Теперь у меня есть один вопрос, касающийся передовых практик развертывания докеров.
UID и GUID используются совместно с хост-системой. Предположим, что в контейнере A есть приложение, которое запускается от имени пользователя db с UID, равным 800, и на соответствующем томе есть очень важные производственные данные. В моей хост-системе UID 800 может быть практически любой службой, предположим, что это простая служба. Эта служба потенциально может получить доступ к данным контейнера.
В этом случае желательно использовать именованные тома, потому что они находятся в каталоге, который защищен от обычного доступа пользователей, или, по крайней мере, не создавая тома в общедоступных местах (/, / srv, ...),
Когда я изначально создаю именованный том, он создается внутри /var/lib/docker/volumes/...
. В большинстве случаев это означает, что приложение внутри контейнера, которое не запускается от имени пользователя root, не может создавать файлы на томе. Следовательно, каждое приложение, которому требуются определенные папки и разрешения, должно установить это в сценарии ENTRYPOINT перед передачей приложению.
Это предполагаемое поведение? А как теперь переместить именованный том? Docker, похоже, не поддерживает это из коробки. Я видел множество подходов, в которых используется только tar или создается контейнер, экспортирующий тома, но кажется, что это очень сложно автоматизировать. Есть ли более простой / официальный / сценарий для переноса (именованных) томов, в идеале путем создания архива, который просто импортировать? Или я что-то здесь не понимаю?
В большинстве случаев это означает, что приложение внутри контейнера, которое не запускается от имени пользователя root, не может создавать файлы на томе.
Это только в том случае, если образ, который вы использовали для создания именованного тома, не имеет каталога в образе или этот каталог в образе не принадлежит правильному пользователю. Тот факт, что / var / lib / docker заблокирован и разрешает только root, никоим образом не мешает контейнерам использовать тома внутри этого каталога в качестве пользователя.
Именованные тома обычно имеют меньше проблем с разрешениями, потому что они будут инициализированы с использованием содержимого образа в указанном месте. Когда вы создаете образ и пользователя внутри этого образа, вы захотите chown / chmod для любых каталогов, к которым пользователю необходим доступ в рамках процесса создания образа. Возможные проблемы, которые я видел у людей, пробующих это:
Определение тома в Dockerfile, а затем попытка обновить каталог. Это не сработает, каталог монтируется как том во временном контейнере во время выполнения команд RUN, и любые изменения этого тома отменяются после завершения команды RUN. Я обычно рекомендую удалить определения томов из Dockerfile, если вы их контролируете.
Изменение пользователя во время выполнения на другой uid от uid внутри образа. В этом случае для образа неправильно настроены права доступа к каталогу, и он неправильно инициализирует именованный том. Поскольку вы изменили uid во время выполнения, вам необходимо исправить разрешения во время выполнения с помощью точки входа или второго контейнера, который монтирует тот же том.
Изменение uid или каталога внутри образа после того, как кто-то уже развернул контейнеры с именованными томами на основе более старой версии. Именованные тома инициализируются только тогда, когда они пусты, поэтому изменение образа не изменит уже существующий том, у которого теперь неправильный владелец / права.
Использование тома с одинаковым именем двумя разными контейнерами одновременно. В этом сценарии именованный том будет инициализирован один раз, и вопрос о том, какой образ используется для инициализации этого тома, является условием гонки, зависящим от того, какой контейнер создается первым.
Обратите внимание, что угроза безопасности хост-томов заключается в том, что уязвимое приложение на хосте, работающее с тем же UID привилегированного приложения внутри контейнера, может получить доступ к этому контейнеру. Хотя это и нехорошо, это не побег из контейнера.
Вы можете включить пространства имен пользователей, чтобы избежать этого риска, но когда вы это сделаете, имейте в виду, что тома хоста, которые намеренно сопоставляются с пользователями или группами на вашем хосте, больше не будут работать, включая разработчиков, монтирующих код для быстрой разработки, и инструменты, которые монтируют докер розетка для управления. Поскольку пользовательские пространства имен реализованы для всего экземпляра докера, а не для каждого контейнера, перед внесением изменений вы должны убедиться, что нет сценариев, в которых они не будут работать для вас.
Перемещение данных в именованный том и из него всегда выполнялось с помощью перенаправления ввода-вывода tar и docker, но после этого вам нужно будет добавить шаг chmod / chown, если вы измените владельца с хоста на контейнер:
# import data
tar -cC source_dir . | \
docker run --rm -i -v target_vol:/target busybox tar -xC /target
# export data
docker run --rm -v source_vol:/source busybox tar -cC /source . | \
tar -xC target_dir