Я переношу существующее приложение с работы на голых экземплярах EC2 на контейнерную установку с ECS. У меня есть две ситуации, когда мне нужно обмениваться данными между контейнерами. Один - это общий ресурс EFS, в котором хранятся некоторые статические и мультимедийные файлы, другой - каталог журналов, так что я могу использовать агент Cloudwatch Logs в дополнительном контейнере для отправки журналов в Cloudwatch.
Веб-сервер должен иметь возможность записывать данные в оба этих места, но пока мне не удалось это сделать. Каталог журналов является локальным томом и принадлежит root:root
. Акция EFS, которую я установил после эти инструкция, принадлежит 1000:xfs
(без имени пользователя). Ни в том, ни в другом случае мой веб-пользователь (www-data
) пишите по этим адресам.
Как я могу указать ECS монтировать тома внутри контейнеров с указанным владельцем и / или группой?
РЕДАКТИРОВАТЬ: Оказывается, это было намного проще, чем я делал.
Когда вы переходите к созданию тома на ECS, он запрашивает у вас имя тома и «исходный путь». При нажатии для объяснения он будет указывать, что исходный путь - это «Путь к экземпляру контейнера хоста, который представлен контейнеру для этого тома. Если он опущен, то демон Docker назначает вам путь к хосту».
Все очень хорошо, но оказывается, что разница больше, чем просто «указание каталога» и «Docker выбирает каталог за вас». В этом разница между объем докера и привязать крепление, и на самом деле если вы docker inspect
в контейнере вы увидите, что тома, для которых вы указали ECS "исходный путь", получите "Type": "bind"
, тогда как тома, которые не указаны, получают "Type": "volume"
.
Одно из ключевых различий между привязками и томами заключается в том, что при привязке монтирования наследуются права собственности от хозяин файловая система, тома наследуют свое право собственности от контейнер файловая система. Итак, невероятно, разочаровывающе простое решение моей проблемы - просто убедиться, что каталог существует в образе с надлежащим владельцем, а затем создать том в ECS. без указание исходного пути.
Между прочим, если ваше приложение включает несколько контейнеров, совместно использующих один и тот же том, том будет получать свои разрешения из существующей структуры каталогов в зависимости от того, какой контейнер будет запущен и запущен. первый. Таким образом, вам необходимо убедиться, что либо а) каталог существует во всех контейнерах, в которых будет монтироваться том, или б) контейнер, в котором есть данный каталог, всегда запускается первым.
Я оставлю свое исходное решение ниже на случай, если оно кому-нибудь пригодится.
Оригинальное решение 1: tmpfs mounts
Тома Docker принимают driver_opts
параметр, который работает аналогично параметру mount
команда в системах Linux. Итак, один из вариантов - использовать tmpfs
mount, который позволяет использовать параметры, устанавливающие владельца и группу результирующих файлов. На ECS это можно сделать следующим образом:
{
"name": "myvolume",
"dockerVolumeConfiguration": {
"scope": "task",
"driver": "local",
"driverOpts": {
"type": "tmpfs",
"device": "tmpfs",
"o": "uid=1000,gid=1000"
}
}
}
Это создаст том, принадлежащий пользователю и группе 1000 в контейнере.
Обратной стороной этого метода является то, что tmpfs
, он хранит файлы в памяти хоста. В зависимости от вашего варианта использования это может быть приемлемым или неприемлемым - для меня это не идеально, потому что мне нужно хранить файлы журналов, которые могут стать довольно большими.
(Обратите внимание, что type
и device
параметры под driverOpts
здесь эквивалентны type
и device
параметры для Linux mount
команда. На это у меня ушло некоторое время и разочарование.)
Исходное решение 2: соответствие UID по NFS
NFS просто сохраняет владельца / группу файла в виде числового идентификатора. Причина, по которой группа появилась как xfs
для меня это было потому, что в рамках моего перераспределения я перехожу с Ubuntu на Alpine. В обоих случаях я хочу использовать www-data
для группы, но www-data
это пользователь / группа 33 в Ubuntu и 82 в Alpine. В Alpine 33 уже существует как пользователь "сервера шрифтов X", следовательно, xfs
.
У меня до сих пор нет идеального решения для непостоянного, общего каталога «рабочих мест», куда я мог бы сбрасывать журналы, пока они ждут отправки в Cloudwatch. Я могу просто использовать решение tmpfs, а затем запустить logrotate с очень агрессивным набором параметров, чтобы файлы журнала никогда не занимали больше нескольких МБ памяти.