воскресенье, 19 октября 2014 г.

Немного про docker и про запуск cron внутри docker контейнера.

Docker хорош, но несмотря на многие плюсы контейнеризации, и мою любовь к докеру, которая впрочем больше похожа на "ну наконец то и под линухом пере-изобрели jail", есть у контейнеров большие и весомые минусы.

Минусов этих много, но лежат они в довольно странной плоскости, и не видны с первого раза.

Я обязательно буду на них еще не раз останавливаться, поэтому очень коротко и только несколько отмечу.

1. Ресурсы. До нормального ограничения еще далеко.
2. Привычки и утилиты управления. Скорее всего ваш админ сходу ответит на любой вопрос о процессах в хост-системе. А вот с контейнерами внезапно не так очевидно становится. Простой пример: netstat -4na, где сокеты от процесосов в конвейрах? И так во всём. Привычные, вбитые годами опыта команды которые сидят на кончиках пальцев вдруг перестают работать.
3. Связи. Только что вас убеждали что контейнеры туда сюда можно носить, но вот внезапно вы отнесли контейнер и --link не сработал на разные машины.
Ну и куча других. Но сегодня не об этом.

Многие минусы видны не сразу, плюс контейнеры сейчас модная тема, поэтому получаем привычный график:

Docker сейчас, как мне кажется,  в самом пике завышенных ожиданий.
Пожелаем ему пережить неизбежный спад, и стабилизироваться.

Возникла на днях, типовая задача, есть скажем так, сайтик, написанный сторонними ребятами, который нужно запустить внутри моей инфраструктуры.

Запускаем в контейнере докера, потому как на время внедрения, будем сильно и интенсивно пилить, разные люди по разному, и хотим на одной кодовой базе иметь пяток клонов, на которых разные люди потренируются.

Затем, когда обучение пройдет,и доработки по выявленным пожеланиям будут сделаны, запустим по взрослому.

Код конечно же на пхп, требований особых нет, всего несколько зависимостей.

Отлично. Настраиваем. поднимаем, клонируем.
Есть у нас несколько веб workers (php5-fpm) и несколько баз (mysql).
Все слинкованы в нужных парах, работают. Общий фронт-nginx для всех корректно выбирает нужный контейнер.

Тут выясняется что там есть некие задания по шедулеру, и нужно в крон напихать кучу всего.

Запустить крон "снаружи" со стороны host системы я не могу.
У него не будет ни зависимостей, ни линка к нужным контейнерам с базами.


Релиз  docker с exec позволяющий подсадить в рабочий контейнер процесс, вышел только-только и до нас еще не докатился.

На помощь приходит supervisord.

Вписываем в Dockerfile
RUN DEBIAN_FRONTEND=noninteractive apt-get install cron
VOLUME ["/etc/cron.d/"]
 ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
 CMD ["/usr/bin/supervisord","-c","/etc/supervisor/supervisord.conf"]
и в supervisord.conf
[supervisord]
nodaemon=true
[program:cron]
directory = /etc/cron.d/
command = /usr/sbin/cron -f
autorestart = true
 [program:php5-fpm]           
directory = /etc/php5
command = /usr/sbin/php5-fpm -R --fpm-config /etc/php5/fpm/php-fpm.conf
autorestart = true
И перезапускаем контейнеры с -v /var/lib/shared/cron:/etc/cron.d/

Всё. заработало.

Но давайте поразмышляем.
У нас же был контейнер под процесс,  из за этого мы хотели нагрузку планировать то сё, ставить лимиты.
И вот в рядовой наипростейшей ситуации уже выяснилось что процесс не один, а разнотипные два, и пришлось колхозить третий (supervisord) который за ними следит.
И уже не так очевидно с лимитами.
И супервизоров этих по числу контейнеров, и как то волосы перестают уже быть шелковистыми.
 Следом понадобится какой нить monit, и какой нить отсылатель логов  в logstash , и пара-тройка итераций, и ты уже пытаешься понять, а не пора ли контейнер этот в виртуалочку бы сунуть?

Разубедите меня. Где ошибка размышлений?