LINUX.ORG.RU

Рабочий процесс по Docker

 ,


0

3

Добрый день!

Знаю как сделать и запустить образ, но есть несколько вопросов уже по эксплуатации:

  1. «Докеризация». Столкнулся с тем, что трудно поддерживать веб-приложение на nodeJS, готовое для запуска как в «обычной среде», так и в Докере.

    Конкретно:

    1. «npm install» под рутом не выполняет скрипт из секции «scripts>install» из «package.json», это обходится, но все же.
    2. для докера надо отдельно ставить crontab и запускать его.
    Получается целых два набора для подготовки среды. Как обычно делают, чтобы работало и там и там?
  2. Концепция один сервис-один контейнер это хорошо, но как связывать их между собой? Подозреваю что есть куча вариантов, какой оптимальный?
  3. Конфигурирование. Например, нужно выставить интервалы крону. Открыть редактор при выполнении "docker build" как оказалось невозможно. Передавать через окружение? Заранее редактировать конфиг? Как обычно делают?

Опеншифт, кубернетес, композ, сварм.

slaykovsky ★★★ ()

1а) Ну так делай контейнер так, чтобы команда запускалась не под рутом.

1б) crontab не вписывается в концепцию один контейнер - один сервис (crontab - второй сервис). Или плоди в кроне хост-системы docker exec, или используй какие-то системы типа кубернетеса, опеншифта, ранчера.

2) Куча вариантов, все относительно оптимальны, смотреть под конкретную задачу. Можешь создавать приватные сетки, можешь делать docker-compose и поднимать все пачками, можешь просто плодить контейнеры и связывать их по хостнейму.

3) Докер предусматривает выполнение только одного процесса единовременно. То есть если у тебя контейнер делает npm start и работает, то он уже не сможет сделать logrotate, cron или что-либо еще. Можно изобретать велосипед и при запуске контейнера стартовать не сам сервис, а какой-то самописный оркестратор, который сначала запустит сервис, а потом будет выполнять какие-то вспомогательные задачи, но это извращение.

Идеальные варианты решения всех проблем, кроме 1а, написал первонах. Я лишь докину в список Rancher.

l0stparadise ★★★★★ ()
Ответ на: комментарий от slaykovsky

Набор слов.

OpenShift - это PaaS-платформа, основанная на Kubernetes. Swarm - альтернатива Kubernetes (не лучшая) Compose - вообще не к месту тут.

dvrts ★★★ ()

Концепция один сервис-один контейнер это хорошо, но как связывать их между собой? Подозреваю что есть куча вариантов, какой оптимальный?

Kubernetes - самое зрелое и правильное решение (даже несмотря на то, что поначалу может быть сложнее в освоении по сравнению с альтернативами).

dvrts ★★★ ()
Ответ на: комментарий от l0stparadise

Ну так делай контейнер так, чтобы команда запускалась не под рутом

Да, пробовал, появились другие проблемы (сейчас не припомню) Во всех манах что я видел, все работает под рутом. Это чтобы не заморачиваться? Как труЪ? :)

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

Крон по-любому нужен. А как иначе что-то делать по расписанию? Поднимать другой контейнер, чтобы он лез в этот? :) Или это будет делать оркестратор? Еще не смотрел как все это работает...

Сейчас так: запускается баш

# Запуск крона
service cron start

# Запуск веб-сервера
pm2 start scripts/server.js

# Запуск клиента телеграммы
pm2 start scripts/telegram.js

# Запуск менеджера задач
pm2 start scripts/taskmanager.js

Тут ведь еще один скрипт работает как веб-сервер, другой для телеграммы, другой работает для получения данных.

Может просто мой случай не укладывается на в концепцию «1 сервис - 1 докер»?

nodejs ()
Ответ на: комментарий от dvrts

Концепция один сервис-один контейнер это хорошо, но как связывать их между собой? Подозреваю что есть куча вариантов, какой оптимальный?

Я написал оптимальные. Ты говоришь набор слов. Ты про Origin не слыхал, шоли? Или чем compose ему не подходит? Swarm не осилил?

slaykovsky ★★★ ()
Ответ на: комментарий от nodejs

Крон подымаешь в отдельном контейнере (можно даже на каждую задачу - отдельный контейнер с кроном). С другими частями системы он общается по API других частей системы.

anonymous ()
Ответ на: комментарий от anonymous

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

Теперь, допустим, у нас балансировка, и фронты веб-приложения раскиданы на несколько нод. Значит крон должен запустить скрипт, который опроси некий мастер-контейнер, который сообщит, какие ноды сейчас активны, и в них надо «залесть»? Схема становится все более и более сложной.

Так обычно делают на продакшенах?

nodejs ()
Ответ на: комментарий от nodejs

какие ноды сейчас активны

это называется Service Discovery

«залесть»

Что значит залезть? Контейнер не должен хранить какое-то состояние внутри себя (если это не контейнер с какой-нибудь базой данных), а значит, и залезать туда незачем. Если тебе надо, к примеру, регулярно заливать порцию внешних данных в БД - это отдельный сервис, он не связан ни с чем, кроме контейнера с БД.

anonymous ()
Ответ на: комментарий от nodejs

Бред. Выкинь крон и используй любые нормальные решения для service discovery, например, consul

Shtsh ★★★★ ()
Ответ на: комментарий от nodejs

Root в контейнере сильно ограничен, так как сильно режутся capabilities. Так что это безопасно.

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

Shtsh ★★★★ ()

1) В Продакшене и при разработке запуск обычно отличается. Альтернатива - при разработке подключаться к развернутому окружению на тестовом окуружени. Самые популярные способы - для разработки используют compose, для деплоймента - что-то поверх mesos (marathon или kubernetes)

2) существует куча решений, например, consul + consul-template для генерации конфигов. Для compose можно использовать docker links.

3) Обычно используют разные key/value storage, например, consul, zookeeper или etcd.

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

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

Shtsh ★★★★ ()
Ответ на: комментарий от Shtsh

ты вообще не удосужился погуглить, как строят распределенные системы

Может меня не поняли. Мне не нужна распределенная система. Я читал как делается шардинг на монге, классно кстати придумано, но мне до этого далеко.

У меня простенькое приложение без распределения, все в одном контейнере. Я столкнулся с тем, что в манах пишут какие-то простые случаи. Хочется посложнее, но не сразу все, а то закопаюсь в инфраструктуре.

регулярно заливать порцию внешних данных в БД - это отдельный сервис

Мой случай - три сервиса: веб-сервер, заливалка данных, бот телеграмма

Правильно понял, что надо все это разбить на три контейнера? Но у них есть общие библиотеки, скриптики лежат рядом с друг другом. Чисто технически как это должно выглядеть? в каждый Dockerfile прописать по одному варианту?

CMD [ "npm", "webserver" ]
CMD [ "npm", "taskmanager" ]
CMD [ "npm", "telegram" ]

или

CMD [ "npm", "start" ]

а что уже должно стартовать - передавать через окружение?

Обычно используют разные key/value storage

буду читать

это называется Service Discovery

спасибо

Что значит залезть?

я имел в виду: нода с кроном дергает другую ноду и говорит «выполни задание»

nodejs ()
Ответ на: комментарий от nodejs

Чисто технически как это должно выглядеть?

Вынеси общий код в библиотеку, опубликуй, подтягивай через зависимости и require. Один сервис - одна кодовая база.

anonymous ()
Ответ на: комментарий от Shtsh

2) существует куча решений, например, consul + consul-template для генерации конфигов. Для compose можно использовать docker links.

consul

спасибо, не слышал о таком, надо попинать.

l0stparadise ★★★★★ ()
Ответ на: комментарий от nodejs

Правильно понял, что надо все это разбить на три контейнера? Но у них есть общие библиотеки, скриптики лежат рядом с друг другом. Чисто технически как это должно выглядеть? в каждый Dockerfile прописать по одному варианту?

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

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

l0stparadise ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.