Задача
На Linux запускать пользовательские приложения максимально изолированно друг от друга, контекст запуска – хостинг (apache, nginx, mysql, php, postgresql, sphinx и что там еще клиентам потребуется).
Обязательно: оградить файлы пользователей друг от друга, возможность ставить любой софт, который потребуется клиенту.
Желательно: ограничить потребление процессора, памяти, изолировать сеть (чтобы по сети к соседнему MySQL не подключались), минимальное падение производительности, простота.
История
Как вариант имел ввиду OpenVZ и создавать каждому клиенту по виртуальной машине. В целом хорошо, но OpenVZ относительно сложно ставится, требует изменений в ядре. Из этого вытекает предполагаемая сложность поддержки и обновлений.
Остановился на варианте созданий chroot-окружений и запуска всех процессов каждого пользователя в этих окружениях в файлово изолированной среде. Проброс общих папок через mount –bind в режиме readonly.
Подход тоже неплохой, проще чем OpenVZ и в целом изоляцию пользователей обеспечивает. Ресурсы можно ограничивать через cgroup.
Из недостатков:
- огромное количество точек монтирования выводимое по mount
- сервер не перезагружается (т.е. при попытке выполнения reboot он что-то там пытается отмонтировать и до перезагружки дело не доходит, приходится перезагружать по плохому)
- оказалось проблемным отправлять почту из chroot (но это решил)
- не работает cron (это тоже решается, например можно из хост-системы запускать стандартный крон и каждый раз chroot’иться).
Начал уже думать над объединением пользовательских процессов в cgroup, попробовал на одном из сайтов как это работает и остался доволен.
Решение
В итоге наткнулся на lxc – linux containers. Собственно это примерно то же самое что я сам делал, только в более зрелом состоянии – утилиты для запуска/остановки, монитор состояния, сразу объединение процессов в cgroup. Плюс очень кстати оказалась изоляция сети.
Из недостатков:
Насколько я понял если пользователь внури lxc получает root-а, то у него есть возможность выбраться в хост-систему. Это нужно иметь вводу, но в моём случае неактуально – у конечных клиентов нет root-доступа.