Rails: стратегия развертывания нескольких приложений
В моей компании в настоящее время у нас есть один главный проект, который представляет собой большое монолитное приложение Rails. Развертывание - это просто, у нас есть пара внешних серверов (с настройкой Puppet), на которые Capistrano развертывается. /var/www/<hostname>/current
, Затем он перезапускает Unicorn (нулевое время простоя!), И все счастливы.
К сожалению, есть проблема. Монолитный характер приложения начинает кусать нас. Теперь на выполнение всех тестов уходит более 30 минут, и это замедляет нас. Мы стремимся разделить его на более мелкие куски и принять архитектуру µService. Однако это заставило меня задуматься о нашей стратегии развертывания. Как оно стоит:
- приложение Rails и Nginx работают как
www-data
пользователь - Развертывать могут все пользователи, имеющие доступ к коробке (в Capistrano мы
chown
материал для пользователя приложения во время развертывания)
Безопасность этого достаточно низкая (все работает под одним и тем же пользователем, каждый может получить доступ ко всему). Это также напоминает мне о том, как мы работали в предыдущей компании - это был кошмар, так как все приложения зависли на Ruby 1.6, поскольку они использовали одну и ту же версию.
Я думаю, что мы можем сделать это лучше, установив rbenv
разрешить каждому приложению запускать свою собственную версию Ruby и иметь пользователей для каждого приложения для повышения безопасности. Но я на самом деле не видел примеров этого на практике. Например, сигналы 37 запускают все приложения от одного и того же пользователя - я обеспокоен тем, что есть веская причина, по которой приложения не должны запускаться как разные пользователи.
Чтобы подвести итог:
- Каков наилучший способ развертывания нескольких приложений Rails на сервере в архитектуре стиля µService?
- Каков наилучший способ изолировать каждое из приложений (с точки зрения версий Ruby и безопасности пользователя)?
Заранее спасибо!
2 ответа
Для нескольких экземпляров Ruby я бы определенно рекомендовал RVM (Ruby enVironemnt Manager). Я нашел его более надежным, чем rbenv для производственных сред.
Nginx может связываться с привилегированными портами (<= 1024), только если запущен как привилегированный пользователь. Таким образом, может потребоваться настройка обратного прокси-сервера для удовлетворения ваших потребностей при запуске каждого экземпляра Unicorn как отдельного процесса разрешенным пользователем.
Если ваша оценка работы каждого из них на отдельной виртуальной машине является окончательной, способ изолировать каждое приложение в GNU/Linux - это SELinux. SELinux довольно сложен, но предоставляет средства, позволяющие безопасно разделять процессы и контекст.
У нас похожая конфигурация (хотя мы работаем с Tomcat и Grails вместо nginx и RoR). Мы настроили индивидуальные идентификаторы пользователей для каждого экземпляра Tomcat. Мы устанавливаем домашние каталоги для Java, Grails и любых других зависимых библиотек в.profile для пользователя в качестве переменных среды, чтобы каждый Tomcat мог работать с любой версией, которую мы установили.
Пользователь ID пользователя нашего программного обеспечения для автоматического развертывания (Atlassian Bamboo) является членом группы, назначенной каждому из каталогов Tomcat.