Назад в блог

Как настроить автозапуск службы Linux после перезагрузки или сбоя системы: Часть 2 (Теоретические объяснения)

Как настроить автозапуск службы Linux после перезагрузки или сбоя системы: Часть 2 (Теоретические объяснения)

Во второй части этого руководства из двух частей по настройке Linux служб для автоматического запуска после перезагрузки или сбоя системы мы подробно обсудим систему инициализации init. Вы можете обратиться к Части 1 этой серии: Как настроить автозапуск службы Linux после перезагрузки или сбоя системы: практические примеры здесь.

Текущее руководство будет насыщено теорией. Поэтому вам следует использовать его в качестве справочника, чтобы глубже понять, как работает система init в Linux. В первой части этого руководства мы поделились некоторыми фрагментами кода и сценариями запуска, которые система init считывает при запуске. Мы также использовали MySQL в качестве примера, чтобы узнать, как включить и отключить автозапуск службы Linux после сбоя или перезагрузки. Как вы узнали из первой части этого руководства, состоящего из двух частей, в различных дистрибутивах Linux используются три системы инициализации: System V, Upstart и Systemd. Вы можете обратиться к первой части этого руководства, чтобы понять, какой дистрибутив и версия настроены на использование конкретной системы инициализации.

В этом руководстве мы объясним код, который мы использовали в первой части руководства. Мы подробно остановимся на командах и конфигурационных файлах, которые использует система init. Давайте начнем!

Предварительные требования

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

  • Ubuntu 9.04 и более ранние версии или Debian 6 x64 (мы будем использовать его для демонстрации системы инициализации System V)
  • Ubuntu 14.04 x64 (мы будем использовать его для демонстрации Upstart). Вот руководство по простой настройке вашего сервера Ubuntu.
  • CentOS 7 x64 (мы будем использовать его для демонстрации Systemd).

У вас должен быть пользователь с привилегиями sudo на каждом из серверов, которые вы будете использовать для запуска команд. Это руководство по настройке файла sudoers в Linux поможет вам.

Примечание:  Команды в руководстве будут вмешиваться в работу системных служб. Поэтому не следует применять их на рабочем сервере.

Уровни запуска

A runlevel — это рабочий уровень, который описывает текущее состояние системы Linux в отношении доступных служб. Эта концепция берет свое начало в System V init. Когда система Linux загружается, она инициализирует ядро, переходит на один runlevel и запускает сценарий запуска, связанный с этим уровнем. При запуске можно выполнить только один runlevel.

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

Существует семь уровней запуска: от 0 до 6. Ниже приведено определение этих семи уровней запуска:

  • Уровень запуска 0: Выключение системы
  • Уровень запуска 1: Однопользовательский режим и режим восстановления
  • Уровни запуска 2, 3, 4: Многопользовательский текстовый режим с поддержкой сети
  • Уровень запуска 5: Многопользовательский графический режим с поддержкой сети
  • Уровень запуска 6: Перезагрузка системы

Уровни запуска не обязательно выполняются последовательно. Уровни запуска 2, 3 и 4 различаются в зависимости от используемого вами дистрибутива Linux. Вы можете реализовать уровень запуска 4 в одних дистрибутивах и не реализовывать в других. Когда вы включили автозапуск службы, как описано в первой части, вы фактически добавили ее на уровень запуска. В System V операционная система запускается с определенным уровнем запуска, и во время загрузки она пытается запустить все службы, связанные с этим уровнем запуска. В Systemd уровни запуска представляют собой цели (targets), которые мы обсудим в разделе, посвященном Systemd.

Init и PID 1

Система init — это самый первый процесс, который запускается при загрузке системы Linux и загрузке ядра в память. Она выполняет различные задачи, включая определение того, как будет загружаться пользовательский процесс или системная служба, в каком порядке и должна ли она запускаться автоматически. В каждом дистрибутиве Linux каждый процесс идентифицируется идентификатором процесса (PID), и init имеет PID 1. Он является родителем всех остальных процессов, которые последовательно запускаются при загрузке системы.

История init

Система инициализации init, используемая в современных дистрибутивах Linux, представляет собой улучшенную версию оригинальной системы. В самых ранних версиях дистрибутивов Linux использовалась система System V init, которая аналогичным образом применялась в системах Unix. По мере развития Linux был внедрен демон инициализации Upstart — он был создан компанией Ubuntu. Сейчас (на момент написания этого руководства, 2021 год) мы имеем демон инициализации Systemd, который впервые был внедрен в Fedora. Поскольку системы Linux продолжают развиваться, в будущем может появиться более новая система инициализации. В этом руководстве мы обсудим эти три: System V, Upstart и Systemd.

Современные версии Linux по умолчанию поставляются с системой инициализации Systemd. Однако в них сохранены другие, более старые системы инициализации для обеспечения обратной совместимости. Существуют различные реализации System V, которые можно использовать в других вариантах Linux. Например, FreeBSD, вариант UNIX, использует BSD init. Более старые версии Debian используют SysVinit. Обе они происходят от System V.

Способ управления службами в каждой версии демона init различается. Улучшения, добавленные в каждую версию, были направлены на создание надежного инструмента управления службами, который справлялся бы со всем, что требуется системе Linux: от служб, устройств и портов до других ресурсов. Возникла необходимость в мощной системе, способной загружать ресурсы параллельно и корректно восстанавливаться после системного сбоя.

Последовательность запуска System V Init

System V использует файл inittab для хранения инструкций по инициализации. Upstart сохраняет файл inittab для обратной совместимости. Ниже представлена схема запуска System V:

  • Система init запускается из бинарного файла /sbin/init.
  • После загрузки в оперативную память система init считывает свой первый файл по пути /etc/inittab.
  • Одна из записей в этом файле определяет уровень запуска (runlevel), на котором должна загружаться машина. Например, если значение уровня запуска указано как 5, Linux загрузится в многопользовательском графическом режиме с включенной сетью (что характерно для дистрибутивов, предназначенных для настольного использования). Указанный здесь уровень запуска называется уровнем запуска по умолчанию, так как он будет использоваться всегда.
  • Затем система init обращается далее к файлу /etc/inittab и считывает, какие скрипты инициализации ей необходимо запустить для этого уровня запуска.

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

Структура скриптов инициализации System V Init

В этом разделе мы подробно рассмотрим скрипты инициализации. Конфигурационные файлы System V или скрипты инициализации — это то, что управляет службами. Скрипты инициализации инициализируют службу, отсюда и название — скрипт инициализации (init script).

Каждая служба имеет свой собственный скрипт инициализации. Например, скрипт инициализации MySQL управляет сервером MySQL. Поставщики приложений предоставляют скрипты инициализации для своих конкретных приложений, в то время как встроенные службы Linux поставляются вместе с операционной системой. При создании собственного приложения вы также можете создать для него свои собственные скрипты инициализации.

Чтобы запустить службу, например сервер MySQL, его исполняемый файл сначала загружается в память. В зависимости от конфигурации программа может продолжать выполняться в фоновом режиме для приема клиентских подключений. Скрипт инициализации службы отвечает за запуск, остановку или перезапуск исполняемого приложения. Скрипты инициализации в System V представляют собой shell-скрипты. Другое их название — rc-скрипты (run command).

Структура каталогов System V

Родительским каталогом для скриптов инициализации является каталог /etc. Каталог /etc/init.d является непосредственным каталогом для shell-скриптов инициализации. На эти скрипты создаются символические ссылки в каталогах rc.

В каталоге /etc находится несколько каталогов rc, каждый из которых содержит число в своем названии. Эти числа представляют различные уровни запуска. Если вы выведете список содержимого каталога, вы увидите такие имена, как /etc/rc0.d, /etc/rc1.d, /etc/rc2.d и т. д.

Если вы просмотрите содержимое каждого из каталогов rc, вы увидите файлы, имена которых начинаются с K или S в имени файла, за которыми следуют две цифры. Эти файлы содержат символические ссылки, указывающие на исходные shell-скрипты инициализации реальной программы. Буквы K и S — это сокращения: K означает Kill или Stop, в то время как S означает Start. Две цифры в именах файлов представляют собой порядок выполнения. Если вы видите файл с именем K05script_name, он будет выполнен перед файлом с именем K09script_name.

Запуск

Продвигаясь по последовательности запуска, давайте посмотрим, как вызываются init-скрипты.

Скрипты S и K не вызываются системой init напрямую. Вместо этого они вызываются другим скриптом: /etc/init.d/rc. Файл /etc/inittab указывает демону init, в каком уровне выполнения (runlevel) система должна загружаться по умолчанию. В зависимости от указанного уровня выполнения, строка в файле /etc/inittab вызывает скрипт /etc/init.d/rc, передавая уровень выполнения по умолчанию в качестве параметра. Используя этот параметр, скрипт будет вызывать файлы в соответствующем каталоге /etc/rcN.d, где N обозначает уровень выполнения. Например, если сервер загружается с уровнем выполнения 5, будут вызываться соответствующие файлы в каталоге /etc/rc5.d.

Внутри каталога rc все скрипты K запускаются в числовом порядке с аргументом stop, в то время как все скрипты S запускаются аналогично с аргументом start. Соответствующие реальные shell-скрипты инициализации для программы, на которые указывают символические ссылки в /etc/rcN.d, будут вызываться с параметрами stop и start соответственно.

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

Автоматический запуск System V

Когда вы включаете автозапуск службы при загрузке, вы напрямую изменяете поведение init. Например, если вы настраиваете службу для автозапуска на уровне выполнения 2, процесс init создает соответствующие символические ссылки в каталоге /etc/rc2.d. Чтобы помочь вам разобраться, мы объясним это на примере.

Пример System V

Чтобы привести практический пример, мы будем использовать конфигурацию службы MySQL из части 1. Итак, войдите на VPS с Debian 6 под вашим пользователем sudo/root с помощью ssh (или putty, если вы работаете в Windows) и выполните следующие шаги.

Шаг 1: Откройте и изучите файл inittab

Сначала введите следующую команду, чтобы просмотреть содержимое файла inittab в терминале:

Содержимое файла должно быть примерно следующим:

Цифра 2 обозначает уровень выполнения, с которого запускается система. В данном случае уровень выполнения 2 является уровнем по умолчанию, поэтому эта система Debian будет запускаться на уровне выполнения 2 в многопользовательском текстовом режиме. Вы можете выполнить следующую команду для подтверждения:

Она покажет вывод, похожий на:

Шаг 2: Изучение каталогов rc

Затем, чтобы вывести список каталогов rc, выполните следующую команду:

Вот скриншот вывода:

root screenshot

Как мы видели в файле inittab ранее, система настроена на загрузку в runlevel 2, поэтому скрипты в /etc/rc2.d будут выполняться при запуске системы. Вы можете вывести список содержимого этого каталога с помощью команды:

Как видно из вывода, файлы представляют собой просто символические ссылки, указывающие на реальные файлы скриптов в /etc/init.d. Вот фрагмент вывода:

service crash 1

В этом каталоге нет скриптов K, только скрипты S (запуск). Скрипты запустят связанные здесь службы, такие как rsync. Вы также можете заметить в списке службу mysql, которую мы обсудим в следующей подтеме.

Шаг 3: Изучение скрипта инициализации

Когда устанавливается служба, совместимая с System V, она создает shell-скрипт в каталоге /etc/init.d. Вы можете проверить наличие shell-скрипта MySQL, введя следующую команду:

Она показывает следующий вывод:

screenshot output

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

Шаг 4: Использование chkconfig или sysv-rc-conf

Chkconfig — это команда, которую вы можете использовать в дистрибутивах на базе RHEL, таких как CentOS, чтобы включить или отключить службы, совместимые с System V. Вы также можете использовать ее для вывода списка установленных служб и соответствующих им уровней запуска. Вот команда для этого (работает в CentOS):

В дистрибутивах Debian такая утилита изначально отсутствует. Утилита update-rc.d в системах Debian только устанавливает и удаляет службы из уровней запуска. Доступен сторонний инструмент, который можно использовать для переноса функциональности chkconfig в системы Debian. Введите следующую команду для его установки:

После установки вы можете запустить следующую команду, чтобы просмотреть поведение уровней запуска для различных служб:

Вывод этой команды отформатирован в виде таблицы, в которой слева показано имя службы, а справа — уровни запуска, на которых она работает:

service crash 2

Символ X указывает уровень запуска, на котором будет работать служба. Этот инструмент позволяет отключать или включать службу для определенного уровня запуска с помощью клавиш со стрелками и пробела. Для выхода из инструмента нажмите Q.

Шаг 5: Тестирование поведения MySQL при запуске во время загрузки системы

На скриншоте выше видно, что служба mysql включена на уровнях запуска 2,3,4,5. Вы можете отключить MySQL с помощью следующей команды:

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

service crash 3

Запустите команду ниже, чтобы просмотреть содержимое каталога:

Посмотрите на строку mysql в выводе ниже:

Вывод показывает, что символическая ссылка изменилась на K, что означает Kill (остановить). Следовательно, MySQL не будет автоматически запускаться по умолчанию на уровне запуска 2. Это происходит каждый раз, когда вы включаете или отключаете службу в System V. Пока в каталоге уровня запуска по умолчанию для службы существует скрипт S (запуск), демон init будет запускать эту службу во время загрузки системы.

Чтобы снова включить службу, введите следующую команду:

Шаг 6: Тестирование поведения MySQL при запуске после сбоя системы

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

В первой части этого руководства мы внесли изменения в файл /etc/inittab, чтобы разрешить автоматический запуск MySQL после сбоя. Мы добавили следующую строку, чтобы включить это поведение:

Мы можем проверить это поведение, проведя несколько тестов. Сначала перезагрузите ваш VPS, введя следующую команду:

После перезагрузки проверьте, с какими идентификаторами процессов (PID) запущены mysql_safe и mysqld, введя следующую команду для получения идентификаторов процессов:

Полученный нами вывод:

Обратите внимание на идентификаторы процессов (PID). В нашем случае это были 1836 и 186338. Теперь симулируйте сбой, завершив процесс с ключом -9, введя следующую команду. Не забудьте заменить идентификаторы процессов на свои:

Через несколько минут проверьте статус MySQL, выполнив следующую команду:

Вывод указывает на то, что MySQL запущен, то есть он был перезапущен после симулированного сбоя. Если вы снова выполните команду ps -ef | grep mysql, то увидите, что оба процесса, mysqld_safe и mysqld, запущены, хотя и с новыми идентификаторами.

Вы можете попробовать завершить процессы несколько раз, и они будут перезапускаться через несколько минут. Такое поведение возможно благодаря строке, которую мы добавили в файл /etc/inittab. Именно так настраивается автоматический перезапуск служб после сбоя в System V. Чтобы снова увидеть синтаксис, обратитесь к части 1 этого руководства.

Некоторые кастомные службы могут содержать ошибки и не перезапускаться после нескольких попыток. Демон init попытается перезапустить службу, но если она завершится сбоем более десяти раз в течение двух минут, система Linux отключит службу на время до 5 минут. Это помогает поддерживать стабильность системы и гарантирует, что системные ресурсы не будут тратиться впустую на аварийно завершающиеся службы. Рекомендуется проверять системные логи для выявления проблем в ваших кастомных приложениях, которые необходимо исправить.

Введение в Upstart

Система инициализации System V долгое время играла важнейшую роль в дистрибутивах Linux. Однако технологии не стоят на месте. Экосистема Linux значительно выросла благодаря поддержке сообщества разработчиков ПО с открытым исходным кодом. System V загружает задачи и службы последовательно, что усложняет процесс и требует времени. Кроме того, появление современных подключаемых носителей информации, для работы с которыми System V не проектировалась, вызвало потребность в другой системе инициализации.

Разработчики Ubuntu начали работу над другой системой инициализации. Эта система была разработана для обеспечения более быстрой загрузки ОС, корректной очистки после сбоя служб, предсказуемости зависимостей между системными службами и поддержки подключаемых носителей. Так появился демон Upstart.

Инициализация Upstart имеет несколько преимуществ перед System V:

  • Upstart не загружает службы последовательно, как System V, что сокращает время загрузки системы.
  • Она разработана для лучшей обработки аварийно завершившихся служб с корректной очисткой и перезапуском служб.
  • Upstart использует гибкую систему событий для настройки обработки служб в различных состояниях.
  • Эта система инициализации позволяет избежать сложных shell-скриптов для загрузки и управления службами, как в System V. Upstart использует простые конфигурационные файлы, которые легко понять и изменить.
  • Upstart создавался с учетом обратной совместимости. Скрипт /etc/init.d/rc по-прежнему запускается для управления нативными службами System V.
  • Она позволяет избежать хранения избыточных символических ссылок, указывающих на один и тот же скрипт.

События Upstart

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

События Upstart включают в себя:

  • Starting
  • Started
  • Stopping
  • Stopped

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

  • Waiting
  • Pre-start
  • Starting
  • Post-start
  • Running
  • Pre-stop
  • Stopping
  • Post-stop

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

Последовательность запуска Upstart Init

При запуске Upstart init выполняет скрипт /etc/init.d/rc, как и System V. Этот скрипт обычным образом запускает любые скрипты инициализации System V для обеспечения обратной совместимости.

Конфигурационные файлы Upstart расположены в каталоге /etc/init, поэтому по умолчанию он ищет их там и выполняет shell-команды, найденные в конфигурационных файлах в этом каталоге.

Конфигурационные файлы Upstart

В отличие от bash-скриптов, используемых в System V, система инициализации Upstart использует файлы конфигурации служб для управления ими. Стандартом именования для этих файлов конфигурации служб является service_name.conf.

Файлы содержат простой текст, разделенный на различные разделы, называемые строфами (stanzas). Каждая строфа описывает определенное состояние службы и ее поведение. Различные строфы управляют различными событиями службы. Например, ожидание (waiting), подготовка к запуску (pre-start), запуск (start), подготовка к остановке (pre-stop), остановка (stopping) и т. д.

Строфа содержит команды оболочки, что позволяет инициировать несколько действий для каждого события каждой службы. Кроме того, каждый конфигурационный файл службы определяет следующие две вещи:

  • На каких уровнях запуска (runlevels) служба должна запускаться и останавливаться.
  • Должна ли служба перезапускаться (respawn) в случае сбоя.

Структура каталогов Upstart

Файлы конфигурации служб Upstart находятся в каталоге /etc/init. Не путайте его с /etc/init.d.

Пример использования Upstart

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

Шаг 1: Войдите на сервер Ubuntu 14.0.4

Во-первых, для тестирования Upstart мы будем использовать второй VPS под управлением Ubuntu 14.0.4. Это связано с тем, что данный дистрибутив Linux изначально поддерживает Upstart. Используйте ssh или putty, если вы работаете в Windows. Вы должны войти под пользователем с правами root или sudo. У меня есть пользователь с именем hackins, и вот как я буду входить:

Замените на вашего пользователя root/sudo и публичный IP-адрес сервера. Затем нажмите Enter и введите пароль или парольную фразу.

Шаг 2: Изучите каталоги init и rc

Файлы конфигурации Upstart хранятся в каталоге /etc/init. Это каталог, который вы будете использовать при создании новых файлов конфигурации служб.

Чтобы вывести список имен конфигурационных файлов в каталоге /etc/init, выполните следующую команду:

Как вы увидите из вывода вышеуказанной команды, под управлением Upstart работает множество служб. Нажмите Q, чтобы выйти из less.

Если вы выполните следующую команду для вывода списка конфигурационных файлов служб System V в каталоге rc, вы увидите лишь несколько:

Шаг 3: Изучите файл Upstart

В первой части этого руководства мы использовали файл mysql.conf для изучения конфигурации сервера. Чтобы расширить наши знания, давайте воспользуемся другой конфигурацией. Файл конфигурации cron является хорошим кандидатом. Введите следующую команду, чтобы открыть этот файл:

Вы должны получить вывод, аналогичный скриншоту ниже:

screenshot 4

Скрипт довольно прост. Обратите внимание на следующие важные поля: start on, stop on, fork, и respawn. Давайте определим, что делают эти директивы:

  • start on указывает Ubuntu запустить демон cron, когда система переходит на уровни запуска 2, 3, 4 или 5. Он не будет работать на других уровнях запуска, не указанных здесь, то есть 0, 1 или 6.
  • stop on указывает Ubuntu остановить работающий демон. Однако в данном случае присутствует восклицательный знак (!), который является знаком отрицания. Скрипт не должен останавливаться на уровнях запуска, указанных после восклицательного знака: 2,3,4,5.
  • fork указывает Upstart отсоединить процесс от консоли и оставить его работать в фоновом режиме.
  • respawn указывает системе автоматически запускать cron в случае его сбоя по какой-либо причине.

Нажмите Ctrl X, чтобы выйти из редактора без ввода каких-либо данных.

Другие конфигурационные файлы Upstart имеют ту же структуру со строфами для запуска (start), остановки (stop) и перезапуска (respawn). Некоторые конфигурационные файлы могут содержать дополнительные блоки скриптов для pre-start, pre-stop, post-start и других состояний. Эти блоки кода сообщают системе, что именно нужно выполнять, когда процесс находится в любом из определенных состояний.

Шаг 4: Протестируйте поведение службы MySQL при запуске после загрузки системы

По умолчанию MySQL настроен на автоматический запуск после загрузки системы. Мы попробуем отключить его и посмотреть на поведение. В Upstart службу можно отключить, создав файл с именем service_name.override в каталоге /etc/init/. Содержимое файла — всего одно слово: manual.

Давайте посмотрим, как мы можем использовать эту команду для отключения службы MySQL. Введите следующую команду, чтобы открыть файл в редакторе nano:

В открывшемся файле добавьте следующую строку:

Сохраните изменения, нажав Ctrl + O, затем Enter. Выйдите из редактора, нажав Ctrl + X. Выполните следующую команду для перезагрузки сервера:

Подождите несколько минут, а затем войдите снова. После входа проверьте статус службы MySQL, введя следующую команду:

Вывод укажет на то, что служба не запущена:

Это указывает на то, что MySQL не запустился автоматически после загрузки системы. Далее откройте конфигурационный файл MySQL и проверьте, изменилась ли директива start:

Вывод укажет на то, что ничего не изменилось:

Это означает, что если ваша служба не запускается автоматически, и вы проверяете только конфигурационный файл службы (service_name.conf), вы можете не обнаружить ошибку. Вам также следует проверить наличие файла service_name.override в этом каталоге.

Введите следующую команду, чтобы удалить файл переопределения и снова включить службу MySQL. Затем перезагрузите сервер:

После загрузки сервера снова проверьте статус службы MySQL:

Должно быть показано, что служба MySQL запустилась автоматически.

Шаг 5. Тестирование поведения службы MySQL при запуске после сбоя системы

По умолчанию служба MySQL автоматически перезапускается в случае сбоя. Чтобы отключить это поведение, мы отредактируем файл mysql.conf. Введите следующую команду, чтобы открыть файл в редакторе nano:

Найдите строки директивы respawn и закомментируйте их, как показано ниже с помощью #:

Выполните следующие команды для перезапуска службы:

Мы использовали вышеуказанные команды для остановки и запуска службы, так как использование initctl restart или initctl reload здесь не сработает. При запуске команды для старта службы MySQL в выводе отобразится PID для MySQL, например:

Наш PID был 1439. Далее запишите то, что вы получили при выполнении команды, мы будем использовать это на следующем шаге. Чтобы симулировать сбой, завершите процесс MySQL с помощью следующей команды, не забудьте заменить PID, как описано выше:

Чтобы проверить, перезапустился ли MySQL после сбоя, подождите несколько минут, а затем введите следующую команду:

Вывод укажет на то, что MySQL остановлен:

Попробуйте проверить статус еще несколько раз, чтобы увидеть, есть ли какие-либо изменения. Вы заметите, что MySQL остается остановленным. Это связано с тем, что в конфигурационном файле службы отсутствуют директивы respawn (те, которые мы закомментировали). Ознакомьтесь с частью 1 этого руководства для получения более подробного объяснения директивы respawn.

Зачем мы показали вам, как отключить автоматический перезапуск служб после загрузки или сбоя системы? В основном это делается для устранения неполадок. Если, например, ваша служба запускается и постоянно падает, вы можете отключить ее, чтобы локализовать проблему и сохранить стабильность системы. Вы также можете предотвратить автоматический перезапуск некоторых старых конфигураций служб, если обновитесь до нового дистрибутива Linux, который поставляется со встроенным systemd, который обсуждается в следующем разделе.

Введение в Systemd

Systemd — это новейшая система инициализации, используемая в большинстве современных дистрибутивов Linux. Она включает в себя множество компонентов, составляющих современную систему Linux.

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

Systemd обратно совместим с инициализационными скриптами и командами System V. Поэтому, если у вас есть службы, настроенные для System V, они также будут работать под управлением Systemd. Большинство административных команд Upstart и System V были изменены для работы с Systemd. Во время загрузки Systemd переименовывает себя в init. Существует файл /sbin/init, который является символической ссылкой на /bin/systemd.

Конфигурационные файлы Systemd: юнит-файлы

Конфигурация Systemd состоит из юнит-файлов. Каждый юнит-файл представляет собой системный ресурс. В то время как две другие системы инициализации (то есть System V и Upstart) отвечали за управление службами системы Linux, Systemd управляет не только демонами служб, но и другими типами системных ресурсов, такими как пути операционной системы к устройствам, сокеты, точки монтирования и т. д. В юнит-файлах хранится информация о ресурсе.

Каждый юнит-файл представляет собой определенный системный ресурс и имеет имя в формате service_name.unit_type. Это означает, что вы найдете такие файлы, как home.mount, dbus.service, sshd.socket и т. д. Юнит-файлы представляют собой простые текстовые файлы с декларативным синтаксисом, который легко понять и изменить.

Структура каталогов

Основным местом хранения стандартных юнит-файлов является каталог /lib/systemd/system/. Юнит-файлы, созданные вами или системными администраторами вручную, а также другие измененные стандартные юнит-файлы хранятся в каталоге /etc/systemd/system.

Если юнит-файл с одинаковым именем существует как в каталоге /lib/systemd/system/, так и в /etc/systemd/system, systemd будет использовать файл из каталога /etc.

Когда вы разрешаете запуск службы при загрузке системы или на любом другом таргете/уровне запуска, для этого юнит-файла службы создается символическая ссылка в соответствующих каталогах в /etc/systemd/system. Юнит-файлы в каталоге /etc/systemd/system представляют собой просто символические ссылки на файлы с аналогичным именем в каталоге /lib/systemd/system directory.

Последовательность инициализации Systemd: таргет-юниты

Таргет-юниты — это особые типы юнит-файлов, которые обычно имеют суффикс .target. Таргет-юниты отличаются от других типов юнит-файлов тем, что они не представляют какой-то один конкретный ресурс. Вместо этого они представляют состояние всей системы в определенный момент времени.

Для достижения этого таргет-юниты группируют и запускают несколько юнит-файлов, которые являются частью определенного состояния. Хотя таргеты Systemd и уровни запуска (runlevels) System V можно условно сравнить, они не тождественны. Файл таргет-юнита имеет имя вместо номера. Например, вы встретите что-то вроде multi-user.target вместо runlevel 3 или reboot.target вместо runlevel 6. Система Linux может загружаться с multi-user.target. В этом случае сервер фактически переводится на уровень запуска 2, 3 или 4, что запускает систему в многопользовательском текстовом режиме с включенной сетью.

Разница заключается в том, как сервер приводится к этому уровню. System V запускает службы последовательно. С другой стороны, при загрузке системы systemd проверяет наличие других служб или ресурсов и определяет порядок их загрузки.

Еще одно различие между целевыми юнитами systemd и уровнями запуска System V заключается в том, что дистрибутив Linux, использующий System V, может находиться только на одном уровне запуска. Если вы измените уровень запуска, он просто переключится на этот новый уровень запуска и будет находиться в нем. С другой стороны, файлы целевых юнитов могут быть инклюзивными. Более того, активация целевого юнита гарантирует, что другие целевые юниты будут загружены как его часть. Например, если вы загружаете систему Linux с графическим интерфейсом пользователя, в ней будет активирован graphical.target. Это, в свою очередь, автоматически гарантирует, что multi-user.target также будет загружен и активирован.

Ниже приведена таблица сравнения уровней запуска и целевых юнитов.

Уровень запуска (System V) Целевые юниты (systemd)
уровень запуска 0 poweroff.target
уровень запуска 1 rescue.target
уровень запуска 2,3,4 multi-user.target
уровень запуска 5 graphical.target
уровень запуска 6 reboot.target

Systemd default.target

В systemd default.target является эквивалентом уровня запуска по умолчанию в System V. Мы видели, что уровень запуска по умолчанию в System V определялся в файле inittab. В systemd у нас есть файл default.target. Файл целевого юнита по умолчанию хранится в каталоге /etc/systemd/system. Он представляет собой символическую ссылку на один из файлов целевых юнитов в /lib/systemd/system. Изменение целевого юнита по умолчанию означает просто повторное создание символической ссылки и изменение уровня запуска системы.

В System V файл inittab указывал, в каком каталоге Linux будет искать сценарии инициализации. Это мог быть любой из каталогов rc, как пояснялось ранее. С другой стороны, целевой юнит по умолчанию в systemd определяет юниты ресурсов для загрузки во время загрузки. Все определенные юниты загружаются. Однако не все они загружаются параллельно и не все загружаются последовательно. Загрузка юнита ресурса зависит от других ресурсов, которые он wants или requires.

Зависимости Systemd: Wants и Requires

В этом разделе мы обсудим, как Systemd обрабатывает зависимости. Мы видели, что в Upstart параллельная загрузка служб возможна при использовании конфигурационных файлов. Мы также обсудили, как System V использует уровни запуска для определения того, какую службу запускать автоматически или ожидать запуска другой службы или ресурса. Аналогичным образом службы Systemd могут быть настроены для загрузки в одном или нескольких целевых юнитах или для ожидания запуска другой службы или ресурса.

В Systemd файл юнита, который requires другой юнит, не запустится до тех пор, пока требуемый юнит не загрузится и не станет активным. Если требуемый юнит не загрузится, пока первый юнит активен, первый юнит остановится.

Такое поведение обеспечивает стабильность системы. Службу, которая requires определенный ресурс (например, порт) для доступности и активности, можно заставить ждать, пока ресурс не станет доступен (т. е. порт не будет открыт).

Напротив, юнит, который wants другой юнит, не накладывает таких ограничений. Он не остановится, если желаемый юнит остановится, пока вызывающий юнит все еще активен. Например, некоторые второстепенные службы в режиме graphical-target.

Пример Systemd

Давайте посмотрим, как мы можем настроить поведение службы в systemd.

Шаг 1. Войдите на свой VPS-сервер

Мы будем использовать MySQL в качестве реальной службы и CentOS 7 в качестве сервера. Чтобы практически пройти все шаги и понять концепции, войдите на свой VPS с CentOS 7 или создайте его на CloudSigma. Для этого раздела подходит VPS под управлением дистрибутива CentOS 7, Debian 7 или 8, либо Ubuntu 15 или новее, так как все они поставляются с systemd. Войдите в систему с помощью команды ssh или, если вы используете Windows, воспользуйтесь PuTTY:

Шаг 2. Изучите файл default.target и зависимости

Последовательность запуска Systemd следует по длинной цепочке зависимостей, которую мы подробно обсудим в этом разделе.

  • default.target

Файл default.target управляет службами, которые запускаются при обычной загрузке. Вы можете вывести список файлов целевого юнита по умолчанию с помощью следующей команды:

Вывод выглядит примерно так, как на скриншоте ниже:

screenshot

На скриншоте видно, что целевой юнит по умолчанию ссылается на файл multi-user.target в каталоге /lib/systemd/system/ каталоге. Это означает, что по умолчанию система будет загружаться в режиме multi-user.target, эквивалентном runlevel 3.

  • multi-user.target.wants

Чтобы увидеть все службы, которые требуются файлу multi-user.target, введите следующую команду:

Вывод содержит много строк, вот фрагмент:

Как видно из вывода, это символические ссылки, указывающие на фактические файлы юнитов в каталоге /lib/systemd/system/ directory. We have highlighted mysqld.service, чтобы показать вам, что он также является частью multi-user.target. Если вы хотите убедиться, настроена ли определенная служба для автозапуска, вы можете изменить команду для этого файла. Например, мы можем отфильтровать вывод, чтобы найти демон mysql или cron, используя следующие команды:

Вывод покажет:

Чтобы отфильтровать результат для демона cron, введите следующую команду:

Вывод покажет:

Помимо multi-user.target, существуют и другие типы таргетов, например system-update.target или basic.target.

Введите следующую команду, чтобы увидеть, от каких таргетов зависит multi-user target:

Вывод показывает:

Это означает, что basic-target должен загрузиться первым, чтобы система запустилась в режиме multi-user.target.

  • basic-target

Введите следующую команду, чтобы увидеть, какие еще таргеты требуются для basic.target:

Вывод покажет:

  • sysinit.target

Вы можете запустить следующую команду, чтобы проверить, есть ли необходимые target-юниты для sysinit.target. Синтаксис команды такой же. Вы можете продолжать изменять ее, чтобы увидеть, какие target-юниты требуются другим target-юнитам по ходу дела. Вот эта команда:

Вывод покажет, что для sysinit.target нет необходимых юнитов. Мы можем проверить, есть ли другие службы и target-юниты, запрашиваемые для sysinit.target с помощью следующей команды:

Вывод показывает длинный список служб и target-юнитов, запрашиваемых для sysinit.target. Часть вывода вы можете увидеть ниже:

Во время инициализации системы с помощью system4 система не остается только в одном target-юните. Вместо этого она загружает службы зависимым образом по мере перехода от одного target-юнита к другому.

Шаг 3. Изучение юнит-файла

Давайте посмотрим, как выглядит юнит-файл. Мы использовали юнит-файл службы MySQL в первой части этого руководства и будем использовать его снова. Однако мы также можем взглянуть на другой юнит-файл службы — юнит-файл sshd. Введите следующую команду, чтобы открыть конфигурационный файл sshd:

Ниже приведен скриншот, показывающий строки в файле:

unit screesnhot

Как видите, выделенные блоки кода в файле облегчают его понимание и изменение при необходимости. Ниже приведены некоторые важные директивы для понимания:

  • AfterAfter указывает системе загружать службу только после загрузки указанных target-юнитов и служб. В данном случае служба SSHD загрузится после загрузки сетевого target-юнита и службы keygen.
  • WantsWants указывает, какие target-юниты запрашивают эту службу. В данном случае ssh-keygen.service запрашивает sshd.service. Однако, если sshd завершится с ошибкой или аварийно завершит работу, это не приведет к остановке ssh-keygen.service.

Нажмите Ctrl + X, чтобы закрыть редактор.

Шаг 4. Тестирование поведения службы MySQL при загрузке системы

В этом разделе мы покажем, как можно изменить и протестировать поведение службы MySQL во время загрузки системы. В предыдущем разделе мы видели, что mysqld.service запрашивается multi-user.target. Следовательно, она будет автоматически запускаться при загрузке.

Вы можете отключить службу, выполнив следующую команду:

Выполнение команды показывает, что символическая ссылка mysql удалена из каталога /etc/systemd/system/multi-user.target.wants/. Чтобы проверить это, выполните следующую команду, чтобы узнать, запрашивается ли по-прежнему MySQL со стороны multi-user.target:

Команда ничего не возвращает. Если вы попытаетесь перезагрузить сервер и проверить статус MySQL, он не будет запущен, что означает, что он не запустился автоматически при загрузке.

Теперь снова включите службу с помощью команды:

В выводе будет показана символическая ссылка. Если вы перезагрузите сервер, MySQL должен запуститься автоматически. Включение службы Systemd создает символическую ссылку в каталоге wants целевого юнита по умолчанию. Отключение службы Systemd удаляет символическую ссылку из wants директории.

Шаг 5. Тестирование поведения службы MySQL при запуске после сбоя службы

По умолчанию служба MySQL автоматически запускается в случае сбоя. Мы можем отключить это поведение в конфигурационном файле Systemd для MySQL. Сначала давайте посмотрим на этот файл. Введите следующую команду, чтобы открыть файл:

На скриншоте ниже показан вывод:

screen shot 5

Значение директивы Restart установлено в on-failure. Это означает, что служба MySQL будет перезапускаться после некорректных кодов выхода, таймаута или некорректных сигналов. Ниже приведена таблица, показывающая некоторые параметры перезапуска из man-страницы.

Настройки перезапуска/Причины выхода no always on-success on-failure on-abnormal on-abort on-watchdog
Корректный код выхода или сигнал X X
Некорректный код выхода X X
Некорректный сигнал X X X X
Таймаут X X X
Watchdog X X X X

Двумя важными директивами в юнит-файле Systemd являются Restart и RestartSec. Они управляют поведением службы при сбое. Restart указывает, когда служба должна перезапускаться, а RestartSec указывает, сколько времени она должна ждать перед перезапуском после сбоя. Чтобы отключить поведение перезапуска, закомментируйте директиву Restart, добавив символ # в начале строки, как показано ниже:

Теперь перезагрузите системный демон, а затем перезапустите службу mysqld, используя следующие команды:

Затем выполните следующую команду, чтобы найти основной PID (Main PID) службы MySQL:

screenshot 7

Основной PID в нашем тесте был 23809. Запишите свой, чтобы использовать его в следующей команде. С помощью команды kill -9 симулируйте сбой, завершив процесс. Также не забудьте заменить номер процесса на тот, который вы получили в своем тесте:

Если вы запустите команду проверки статуса MySQL, вы увидите, что служба неактивна и не смогла перезапуститься:

screesnshot 8

Она будет оставаться в состоянии сбоя (failed) до тех пор, пока директива Restart закомментирована в конфигурационном файле mysqld.service. Это имитирует сбой, при котором служба останавливается и не запускается снова.

Чтобы снова включить службу, вы можете отредактировать конфигурационный файл mysqld.service, раскомментировать директиву Restart, затем сохранить и закрыть его. Как и ранее, перезагрузите демон и перезапустите службу. Это вернет службу к ее первоначальной конфигурации, и теперь она сможет автоматически запускаться после сбоя. На этом все, что касается настройки автоматического запуска службы после сбоя. Если вы хотите настроить автоматический запуск служб после сбоя, вам просто нужно добавить директиву Restart (и, при желании, вы также можете добавить директиву RestartSec) в раздел [Service] юнит-файла службы.

Заключение

В этом руководстве мы обсудили, как Linux обрабатывает службы во время запуска или после сбоя. Чтобы понять процесс инициализации системы Linux, мы рассмотрели три системы инициализации, которые использует Linux: System V, Upstart и Systemd. Мы обсудили их эволюцию и то, как работает каждый процесс init в отношении автоматического запуска службы после перезагрузки системы или сбоя.

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

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

Приятной работы!

author

Manpreet Singh

Автор · CloudSigma

Preslav Dobrev — креативный дизайнер в CloudSigma, сосредоточенный на формировании последовательного корпоративного образа с помощью традиционных и инновационных маркетинговых каналов. Он умело сочетает художественное видение со стратегическим маркетингом, создавая убедительные истории бренда.

Комментарии

Комментариев пока нет. Будьте первым.