Скрипт перезагрузки сервера linux

Обновлено: 07.07.2024

Abstract: описание видов ребута, рассказ про sysrq, ipt_SYSRQ, ipmi, psu.

Как перезагрузить сервер? — Это вопрос, который обычно задают ну очень начинающим пользователям, которые путаются между halt, shutdown -r, reboot, init 6 и т.д.

Опытный администратор уточнит вопрос: «а что с сервером не так?» Разные виды отказов серверов требуют разных видов ребута — и неверно выбранный вариант приведёт к тяжелейшим последствиям, из которых визит в веб-морду IPMI/DRAC/iLO с целью «доперезагрузить» будет самым лёгким. Самым тяжёлым в моей личной практике была командировка эникейщика в соседний город. С целью «нажать ребут» на одиноко стоящем сервере.

В этой статье: что мешает серверу перезагрузиться и как ему помочь.

Начнём с теории ребута.

При выключении или перезагрузке сервера менеджер инициализации (в большинстве современных дистрибутивов — systemd, в эксцентричной Ubuntu 14.04 до сих пор upstart, в архаичном хламе — sysv-init) в определённом порядке посылает всем демонам команду «выключись». И большинство демонов (например, СУБД, вроде mysql) знают, как выключаться правильно. Например, закончить все транзакции, сохранить все несохранённые данные на диск и т.д. Для in-memory СУБД, наподобие redis, это и вовсе может быть критичным: не сохранил — потерял.

Старые системы иницализации ждали неограниченно долго каждый из инит-скриптов. Например, если «шутник» добавил вам в «stop» веточку «sleep 3600», то ваш сервер будет перезагружаться час с хвостиком. А если там цифра поболе, или просто программа, которая не хочет завершаться, то и ребут никогда не закончится.

Новые системы инициализации (собственно, не стесняемся — остался только systemd) дают некий таймаут (обычно 120 или 180 секунд) на сохранение данных, после чего завершают процесс силком. Помимо остановки демонов, отмонтируются файловые системы (то есть скидываются все блочные кеши), останавливаются iscsi target'ы (тоже с скидыванием кеша), и т.д. и т.п. При том, что время шатдауна получается неопределённо долгим, оно всё таки конечно. Плюс, есть хоть какая-то надежда на правильное завершение всех демонов, скидывание файловых кешей и т. д.

Таким образом, на здоровой системе правильный ответ на вопрос «как перезагрузиться» — выполнить команду reboot. В ряде случаев — даже единственный правильный (поправка: если в графическом интерфейсе сделать «reboot», то desktop environment будет думать, что это ребут аварийный — для перезагрузки из графического режима надо использовать «reboot» в интерфейсе DE).

Что может пойти не так при «обычном ребуте»? Ну, во-первых, какой-то из процессов-демонов может начать «тупить» — см выше.

  • fallocate /fs/swap -l 1G;mkswap /fs/swap; swapon /fs/swap
  • dd if=/dev/sda of=/fs/image; kpartx /fs/image
  • losetup --find --show /fs/image

Чем это чревато? Неотмонтированной файловой системой. Systemd в этой ситуации пытается-пытается, да и бросает (неотмонтированную файловую систему). То есть reboot в этой ситуации будет ОЧЕНЬ долгим, но всё-таки пройдёт. Но это если umount вернёт ошибку.

А бывает так, что umount не может завершить операцию из-за того, что что-то не доступно. Например, файл на nfs-сервере. Если какой-то процесс обратится к такому файлу, то его завершить нельзя (даже с помощью kill -9). И в этой ситуации 'reboot' просто завесит сервер. Опять же, наиболее типовые места у systemd „прикрыты“, но вероятность наткнуться на TASK_UNINTERRUPTIBLE ('D' в ps aux) всё равно можно.
Что делать? Можно перезагрузиться без синхронизации файловых систем и завершения чего-либо reboot -f. Но он тоже может повиснуть. Про причины ниже, а пока про последствия: все процессы не остановлены и умирают мгновенно, tcp сессии не закрыты, дисковые кеши не сброшены. Однако, ядро всё-таки выполняет какие-то движения в районе ребута (и, возможно, часть кешей будет сброшена). Главное же — в процессе ребута будет задействована большая часть ядра. И это означает, что если ядру поплохело, то мы можем и не вернуться обратно.

Вторая, крайне неприятная ситуация: проблемы с файловой системой на / (в корне). Любая попытка сделать ls, grep, и даже 'reboot' вызывает либо зависание консоли, либо ошибку. По той же категории проходят проблемы с libc (включая её удаление), когда на попытку 'reboot' говорят о проблеме линковки и отказываются что-то делать. Или, мы достигли лимита на число pid'ов и все они в 'D' стейт. или ещё какая-то гадость того же калибра, идущая по категории „серверу плохо“.

Бывает так, что на сервер осталась открыта только одна консоль (а вторая уже не открывается). Почему? Потому что кто-то что-то подхимичил с драйвером дисков. Или рейд-контроллером. Или ещё чем-то, после чего от '/' остаются только воспоминания в дисковом кеше. Это означает, что у нас есть только команды bash'а (встроенные), которые выполняются без запуска новых процессов.

Существует метод перезагрузки, который не требует выполнения каких-либо исполняемых файлов (т.е. чтения с отсутствующего диска). Это (от рута): echo b >/proc/sysrq-trigger . Файл sysrq-trigger позволяет „нажать“ любую кнопку из SysRq комбинаций (аварийные кнопки ядра). В том числе и SysRq-b, то есть аварийный „reboot“. Часто бывает так, что после нажатия enter даже не успевает появиться перевод строки — сервер уже в ребуте до того, как syscall вернулся. Это самое сильное из софтового, что есть для ребута.
Замечание: кажующееся правильным в этой ситуации „sync, reboot“, т.е. SysRq-s, SysRq-B это ошибка, т.к. после SysRq-S, ядро может попытаться начать общаться с пустым множеством, и, потенциально, упасть в панику или отломать вам последнюю из доступных консолей. Если делается аварийный ребут — он должен быть аварийным

Это всё работает, если у вас есть консоль на сервер. А если логин виснет и открытой консоли нет? Есть модуль ipt_SYSRQ, позволяющий выполнить sysrq запросы по получению определённого сетевого пакета (точнее, по правилу iptables). Работает целиком в ядре, т.е. от FS не зависит. К нему же прилагается команда send_sysrq.

Можно было бы подумать, что на этом „всё“, но бывают ещё более неприятные зависания. Например, зависла сетевая карта. И обычный reboot (в т.ч. через sysrq) не помогает. Вторым примером таких плохой ситуации бывает зависание enclosure, которая залипла на плохом диске и игнорирует все bus reset. Перезагрузка вроде бы всё сбрасывает, а диски недоступны.

В этом случае нам нужен power cycle (включить/выключить). Физически бегать к серверу не интересно, так что можно посмотреть на возможности современных серверов: IPMI. Это встренный микрокомпьютер, позволяющий управлять „большим“ компьютером. Он обычно называется IPMI, DRAC, iLO, etc.

Интресующая нас команда: ipmitool chassis power cycle. Она более требовательна к работоспособности системы (должны быть загружены модули ядра, сам ipmitool должен успешно запуститься, ipmi должен быть рабочим и т.д.). Но зато она позволяет передёрнуть по питанию всех. Точнее, почти всех — если у сервера есть jbod'ы, то до них эта команда не доходит. Но, всё-таки, это очень добротный и хороший ребут.

Если ядру совсем поплохело, то команду можно выполнить и удалённо (ipmitool -H ipmi.server.local chassis power cycle)

Ещё одна сложная ситуация — когда завис ipmi. Если система при этом более-менее жива, то можно „перезагрузить ipmi“: ipmitool mc reboot hard . После этого можно будет сделать power cycle для шасси. Звучит странно, но я несколько раз в жизни „вытаскивал“ сервер в нормальный ребут именно такой последовательностью. (После mc reboot hard надо дать пару минут на загрузку BMC).

Следующая точка „боли“ — это зависающие блоки питания. Да, такое бывает. Баги в прошивке блоков питания исправляют, их нужно прошивать. Разумеется, любые мягкие ребуты (такие как ipmi power cycle) в этой ситуации не работают. Нужно либо физически тыкать кабель, либо передёргивать питание удалённо. В этой ситуации помогает IP-розетка.

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

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

Автоматический перезапуск сервиса в systemd

По умолчанию, если ваш сервис будет убит или завершится некорректно, systemd не будет с ним ничего делать. Но можно настроить сервис так, чтобы при падении или даже остановке он автоматически перезапускался. Для этого используется директива Restart, которую надо добавить в секцию Service. Например, рассмотрим настройку автоматического перезапуска сервиса Apache:

sudo systemctl edit apache2

[Service]
Restart=on-failure
RestartSec=5s


Директива RestartSec указывает сколько ждать перед перезапуском сервиса. Когда завершите сохраните изменения и выполните команду daemon-reload, чтобы перечитать конфигурацию:

sudo systemctl daemon-reload

Затем чтобы проверить что всё работает посмотрите состояние процесса, завершите процесс сигналом kill:

sudo systemctl status apache2
kill -KILL 32091


И снова посмотрите состояние. Процесс будет запущен. Система инициализации автоматически перезапустит его как только он завершится с кодом возврата ошибки. Если вы хотите чтобы процесс перезапускался всегда, необходимо использовать директиву Restart: always. Однако с ней надо быть осторожным, она вовсе не даст вам завершить процесс, даже если будет необходимо. Для того, чтобы процесс, который постоянно падает не перезапускался, можно добавить лимит на количество перезапусков в секцию Service:

sudo systemctl edit apache2

[Service]
StartLimitIntervalSec=500
StartLimitBurst=5
Restart=on-failure
RestartSec=5s

Директивы StartLimitBurst и StartLimitIntervalSec указывают, что надо попытаться перезапустить сервис пять раз, и если он все эти пять раз упадёт, то больше его не трогать. Вторая директива ограничивает время перезапусков сервиса до 500 секунд.

Автоматический перезапуск сервиса с помощью скрипта

Это самый простой и самый надежный способ работающий абсолютно во всех дистрибутивах linux и не требующий установки дополнительных утилит. Для того же Apache скрипт выглядит следующим образом:

sudo vi /usr/local/bin/apache-monitor.sh

Сохраните файл, сделайте его исполняемым:

chmod ugo+x /usr/local/bin/apache-monitor.sh

Теперь добавьте запись в cron для периодического запуска скрипта:

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

В статье рассмотрим, как перезагрузить (перезапустить) по SSH сервер Linux. Например, перезагрузить сервер Ubuntu, CentOS Debian и основанные на них дистрибутивы можно удаленно по SSH или подключившись к командной строке другим способом.

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

Когда требуется перезагрузка?

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

Так когда перезагружаем?

  1. Сервер завис или тормозит;
  2. Некорректно работают установленные программы;
  3. При смене операционной системы;
  4. При работе с BIOS (если есть физический доступ или его эмуляция);
  5. При использовании программ низкоуровневого копирования и восстановления данных (например, Acronis Backup).

На всякий пожарный: не перезагружайте сервер во время установки/удаления программ.

Как перезагрузить сервер через консоль?

Linux-серверы можно перезагрузить в консоли 3 простыми способами (команды shutdown, reboot и init).

Вы можете использовать любое решение для удаленного подключения к серверу. Мы остановимся на SSH.

Как перезагрузить сервер по SSH?

Все действия должны выполняться из-под пользователя root.

Подключитесь к вашему серверу под root-пользователем. Пароль суперпользователя указан в личном кабинете и письме, отправленном после активации сервера:

После ввода команды соединение с сервером будет прервано. Перезагрузка займет до 15 минут.

1. Команда shutdown -r

Это базовая команда, которая используется для перезагрузки Linux-сервера с Ubuntu.

Введите команду, и сервер будет перезагружен сразу:

Еще можно запланировать перезагрузку, введя вместо now конкретное время. Например, назначим перезагрузку сервера на 11 утра:

shutdown -r 11:00

Также можно перезагрузить сервер через небольшой промежуток времени. Например, через 5 минут:

2. Команда reboot

Также можно перезагрузить Linux-серверы с Ubuntu, Debian, CentOS или другим дистрибутивом с помощью универсальной команды reboot.

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

Введите команду, и сервер будет перезагружен сразу:

После ввода команды соединение с сервером будет прервано. Консоль оповестит: The system is going down for reboot NOW!

3. Команда init 6

Также для перезагрузки можно использовать уровни системы инициализации Init Scripts. Всего в этой системе 6 уровней: где 0 — выключение, а 6 — перезагрузка. Чтобы перейти к этому уровню, используйте команду:

Что делать, если сервер не работает после перезагрузки

Если в ходе перезагрузки что-то пошло не так, можно узнать о состоянии сервера, подключившись через IP-KVM.

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

У меня есть резервный скрипт, который выполняется ежедневно с помощью задания cron. Это копирование с FTP-серверов и подключенных жестких дисков USB, баз данных и т. Д.

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

Но если на следующий день набрать uptime, то обнаружится, что он не перезагрузился. Задание cron выполняется пользователем root, поэтому мне не нужно ставить sudo или su перед командой afaik. Поэтому вместо этого я попробовал другие варианты команды, такие как:

Одна попытка за раз, конечно, не все вышеперечисленные 5 строк друг за другом. ПК просто не перезагружается.

У кого-нибудь есть идеи по этому поводу?

проверьте журналы примерно в то время, когда должна произойти перезагрузка. обратите внимание, что переменная PATH не получена из конфигурации оболочки для заданий cron, поэтому «завершение» не будет найдено. Это скрипт bash. И задание cron вызывается с использованием пути (/home/username/backup.sh), но отдельные команды в сценарии вызываются без путей, и все они работают нормально. Только команда перезагрузки отказывается выполняться. Не существует ограничений на скрипты cron или shell для предотвращения перезагрузки. Я только что проверил это на виртуальной машине RHEL с успехом. Одна из очень веских причин для этого может заключаться в том, что в сценарии есть предыдущий возврат или ошибка, в результате чего сценарий останавливается до обработки команды перезагрузки. Попробуйте запустить скрипт вручную в оболочке в безопасное время. Следите за ошибками в задачах копирования файлов, которые преждевременно останавливают скрипт. Проверьте статус ошибки через echo $? после, если перезагрузка не работает. Разобрать скрипт, чтобы проверить, что он не заканчивается вручную перед вашей командой перезагрузки.

Адский способ перезагрузки это использовать

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

Также shutdown может не распознать аргумент "-t", взяв вместо этого аргумент time:

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

По умолчанию выставлено, что в случае падения сервиса Systemd ничего с ним не будет делать. Но пользователь всегда может выстроить настройки таким образом, чтобы в случае падения или остановки сервис автоматически перезапускался. Для этого используется директива Restart, которую надо добавить в секцию Service. Дальше рассмотрим пример настройки автоматического перезапуска сервиса Apache:

$ sudo systemctl edit apache2

[Service]

Restart=on-failure

RestartSec=5s

настройка автоматического перезапуска сервиса Apache:

Здесь RestartSec указывает, сколько ждать перед перезапуском сервиса. Когда завершите работу, сохраните изменения и выполните команду daemon-reload, чтобы перечитать конфигурацию:

Дальше, чтобы проверить все ли работает исправно, посмотрите состояние процесса, завершите процесс сигналом kill:

$ sudo systemctl status apache2

$ kill -KILL 32091

Процесс сигналом kill

Еще раз посмотрите состояние, процесс должен быть запущен. Для установки запуска инициализации каждый раз, используйте специальную директиву Restart: always. Но пользоваться ею необходимо крайне осторожно, ведь она не позволит завершить процесс, даже если в этом возникнет необходимость. Если процесс постоянно падает, чтобы он перезапускался, можно добавить лимит на количество перезапусков в секцию Service:

$ sudo systemctl edit apache2

[Service]

StartLimitIntervalSec=500

StartLimitBurst=5

Restart=on-failure

RestartSec=5s

Лимит на количество перезапусков в секцию Service

Здесь StartLimitBurst и StartLimitIntervalSec указывают на важность перезапуска сервиса пять раз, и если он все эти пять раз упадёт, то оставить его и не трогать. Вторая директива ограничивает время перезапусков сервиса до 500 секунд.

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

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

Файл нужно сохранить и обязательно сделать его исполняемым:

chmod ugo+x /usr/local/bin/apache-monitor.sh

Не забудьте добавить запись в cron для периодического запуска скрипта:

$ sudo crontab -e

*/5 * * * * /usr/local/bin/apache-monitor.sh

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

Читайте также: