SysV, Вискочка, systemd в ролі асортименту граблів Debian/Ubuntu

Знаєте, чим я зараз займаюся? Пишу стартові скрипти для systemd, і це мене бісить.

Начебто як ми беремо операційну систему для того, щоб економити час на таких речах. Ніби як пакети повинні були полегшити нам життя. Цілком можливо, що мій вибір операційної системи був поганий, але до сьогоднішнього дня жити в області Debian/Ubuntu мені було цілком комфортно.

З іншого боку, «було» — це умовність. Всі ми часто перебуваємо у відносному невіданні щодо того, як влаштована наша операційна система. А якось, побачивши код /usr/sbin/service ти вже не можеш развидеть його. Так само як і користуватися цим інструментом.

Напевно, потрібно повернутися назад. Щоб зрозуміти, як ми опинилися в такій дупі з сумішшю SysV і systemd, приправленою Upstart.

TL; DR: автор ниє з приводу зоопарку з SysV, Вискочка і systemd в сучасних Debian/Ubuntu.

SysV

Здавалося б, що може бути простіше? В директорії /etc/init.d/ знаходиться файл з ім'ям служби, він відповідає за запуск і зупинку. Ми робимо /etc/init.d/stop service або /etc/init.d/service start і все працює відмінно.

Операційна система робить те ж саме, тільки в залежності від runlevel, два — так два, буду послідовно виконувати симлинки з /etc/rc2.d, які по суті своїй ведуть до /etc/init.d, життя проста і прекрасна. Щоб керувати послідовністю достатньо змінити сортування файлів за допомогою числа. Є утиліти, щоб автоматизувати створення цих символьних посилань.

Чому ми не могли залишитися в тому місці? Тому що системи змінилися. Вони стали, гм, складними.

По-перше, стан системи раніше було практично монолітним, а сьогодні може бути мінливим. Бах — і по USB підключили мережевий адаптер. При Томпсона такого не було! Треба реагувати, тобто повідомити службу про це, когось перезапустити, когось запустити, когось погасити.

По-друге, SysV було глибоко плювати на інтимне життя програм. Він запускав на старті, але якщо в тебе щось не виходило, то це їх особисті проблеми. Налагоджувати такі речі, практично неможливо. Segmentation fault? Справжні чоловіки пишуть програми, які запускаються з першого разу і не сегфолтят, слабак.

По-третє, структура залежностей в SysV була досить проста, чого не завжди вистачало.

По-четверте, старт системи не міг бути паралельним. Запуск скриптів був строго послідовний. Це легко побачити, якщо подивитися на час старту OpenSUSE, наприклад, кошлатою 12 версії.

Правда, основна особливість SysV була не тільки в простоті. З простотою приходили проблеми. Наприклад, якщо у мене кожен запуск скрипта start або stop окремий, то як дізнатися, запущена програма чи ні? Адже їй потрібно послати сигнал kill, а без PID його нікуди посилати.

Свіжою ідеєю було зберігати цю цифру у файлі .pid, прямо ну серйозно, свіжої для своїх далеких років. Однак що робити, якщо програма вилетіла з segmentation fault? Коротко: нічого, PID треба перевірити, перед тим, як використовувати.

Upstart

Мені здається, що проблеми почалися саме тут. Тобто, з того, як співтовариство прийняло Upstart. Це і поставило подальший тон. Але по порядку.

Upstart підтримував події. Він міг стежити і перезапускати програми. Він умів вибудовувати залежності. Ну і з паралельністю у нього теж було все в порядку.

Окрім однієї величезної бочки дьогтю, про яку я скажу далі, я не пам'ятаю толком ніяких претензій до Upstart. А ось бочкою було те, що розробники софта його в цілому проігнорували.

Чому? Я не знаю. Швидше за все тому, що сумісність з SysV була пріоритетом для Upstart. Тому розробникам нічого не потрібно було міняти.

У підсумку, незважаючи на те, що Upstart царював в Ubuntu 5 років на протязі з 2009 до 2014 року, величезна кількість софта так і не перейшла на нього!

З одного боку, я не можу звинувачувати в цьому тільки розробників. Вони, зрештою, пишуть програми. Як краще запускати ці програми в системі — не їх справа. Однак скрипти для SysV вони пишуть. Хочете прикладів? Подивіться, на що схожий скрипт запуску postfix в Debian. Цей код монструозен, він жахливий, це ж просто страшно.

Однак ще страшніше те, що багато адміністраторів взагалі не бачать і не розуміють різниці. Вони пишуть:

sudo service apache2 start
 

І свято вірять, що apache2 повинен стартувати. Аргх, він не повинен. Розумієте? Не має. Запуститься утиліта /usr/bin/service, яка візьметься зі страшною силою вгадувати, як же потрібно стартувати цю службу, а потім передасть ваше прохання SysV чи Вискочка. Якщо зможе правильно вгадати, ага.

service взагалі не частина пакета Upstart. Воно взагалі не звідти, але якось уживається в цьому веселому колі. Щоб збільшити кількість пекла, деякі розробники роблять скрипти /etc/init.d які посилаються на Upstart. Такий уроборос, щоб якщо раптом адміністратор з лісу вийшов і в Ubuntu 16.04 LTS напише

/etc/init.d/service restart
 

Щоб все працювало.

Окремо слід сказати про PID. Upstart не потрібен PID у файлі. Чому? Тому що будь запущений процес залишається його дочірнім. Якщо раптом він вилетить, то Upstart про це дізнається. І оскільки команди запуску і зупинки теж проходять через нього, то тут немає ніякої проблеми.

Однак як бути з сервісами, яким потрібен fork? Ну для початку їх треба запитати, навіщо їм це? Адже в цілому, fork застосовувався в основному для того, щоб детачнуться від стартував їх процесу, але у випадку з Upstart це робити нема чого. Якщо у нас помер init, то у нас є трохи більше проблем, ніж непрацюючий postfix.

Та що вже там, зараз, коли 16.04 LTS вже тут, як думаєте, за допомогою чого стартує Apache2? postfix? Ще купа всякого? SysV.

Правда, в 16.04 їм допомагає systemd.

systemd

В цілому, мені подобається systemd, чесно. Його логіка мені набагато приємніше тієї, що була у Upstart. Правда, якщо б ще Debian взяла б не 215 реліз, а 218, то жити було б ще краще, але чорт з ним, ми переживемо і без команди edit, якщо треба.

І systemd можна довго лаяти, але це вже стандарт. Однак як ви думаєте, що роблять розробники з systemd? Здебільшого ігнорують.

Отже, що привніс systemd? Генератори! Тисячі їх!

Коротко, якщо Upstart не випендрювався, а просто повторював поведінка SysV, то systemd до такого не опускається. Він бере існуючий /etc/init.d/service і на основі нього генерує скрипт для systemd. Його потім і запускає.

ExecStart=/etc/init.d/service start
 
ExecStop=/etc/init.d/service stop
 

Ну от як би так, ось приблизно ось так воно й виходить. Я не буду розповідати про те, що це далеко не завжди працює так, як треба. Вірніше, стартувати воно стартує. Не здумайте в якому-небудь продакшені покластися на рестарт такого сервісу, моніторинг стане вашим кращим будильником.

І так, ви ж розумієте, що systemd тим більше не потрібен PID, але на жаль. У співтоваристві це досі залишається толком не зрозумілим.

До розробників

Так, хлопці, я згоден, ще раз, запуск програми не є ваша турбота. Проте хто, як не ви, краще знає, як спроектувати безпроблемний старт? Адже одна справа, якщо команда старту виглядає так:

ExecStart=/usr/bin/control-bin start
 

А зовсім інша, якщо так

ExecStart=/usr/sbin/postfwd2 --file=/etc/postfwd/postfwd.cf --interface=127.0.0.1 --port=10040 --shortlog --summary=600 --cache=600 --cache-rbl-timeout=3600 --cleanup-requests=1200 --cleanup-rbls=1800 --cleanup-rates=1200 --user=postfwd --group=postfwd
 

Давайте перестанемо вже розмазувати налаштування між /etc/config.conf /etc/default/service?

Давайте перестанемо намагатися керувати стартом служби за допомогою параметра START=yes в /etc/default/service? Ні, я розумію, що «xyes» відмінною виглядає жартом, але набридло вже!

Давайте вже вирішимо, що systemd — він скрізь. І що під нього можна сміливо адаптуватися.

До самого себе

Змирися, ганчірка, і не ний. Keep calm and systemd.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.