Назад | Перейти на главную страницу

Разрешения на том Docker в ECS

Я переношу существующее приложение с работы на голых экземплярах 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 с очень агрессивным набором параметров, чтобы файлы журнала никогда не занимали больше нескольких МБ памяти.