Попал сегодня в неожиданную ситуацию, о которой хочу вас предупредить. Речь пойдет о systemd-mount в linux. Вообще, systemd должен был упростить жизнь системных администраторов. По факту, все не так однозначно. Как известно, у systemd есть свой планировщик (timer), свой ntp клиент (timesyncd). Как я сегодня узнал, еще и свое средство для монтирования разделов.
Узнал я вот о нем как. Есть облачный хостинг, который позволяет подключать к серверам высокопроизводительные сетевые диски. Я ими активно пользуюсь. Мне нужно было один диск заменить на другой и прицепить его к той же точке монтирования, что и старый.
Никаких проблем. Создаю второй диск, подключаю к серверу. Останавливаю приложение и копирую (!важно, лучше всегда копировать, а потом удалять, не переносить) данные на новый диск. Потом отключаю старый и монтирую новый в ту же точку монтирования. Запускаю приложение и убеждаюсь, что все нормально работает. А дальше самое неожиданное.
Иду в панель управления хостера и отключаю старый диск от сервера. Напоминаю, что в системе я его предварительно уже отмонтировал. Диск как-то подозрительно долго не отключался. Иду в системный лог сервера посмотреть, отключился ли диск. И вижу там очень неожиданную информацию.
Идут постоянные попытки от systemd отмонтировать раздел, к которому подмонтирован уже НОВЫЙ диск. То есть у него записано где-то (я нашел в /run/systemd/generator), что к этой точке монтирования подключен старый диск. Софт хостера по управлению ресурсами просит systemd отключить старый диск от его точки монтирования, хотя по факту она уже занята другим диском.
В общем, я в итоге не пострадал, так как приложение активно писало на диск и не дало его отмонтировать. В итоге systemd отстал и отключил диск принудительно. Будьте внимательны с systemd. Он уже не первый раз преподносит мне сюрприз.
#systemd
Узнал я вот о нем как. Есть облачный хостинг, который позволяет подключать к серверам высокопроизводительные сетевые диски. Я ими активно пользуюсь. Мне нужно было один диск заменить на другой и прицепить его к той же точке монтирования, что и старый.
Никаких проблем. Создаю второй диск, подключаю к серверу. Останавливаю приложение и копирую (!важно, лучше всегда копировать, а потом удалять, не переносить) данные на новый диск. Потом отключаю старый и монтирую новый в ту же точку монтирования. Запускаю приложение и убеждаюсь, что все нормально работает. А дальше самое неожиданное.
Иду в панель управления хостера и отключаю старый диск от сервера. Напоминаю, что в системе я его предварительно уже отмонтировал. Диск как-то подозрительно долго не отключался. Иду в системный лог сервера посмотреть, отключился ли диск. И вижу там очень неожиданную информацию.
Идут постоянные попытки от systemd отмонтировать раздел, к которому подмонтирован уже НОВЫЙ диск. То есть у него записано где-то (я нашел в /run/systemd/generator), что к этой точке монтирования подключен старый диск. Софт хостера по управлению ресурсами просит systemd отключить старый диск от его точки монтирования, хотя по факту она уже занята другим диском.
В общем, я в итоге не пострадал, так как приложение активно писало на диск и не дало его отмонтировать. В итоге systemd отстал и отключил диск принудительно. Будьте внимательны с systemd. Он уже не первый раз преподносит мне сюрприз.
#systemd
Когда работаешь в консоли Linux, постоянно приходится использовать команду systemctl для управления службами systemd. Решил собрать наиболее популярные команды в шпаргалку, чтобы удобно было сохранить и пользоваться.
Запустить службу. После внедрения systemd постоянно путался и сначала писал имя службы, а потом команду start. Сейчас уже переучился.
Добавить в автозагрузку:
Добавить сервис в автозагрузку и сразу запустить. Заменяет две предыдущие команды. Я не так давно узнал и стал использовать именно объединённую команду:
Перечитать настройки служб. Обязательно нужно выполнить после того, как изменили какие-то настройки юнитов systemd.
Список всех unit-files, а так же их состояний:
Список выше можно ограничить по типам:
Посмотреть статус конкретной службы:
Проверить статус автозапуска:
Посмотреть конфигурацию юнита:
Перечислил основное, с чем самому приходится сталкиваться. Если пропустил какую-то популярную и полезную команду, дайте знать, добавлю в список. Про stop, restart, reload, status не стал писать. Очевидные команды. Есть еще is-active и try-restart, но на практике я их вообще не использую.
Добавлю еще, что с помощью systemctl можно перезагружать и завершать работу системы, но лично я по старинке использую старые команды reboot и shutdown.
#terminal #systemd
Запустить службу. После внедрения systemd постоянно путался и сначала писал имя службы, а потом команду start. Сейчас уже переучился.
systemctl start mysql
Добавить в автозагрузку:
systemctl enable nginx
Добавить сервис в автозагрузку и сразу запустить. Заменяет две предыдущие команды. Я не так давно узнал и стал использовать именно объединённую команду:
systemctl enable --now mariadb
Перечитать настройки служб. Обязательно нужно выполнить после того, как изменили какие-то настройки юнитов systemd.
systemctl daemon-reload
Список всех unit-files, а так же их состояний:
systemctl list-unit-files
Список выше можно ограничить по типам:
systemctl -t service
systemctl -t timer
systemctl -t mount
Посмотреть статус конкретной службы:
systemctl | grep ssh
Проверить статус автозапуска:
systemctl is-enabled nginx
Посмотреть конфигурацию юнита:
systemctl cat sshd
Перечислил основное, с чем самому приходится сталкиваться. Если пропустил какую-то популярную и полезную команду, дайте знать, добавлю в список. Про stop, restart, reload, status не стал писать. Очевидные команды. Есть еще is-active и try-restart, но на практике я их вообще не использую.
Добавлю еще, что с помощью systemctl можно перезагружать и завершать работу системы, но лично я по старинке использую старые команды reboot и shutdown.
systemctl poweroff
systemctl reboot
#terminal #systemd
Подсистема инициализации и управления службами в Linux под названием Systemd плотно вошла в нашу повседневную рутину по управлению серверами. Есть в ней отдельный компонент Timers, который служит заменой классического планировщика мира Unix - cron.
Хочешь не хочешь, но с Timers работать придётся. В том же Debian 11 все повторяющиеся действия реализованы через timers и продублированы в старом cron. Список можно посмотреть вот так:
Увидите там logrotate.timer, man-db.timer, apt-daily.timer, apt-daily-upgrade.timer и т.д. Если установить php, certbot, то они также добавят свои таймеры наравне с записями в классический cron. Я так подозреваю, что в какой-то момент в обычном cron они исчезнут.
Можно по-разному относиться к нововведениям, но лично мне в таком виде они не нравятся. Это как в Windows функции размазались по Настройкам и Панели управления. В итоге приходится тратить больше времени на настройку и проверять всё в двух местах. Если уж переехали на таймеры, то в cron зачем дублировать? Там всё равно стоят проверки и если уже есть таймер для задачи, то cron ничего не делает. Но проверять приходится.
Когда я познакомился с Unix, его cron был одним из тех инструментов, который мне понравился больше всего. Простота и гибкость настройки подкупали. Все задания в одном файле. Просто скопировал и перенёс его на любой другой сервер, то есть очень простой бэкап всех заданий. Я даже на Windows устанавливал порт крона.
Смотрим на таймеры. Из удобств лично я увидел более гибкий планировщик, который может быть не только календарным, как в cron, но и событийным. Например, можно задать интервал на запуск через 10 минут после загрузки системы и потом повторять каждые 3 часа. Вроде удобно, но лично у меня никогда не было задачи, которой бы требовалось такое расписание. Ни разу не возникло ситуации, когда планировщик cron не справился бы. Максимум, иногда в скрипт добавишь sleep, но это редко бывает. Стараюсь так не делать, потому что костыль.
Вторым плюсом можно отметить логирование каждого отдельного таймера. Это удобно, но не сказать, что очень сильно надо. Grep общего лога cron с таким же успехом покажет все события отдельной задачи. В таймерах смотрим лог вот так:
Ещё одним несомненным плюсом таймеров является возможность настройки зависимостей задач от других служб. Это реально удобно и в обычном cron никак не реализуется. Только если закладывать логику проверки в сам скрипт. Также таймеры могут быть присоединены к разным cgroups.
Я решил написать эту заметку, потому что на днях возникла простая задача. Надо было настроить периодический перезапуск службы 1С на Linux сервере. Прикинул, как это можно сделать через Timers. Получилась такая схема:
1. Создаём отдельную службу, которая перезапускает процесс srv1cv83.
2. Создаём таймер, который запускает эту службу.
Второй вариант, в описание самой службы srv1cv83 добавить параметр WatchdogSec, который будет автоматически перезапускать службу через заданный промежуток времени. Но так трудно попасть в конкретное время. Можно рано или поздно в середине рабочего дня перезапуститься.
Мне показалось, что проще просто добавить в crontab:
и перезапускать службу каждое воскресенье в 6:55. На этом решении в итоге и остановился.
А вы используете systemd timers? Какие задачи решаете? Может я туплю и не понимаю, как красиво и просто перезапускать в нужное время существующую работающую службу, управляемую systemd?
#linux #systemd #cron
Хочешь не хочешь, но с Timers работать придётся. В том же Debian 11 все повторяющиеся действия реализованы через timers и продублированы в старом cron. Список можно посмотреть вот так:
# systemctl list-timers
Увидите там logrotate.timer, man-db.timer, apt-daily.timer, apt-daily-upgrade.timer и т.д. Если установить php, certbot, то они также добавят свои таймеры наравне с записями в классический cron. Я так подозреваю, что в какой-то момент в обычном cron они исчезнут.
Можно по-разному относиться к нововведениям, но лично мне в таком виде они не нравятся. Это как в Windows функции размазались по Настройкам и Панели управления. В итоге приходится тратить больше времени на настройку и проверять всё в двух местах. Если уж переехали на таймеры, то в cron зачем дублировать? Там всё равно стоят проверки и если уже есть таймер для задачи, то cron ничего не делает. Но проверять приходится.
Когда я познакомился с Unix, его cron был одним из тех инструментов, который мне понравился больше всего. Простота и гибкость настройки подкупали. Все задания в одном файле. Просто скопировал и перенёс его на любой другой сервер, то есть очень простой бэкап всех заданий. Я даже на Windows устанавливал порт крона.
Смотрим на таймеры. Из удобств лично я увидел более гибкий планировщик, который может быть не только календарным, как в cron, но и событийным. Например, можно задать интервал на запуск через 10 минут после загрузки системы и потом повторять каждые 3 часа. Вроде удобно, но лично у меня никогда не было задачи, которой бы требовалось такое расписание. Ни разу не возникло ситуации, когда планировщик cron не справился бы. Максимум, иногда в скрипт добавишь sleep, но это редко бывает. Стараюсь так не делать, потому что костыль.
Вторым плюсом можно отметить логирование каждого отдельного таймера. Это удобно, но не сказать, что очень сильно надо. Grep общего лога cron с таким же успехом покажет все события отдельной задачи. В таймерах смотрим лог вот так:
# journalctl -u logrotate.timer
Ещё одним несомненным плюсом таймеров является возможность настройки зависимостей задач от других служб. Это реально удобно и в обычном cron никак не реализуется. Только если закладывать логику проверки в сам скрипт. Также таймеры могут быть присоединены к разным cgroups.
Я решил написать эту заметку, потому что на днях возникла простая задача. Надо было настроить периодический перезапуск службы 1С на Linux сервере. Прикинул, как это можно сделать через Timers. Получилась такая схема:
1. Создаём отдельную службу, которая перезапускает процесс srv1cv83.
2. Создаём таймер, который запускает эту службу.
Второй вариант, в описание самой службы srv1cv83 добавить параметр WatchdogSec, который будет автоматически перезапускать службу через заданный промежуток времени. Но так трудно попасть в конкретное время. Можно рано или поздно в середине рабочего дня перезапуститься.
Мне показалось, что проще просто добавить в crontab:
55 6 * * 7 root /usr/bin/systemctl restart srv1cv83
и перезапускать службу каждое воскресенье в 6:55. На этом решении в итоге и остановился.
А вы используете systemd timers? Какие задачи решаете? Может я туплю и не понимаю, как красиво и просто перезапускать в нужное время существующую работающую службу, управляемую systemd?
#linux #systemd #cron
Одна из особенностей Unix систем, которая меня сразу привлекла по сравнению с Windows, это наличие там CRON. По мне так это очень крутой, простой, удобный инструмент для управления периодическими задачами.
На своих серверах я привык все задачи писать в системный crontab, чтобы всё было в одном месте. Мне так удобнее управлять заданиями. Не надо проверять разные файлы. После планировщика Windows юниксовый cron очень понравился.
Сейчас на смену cron пришли systemd timers. Мне не особо нравится формат работы с ними, но приходится мириться и использовать, потому что всё больше софта по умолчанию свои задачи хранит там. Timers предлагают более широкий функционал по сравнению с cron и более гибкие настройки. Так что надо привыкать и пользоваться. Для этого решил сделать для себя шпаргалку и сразу поделиться с вами.
Сначала поясню, что умеют таймеры из того, что не умеет cron. Например, запустить какую-то задачу через заданное время после какого-то события. Для cron такое событие, насколько мне известно, может быть только — @reboot. Таймер же может запуститься, например, через некоторое время после завершения работы какого-то сервиса, возможно тоже вызванного по таймеру.
Таймер может проверять зависимости от других служб и не запускать задание, если какая-то служба недоступна. В случае cron подобную логику приходится реализовывать в самих скриптах. Например, проверять монтирование диска при бэкапе на удалённое хранилище.
Для каждого таймера systemd ведёт отдельный журнал, что удобно для отладки или анализа работы. Не надо грепать общий лог крона, или вообще системный лог, если по умолчанию cron не имеет отдельного журнала, как, например, в Debian. Я обычно это исправляю сразу же после установки системы.
В целом, удобство timers очевидно, хотя лично я ещё ни разу не сталкивался с ситуацией, где бы мне было проще и быстрее добавить таймер, а не воспользоваться cron. Для запуска скриптов крона вполне хватает. А с таймерами приходится взаимодействовать, когда настраиваешь какой-то софт. Например, certbot. Или смотришь системные залачи.
Посмотреть список всех таймеров:
Только активных:
Более подробная информация:
Пример создания таймера, который выполняет команду df -h. Сначала создаём конфигурацию сервиса в файле /etc/systemd/system/mydf.service:
Запустим и проверим результат. По умолчанию, вывод пишется в журнал systemd.
После нескольких запусков журнал можно посмотреть вот так:
Добавим задачу в планировщик, создав для неё минутный таймер в файле /etc/systemd/system/mydf.timer
Запускаем таймер:
Через несколько минут проверяем:
Если лог очень большой, его имеет смысл ограничить:
Формат systemd.time, в том числе и для таймеров, можно посмотреть в документации (сразу приведу шаблон DOW YYYY-MM-DD HH:MM:SS). Чаще всего при просмотре логов используется сокращение today или yesterday. То, что таймер пишет вывод в лог, удобно, но имейте ввиду, что за этим выводом стоит следить, если он большой.
Добавляем таймер в автозагрузку:
Удаляем из автозагрузки и останавливаем:
Примеры служб и таймеров удобно посмотреть в уже готовых системных, в директории /lib/systemd/system. Показательны примеры для apt-daily и apt-daily-upgrade. Там и зависимости, и запуск одного после другого. Ну и про документацию не забываем.
#systemd #terminal #linux
На своих серверах я привык все задачи писать в системный crontab, чтобы всё было в одном месте. Мне так удобнее управлять заданиями. Не надо проверять разные файлы. После планировщика Windows юниксовый cron очень понравился.
Сейчас на смену cron пришли systemd timers. Мне не особо нравится формат работы с ними, но приходится мириться и использовать, потому что всё больше софта по умолчанию свои задачи хранит там. Timers предлагают более широкий функционал по сравнению с cron и более гибкие настройки. Так что надо привыкать и пользоваться. Для этого решил сделать для себя шпаргалку и сразу поделиться с вами.
Сначала поясню, что умеют таймеры из того, что не умеет cron. Например, запустить какую-то задачу через заданное время после какого-то события. Для cron такое событие, насколько мне известно, может быть только — @reboot. Таймер же может запуститься, например, через некоторое время после завершения работы какого-то сервиса, возможно тоже вызванного по таймеру.
Таймер может проверять зависимости от других служб и не запускать задание, если какая-то служба недоступна. В случае cron подобную логику приходится реализовывать в самих скриптах. Например, проверять монтирование диска при бэкапе на удалённое хранилище.
Для каждого таймера systemd ведёт отдельный журнал, что удобно для отладки или анализа работы. Не надо грепать общий лог крона, или вообще системный лог, если по умолчанию cron не имеет отдельного журнала, как, например, в Debian. Я обычно это исправляю сразу же после установки системы.
В целом, удобство timers очевидно, хотя лично я ещё ни разу не сталкивался с ситуацией, где бы мне было проще и быстрее добавить таймер, а не воспользоваться cron. Для запуска скриптов крона вполне хватает. А с таймерами приходится взаимодействовать, когда настраиваешь какой-то софт. Например, certbot. Или смотришь системные залачи.
Посмотреть список всех таймеров:
# systemctl list-timers --all
Только активных:
# systemctl list-timers
Более подробная информация:
# systemctl status *timer
Пример создания таймера, который выполняет команду df -h. Сначала создаём конфигурацию сервиса в файле /etc/systemd/system/mydf.service:
[Unit]
Description=Start df and log result in systemd journal
Wants=mydf.service
[Service]
Type=oneshot
ExecStart=/usr/bin/df -h
[Install]
WantedBy=multi-user.target
Запустим и проверим результат. По умолчанию, вывод пишется в журнал systemd.
# systemctl start mydf.service
# systemctl status mydf.service
После нескольких запусков журнал можно посмотреть вот так:
# journalctl -u mydf.service
Добавим задачу в планировщик, создав для неё минутный таймер в файле /etc/systemd/system/mydf.timer
[Unit]
Description=Log df results every minute
Requires=mydf.service
[Timer]
Unit=mydf.service
OnCalendar=*-*-* *:*:00
[Install]
WantedBy=timers.target
Запускаем таймер:
# systemctl start mydf.timer
Через несколько минут проверяем:
# journalctl -u mydf.service
Если лог очень большой, его имеет смысл ограничить:
# journalctl -S "5min ago" -u mydf.service
Формат systemd.time, в том числе и для таймеров, можно посмотреть в документации (сразу приведу шаблон DOW YYYY-MM-DD HH:MM:SS). Чаще всего при просмотре логов используется сокращение today или yesterday. То, что таймер пишет вывод в лог, удобно, но имейте ввиду, что за этим выводом стоит следить, если он большой.
Добавляем таймер в автозагрузку:
# systemctl enable mydf.timer
Удаляем из автозагрузки и останавливаем:
# systemctl disable mydf.timer
# systemctl stop mydf.timer
Примеры служб и таймеров удобно посмотреть в уже готовых системных, в директории /lib/systemd/system. Показательны примеры для apt-daily и apt-daily-upgrade. Там и зависимости, и запуск одного после другого. Ну и про документацию не забываем.
#systemd #terminal #linux
В systemd есть удобный механизм автозапуска сервиса в случае его завершения работы по той или иной причине. Какой-то стандартный софт имеет эту настройку в том или ином виде по умолчанию, например, Mariadb в Debian, какой-то нет, и это нужно сделать вручную.
Автозапуском сервиса управляет параметр
◽always — перезапускать всегда, когда сервис был остановлен корректно (exit code 0), с кодом ошибки или завис по таймауту
◽on-success — перезапускать, только если служба завершилась без ошибок (exit code 0)
◽on-failure — перезапускать, только если код завершения был не нулевым, был прибит одним из сигналов принудительного завершения работы (например SIGKILL), завис по таймауту
◽on-abnormal — перезапускать только если сервис был прибит одним из сигналов принудительного завершения работы или завис по таймауту
◽on-abort — перезапускать только если сервис был прибит одним из сигналов принудительного завершения работы
◽on-watchdog — перезапускать только если наступил настроенный для сервиса watchdog timeout
◽no — автоматического перезапуска нет
Надеюсь нигде не наврал. Перевёл кратенько отрывок документации, чтобы не притащить чьи-то ошибки. Так то в инете много статей по этой теме. По умолчанию, если явно не указан параметр, он принимает значение
Для того, чтобы настроить автоматический запуск сервиса, не надо редактировать его основной unit файл. Сделайте отдельный файл изменений
Добавьте туда:
После изменений надо перечитать настройки служб:
Теперь можно прибить Nginx и убедиться, что через 5 секунд он поднимется снова:
К автозапуску процессов надо подходить с умом. Не стоит для всех подряд его настраивать. Особенное внимание надо уделить службам СУБД. После аварийного завершения работы может запускаться очень ресурсоёмкая процедура восстановления данных, которая в нагруженном сервере может быть прибита oom killer и так по кругу. Это может привести к более серьезным последствиям или потере данных.
То же самое касается каких-то кластерных служб. Они могут падать и подниматься в цикле и приводить к рассинхронизации или каким-то ещё проблемам. Например, elasticsearch может подниматься очень долго на слабом железе. Иногда приходится стандартные таймауты systemd увеличивать, чтобы он удачно стартовал. Если настроить автозапуск, он может в цикле прибивать службу по таймауту.
А тот же самый Nginx, Postfix, Dovecot, Apache, Zabbix Agent можно спокойно ставить в автозапуск в случае падений. Проблем быть не должно.
У автозапуска есть более тонкие настройки и зависимости. Я описал только основной функционал, который нужен чаще всего. Более подробно всё описано в документации. Там настраиваются таймауты, различные статусы завершения работы, которые стоит считать успешными, количество попыток перезапуска, прежде чем они прекратятся и т.д. Можно слать оповещения на почту в случае падения и перезапуска службы. Это делается через параметр
Табличку себе сохраните на память для настройки. Без неё неочевидно, какой параметр лучше использовать. Например, Mariadb по умолчанию имеет настройку
#systemd #linux
Автозапуском сервиса управляет параметр
Restart
в разделе [Service]
. Он может принимать следующие значения:◽always — перезапускать всегда, когда сервис был остановлен корректно (exit code 0), с кодом ошибки или завис по таймауту
◽on-success — перезапускать, только если служба завершилась без ошибок (exit code 0)
◽on-failure — перезапускать, только если код завершения был не нулевым, был прибит одним из сигналов принудительного завершения работы (например SIGKILL), завис по таймауту
◽on-abnormal — перезапускать только если сервис был прибит одним из сигналов принудительного завершения работы или завис по таймауту
◽on-abort — перезапускать только если сервис был прибит одним из сигналов принудительного завершения работы
◽on-watchdog — перезапускать только если наступил настроенный для сервиса watchdog timeout
◽no — автоматического перезапуска нет
Надеюсь нигде не наврал. Перевёл кратенько отрывок документации, чтобы не притащить чьи-то ошибки. Так то в инете много статей по этой теме. По умолчанию, если явно не указан параметр, он принимает значение
no
.Для того, чтобы настроить автоматический запуск сервиса, не надо редактировать его основной unit файл. Сделайте отдельный файл изменений
override.conf
и положите его в директорию сервиса со специальным именем. Для nginx оно будет такое: /etc/systemd/system/nginx.service.d/override.conf
.Добавьте туда:
[Service]
Restart=always
RestartSec=5s
После изменений надо перечитать настройки служб:
# systemctl daemon-reload
Теперь можно прибить Nginx и убедиться, что через 5 секунд он поднимется снова:
# systemctl status nginx ; смотрим pid корневого процесса (Main PID)
# kill -9 1910155
# systemctl status nginx
К автозапуску процессов надо подходить с умом. Не стоит для всех подряд его настраивать. Особенное внимание надо уделить службам СУБД. После аварийного завершения работы может запускаться очень ресурсоёмкая процедура восстановления данных, которая в нагруженном сервере может быть прибита oom killer и так по кругу. Это может привести к более серьезным последствиям или потере данных.
То же самое касается каких-то кластерных служб. Они могут падать и подниматься в цикле и приводить к рассинхронизации или каким-то ещё проблемам. Например, elasticsearch может подниматься очень долго на слабом железе. Иногда приходится стандартные таймауты systemd увеличивать, чтобы он удачно стартовал. Если настроить автозапуск, он может в цикле прибивать службу по таймауту.
А тот же самый Nginx, Postfix, Dovecot, Apache, Zabbix Agent можно спокойно ставить в автозапуск в случае падений. Проблем быть не должно.
У автозапуска есть более тонкие настройки и зависимости. Я описал только основной функционал, который нужен чаще всего. Более подробно всё описано в документации. Там настраиваются таймауты, различные статусы завершения работы, которые стоит считать успешными, количество попыток перезапуска, прежде чем они прекратятся и т.д. Можно слать оповещения на почту в случае падения и перезапуска службы. Это делается через параметр
OnFailure
. Табличку себе сохраните на память для настройки. Без неё неочевидно, какой параметр лучше использовать. Например, Mariadb по умолчанию имеет настройку
on-abort
.#systemd #linux
В современных дистрибутивах Linux почти везде вместо традиционных текстовых логов средствами syslog используются бинарные логи journald. Они также, как и текстовые логи, иногда разрастаются до больших размеров, так что необходимо заниматься чисткой. Вот об этом и будет заметка. На днях пришлось на одном сервере этим заняться, поэтому решил сразу оформить заметку. Написана она будет по мотивам Debian 11.
Смотрим, сколько логи занимают места:
Обычно они хранятся в директории
Настройки ротации логов могут быть заданы в файле
Параметров, относящихся к настройке хранения логов намного больше, но эти два основные, которых достаточно для простого ограничения размера. Первый параметр ограничивает суммарный размер логов, а второй размер отдельного лог файла. Journald автоматически разделяет логи на файлы определённого размера. После изменения параметров, надо перезапустить службу:
Так же вы можете обрезать логи в режиме реального времени. Примерно так:
В первом случае обрезали старые логи, чтобы их осталось не больше 1024 мегабайт. Во втором обрезали все логи, старше 7-ми дней.
Кстати, если вы не хотите связываться с настройками journald, то можете команды выше просто в cron добавить на регулярное выполнение. Это тоже будет решение по ротации логов.
По умолчанию journald может занимать до 10% объёма раздела, на котором он находится. Но не более 4 Гб. На деле именно с ограничением в 4 Гб я чаще всего и сталкивался. Если у вас общий системный диск 40+ Гб, то как раз логи в 4 Гб у вас и будут.
Если у вас в логи спамит какая-то конкретная служба, то имеет смысл для неё отдельно настроить ограничение, выделив её логи в отдельный namespace. Для этого в unit службы в раздел
Добавляем:
Создаём в директории
Перезапускаем службу:
Смотрим его логи отдельно:
Я, кстати, по старинке, всегда запускаю текстовые логи через syslog. Просто привык к ним. В итоге у меня и бинарные логи в journal, и текстовые в syslog. Примерно как с cron и timers. Через systemd больше функциональности и настройки гибче, но старые инструменты проще и быстрее в настройке.
#linux #logs #systemd #journal
Смотрим, сколько логи занимают места:
# journalctl --disk-usage
Обычно они хранятся в директории
/var/log/journal
. Настройки ротации логов могут быть заданы в файле
/etc/systemd/journald.conf
. Управляются они следующими параметрами:[Journal]
SystemMaxUse=1024M
SystemMaxFileSize=50M
Параметров, относящихся к настройке хранения логов намного больше, но эти два основные, которых достаточно для простого ограничения размера. Первый параметр ограничивает суммарный размер логов, а второй размер отдельного лог файла. Journald автоматически разделяет логи на файлы определённого размера. После изменения параметров, надо перезапустить службу:
# systemctl restart systemd-journald.service
Так же вы можете обрезать логи в режиме реального времени. Примерно так:
# journalctl --vacuum-size=1024M
# journalctl --vacuum-time=7d
В первом случае обрезали старые логи, чтобы их осталось не больше 1024 мегабайт. Во втором обрезали все логи, старше 7-ми дней.
Кстати, если вы не хотите связываться с настройками journald, то можете команды выше просто в cron добавить на регулярное выполнение. Это тоже будет решение по ротации логов.
По умолчанию journald может занимать до 10% объёма раздела, на котором он находится. Но не более 4 Гб. На деле именно с ограничением в 4 Гб я чаще всего и сталкивался. Если у вас общий системный диск 40+ Гб, то как раз логи в 4 Гб у вас и будут.
Если у вас в логи спамит какая-то конкретная служба, то имеет смысл для неё отдельно настроить ограничение, выделив её логи в отдельный namespace. Для этого в unit службы в раздел
[Service]
добавьте отдельное пространство логов. Покажу на примере ssh. Запускаем редактирования юнита. # systemctl edit ssh
Добавляем:
[Service]
LogNamespace=ssh
Создаём в директории
/etc/systemd/
отдельный конфиг для этого namespace journald@ssh.conf
со своими параметрами:[Journal]
SystemMaxUse=20M
Перезапускаем службу:
# systemctl restart ssh
Смотрим его логи отдельно:
# journalctl --namespace ssh
Я, кстати, по старинке, всегда запускаю текстовые логи через syslog. Просто привык к ним. В итоге у меня и бинарные логи в journal, и текстовые в syslog. Примерно как с cron и timers. Через systemd больше функциональности и настройки гибче, но старые инструменты проще и быстрее в настройке.
#linux #logs #systemd #journal
В systemd есть все необходимые инструменты для централизованного сбора логов. Вот они:
▪ systemd-journal-remote — служба, принимающая или забирающая записи журналов на центральном сервере
▪ systemd-journal-upload — служба, отправляющая локальные журналы на центральный сервер
Всё это позволяет без сторонних инструментов настроить централизованный сбор логов со множества серверов в одном месте. В Debian эти службы устанавливаются одним пакетом
После этого можно подготовить конфиг службы. Если нет нужды, то можно отключить работу по https, чтобы не заморачиваться с сертификатом, если сбор логов идёт по закрытым каналам связи. Для этого копируем системный unit в
Заменили ключ
Служба запустится на tcp порту 19532.
Перемещаемся на сервер, который будет отправлять логи и устанавливаем туда этот же пакет. Затем идём в конфигурационный файл
Запускаем службу и проверяем, что она успешно начала отправку логов:
Если ошибок нет, то можно идти на центральный сервер и там смотреть логи от удалённого сервера.
Сами логи будут лежать в отдельных файлах с ip адресом отправляющего сервера в названии. Примерно так:
Для этих логов действуют те же правила фильтрации, что и для локальных. Смотрим все логи юнита ssh:
Или только сообщения ядра:
Если я правильно понял, то ротация удалённых логов будет производиться по тем же правилам и настройкам, что и всего системного журнала journald. Я рассказывал об этом. Отдельно настраивать не нужно.
С помощью systemd-journal удобно собирать логи в одно место с множества хостов без установки на них стороннего софта. А потом уже централизованно отправить в любую другую систему хранения логов на обработку. Я ещё забыл упомянуть, что systemd-journal-remote можно настроить так, что он сам будет ходить по серверам и забирать с них логи.
#linux #logs #systemd #journal
▪ systemd-journal-remote — служба, принимающая или забирающая записи журналов на центральном сервере
▪ systemd-journal-upload — служба, отправляющая локальные журналы на центральный сервер
Всё это позволяет без сторонних инструментов настроить централизованный сбор логов со множества серверов в одном месте. В Debian эти службы устанавливаются одним пакетом
systemd-journal-remote
. # apt install systemd-journal-remote
После этого можно подготовить конфиг службы. Если нет нужды, то можно отключить работу по https, чтобы не заморачиваться с сертификатом, если сбор логов идёт по закрытым каналам связи. Для этого копируем системный unit в
/etc/systemd/system
и меняем параметр ExecStart
:# cp /lib/systemd/system/systemd-journal-remote.service \
/etc/systemd/system/systemd-journal-remote.service
[Service]
ExecStart=/lib/systemd/systemd-journal-remote --listen-http=-3 --output=/var/log/journal/remote/
Заменили ключ
--listen-https
на --listen-http
. Если захотите использовать https, то сертификат надо будет прописать в /etc/systemd/journal-remote.conf
. Далее достаточно создать необходимую директорию, назначить права и запустить службу:# mkdir -p /var/log/journal/remote
# chown systemd-journal-remote:systemd-journal-remote /var/log/journal/remote
# systemctl daemon-reload
# systemctl start systemd-journal-remote
Служба запустится на tcp порту 19532.
Перемещаемся на сервер, который будет отправлять логи и устанавливаем туда этот же пакет. Затем идём в конфигурационный файл
/etc/systemd/journal-upload.conf
и добавляем туда путь к серверу:[Upload]
URL=http://10.20.1.36:19532
Запускаем службу и проверяем, что она успешно начала отправку логов:
# systemctl start systemd-journal-upload
# systemctl status systemd-journal-upload
Если ошибок нет, то можно идти на центральный сервер и там смотреть логи от удалённого сервера.
# journalctl -D /var/log/journal/remote -f
Сами логи будут лежать в отдельных файлах с ip адресом отправляющего сервера в названии. Примерно так:
remote-10.20.1.56.journal
. Можно посмотреть конкретный файл:# journalctl --file=remote-10.20.1.56.journal -n 100
Для этих логов действуют те же правила фильтрации, что и для локальных. Смотрим все логи юнита ssh:
# journalctl --file=remote-10.20.1.56.journal -u ssh
Или только сообщения ядра:
# journalctl --file=remote-10.20.1.56.journal -k
Если я правильно понял, то ротация удалённых логов будет производиться по тем же правилам и настройкам, что и всего системного журнала journald. Я рассказывал об этом. Отдельно настраивать не нужно.
С помощью systemd-journal удобно собирать логи в одно место с множества хостов без установки на них стороннего софта. А потом уже централизованно отправить в любую другую систему хранения логов на обработку. Я ещё забыл упомянуть, что systemd-journal-remote можно настроить так, что он сам будет ходить по серверам и забирать с них логи.
#linux #logs #systemd #journal
Ещё одна заметка про systemd и его встроенные инструменты для работы с логами. Есть служба systemd-journal-gatewayd, с помощью которой можно смотреть логи systemd через браузер. Причём настраивается она максимально просто, буквально в пару действий. Показываю на примере Debian.
Устанавливаем пакет systemd-journal-remote:
Запускаем службу:
Порт по умолчанию 19531. Идём смотреть логи в браузер: http://10.20.1.36:19531/browse. Это обзорный url. Тут в выпадающем списке можно выбирать любой лог.
Можно посмотреть логи только текущей загрузки: http://10.20.1.36:19531/entries?boot.
Можно через curl забирать эти же логи в json формате. Примерно так для юнита ssh:
Все параметры и возможности описаны в документации. Обращаю внимание, что можно не только локальные логи открывать для доступа, но и собранные с удалённых машин. Если вы настроили такой сбор по моей вчерашней заметке, то директорию с логами для systemd-journal-gatewayd можно указать отдельно. Параметр
#linux #logs #systemd #journal
Устанавливаем пакет systemd-journal-remote:
# apt install systemd-journal-remote
Запускаем службу:
# systemctl start systemd-journal-gatewayd.service
Порт по умолчанию 19531. Идём смотреть логи в браузер: http://10.20.1.36:19531/browse. Это обзорный url. Тут в выпадающем списке можно выбирать любой лог.
Можно посмотреть логи только текущей загрузки: http://10.20.1.36:19531/entries?boot.
Можно через curl забирать эти же логи в json формате. Примерно так для юнита ssh:
# curl --silent -H 'Accept: application/json' \
'http://10.20.1.36:19531/entries?UNIT=ssh.service'
Все параметры и возможности описаны в документации. Обращаю внимание, что можно не только локальные логи открывать для доступа, но и собранные с удалённых машин. Если вы настроили такой сбор по моей вчерашней заметке, то директорию с логами для systemd-journal-gatewayd можно указать отдельно. Параметр
-D DIR, --directory=DIR
.#linux #logs #systemd #journal
В Linux есть любопытный бинарник
Бинарник этот по своей сути программа-пустышка. Он делает одну простую вещь - завершается с нулевым кодом выхода. То есть означает успешно выполненную команду. Используют её обычно для каких-то целей в скриптах.
Изначально true был обычным shell скриптом в unix вот такого содержания:
По сути это пустой скрипт, который, если его запустить, ничего не делает, но завершается с нулевым кодом выхода. И вот этот скрипт компания AT&T запатентовала. Для того, чтобы его можно было использовать в Linux, пришлось написать то же самое на C и скомпилировать. Поэтому в Linux не скрипт, а бинарник, который делает то же самое, что и задумывалось изначально.
Аналогичной утилитой, только возвращающей код ошибки является
Код выхода у неё ошибочный, то есть 1.
Узнал про
Вообще не понятно, к чему всё это и почему при этом служба работает корректно. Как она запускается? Оказалось, что для управления работой postfix используются шаблоны systemd. И рядом лежит файл
В итоге, сначала запускается основной unit, в котором прописана команда /bin/true, успешно отрабатывает, а потом то, что описано шаблоном.
Если честно, я не совсем понял, зачем для postfix используют шаблон. Они обычно нужны для удобного управления пулом запущенных сервисов единой командой. Когда у вас через шаблон запущены процессы, их все остановить или запустить можно одной командой. Но postfix обычно работает одним экземпляром на сервере.
Потом уже почитал ещё немного, увидел режим multiple Postfix instances в рамках одного хоста. Не буду на этом останавливаться подробно, но смысл в том, что можно запускать несколько экземпляров postfix, которые будут использовать разные файлы конфигураций и рабочие директории. Сам никогда подобное не настраивал и не вижу особо смысла в современных реалиях.
#postfix #systemd
/bin/true
, про который я узнал случайно. Стал искать подробности и наткнулся на интересную информацию про него. Сначала про него расскажу, а потом как я на него наткнулся. Бинарник этот по своей сути программа-пустышка. Он делает одну простую вещь - завершается с нулевым кодом выхода. То есть означает успешно выполненную команду. Используют её обычно для каких-то целей в скриптах.
Изначально true был обычным shell скриптом в unix вот такого содержания:
# Copyright (c) 1984 AT&T
# All Rights Reserved
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
# The copyright notice above does not evidence any
# actual or intended publication of such source code.
#ident "@(#)cmd/true.sh 50.1"
По сути это пустой скрипт, который, если его запустить, ничего не делает, но завершается с нулевым кодом выхода. И вот этот скрипт компания AT&T запатентовала. Для того, чтобы его можно было использовать в Linux, пришлось написать то же самое на C и скомпилировать. Поэтому в Linux не скрипт, а бинарник, который делает то же самое, что и задумывалось изначально.
Аналогичной утилитой, только возвращающей код ошибки является
/bin/false
:# /bin/false
# echo $?
1
Код выхода у неё ошибочный, то есть 1.
Узнал про
/bin/true
я случайно, когда в Debian смотрел systemd unit от postfix /lib/systemd/system/postfix.service
. Открываю, а там такое:[Unit]
Description=Postfix Mail Transport Agent
Conflicts=sendmail.service exim4.service
ConditionPathExists=/etc/postfix/main.cf
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecReload=/bin/true
[Install]
WantedBy=multi-user.target
Вообще не понятно, к чему всё это и почему при этом служба работает корректно. Как она запускается? Оказалось, что для управления работой postfix используются шаблоны systemd. И рядом лежит файл
postfix@.service
, где уже описаны все параметры запуска конкретного экземпляра почтового сервера. При этом в /etc/systemd/system/multi-user.target.wants
есть символьная ссылка только на postfix.service
, поэтому сразу не очевидно, что там зависимые юниты есть.В итоге, сначала запускается основной unit, в котором прописана команда /bin/true, успешно отрабатывает, а потом то, что описано шаблоном.
Если честно, я не совсем понял, зачем для postfix используют шаблон. Они обычно нужны для удобного управления пулом запущенных сервисов единой командой. Когда у вас через шаблон запущены процессы, их все остановить или запустить можно одной командой. Но postfix обычно работает одним экземпляром на сервере.
Потом уже почитал ещё немного, увидел режим multiple Postfix instances в рамках одного хоста. Не буду на этом останавливаться подробно, но смысл в том, что можно запускать несколько экземпляров postfix, которые будут использовать разные файлы конфигураций и рабочие директории. Сам никогда подобное не настраивал и не вижу особо смысла в современных реалиях.
#postfix #systemd
Постоянно использую systemctl, чтобы посмотреть статус службы:
И никогда не приходило в голову, что без указания службы эта команда тоже работает:
Заметил случайно, когда забыл указать службу. Удивился выводу, так как увидел впервые. Причём в самом начале было указано и подсвечено красным:
Стал разбираться, о чём тут идёт речь. Что там за сфейлившийся юнит:
Оказалось, что это
Тут уже увидел конкретную ошибку в логе службы. Не загрузился один из модулей ядра, перечисленных в
Помимо ошибок запуска юнитов, команда
◽количество запущенных Units
◽uptime самой systemd
◽версию systemd
◽иерархический список запущенных служб
При этом список служб представлен в удобном виде. Более наглядно, чем в том же htop с иерархическим отображением. Так что команду надо запомнить и пользоваться.
#systemd
# systemctl status mariadb
И никогда не приходило в голову, что без указания службы эта команда тоже работает:
# systemctl status
Заметил случайно, когда забыл указать службу. Удивился выводу, так как увидел впервые. Причём в самом начале было указано и подсвечено красным:
State: degraded
Failed: 1 units
Стал разбираться, о чём тут идёт речь. Что там за сфейлившийся юнит:
# systemctl list-units --failed
Оказалось, что это
systemd-modules-load.service
юнит сфейлился на этапах ACTIVE и SUB. Мне это вообще ни о чём не сказало, поэтому стал разбираться дальше:# systemctl status systemd-modules-load.service
# journalctl -u systemd-modules-load.service
Тут уже увидел конкретную ошибку в логе службы. Не загрузился один из модулей ядра, перечисленных в
/etc/modules-load.d
. Когда-то настроил и забыл об этом. Он и не нужен уже, но при этом он и не грузился, потому что добавил его с ошибкой 😎.Помимо ошибок запуска юнитов, команда
systemctl status
покажет:◽количество запущенных Units
◽uptime самой systemd
◽версию systemd
◽иерархический список запущенных служб
При этом список служб представлен в удобном виде. Более наглядно, чем в том же htop с иерархическим отображением. Так что команду надо запомнить и пользоваться.
#systemd
Я делал несколько заметок на тему systemd, где встроенные возможности этой системы управления службами заменяют функциональность других линуксовых программ и утилит:
◽Systemd timers как замена Cron
◽Journald как замена Syslog
◽Systemd-journal-remote - централизованное хранение логов
◽Systemd-journal-gatewayd - просмотр логов через браузер
◽Systemd-mount для монтирования дисков
◽Есть ещё timesyncd как замена ntp или chrony.
Сегодня расскажу про ещё одну такую службу, которая заменяет локальный кэширующий DNS сервер - systemd-resolved. Изначально я научился настраивать DNS сервер Bind ещё в те времена, когда было привычным делом держать свою зону на своих серверах. Везде использовал его, даже в простых случаях, где нужно простое кэширование без поддержки своих зон. Потом познакомился с Dnsmasq и для обычного кэширования стал использовать его, так как настроить быстрее и проще. На пути к упрощению решил попробовать systemd-resolved. Он выступает в роли локального кэширующего сервера, то есть обрабатывает только запросы сервера, где он установлен, и его приложений.
В каких-то дистрибутивах systemd-resolved может быть в составе systemd. В Debian 12 это не так, поэтому придётся поставить отдельно:
Далее открываем конфиг
Это минимальный набор настроек для локального кэширующего сервера. Сервера из списка FallbackDNS будут использоваться в случае недоступности основного списка.
Перезапускаем службу:
После установки systemd-resolved удаляет
или так:
То есть локальный DNS сервис имеет адрес 127.0.0.54. Он же и указан в виде
Посмотреть статус службы можно так:
Если захотите посмотреть подробности работы службы, например, увидеть сами запросы и узнать сервера, к которым они были переадресованы, то можно включить режим отладки.
Добавляем параметр:
Перезапускаем службу и смотрим логи:
Если ответа нет в кэше, то вы увидите информацию о том, что был запрос к публичному DNS серверу. Если в кэше есть запись об этом домене, то увидите строку:
Посмотреть статистику по запросам:
Очистить локальный кэш:
В принципе, простой и эффективный инструмент. Можно пользоваться, особенно если он идёт в комплекте с systemd. Было бы интересно его приспособить и для удалённых запросов. Например, поставить на гипервизор и обслуживать запросы виртуальных машин. Но как я понял, он так не умеет и не предназначен для этого.
#systemd #dns
◽Systemd timers как замена Cron
◽Journald как замена Syslog
◽Systemd-journal-remote - централизованное хранение логов
◽Systemd-journal-gatewayd - просмотр логов через браузер
◽Systemd-mount для монтирования дисков
◽Есть ещё timesyncd как замена ntp или chrony.
Сегодня расскажу про ещё одну такую службу, которая заменяет локальный кэширующий DNS сервер - systemd-resolved. Изначально я научился настраивать DNS сервер Bind ещё в те времена, когда было привычным делом держать свою зону на своих серверах. Везде использовал его, даже в простых случаях, где нужно простое кэширование без поддержки своих зон. Потом познакомился с Dnsmasq и для обычного кэширования стал использовать его, так как настроить быстрее и проще. На пути к упрощению решил попробовать systemd-resolved. Он выступает в роли локального кэширующего сервера, то есть обрабатывает только запросы сервера, где он установлен, и его приложений.
В каких-то дистрибутивах systemd-resolved может быть в составе systemd. В Debian 12 это не так, поэтому придётся поставить отдельно:
# apt install systemd-resolved
Далее открываем конфиг
/etc/systemd/resolved.conf
и приводим его примерно к такому виду:[Resolve]
DNS=77.88.8.1 1.1.1.1 8.8.8.8
FallbackDNS=77.88.8.8 8.8.4.4
Cache=yes
Это минимальный набор настроек для локального кэширующего сервера. Сервера из списка FallbackDNS будут использоваться в случае недоступности основного списка.
Перезапускаем службу:
# systemctl restart systemd-resolved
После установки systemd-resolved удаляет
/etc/resolv.conf
и заменяет ссылкой на /run/systemd/resolve/stub-resolv.conf
. Проверить работу службы можно разными способами. Например так:# resolvectl query ya.ru
или так:
# dig @127.0.0.54 ya.ru
То есть локальный DNS сервис имеет адрес 127.0.0.54. Он же и указан в виде
nameserver 127.0.0.53
в resolv.conf
. Посмотреть статус службы можно так:
# resolvectl status
Если захотите посмотреть подробности работы службы, например, увидеть сами запросы и узнать сервера, к которым они были переадресованы, то можно включить режим отладки.
# systemctl edit systemd-resolved
Добавляем параметр:
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
Перезапускаем службу и смотрим логи:
# systemctl restart systemd-resolved
# journalctl -f -u systemd-resolved
Если ответа нет в кэше, то вы увидите информацию о том, что был запрос к публичному DNS серверу. Если в кэше есть запись об этом домене, то увидите строку:
Positive cache hit for example.com IN A
Посмотреть статистику по запросам:
# resolvectl statistics
Очистить локальный кэш:
# resolvectl flush-caches
В принципе, простой и эффективный инструмент. Можно пользоваться, особенно если он идёт в комплекте с systemd. Было бы интересно его приспособить и для удалённых запросов. Например, поставить на гипервизор и обслуживать запросы виртуальных машин. Но как я понял, он так не умеет и не предназначен для этого.
#systemd #dns
Короткая справочная заметка. С недавних пор (последние ~два года) для просмотра информации о системе использую простую команду:
Потихоньку ушёл от всех других вариантов. Раньше пользовался:
Уже забывать всё это стал. Hostnamectl даёт всю базовую информацию сразу, так что никуда заглядывать больше не надо. Тут и имя системы, и версия ОС, и ядро. Сразу видно, виртуальная машина это или контейнер. Если контейнер, то будет показан его тип: docker, lxc или openvz. Если VM, то тип виртуализации.
#systemd
# hostnamectl
Static hostname: serveradmin.ru
Icon name: computer-vm
Chassis: vm
Machine ID: 3cdf45d116364add90df898f553e5665
Boot ID: de9b9d3b12e54447abd7fdccc4543ebd
Virtualization: microsoft
Operating System: Debian GNU/Linux 11 (bullseye)
Kernel: Linux 5.10.0-26-amd64
Architecture: x86-64
Потихоньку ушёл от всех других вариантов. Раньше пользовался:
# lsb_release -a
# uname -a
# cat /etc/os-release
# cat /etc/redhat-release
Уже забывать всё это стал. Hostnamectl даёт всю базовую информацию сразу, так что никуда заглядывать больше не надо. Тут и имя системы, и версия ОС, и ядро. Сразу видно, виртуальная машина это или контейнер. Если контейнер, то будет показан его тип: docker, lxc или openvz. Если VM, то тип виртуализации.
#systemd