С Новым Годом, Хабр!
Первого января все нормальные люди занимаются прокрастинацией, уничтожением стратегического запаса оливье и прочими, не связанными с физической или интеллектуальной нагрузкой вещами. Вот и я планировал присоединиться к этой новогодней армии, но не тут-то было!
Во всём виноват Хабр!
…. Точнее хабражители! А, если ещё точнее, всему виной — предновогодние статьи, в которых два никак не связанных между собой юзера изобрели два почти одинаковых велосипеда. Итак, встречайте моих сегодняшних героев!
Как создавался новогодний Хабрачат в этом году
Скачивается бинарник под нужную платформу из релизов на github. Можно положить его, например, в
/usr/bin
. Далее пишем простой скрипт, который будет перезапускать сервер, в случае падения.… (пропущен башизм с бесконечным циклом и прочими sleep-ами)
© оригинал
Безумный дом
В процессе эксплуатации я заметил, что Domoticz иногда падает с ошибкой. Чтобы поднимать его автоматически, напишу watchdog с помощью cron.
… (пропущены башизм, на пару с кронтабом)
Теперь каждые 5 минут будет запускаться скрипт, который проверит, работает ли Domoticz и перезапустит его, если это необходимо
© оригинал
Что с этим делать и как дальше жить?
Я совершенно не планировал писать статью освещающую самые основы systemd, у меня в планах цикл статей из разряда «systemd для продолжающих», но жизнь, как видно, вносит свои коррективы, в результате пусть моя сегодняшняя, коротенькая статья будет своеобразным прологом к планируемуму циклу. Но так как про написание сервисных юнитов systemd написано 100500 хаутушек, то мы осветим только параметры относящиеся к автоматическому перезапуску сервисов, на конкретных примерах (и на затравку кое-что ещё ;-), в применении к статьям двух уважаемых хабровчан.
Делаем всё по фен-шую
Ну, я надеюсь, вы тут все достаточно технически грамотные, поэтому я сразу приведу готовые, самодокументированные юниты и конфиги, а также команды запуска всего этого безобразия.
«Как создавался Хабрачат в этом году»
Юнит(/etc/systemd/system/ssh-chat.service
):
[Unit]
Description=SSH Chat Service
After=network.target network-online.target
[Service]
# Пользователь и группа, с правами которых будет запускаться сервис
User=ssh-chat
Group=ssh-chat
Type=Simple
ExecStart=/usr/local/bin/ssh-chat --admin=/etc/ssh-chat/admins --bind=0.0.0.0:22 --log /var/log/ssh-chat.log --motd=/etc/ssh-chat/motd
# В каких случаях сервис будет автоматически перезагружаться.
# on-failure — в случае выхода с ненулевым кодом возврата.
Restart=on-failure
# Таймаут перед загрузкой сервиса, после падения.
RestartSec=1
# Capablities для сервиса. В данном случае - разрешение сервису
# биндиться на привилегированные порты (< 1000)
AmbientCapablities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multiuser.target
Конфиг для systemd-sysusers.service(/etc/sysusers.d/ssh-chat.conf
):
u ssh-chat - "SSH Chat user" /etc/ssh-chat
# Поля записи:
# u : создаём пользователя
# ssh-chat : username
# - : или UID[:GID] в данном случае автоматически занять свободные UID/GID < 1000
# "SSH Chat user" : Описание, или "-", если не нужно.
# /etc/ssh-chat : Home Directory
# Может быть ещё одно поле -- login shell. По умолчанию /usr/bin/nologin
Инсталляция и запуск:
sudo systemctl restart systemd-sysusers.service && sudo systemctl enable --now ssh-chat
«Безумный дом»
Юнит(/etc/systemd/system/domoticz.service
):
[Unit]
Description=Domoticz Daemon
After=network.target
[Service]
User=http
Group=http
# Эта директива позволяет выполнять подготовительные действия перед
# запуском сервиса. Модификатор "+" указывает выполнять их от рута.
ExecStartPre=+/usr/bin/install -d -m 0700 -o http -g http /var/run/domoticz
ExecStart=/opt/domoticz/domoticz -www 8080 -pidfile /var/run/domoticz/domoticz.pid
PIDFile=/var/run/domoticz/domoticz.pid
WorkingDirectory=/opt/domoticz
# Всё то же самое, что и в случае "хабрачата", только таймаут 5 секунд.
RestartSec=5
Restart=on-failure
[Install]
WantedBy=multi-user.target
Инсталляция и запуск:
sudo systemctl enable --now domoticz
Что дальше?
Возможности systemd, кратко освещённые в этой статье, а так-же многие другие, более подробно будут разобраны в следующих статьях цикла. Триггеры, поддержка бинарных форматов, «прозрачные»(transient) юниты, встроенная контейнеризация and more, more... Но нетерпеливые могут уже «вот прям щаз» заняться чтением одной из лучших документаций в мире линукс. Маны которые можно почитать по сегодняшней теме:
man systemd.unit
man systemd.service
man systemd.exec
man systemctl
man sysusers.d
man systemd-sysusers
И на закуску маленький секрет. Один из моих любимых манов: man systemd.directives
- путеводитель по всем директивам конфигурации которые могут встретиться вам в процессе изучения systemd.
Ещё раз С новым Годом, Хабр! И используйте правильные инструменты!
PS: Добавил ссылку на ман по systemd.exec. Как-то я про него малость забыл.
PPS: Добавил ссылки на ресурсы.
Список статей серии
Почему хабражители предпочитают велосипеды, вместо готовых решений? Или о systemd, part 0
Systemd для продолжающих. Part 1 — Запуск юнитов по временным событиям
Ресурсы
systemd.io — Статьи по внутренней кухне systemd. Частенько упоминается в манах.
systemd @ freedesktop.org — Основная страница с манами, документацией, видео, блогами и прочими ссылками на ресурсы.
@ru_systemd — Русскоязычный чат в Telegram. У нас тепло и лампово.
apapacy
Интересная тема. Необходимость заполнить конфиги sgstemd возникает крайне редко, чтобы изучать всё тонкости. Как правило обзожусь копипастой с беглым пролитыванием документации. Поэтому узнать как правильно нужно сделать и почему у очень хорошая задумка
Oxyd Автор
Ну на самом деле, если не закапываться, то обычному пользователю достаточно почитать маны перечисленные выше, плюс маны по journad/journalctl и маны по таймерам, если хочется функциональности и удобства побольше чем в cron. Дальше уже идут всякие интересные, но не так сильно распространённые, штуковины.
VolCh
Тут проблема в том, что обычному пользователю (разработчику, например) чтение маеов по администрированию впрок, мало полезно. Хорошо, если получится запомнить какие возможности есть в теории.
С другой стороны, systemd есть не везде по дефолту, если говорить о мире виртуалок, контейнеров и прочих облак.
vvbob
Пользователю полезно держать в голове набор правил вида — «если тебе нужно это, то используй вот то», часто люди начинают городить велосипеды на костылях просто потому что не знают что есть готовое решение, которое просто нужно использовать.
Зная что для твоей задачи лучше всего использовать, например, systemd, уже легко сможешь найти всю необходимую информацию о том как его использовать, в сети или в манах все легко находится.
VolCh
А маны по другому устроены:
:(
vvbob
Это да, но вот лично для меня обычно главная проблема это понять каким инструментом лучше всего решается задача, вопрос как ее решать уже чаще всего намного проще, тем более по распространенным инструментам обычно в сети много инструкций в которых все подробно описано.
dikkini
так именно этими знаниями (знанием что лучше использовать) и ценится IT специалист (developer, system/software engineer), а не способностью печатать буковки на клавиатуре — это и обезьяна умеет
gecube
Недостоверно. На уровне операционки — он есть уже везде. Там, где нет — это маргиналы, которые скорее всего знают, как жить без него.
Единственное, где боль — это «засунуть системди в контейнер», но это не нужно, потому что там сама система оркестрации (тот же кубернетес) берет на себя функции системди (запуск, хелсчеки, управление ресурсами и пр)
Oxyd Автор
У systemd есть своя собственная система контейнеризации systemd-nspawn, в которой запихать в контейнеры systemd можно, а местами даже нужно. Так что это не принципиальная невозможность, а особенности конкретной реализации контейнеров. Но для контейнеров приложений, где 1 контейнер == 1 приложение (докер/кубер и и же с ними) systemd внутрь запихивать и не нужно.
gecube
спасибо, я в курсе. А еще можно не играть с контейнеризацией nspawn, а попросту использовать те механизмы изоляции, которые предоставляет сам systemd — там и изоляция неймспейсов, и cgroups, и лимиты на ресурсы, и возможно сделать chroot в различных формах — вот контейнер и получился.
Oxyd Автор
Ну это-то да.
Roman2dot0
В LXC systemd присутствует.
13werwolf13
никакой боли если ты используешь нормальные контейнеры а не docker
chemistmail
А если закапываться, то есть конкретные вопросы на решение которых просто положили, из расчета кому надо и кто понимает, найдет решение, а остальным хватит 640kB
Собственно про journald выше упомянутый, который ну нифига не является достаточно производительным решением by design
Хотя в основном решение неплохое. ))
Oxyd Автор
Если нечто слишком много льёт в логи, это нечто есть смысл вынести в отдельный journald namespace.
chemistmail
На него отдельный процесс journald создастся?
Oxyd Автор
Да. Почитайте ман systemd-journald.service, раздел JOURNAL NAMESPACES Там на каждый неймспейс создаётся свой экземпляр сервиса из шаблонов. Это можно использовать ещё и для безопасности, если, вдруг, какой сервис пишет чувствительные данные.
chemistmail
Почитал в доках, похоже что то в этом направлении делают.
Но пока не вижу решения, вариант выделите явный источник логов в отдельный канал предварительным описанием конфигов явно не решение. Пока костыль, возможно даже поможет, если не дешевле мимо него обработать.
gecube
Вообще принципиально лучшее решение не сделать. Пайплайны обработки логов очевидно имеют разные ограничения. В частности, если речь про аудит логи. И что хуже — нам нужно всегда выбирать между наблюдаемостью системы, производительность и целостностью (блокируемся ли мы для входящих запросов, если мы не можем, логи, например, отгрузить в SIEM)
hogstaberg
journald достаточно производительный by design, у него даже rate limit, например, в общем-то аналогичен rsyslog'у (1000msg/30sec vs 20000msg/10min соответственно). Да, он однопоточный, но можно запустить отдельный поток, тут про это уже написали.
А ещё я бы серьёзно поразмыслил над вопросом реальной необходимости логирования в таких количествах, что озвученная проблема производительности так остро стоит.
chemistmail
Я просто оставлю это здесь, пока не ушел
www.researchgate.net/publication/228694459_Rsyslog_going_up_from_40K_messages_per_second_to_250K
тут просто тупо решают проблему увеличения производительности с 40k в секунду до 250 к в секунду
до 40к в проде не приходилось, 20к было, оно в эластик штатно укладывалось
гдет пара терабайт в день по объему выходило.
На машину это около 500 — 4000 в сообщений в секунду. Без особой оптимизации.
Только ключевое условие, весь софт писал напрямую в локалхост по udp на rsyslog.
journald критично не справлялся.
По стоимости это выходило < гита оперативы на машину, и 1 — 4% cpu, ну машины толстые были.
Все мысли на тему реальной необходимости в практике спускаются свыше, и далее в результате консенсуса цена — возможность реализуются на практике.
KivApple
Вероятно, идея была в том, что в таком количестве данные надо класть в какую-нибудь БД, а не в сислог. Там и производительность может быть выше, и возможностей хитрых поисковых запросов (надо же потом эти данные как-то смотреть) больше.
Oxyd Автор
Ну не зря-ж придумали всякий ELK… Хотя нет. На момент написания статьи, ещё не придумали.