Debian 8 Jessie вышел: systemd по умолчанию, обновляем скрипты и документацию
Debian 8 Jessie вышел с systemd в качестве init-системы. Разбираем что меняется для серверов на сопровождении: unit-файлы, journald, новые команды.
Debian 8 Jessie вышел с systemd по умолчанию - то, что долго обсуждалось в рассылках, стало фактом
25 апреля выйдет Debian 8 Jessie - и это уже не слухи, а факт: релиз объявлен, RC-версии прошли тестирование, systemd стал init-системой по умолчанию. Пока мы пишем этот пост, финальный ISO ещё не опубликован, но мы уже разворачиваем тестовый стенд по бета-образам. Серверов на Debian у нас в сопровождении достаточно, чтобы не ждать релиза с пустыми руками.
Для нас это в некотором смысле дежавю: с CentOS 7 через systemd мы прошли ещё в прошлом году. Но Debian - другая история. Аудитория другая, привычки другие, и та самая дискуссия про systemd-vs-sysvinit в Debian шла дольше и громче, чем где-либо ещё.
Что именно меняется при обновлении с Wheezy
Апгрейд с Debian 7 Wheezy на Jessie - это не просто apt-get dist-upgrade. На большинстве наших стендов он прошёл относительно ровно, но несколько вещей потребовали внимания.
init.d-скрипты никуда не исчезают. Это важный момент, который люди часто упускают. systemd умеет запускать SysV-совместимые init.d-скрипты через слой совместимости. Большинство старых пакетных скриптов продолжат работать. Проблема в другом - они работают, но без преимуществ: без cgroup-изоляции, без встроенного перезапуска, без нормального journald. Де-факто это временный костыль, а не постоянное решение.
Кастомные init.d-скрипты на грани. Всё что было написано с нетривиальной логикой - ловит демона по PID-файлу вручную, делает su - user -c "...", содержит хаки для конкретных дистрибутивных особенностей - нужно проверять. Один наш скрипт для самописного агента упал именно из-за того, что /lib/lsb/init-functions в Jessie немного изменился.
/var/run и /run. В Jessie /var/run - это символическая ссылка на /run, который tmpfs и монтируется на старте. Скрипты которые создают PID-файлы в /var/run/ при загрузке - работают. Скрипты которые создают структуру директорий при установке пакета и ожидают её найти при старте - иногда нет.
Новая документация для команды
Мы ведём внутреннюю вики по командам управления серверами. После перехода CentOS 7 в продакшн добавили раздел systemd. Теперь его нужно расширить - потому что Debian добавляет свои особенности.
Основные команды которые переписываем в шпаргалке:
service nginx start->systemctl start nginxupdate-rc.d nginx defaults->systemctl enable nginxinvoke-rc.d nginx restart->systemctl restart nginxservice --status-all->systemctl list-units --type=service
invoke-rc.d - специфически дебиановская вещь, которую мы у себя используем в нескольких скриптах. В Jessie он не исчез, но теперь вызывает systemctl под капотом. Логировать это стоит - при отладке неожиданно встретить два уровня косвенности неприятно.
journald и rsyslog
В Debian 7 journald не используется вообще - только rsyslog и текстовые логи. В Jessie journald включается по умолчанию и пишет в /run/log/journal/. По умолчанию - в память, без персистентности между перезагрузками.
Для продакшн-серверов это надо менять сразу:
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald
После этого журнал пишется на диск и переживает перезагрузку. Ещё одна настройка которую делаем сразу - ограничение размера в /etc/systemd/journald.conf:
[Journal]
SystemMaxUse=500M
SystemKeepFree=200M
По умолчанию journald может занять до 10% диска. На небольших VPS это может быть сюрпризом.
rsyslog в Jessie тоже есть и тоже работает - читает из journald и пишет в привычные /var/log/syslog, /var/log/auth.log и так далее. Для централизованного сбора логов через ELK-стек у нас logstash читает именно текстовые файлы rsyslog - значит ничего ломать не нужно. Переходить на нативную отдачу из journald пока не планируем.
Unit-файлы: что писать для новых сервисов
С синтаксисом unit-файлов мы уже разобрались на CentOS 7 - разница с Debian минимальная. Директории те же: /lib/systemd/system/ для пакетных unit-файлов, /etc/systemd/system/ для своих и переопределений.
Одна дебиановская особенность: если у пакета есть и unit-файл и init.d-скрипт - systemd предпочтёт unit-файл. Это хорошо. Но если нужно только переопределить одну опцию в пакетном unit-файле - делаем через drop-in:
mkdir /etc/systemd/system/nginx.service.d/
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
Это чище чем копировать весь unit-файл из /lib/systemd/system/ - при обновлении пакета оригинальный файл обновится, а наша настройка останется.
Ansible-плейбуки
В нашем провизионирующем плейбуке модуль service уже умеет работать с systemd - разницы в том как Ansible управляет сервисами нет. Проблема в другом: условия when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '7' нужно актуализировать. Там где мы делали особые вещи для Wheezy - часть из них теперь ненужна, часть работает по-другому.
Конкретно: таски которые настраивали автозапуск через update-rc.d - заменяем на systemctl enable. ansible_service_mgr в Ansible 1.9 уже возвращает systemd для Jessie, так что можно делать условия чище.
Где мы сейчас
Стенд с Jessie работает несколько дней. Финальный релиз ждём по заявленному расписанию - 25 апреля. Когда выйдет, начнём готовить план миграции для клиентских серверов на Wheezy.
Ничего критичного пока не нашли. Больше всего времени ушло не на технические проблемы, а на инвентаризацию: какие у нас вообще есть кастомные init.d-скрипты, кто их писал, что они делают. Несколько штук оказались артефактами которые давно не нужны. Хорошая возможность разгрести накопившееся.