Что такое система инициализации

Процесс загрузки ОС выглядит следующим образом:

  • Подаётся питание на материнскую плату.
  • Запускается BIOS (нет) Basic IO System. Задача: инициализация и проверка ключевых систем. Проблема: инициализация долгая, подсистемы сложные, plug & play. => Запускается UEFI. Его ключевая задача - запустить ОС с минимально возможной игрой с железками.
  • Загрузчик ОС. В некоторых минимальных случаях загрузчик уже является ядром ОС, но так никто не делает (почти).
  • Выполняется ядро ОС.

Далее смотрим на то как это сделано в Linux.

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

В процессе свой загрузки ядро инициализирует железо (2 раз, если используется BIOS), подключает ключевые файловые системы, которые нужны для запуска первого процесса. Данный процесс носит имя init.

Конкретная система инициализации может быть выбрана на уровне отдельного дистрибутива.

Задачами системы инициализации являются:

  • Подключение ВСЕХ файловых систем.
  • Настройка оборудования согласно конфигурации пользователя. Обычно не выполняется самой системой инициализации, но она вызывает нужные приложения.
  • Запускает системные службы:
    • Служба журналирования
    • Службы обмена сообщениями между процессами
    • Служба обновления ОС
    • ….
    • nginx
    • СУБД: mariadb, postgresql, mongodb, …

Т.е. благодаря системе инициализации мы переходим из ситуации пустого виртуального мира в мир с необходимым количеством включённых служб (приложений).

Система инициализации также ответвтена за выключение системы. Т.е. тот, кто породил, тот и будет уничтожать.

Какие бывают системы инициализации

Разными :)

Можно выделить несколько классов:

  • Классическая система SysVInit и её потомки.
  • Обновлённые системы старта: upstart, …
  • Мега-комбайн SystemD

SysVInit - это классика. Она основана на том, что у нас есть набор BASH-скриптов, которые и выполняют инициализацию. Порядок их выопленния определяется их именем. Т.е. 01-…. 02-… и так далее.

Плюс в такой организации: мы можем написать любую логику, не ограничены BASH. Минусы:

  • Зависимости. Их трудно отслеживать, на управление зависимостями может уйти много трудов у администратора. Пример: надо запускать базу данных только тогда, когда сетевые интерфейсы уже настроены.
  • Для каждого скрипта запускается отдельный BASH-процесс. В результате процесс запуска становится достаточно медленным.

Обновлённые системы попытались решить данную проблему различными способами. Один из них - отказ от bash или серьёзное ограниченние в организации скриптов.

SystemD предложил кардинальный подход к решению задачи инициализации. Они (Леонард Поттеринг) сказали, что сама задача по инициализации тесно связана с жизнью всей ОС. Т.е. надо не только запустить процесс, но желательно также его обслуживать во время работы: собирать информацию в журнал, отслеживать падения и т.д.

В старых системах иниализации реализовать логику “перезапустить, если упало” было крайне сложно. Для этого выделялась отдельная подсистема, которая по логике уже конфликтовала с системой инициализации.

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

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

Мы с вами посмотрим на SystemD, т.к. де-факто это сейчас самая распространённая система инициализации.

Как настраивать SystemD

Его конфигурационные файлы лежат по набору каталогов. Нас в первую очередь будет интересовать /etc/systemd/.

Большое число файлов связано с тем, что в SystemD много различных подсистем:

  • JournalD - система ведения журналов.
  • LoginD - система отслеживания авторизации в системе.
  • NetworkD - управление (отслеживание) сетевыми интерфейсами
  • ResolveD - управление настройкой DNS-серверов в системе.
  • TimeSyncD - синхронизация времени на компьютере.
  • SystemD (system.conf и user.conf) - управление и отслеживание состоянием служб системных и пользовательских.

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

Для разбора деталей работы SystemD надо будет обратиться на официальный сайт и в документацию: man systemd.

Как настраивать службы в SystemD

Для настройки SystemD используются так называемые модули, unit. Эти модули могут описывать как конкретную службу, так и другие элементы настройки SystemD.

Если смотреть с точки зрения ООП, то unit - это базовый класс для всех остальных классов настроек.

Существуют следующие типы модулей:

  • .service - управление службами
  • .socket - запуск служб по обращению к сетевому сокету
  • .device - управление? устройствами
  • .mount - подключение файловых систем
  • .automount - подключение файловых систем при подключении устройств (флешек, дисков и т.п.)
  • .swap - подключение разделов подкачки
  • .target - цель по настройке системы. Цели могут быть: системная, одно-пользовательская, много-пользовательская и т.п. Т.е. цель определяет некоторый логический этап загрузки системы. В классическом SysVInit целей было 7 от 0 до 6. 0 - загруска системы, 6 - её выключение. 3 - много-пользовательский режим. Для достижения цели №3 надо было выполнить также и 0, 1, 2.
  • .path - ?
  • .timer - запуск служб по расписанию.
  • .slice - ?
  • .scope - ?

Информацию по настройке unit-элементов systemd можно прочитать в man systemd.unit.

Информация по настройке слжуб находится в man systemd.service

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

Пример настройки службы через SystemD

Сделаем простую службу, которая создаёт файл на жёстком диске.

  1. Надо создать службу, которая будет запускаться. Запишем следующий код в файл create-file.sh. И сделаем его исполняемым.
#!/usr/bin/env bash

echo 'I have started!' > /tmp/greeting.txt
  1. Надо создать конфигурационный файл для SystemD. Файл должен иметь расширение .service. Назовём его my-service.service.
[Unit]
Description=File creation service

[Service]
Type=oneshot
ExecStart=/home/user/create-file.sh
  1. Надо положить конфигурационный файл в каталог /etc/systemd/system
  2. Надо сказать SystemD, чтобы он прочитал заново конфигурационные файлы: systemctl daemon-reload. Мы де-факто просим перезапуститься SystemD, чтобы она заново считала конфигурационные файлы.
  3. Затем надо убедиться, что наш файл был успешно считан и SystemD распознала его как конфигурацию службы: systemctl status my-service.

    Loaded - показывает был ли загружен файл с жёсткого диска или нет.

    Active - работает ли сейчас служба.

  4. Надо запустить службу. Для этих целей systemctl start my-service