В современных дистрибутивах 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=1024MSystemMaxFileSize=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
👍130👎2
В 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
👍88👎2
Ещё одна заметка про 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
👍109👎1
В 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 AgentConflicts=sendmail.service exim4.serviceConditionPathExists=/etc/postfix/main.cf[Service]Type=oneshotRemainAfterExit=yesExecStart=/bin/trueExecReload=/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
👍75👎5
Постоянно использую systemctl, чтобы посмотреть статус службы:
И никогда не приходило в голову, что без указания службы эта команда тоже работает:
Заметил случайно, когда забыл указать службу. Удивился выводу, так как увидел впервые. Причём в самом начале было указано и подсвечено красным:
Стал разбираться, о чём тут идёт речь. Что там за сфейлившийся юнит:
Оказалось, что это
Тут уже увидел конкретную ошибку в логе службы. Не загрузился один из модулей ядра, перечисленных в
Помимо ошибок запуска юнитов, команда
◽количество запущенных Units
◽uptime самой systemd
◽версию systemd
◽иерархический список запущенных служб
При этом список служб представлен в удобном виде. Более наглядно, чем в том же htop с иерархическим отображением. Так что команду надо запомнить и пользоваться.
#systemd
# systemctl status mariadbИ никогда не приходило в голову, что без указания службы эта команда тоже работает:
# systemctl status Заметил случайно, когда забыл указать службу. Удивился выводу, так как увидел впервые. Причём в самом начале было указано и подсвечено красным:
State: degradedFailed: 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
👍204👎5
Я делал несколько заметок на тему 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.8FallbackDNS=77.88.8.8 8.8.4.4Cache=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
👍106👎1
Короткая справочная заметка. С недавних пор (последние ~два года) для просмотра информации о системе использую простую команду:
Потихоньку ушёл от всех других вариантов. Раньше пользовался:
Уже забывать всё это стал. Hostnamectl даёт всю базовую информацию сразу, так что никуда заглядывать больше не надо. Тут и имя системы, и версия ОС, и ядро. Сразу видно, виртуальная машина это или контейнер. Если контейнер, то будет показан его тип: docker, lxc или openvz. Если VM, то тип виртуализации.
#systemd
# hostnamectlStatic hostname: serveradmin.ruIcon name: computer-vmChassis: vmMachine ID: 3cdf45d116364add90df898f553e5665Boot ID: de9b9d3b12e54447abd7fdccc4543ebdVirtualization: microsoftOperating System: Debian GNU/Linux 11 (bullseye)Kernel: Linux 5.10.0-26-amd64Architecture: x86-64Потихоньку ушёл от всех других вариантов. Раньше пользовался:
# lsb_release -a# uname -a# cat /etc/os-release# cat /etc/redhat-releaseУже забывать всё это стал. Hostnamectl даёт всю базовую информацию сразу, так что никуда заглядывать больше не надо. Тут и имя системы, и версия ОС, и ядро. Сразу видно, виртуальная машина это или контейнер. Если контейнер, то будет показан его тип: docker, lxc или openvz. Если VM, то тип виртуализации.
#systemd
👍288👎1
Я делал уже много заметок на тему systemd, где эта изначально система инициализации и управления службами стала заменять старые компоненты системы Linux. Повествование не будет полным без рассказа о монтировании файловых систем с помощью systemd. Сейчас этот механизм встречается повсеместно, особенно у облачных провайдеров, так что знать о нём необходимо.
Давно уже рассказывал, как попал в неприятную ситуацию с облачной виртуалкой, где нужно было заменить диск. Я не учёл момент, что провайдер напрямую управляет монтированием внутри пользовательских виртуалок через systemd, из-за чего я чуть не потерял все данные.
Монтирование файловых систем с помощью systemd обладает явными преимуществами перед привычным fstab:
1️⃣ Есть возможность автомонтирования при обращении и отключения устройства по заданным параметрам.
2️⃣ Можно автоматически создавать директории для точек монтирования. За их наличием не обязательно следить.
3️⃣ Можно настроить таймаут подключения устройства. Если оно не доступно, это не заблокирует загрузку системы, как это бывает с fstab.
4️⃣ Можно настраивать зависимость монтирования от других служб. Актуально для монтирования после подключения по VPN, либо запуска какого-то специального софта для работы с диском.
Самый простой пример монтирования локального диска в
На диске должен быть создан раздел с файловой системой ext4. Если раздела нет, то создайте с помощью
Uuid диска смотрим с помощью blkid:
Перечитываем содержание юнитов и монтируем файловую систему:
Если всё в порядке, можно добавить в автозагрузку:
Теперь покажу пример юнита автомонтирования на примере диска NFS, который доступен только после подключения по openvpn с помощью локального клиента. Он будет автоматически подключаться при обращении к точке монтирования и отключаться в случае отсутствия активности в течении 60 секунд. У него должно быть расширение .automount. Для этого мы должны создать обычный юнит
mnt-backup.mount:
mnt-backup.automount:
Добавляем автомонтирование в автозагрузку:
Теперь при старте системы ничего монтироваться не будет. При обращении к точке монтирования /mnt/backup будет предпринята попытка примонтировать сетевой диск при условии запущенной службы openvpn@client.service. Если служба будет отключена, диск принудительно будет отмонтирован, так как .automount жёстко привязан не только к запуску службы, но и к её работе.
Документация по mount и automount:
- systemd.mount — Mount unit configuration
- systemd.automount — Automount unit configuration
📌 Полезные ссылки по теме systemd:
◽️Systemd timers как замена Cron
◽️Journald как замена Syslog
◽️Systemd-journal-remote - централизованное хранение логов
◽️Systemd-journal-gatewayd - просмотр логов через браузер
◽️Hostnamectl для просмотра информации о системе
◽️Systemd-resolved - кэширующий DNS сервер
#systemd
Давно уже рассказывал, как попал в неприятную ситуацию с облачной виртуалкой, где нужно было заменить диск. Я не учёл момент, что провайдер напрямую управляет монтированием внутри пользовательских виртуалок через systemd, из-за чего я чуть не потерял все данные.
Монтирование файловых систем с помощью systemd обладает явными преимуществами перед привычным fstab:
1️⃣ Есть возможность автомонтирования при обращении и отключения устройства по заданным параметрам.
2️⃣ Можно автоматически создавать директории для точек монтирования. За их наличием не обязательно следить.
3️⃣ Можно настроить таймаут подключения устройства. Если оно не доступно, это не заблокирует загрузку системы, как это бывает с fstab.
4️⃣ Можно настраивать зависимость монтирования от других служб. Актуально для монтирования после подключения по VPN, либо запуска какого-то специального софта для работы с диском.
Самый простой пример монтирования локального диска в
/mnt/backup со стандартными настройками. Создаём юнит в /etc/systemd/system с именем mnt-backup.mount:[Unit]Description=Disk for backups[Mount]What=/dev/disk/by-uuid/f774fad3-2ba0-47d1-a20b-0b1c2ae1b7d6Where=/mnt/backupType=ext4Options=defaults[Install]WantedBy=multi-user.targetНа диске должен быть создан раздел с файловой системой ext4. Если раздела нет, то создайте с помощью
cfdisk. Если нет файловой системы, то создайте: # mkfs -t ext4 /dev/sdb1Uuid диска смотрим с помощью blkid:
# blkid/dev/sdb1: UUID="f774fad3-2ba0-47d1-a20b-0b1c2ae1b7d6" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="a6242d02-8cff-fd44-99ce-a37c654c446c"Перечитываем содержание юнитов и монтируем файловую систему:
# systemctl daemon-reload# systemctl start mnt-backup.mountЕсли всё в порядке, можно добавить в автозагрузку:
# systemctl enable mnt-backup.mountТеперь покажу пример юнита автомонтирования на примере диска NFS, который доступен только после подключения по openvpn с помощью локального клиента. Он будет автоматически подключаться при обращении к точке монтирования и отключаться в случае отсутствия активности в течении 60 секунд. У него должно быть расширение .automount. Для этого мы должны создать обычный юнит
mnt-backup.mount, но не включать его автозагрузку, и к нему добавить mnt-backup.automount.mnt-backup.mount:
[Unit]Description=NFS share[Mount]What=srv.example.com:/backup/nfs_shareWhere=/mnt/backupType=nfs4Options=rwTimeoutSec=15mnt-backup.automount:
[Unit]Description=NFS shareRequires=network-online.targetBindsTo=openvpn@client.service After=openvpn@client.service[Automount]Where=/mnt/backupTimeoutIdleSec=60[Install]WantedBy=graphical.targetДобавляем автомонтирование в автозагрузку:
# systemctl daemon-reload# systemctl enable --now mnt-backup.automountТеперь при старте системы ничего монтироваться не будет. При обращении к точке монтирования /mnt/backup будет предпринята попытка примонтировать сетевой диск при условии запущенной службы openvpn@client.service. Если служба будет отключена, диск принудительно будет отмонтирован, так как .automount жёстко привязан не только к запуску службы, но и к её работе.
Документация по mount и automount:
- systemd.mount — Mount unit configuration
- systemd.automount — Automount unit configuration
📌 Полезные ссылки по теме systemd:
◽️Systemd timers как замена Cron
◽️Journald как замена Syslog
◽️Systemd-journal-remote - централизованное хранение логов
◽️Systemd-journal-gatewayd - просмотр логов через браузер
◽️Hostnamectl для просмотра информации о системе
◽️Systemd-resolved - кэширующий DNS сервер
#systemd
👍221👎4
Недавно делал заметку про ограничение использования диска при создании дампов базы данных, чтобы не вызывать замедление всех остальных процессов в системе. Использовал утилиту pv. Способ простой и рабочий, я его внедрил и оставил. Поставленную задачу решает.
Тем не менее, захотелось сделать это более изящно через использование приоритетов. Если диск не нагружен, то неплохо было бы его использовать с максимальной производительностью. А если нагружен, то отдать приоритет другим процесса. Это был бы наиболее рациональный и эффективный способ.
Я знаю утилиту ionice, которая в большинстве дистрибутивов есть по умолчанию. Она как раз существует для решения именно этой задачи. У неё не так много параметров, так что пользоваться ей просто. Приоритет можно передать через ключи. Для этого нужно задать режим работы:
◽Idle - идентификатор 1, процесс работает с диском только тогда, когда он не занят
◽Best effort - идентификатор 2, стандартный режим работы с возможностью выставления приоритета от 0 до 7 (0 - максимальный)
◽Real time - режим работы реального времени тоже с возможностью задавать приоритет от 0 до 7
На практике это выглядит примерно так:
Скопировали tempfile в домашний каталог в режиме idle. По идее, это то, что нужно. На практике этот приоритет не работает. Провёл разные тесты и убедился в том, что в Debian 12 ionice не работает вообще. Стал копать, почему так.
В Linux системах существуют разные планировщики процессов в отношении ввода-вывода. Раньше использовался Cfq, и ionice работает только с ним. В современных системах используется более эффективный планировщик Deadline. Проверить планировщик можно так:
Принципиальная разница этих планировщиков в том, что cfq равномерно распределяет процессы с операциями ввода-вывода, и это нормально подходит для hdd, а deadline отдаёт приоритет чтению в ущерб записи, что в целом уменьшает отклик для ssd дисков. С ними использовать его более рационально. Можно заставить работать ionice, но тогда придётся вернуть планировщик cfq, что не хочется делать, если у вас ssd диски.
Для планировщика deadline не смог найти простого и наглядного решения приоритизации процессов записи на диск. Стандартным решением по ограничению скорости, по типу того, что делает pv, является использование параметров systemd:
- IOReadBandwidthMax - объём данных, который сервису разрешается прочитать с блочных устройств за одну секунду;
- IOWriteBandwidthMax - объём данных, который сервису разрешается записать на блочные устройства за одну секунду.
Причём у него есть также параметр IODeviceWeight, что является примерно тем же самым, что и приоритет. Но работает он тоже только с cfq.
Для того, чтобы ограничить скорость записи на диск с помощью systemd, необходимо создать юнит для этого. Покажу на примере создания тестового файла с помощью dd с ограничением скорости записи в 20 мегабайт в секунду.
Запускаем:
Проверяем:
Это можно использовать как заготовку для реального задания. Если хочется потестировать в консоли, то запускайте так:
Простое рабочее решение без использования дополнительных утилит. Обращаю внимание, что если сработает кэширование записи, то визуально ограничение можно не увидеть. Я это наблюдал. И только с флагом sync её хорошо сразу же видно.
#systemd
Тем не менее, захотелось сделать это более изящно через использование приоритетов. Если диск не нагружен, то неплохо было бы его использовать с максимальной производительностью. А если нагружен, то отдать приоритет другим процесса. Это был бы наиболее рациональный и эффективный способ.
Я знаю утилиту ionice, которая в большинстве дистрибутивов есть по умолчанию. Она как раз существует для решения именно этой задачи. У неё не так много параметров, так что пользоваться ей просто. Приоритет можно передать через ключи. Для этого нужно задать режим работы:
◽Idle - идентификатор 1, процесс работает с диском только тогда, когда он не занят
◽Best effort - идентификатор 2, стандартный режим работы с возможностью выставления приоритета от 0 до 7 (0 - максимальный)
◽Real time - режим работы реального времени тоже с возможностью задавать приоритет от 0 до 7
На практике это выглядит примерно так:
# ionice -c 3 cp tempfile ~/Скопировали tempfile в домашний каталог в режиме idle. По идее, это то, что нужно. На практике этот приоритет не работает. Провёл разные тесты и убедился в том, что в Debian 12 ionice не работает вообще. Стал копать, почему так.
В Linux системах существуют разные планировщики процессов в отношении ввода-вывода. Раньше использовался Cfq, и ionice работает только с ним. В современных системах используется более эффективный планировщик Deadline. Проверить планировщик можно так:
# cat /sys/block/sda/queue/scheduler[none] mq-deadlineПринципиальная разница этих планировщиков в том, что cfq равномерно распределяет процессы с операциями ввода-вывода, и это нормально подходит для hdd, а deadline отдаёт приоритет чтению в ущерб записи, что в целом уменьшает отклик для ssd дисков. С ними использовать его более рационально. Можно заставить работать ionice, но тогда придётся вернуть планировщик cfq, что не хочется делать, если у вас ssd диски.
Для планировщика deadline не смог найти простого и наглядного решения приоритизации процессов записи на диск. Стандартным решением по ограничению скорости, по типу того, что делает pv, является использование параметров systemd:
- IOReadBandwidthMax - объём данных, который сервису разрешается прочитать с блочных устройств за одну секунду;
- IOWriteBandwidthMax - объём данных, который сервису разрешается записать на блочные устройства за одну секунду.
Причём у него есть также параметр IODeviceWeight, что является примерно тем же самым, что и приоритет. Но работает он тоже только с cfq.
Для того, чтобы ограничить скорость записи на диск с помощью systemd, необходимо создать юнит для этого. Покажу на примере создания тестового файла с помощью dd с ограничением скорости записи в 20 мегабайт в секунду.
[Unit]Description=Create file with dd[Service]IOWriteBandwidthMax=/dev/sda 20MExecStart=/usr/bin/dd if=/dev/zero of=/tempfile bs=1M count=1000 oflag=sync[Install]WantedBy=multi-user.targetЗапускаем:
# systemctl start createfile.serviceПроверяем:
# systemctl status createfile.servicesystemd[1]: Started createfile.service - Create file with dd.dd[1423]: 1000+0 records indd[1423]: 1000+0 records outdd[1423]: 1048576000 bytes (1.0 GB, 1000 MiB) copied, 52.417 s, 20.0 MB/ssystemd[1]: createfile.service: Deactivated successfully.Это можно использовать как заготовку для реального задания. Если хочется потестировать в консоли, то запускайте так:
# systemd-run --scope -p IOWriteBandwidthMax='/dev/sda 20M' dd status=progress if=/dev/zero of=/tempfile bs=1M count=1000 oflag=syncПростое рабочее решение без использования дополнительных утилит. Обращаю внимание, что если сработает кэширование записи, то визуально ограничение можно не увидеть. Я это наблюдал. И только с флагом sync её хорошо сразу же видно.
#systemd
👍80👎3
Если вам нужно ограничить процессу потребление памяти, то с systemd это сделать очень просто. Причём там есть гибкие варианты настройки. Вообще, все варианты ограничения ресурсов с помощью systemd описаны в документации. Там внушительный список. Покажу на примере памяти, какие настройки за что отвечают.
◽MemoryAccounting=1
Включение подсчёта памяти (Turn on process and kernel memory accounting for this unit)
◽MemoryHigh=16G
Это основной механизм ограничения потребления памяти (This is the main mechanism to control memory usage of a unit). Указанный лимит может быть превышен, если это необходимо, но процесс при этом будет замедляться, а память у него активно забираться назад.
◽MemoryMax=20G
Жёсткий лимит по потреблению памяти. Если процесс до него дойдет, то он будет завершён OOM Killer. В общем случае этот лимит лучше не использовать, только в крайних случаях, чтобы сохранить работоспособность системы.
◽MemorySwapMax=3G
Ограничение по использованию swap.
◽Restart=on-abnormal
Параметр не имеет отношения к потреблению памяти, но добавил сюда для справки. Если хотите, чтобы процесс перезапускался автоматически после того, как его прибьют по превышению MemoryMax, то используйте этот параметр.
◽OOMPolicy=stop
Тоже косвенный параметр, который устанавливает то, как OOM Killer будет останавливать процесс. Либо это будет попытка корректно остановить процесс через stop, либо он его просто прибьёт через kill. Выбирайте в зависимости от того, что ограничиваете. Если у процесса жор памяти означает, что он завис и его надо прибить, то ставьте kill. А если он ещё живой и может быть остановлен, тогда stop.
Параметры эти описываются в секции юнита [Service] примерно так:
Потестировать лимиты можно в консоли. Для примера возьмём python и съедим гигабайт памяти:
Команда будет висеть без ошибок, по По
Теперь зажимаем её:
Процесс работает, но потребляет разрешённые ему 200M. На практике чуть меньше. Смотрим через pmap:
Значения в килобайтах. Первое - виртуальная память (VSZ), сколько процесс запросил, столько получил. Занял весь гигабайт. Второе значение - RSS, что условно соответствует реальному потреблению физической памяти, и тут уже работает лимит. Реальной памяти процесс потребляет не больше лимита.
RSS можно ещё вот так быстро глянуть:
Вообще, с памятью у Linux всё непросто. Кому интересно, я как-то пытался в этом разобраться и рассказать простым языком.
Systemd удобный инструмент в плане управления лимитами процессов. Легко настраивать и управлять.
Считаю, что эта заметка достойна того, чтобы быть сохранённой в избранном.
#systemd
◽MemoryAccounting=1
Включение подсчёта памяти (Turn on process and kernel memory accounting for this unit)
◽MemoryHigh=16G
Это основной механизм ограничения потребления памяти (This is the main mechanism to control memory usage of a unit). Указанный лимит может быть превышен, если это необходимо, но процесс при этом будет замедляться, а память у него активно забираться назад.
◽MemoryMax=20G
Жёсткий лимит по потреблению памяти. Если процесс до него дойдет, то он будет завершён OOM Killer. В общем случае этот лимит лучше не использовать, только в крайних случаях, чтобы сохранить работоспособность системы.
◽MemorySwapMax=3G
Ограничение по использованию swap.
◽Restart=on-abnormal
Параметр не имеет отношения к потреблению памяти, но добавил сюда для справки. Если хотите, чтобы процесс перезапускался автоматически после того, как его прибьют по превышению MemoryMax, то используйте этот параметр.
◽OOMPolicy=stop
Тоже косвенный параметр, который устанавливает то, как OOM Killer будет останавливать процесс. Либо это будет попытка корректно остановить процесс через stop, либо он его просто прибьёт через kill. Выбирайте в зависимости от того, что ограничиваете. Если у процесса жор памяти означает, что он завис и его надо прибить, то ставьте kill. А если он ещё живой и может быть остановлен, тогда stop.
Параметры эти описываются в секции юнита [Service] примерно так:
[Unit]Description=Python ScriptAfter=network.target[Service]WorkingDirectory=/opt/runExecStart=/opt/run/scrape.pyRestart=on-abnormalMemoryAccounting=1MemoryHigh=16GMemoryMax=20GMemorySwapMax=3GOOMPolicy=stop[Install]WantedBy=multi-user.targetПотестировать лимиты можно в консоли. Для примера возьмём python и съедим гигабайт памяти:
# python3 -c 'a="a"*1024**3; input()'Команда будет висеть без ошибок, по По
ps или free -m будет видно, что скушала 1G оперативы. Теперь зажимаем её:
# systemd-run --scope -p MemoryMax=256M -p MemoryHigh=200M python3 -c 'a="a"*1024**3; input()'Процесс работает, но потребляет разрешённые ему 200M. На практике чуть меньше. Смотрим через pmap:
# ps ax | grep python 767 pts/0 S+ 0:00 /usr/bin/python3 -c a="a"*1024**3; input()# pmap 767 -x | grep totaltotal kB 1065048 173992 168284Значения в килобайтах. Первое - виртуальная память (VSZ), сколько процесс запросил, столько получил. Занял весь гигабайт. Второе значение - RSS, что условно соответствует реальному потреблению физической памяти, и тут уже работает лимит. Реальной памяти процесс потребляет не больше лимита.
RSS можно ещё вот так быстро глянуть:
# ps -e -o rss,args --sort -rssВообще, с памятью у Linux всё непросто. Кому интересно, я как-то пытался в этом разобраться и рассказать простым языком.
Systemd удобный инструмент в плане управления лимитами процессов. Легко настраивать и управлять.
Считаю, что эта заметка достойна того, чтобы быть сохранённой в избранном.
#systemd
👍143👎3
Давно не занимался настройкой времени на серверах. Сейчас в Debian по умолчанию запущена служба systemd-timesyncd. Там либо стандартные дебиановские сервера указаны, типа
А тут один внешний сервер стал в мониторинге мигать проблемами с синхронизацией. Просмотрел логи, увидел ошибку:
Почему-то иногда подвисают соединения и синхронизация не происходит. Решил для начала просто поменять набор серверов. Конфигурация timesyncd хранится в файле
И уже в него добавляем свои параметры. В данном случае я добавил несколько основных и один резервный сервер:
Перечитываем конфигурацию служб и перезапускаем timesyncd:
Проверяем общие настройки времени:
И конкретно статус синхронизации:
Видно, что он взял первый сервер из списка, который мы указали.
Посмотреть логи службы можно так:
☝️ Дам одну подсказу, если у вас вообще не синхронизируется время, нет соединения с внешними серверами. Такие соединения очень часто блокируют сами провайдеры, предоставляя свои внутренние сервера времени. Это делают специально, потому что протокол NTP, как и DNS очень часто используют для усиления DDOS атак. Так что если у вас не синхронизируется время на сервере с внешними источниками, задайте сразу вопрос провайдеру. Сэкономите кучу времени.
Это ограничение можно обойти различными способами. Например, использовать htpdate (
Замена серверов мне, кстати, в итоге не помогла. Всё равно часть запросов подвисают с ошибкой
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd
0.debian.pool.ntp.org, либо из шаблона хостера какие-то его или другие публичные сервера. Обычно всё это сразу работает и трогать не обязательно. Я даже подзабыл и названия служб, и расположение конфигураций.А тут один внешний сервер стал в мониторинге мигать проблемами с синхронизацией. Просмотрел логи, увидел ошибку:
systemd-timesyncd[308]: Timed out waiting for reply from 195.90.182.235:123 (0.debian.pool.ntp.org)Почему-то иногда подвисают соединения и синхронизация не происходит. Решил для начала просто поменять набор серверов. Конфигурация timesyncd хранится в файле
/etc/systemd/timesyncd.conf. Но трогать его не рекомендуется, а как это обычно бывает с systemd, создать отдельный каталог с корректирующей конфигурацией:# mkdir /etc/systemd/timesyncd.conf.d# touch /etc/systemd/timesyncd.conf.d/timesyncd.confИ уже в него добавляем свои параметры. В данном случае я добавил несколько основных и один резервный сервер:
NTP=0.ru.pool.ntp.org 1.ru.pool.ntp.org 2.ru.pool.ntp.org 3.ru.pool.ntp.orgFallbackNTP=ntp0.vniiftri.ruПеречитываем конфигурацию служб и перезапускаем timesyncd:
# systemd daemon-reload# systemctl restart systemd-timesyncdПроверяем общие настройки времени:
# timedatectlИ конкретно статус синхронизации:
# timedatectl timesync-status Server: 51.250.35.68 (0.ru.pool.ntp.org) ................................Видно, что он взял первый сервер из списка, который мы указали.
Посмотреть логи службы можно так:
# journalctl -u systemd-timesyncd☝️ Дам одну подсказу, если у вас вообще не синхронизируется время, нет соединения с внешними серверами. Такие соединения очень часто блокируют сами провайдеры, предоставляя свои внутренние сервера времени. Это делают специально, потому что протокол NTP, как и DNS очень часто используют для усиления DDOS атак. Так что если у вас не синхронизируется время на сервере с внешними источниками, задайте сразу вопрос провайдеру. Сэкономите кучу времени.
Это ограничение можно обойти различными способами. Например, использовать htpdate (
apt install htpdate), которая берёт точное время по протоколу HTTP.Замена серверов мне, кстати, в итоге не помогла. Всё равно часть запросов подвисают с ошибкой
Timed out waiting for reply. Случается это без какой-то системы, но время в итоге всё равно синхронизируется. Не знаю точно, с чем связано. Думаю, что это особенность пула pool.ntp.org. Надо использовать какие-то конкретные адреса.❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd
4👍174👎4
Изучал на днях один инструмент и случайно наткнулся на информацию про Systemd.path - триггер на события в файловой системе. Удивился, что не знаком с этой функциональностью. Либо уже забыл это. Но сам точно не использовал. С помощью Systemd.path можно отслеживать изменения в файловой системе и выполнять какие-то действия на их основе.
Функциональность очень полезная. Сразу покажу на примере. Допустим, нам надо выполнить какое-то действие при изменении файла. Настраиваем сначала слежение за файлом. Создаём файл
Будем следить за изменением файла
Для теста и понимания, как это работает, настроил простейшее действие. Команда echo будет писать текущую дату перезапуска службы в файл
Убеждаемся, что первое выполнение службы было сделано в момент старта:
Должен был создаться файл
Такой вот простой и удобный механизм. В строку
В данном примере я использовал директиву слежения за записью в файл PathModified. Помимо неё есть другие:
◽️PathExists= реагирует на появление заданного файла или директории.
◽️PathExistsGlob= то же самое что и предыдущее, но можно использовать маски для имён.
◽️PathChanged= отличается от PathModified тем, что реагирует не на запись в файл, а на закрытие файла после записи.
◽️DirectoryNotEmpty= реагирует на появление файла в пустой директории.
📌 Другая полезная (и не очень) функциональность SystemD:
◽️Systemd timers как замена Cron
◽️Journald как замена Syslog
◽️Systemd-journal-remote - централизованное хранение логов
◽️Systemd-journal-gatewayd - просмотр логов через браузер
◽️Hostnamectl для просмотра информации о системе
◽️Systemd-resolved - кэширующий DNS сервер
◽️Параметры Systemd для приоритизации дисковых операций
◽️Ограничение потребления памяти с Systemd
◽️Синхронизация времени с помощью systemd-timesyncd
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd
Функциональность очень полезная. Сразу покажу на примере. Допустим, нам надо выполнить какое-то действие при изменении файла. Настраиваем сначала слежение за файлом. Создаём файл
/etc/systemd/system/daemon.path:[Unit]Description=Watch /etc/daemon/daemon.conf for changes[Path]PathModified=/etc/daemon/daemon.conf[Install]WantedBy=multi-user.targetБудем следить за изменением файла
daemon.conf. А если оно случится, перезапустим службу daemon.service. Для этого создаём саму службу в файле /etc/systemd/system/daemon.service:[Unit]Description=Restart Daemon ServiceAfter=network.target[Service]Type=oneshotExecStart=sh -c "/usr/bin/echo daemon service restarted at `date` >> /etc/daemon/restart.date"[Install]RequiredBy=daemon.pathДля теста и понимания, как это работает, настроил простейшее действие. Команда echo будет писать текущую дату перезапуска службы в файл
/etc/daemon/restart.date. Запускаем проверку и саму службу:# systemctl enable daemon.{path,service}# systemctl start daemon.{path,service}Убеждаемся, что первое выполнение службы было сделано в момент старта:
# systemctl status daemon.serviceДолжен был создаться файл
/etc/daemon/restart.date. Теперь изменяем файл /etc/daemon/daemon.conf и проверяем снова restart.date. Там должна появиться новая строка с текстом daemon service restarted at и текущее время с датой.Такой вот простой и удобный механизм. В строку
ExecStart вместо echo можно указать любую команду или скрипт. Можете какую-то службу перезапускать или копировать куда-то файл при его изменении. Например, изменился TLS сертификат, можно его скопировать куда-то или перезапустить службу, которая его использует. Удобство тут в том, что всё логируется в systemd. И если у вас логи уже где-то хранятся и анализируются, то все события с path и service поедут туда автоматически и не надо отдельно об этом беспокоиться.В данном примере я использовал директиву слежения за записью в файл PathModified. Помимо неё есть другие:
◽️PathExists= реагирует на появление заданного файла или директории.
◽️PathExistsGlob= то же самое что и предыдущее, но можно использовать маски для имён.
◽️PathChanged= отличается от PathModified тем, что реагирует не на запись в файл, а на закрытие файла после записи.
◽️DirectoryNotEmpty= реагирует на появление файла в пустой директории.
📌 Другая полезная (и не очень) функциональность SystemD:
◽️Systemd timers как замена Cron
◽️Journald как замена Syslog
◽️Systemd-journal-remote - централизованное хранение логов
◽️Systemd-journal-gatewayd - просмотр логов через браузер
◽️Hostnamectl для просмотра информации о системе
◽️Systemd-resolved - кэширующий DNS сервер
◽️Параметры Systemd для приоритизации дисковых операций
◽️Ограничение потребления памяти с Systemd
◽️Синхронизация времени с помощью systemd-timesyncd
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd
2👍239👎5
В своей деятельности нередко приходится вносить изменения в стандартные юниты systemd. Я не буду писать длинное руководство со всеми командами и параметрами. Их всё равно не запомнишь все. А 1-2 момента можно выхватить и сразу начать применять. Вот такими моментами и поделюсь, которые когда-то не знал, увидел, запомнил и применяю.
Покажу на примере службы Nginx, установленной из пакета в стандартном репозитории. По умолчанию служба автоматически не поднимется, если по какой-то причине завершится. Вот это и исправим, добавив принудительный автозапуск.
1️⃣ Раньше я шёл в
Содержимое юнита прилетит в консоль. Удобно, и никуда ходить не надо. Простая вещь, но узнал я о ней относительно недавно. Там сразу и путь видно, где лежит файл с настройками, если захочется его посмотреть напрямую.
2️⃣ Теперь добавляем изменение. Можно создать директорию
Открывается текстовый редактор по умолчанию. Вносим изменение:
Сохраняем. Конфигурация автоматически применяется. Теперь если набрать:
То мы увидим и исходную конфигурацию и файл
Не зная про команду
3️⃣ Расскажу про ещё один нюанс, который иногда забываю, потом разбираюсь, почему не работает, и вспоминаю, в чём проблема. Если добавляется новый параметр, то никаких нюансов нет, просто указываете его и всё. Если же параметры в
Переписали параметры запуска, которые в основном юните выглядят так:
Обнулять надо не все параметры. Не помню точно, какие нужно, а какие нет. Точно знаю, что всё, что относится к Exec надо обнулять, переменные окружения, если хотите полностью все переопределить, пользователей, наверняка что-то ещё. Если какие-то добавленные изменения не работают, просто обнулите их перед переопределением.
Рекомендую не добавлять эту статью в закладки, а сразу попробовать то, что тут описано, если не знакомы с этими командами. Это реально удобно. Вряд ли кто-то специально проходит курсы по systemd или изучает все её команды. Зачастую всё знать не нужно, лишнее быстро забывается, в итоге только время тратишь. А такую мелочь где-то выхватишь, запомнишь и потом используешь. Я поэтому любою смотреть, как другие в терминале работают. Постоянно что-то новое узнаешь и обогащаешь свой опыт.
#systemd
Покажу на примере службы Nginx, установленной из пакета в стандартном репозитории. По умолчанию служба автоматически не поднимется, если по какой-то причине завершится. Вот это и исправим, добавив принудительный автозапуск.
/etc/systemd/system/multi-user.target.wants, искал юнит nginx и смотрел, какие там установлены параметры. А можно сделать вот так:# systemctl cat nginx.serviceСодержимое юнита прилетит в консоль. Удобно, и никуда ходить не надо. Простая вещь, но узнал я о ней относительно недавно. Там сразу и путь видно, где лежит файл с настройками, если захочется его посмотреть напрямую.
/etc/systemd/system/nginx.service.d и туда положить конфигурацию override.conf с перекрывающими или дополнительными параметрами. Так давно не делаю, потому что помню команду:# systemctl edit nginx.serviceОткрывается текстовый редактор по умолчанию. Вносим изменение:
[Service]Restart=alwaysRestartSec=5sСохраняем. Конфигурация автоматически применяется. Теперь если набрать:
# systemctl cat nginx.serviceТо мы увидим и исходную конфигурацию и файл
/etc/systemd/system/nginx.service.d/override.conf, который был создан автоматически после команды edit. Не зная про команду
cat, я каждый раз вручную проверял override.conf и исходный юнит. Просто не довелось о ней услышать или где-то увидеть.override.conf перекрывают такие же в основном юните, например ExecStart и некоторые другие, то значение нужно сначала обнулить, а потом записать новое значение. Например:ExecStart=ExecStart=/usr/sbin/nginx -g 'daemon off; master_process off;'Переписали параметры запуска, которые в основном юните выглядят так:
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'Обнулять надо не все параметры. Не помню точно, какие нужно, а какие нет. Точно знаю, что всё, что относится к Exec надо обнулять, переменные окружения, если хотите полностью все переопределить, пользователей, наверняка что-то ещё. Если какие-то добавленные изменения не работают, просто обнулите их перед переопределением.
Рекомендую не добавлять эту статью в закладки, а сразу попробовать то, что тут описано, если не знакомы с этими командами. Это реально удобно. Вряд ли кто-то специально проходит курсы по systemd или изучает все её команды. Зачастую всё знать не нужно, лишнее быстро забывается, в итоге только время тратишь. А такую мелочь где-то выхватишь, запомнишь и потом используешь. Я поэтому любою смотреть, как другие в терминале работают. Постоянно что-то новое узнаешь и обогащаешь свой опыт.
#systemd
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍225👎3
С системным временем в Linux с одной стороны всё просто - установил и запустил какую-то службу для синхронизации и дальше всё работает автоматически. Например службу systemd-timesyncd, chrony или ntp. А с другой - есть множество нюансов, которые в основном связаны с особенностями systemd.
В целом, любой из способов задачу решает, но иногда возникают небольшие проблемы. Например, бывают виртуалки, которые со старта имеют сильный сдвиг по времени - 2-3 минуты, или даже больше. Я не знаю, с чем конкретно это может быть связано. Наблюдал и на арендованных виртуалках, и на своих. Служба синхронизации времени исправляет эту погрешность, но в зависимости от системы и настроек в ней, служба синхронизации времени может стартануть после другой службы. В итоге в логах после загрузки системы некоторое время может быть небольшая путаница, пока все службы не получат актуальное время.
Заметил ещё такую особенность. Служба chrony в Debian как правило со своими стандартными настройками запускается и отрабатывает раньше всех, а вот в Ubuntu - нет, хотя настройки юнитов вроде как схожи. Но я не разбирался детально. В systemd не так просто разобраться. Много нюансов и ссылок с зависимостями юнитов, таргетов и т.д. А если взять службу systemd-timesyncd, то она по умолчанию может довольно поздно запуститься. Я последнее время именно её использую, чтобы не ставить лишних пакетов в систему, но по факту chrony удобнее и функциональнее.
Эту проблему частично можно решить простым хаком в лоб. Ставим chrony и создаём службу, которая будет стартовать раньше всех остальных, один раз запускать синхронизацию и выключаться. А дальше уже всё остальное будет загружаться как обычно. Не нужно будет лезть в потроха systemd и разбираться в настройках и зависимостях стандартных служб.
Можно посмотреть зависимости служб:
Chrony-once-sync.service должна стоять первой в списке
Также можно посмотреть весь лог загрузки и убедиться, что chrony-once-sync.service отработала раньше всех остальных. Практически сразу после активации сети.
Не претендую на полноту и правильность решения. Решил задачу, как говорится, в лоб. Более правильным было бы разобраться с зависимостями служб. Например, выставить службам, критичным к точному времени зависимость от chrony:
Хотя тут правильнее было бы привязаться к специальному таргету, который придуман для этих задач -
В этом случае придётся вручную каждый раз разбираться со службами, а с одноразовым юнитом можно особо не заморачиваться. Он просто запустится раньше всех и если служба точного времени у вас локальная, отработает очень быстро, остальные сервисы уже подхватят точное время. При этом такое решение подойдёт для разовой начальной синхронизации, а дальше можно использовать любые другие службы, не обязательно chrony. Или вообще не использовать, если запускаете какое-то одноразовое окружение.
☝️ Представленный юнит можно использовать как заготовку для других подобных задач с разовыми задачами раньше всех остальных служб.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd
В целом, любой из способов задачу решает, но иногда возникают небольшие проблемы. Например, бывают виртуалки, которые со старта имеют сильный сдвиг по времени - 2-3 минуты, или даже больше. Я не знаю, с чем конкретно это может быть связано. Наблюдал и на арендованных виртуалках, и на своих. Служба синхронизации времени исправляет эту погрешность, но в зависимости от системы и настроек в ней, служба синхронизации времени может стартануть после другой службы. В итоге в логах после загрузки системы некоторое время может быть небольшая путаница, пока все службы не получат актуальное время.
Заметил ещё такую особенность. Служба chrony в Debian как правило со своими стандартными настройками запускается и отрабатывает раньше всех, а вот в Ubuntu - нет, хотя настройки юнитов вроде как схожи. Но я не разбирался детально. В systemd не так просто разобраться. Много нюансов и ссылок с зависимостями юнитов, таргетов и т.д. А если взять службу systemd-timesyncd, то она по умолчанию может довольно поздно запуститься. Я последнее время именно её использую, чтобы не ставить лишних пакетов в систему, но по факту chrony удобнее и функциональнее.
Эту проблему частично можно решить простым хаком в лоб. Ставим chrony и создаём службу, которая будет стартовать раньше всех остальных, один раз запускать синхронизацию и выключаться. А дальше уже всё остальное будет загружаться как обычно. Не нужно будет лезть в потроха systemd и разбираться в настройках и зависимостях стандартных служб.
# apt install chrony# systemctl edit --full --force chrony-once-sync.service[Unit]Description=Chrony one time sync and exitWants=network-online.targetAfter=network-online.targetBefore=multi-user.target[Service]Type=oneshotExecStart=/usr/sbin/chronyd -t 10 -qRemainAfterExit=True[Install]WantedBy=multi-user.target# systemctl enable chrony-once-sync.serviceМожно посмотреть зависимости служб:
# systemctl list-dependencies --afterChrony-once-sync.service должна стоять первой в списке
multi-user.target. Перезагружаемся и проверяем. Смотрим, как отработала служба:# journalctl -u chrony-once-syncТакже можно посмотреть весь лог загрузки и убедиться, что chrony-once-sync.service отработала раньше всех остальных. Практически сразу после активации сети.
# journalctlНе претендую на полноту и правильность решения. Решил задачу, как говорится, в лоб. Более правильным было бы разобраться с зависимостями служб. Например, выставить службам, критичным к точному времени зависимость от chrony:
[Unit]After=chrony.serviceХотя тут правильнее было бы привязаться к специальному таргету, который придуман для этих задач -
time-sync.target. Можно использовать его в зависимостях, но надо внимательно смотреть, что все остальные зависимости с этим таргетом корректно настроены.В этом случае придётся вручную каждый раз разбираться со службами, а с одноразовым юнитом можно особо не заморачиваться. Он просто запустится раньше всех и если служба точного времени у вас локальная, отработает очень быстро, остальные сервисы уже подхватят точное время. При этом такое решение подойдёт для разовой начальной синхронизации, а дальше можно использовать любые другие службы, не обязательно chrony. Или вообще не использовать, если запускаете какое-то одноразовое окружение.
☝️ Представленный юнит можно использовать как заготовку для других подобных задач с разовыми задачами раньше всех остальных служб.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd
👍122👎6
Утром писал о том, что нравятся текстовые логи в том числе потому, что привык их грепать. А в journalctl искать не так удобно. После этого задумался, как удобнее всего погрепать логи systemd.
Пошёл по самому простому пути и посмотрел man:
Оказывается, есть ключ
Причём этот параметр там был не всегда. Я точно знаю, что раньше не было. Зашёл на сервер с Centos 7 и проверил:
Ключ появился в каком-то обновлении.
На самом деле очень удобно. Я решил сделать об этом заметку и не кидать сюда другие команды journalctl, чтобы не размывать тему. Просто запомните, если не знали, что с помощью journalctl можно грепать логи. А так как он ищет по всему системному логу, который может быть очень большим, это удобнее, чем смотреть по разным файлам syslog или как-то их объединять, чтобы охватить бОльший период.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd #logs
Пошёл по самому простому пути и посмотрел man:
# man journalctlОказывается, есть ключ
-g или --grep, который делает примерно то же самое, что и утилита grep. Из всего журнала выводит строки с нужным тебе выражением. Поддерживает в том числе регулярки.Причём этот параметр там был не всегда. Я точно знаю, что раньше не было. Зашёл на сервер с Centos 7 и проверил:
# journalctl --grep ovpnjournalctl: unrecognized option '--grep'Ключ появился в каком-то обновлении.
На самом деле очень удобно. Я решил сделать об этом заметку и не кидать сюда другие команды journalctl, чтобы не размывать тему. Просто запомните, если не знали, что с помощью journalctl можно грепать логи. А так как он ищет по всему системному логу, который может быть очень большим, это удобнее, чем смотреть по разным файлам syslog или как-то их объединять, чтобы охватить бОльший период.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#systemd #logs
4👍264👎2
В systemd есть несколько команд, которые удобно использовать для получения информации о системе. Основное удобство в том, что они одинаковые везде, где используется systemd. А это фактически все современные дистрибутивы. Покажу основные из них.
На первом месте безусловный лидер - команда для получения информации о системе, которую я постоянно использую. Это без каких-либо компромиссов самый удобный вариант решения задачи, в том числе для того, чтобы узнать, где ты находишься: в контейнере, в виртуальной машине или на железе.
📌
Получаем всю необходимую информацию о системе. Не нужно идти куда-то ещё и уточнять. По крайней мере мне обычно этого достаточно. Команда заменяет все другие более старые, типа
📌
Эту команду тоже постоянно использую. Тут сразу и время с часовым поясом видно, и что важнее, настроена ли какая-то синхронизация. Если нужно посмотреть только время, дату и пояс, то удобнее короткая
📌
В таком виде команда малоинформативна, поэтому лично я её не использую. Нужно вспоминать дополнительные параметры. Для информации о пользователях по привычке использую просто
Тут уже и дата подключения, и IP, и запущенные процессы.
📌
Про эту команду, думаю, рассказывать нет смысла. Постоянно упоминаю её в заметках, регулярно использую. Аналогов для просмотра бинарных логов systemd нет, так что выбирать не приходится.
В таком стиле знаю ещё одну команду:
📌
Не использую вообще, потому что привычная
Если знаете ещё какие-то полезные команды в составе systemd, поделитесь информацией. Я не знаю и не видел где-либо чтобы кто-то пользовался чем-то ещё.
#systemd
На первом месте безусловный лидер - команда для получения информации о системе, которую я постоянно использую. Это без каких-либо компромиссов самый удобный вариант решения задачи, в том числе для того, чтобы узнать, где ты находишься: в контейнере, в виртуальной машине или на железе.
📌
# hostnamectlStatic hostname: debian12-vm
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: c0cf2b29ca074056823a0f6a481b83b1
Boot ID: 74089e7977524666bc0a2f0b175b0967
Virtualization: kvm
Operating System: Debian GNU/Linux 12 (bookworm)
Kernel: Linux 6.1.0-26-amd64
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _i440FX + PIIX, 1996_
Firmware Version: rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org
Получаем всю необходимую информацию о системе. Не нужно идти куда-то ещё и уточнять. По крайней мере мне обычно этого достаточно. Команда заменяет все другие более старые, типа
lsb_release -a, uname -a, cat /etc/os-release и т.д.📌
# timedatectlLocal time: Thu 2025-04-10 15:01:26 MSK
Universal time: Thu 2025-04-10 12:01:26 UTC
RTC time: Thu 2025-04-10 12:01:26
Time zone: Europe/Moscow (MSK, +0300)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Эту команду тоже постоянно использую. Тут сразу и время с часовым поясом видно, и что важнее, настроена ли какая-то синхронизация. Если нужно посмотреть только время, дату и пояс, то удобнее короткая
date.📌
# loginctlВ таком виде команда малоинформативна, поэтому лично я её не использую. Нужно вспоминать дополнительные параметры. Для информации о пользователях по привычке использую просто
w. Тем не менее loginctl может быть полезна, если нужны какие-то подробности. Например, команда без параметров выводит просто список сессий с номерами. Можно посмотреть детали:# loginctl session-status 11 - root (0)
Since: Thu 2025-04-10 14:46:32 MSK; 15min ago
Leader: 676 (sshd)
Remote: 10.8.2.2
Service: sshd; type tty; class user
State: active
Unit: session-1.scope
├─676 "sshd: root@pts/0"
├─699 -bash
├─734 loginctl session-status 1
└─735 pager
Тут уже и дата подключения, и IP, и запущенные процессы.
loginctl может выдать много всего о пользователях, но лично я обхожусь без неё и использую, как уже сказал w, id, cat /etc/passwd. Мне это видится короче и удобнее. Мои вопросы закрывает.📌
# journalctlПро эту команду, думаю, рассказывать нет смысла. Постоянно упоминаю её в заметках, регулярно использую. Аналогов для просмотра бинарных логов systemd нет, так что выбирать не приходится.
В таком стиле знаю ещё одну команду:
📌
# localectlНе использую вообще, потому что привычная
locale показывает всю необходимую информацию.Если знаете ещё какие-то полезные команды в составе systemd, поделитесь информацией. Я не знаю и не видел где-либо чтобы кто-то пользовался чем-то ещё.
#systemd
👍214👎5
Какое-то дёрганное лето получается. Новые проблемы сыпятся, как из рога изобилия. Жара что ли на сервера так влияет? Расскажу историю очередной проблемы, с которой столкнулся. Там есть несколько поучительных моментов.
На одном проекте ночью упал Redis, сайт начал 500-ю ошибку отдавать. Нечасто такое случается. Редис если и упадёт, то обычно быстро поднимается, потому что используют его в основном под кэш в оперативной памяти, данные можно не сохранять.
Redis словил ошибку Segmentation fault. Эта такая мутная тема, потому что нельзя однозначно сказать, из-за чего она возникает. Это могут быть как проблемы с железом, так и с самим софтом. Либо банально оперативной памяти на сервере не хватило.
У меня скорее всего последний вариант, так как в момент падения сервер реально сильно нагрузили, причём разносторонней нагрузкой. Рядом работающая СУБД в этот же момент скинула на диск свой пул и буферный кэш. Это осталось в её логе. Они это делают, чтобы освободить оперативную память, если её не хватает.
В настройках systemd юнита Redis указан параметр
Redis всю ночь поднимался и падал, постоянно записывая что-то на диск. Это видно по мониторингу. Забил весь ресурс дисков своей записью. Он писал свои трейсы в лог, но помимо них ещё какую-то информацию. Судя по всему своё состояние пытался скинуть, но не получалось. Я трейсы бегло посмотрел, но особо не вникал, так как там без должного понимания ничего особо не увидишь.
В общем случае с параметром
Но как я уже сказал, у меня что-то пошло не так. В данном случае было бы лучше, если бы он тихо помер и не мучал больше сервер. Помогло в итоге то, что я туром проснулся, вручную остановил его и запустил заново:
Так что сильно рассчитывать на systemd в таких вопросах не стоит. Очень желательно настраивать для критичных сервисов внешний мониторинг службы, чтобы она отвечала по настроенному TCP порту или Unix сокету. Отдавала какие-то данные или своё состояние передавала. И если не отвечает, то каким-то образом гарантированно перезапускать её, в зависимости от того, где она запущена, как служба на сервере или в отдельном контейнере.
Если бы это была СУБД, типа MySQL или Postgres, которая всю ночь пыталась подняться и падала, то даже не знаю, что бы стало с данными. Для этих баз данных такое поведение может быть фатальным, особенно если они упали из-за проблем с диском, а при старте запускали восстановление данных. Постоянные перезапуски их добьют. Так что аккуратнее с параметром
Я в итоге снизил потребление памяти у некоторых служб, чтобы избежать ситуаций, когда память вся закончится. Буду наблюдать. Надеюсь, что проблема не повторится.
#linux #systemd #ошибка
На одном проекте ночью упал Redis, сайт начал 500-ю ошибку отдавать. Нечасто такое случается. Редис если и упадёт, то обычно быстро поднимается, потому что используют его в основном под кэш в оперативной памяти, данные можно не сохранять.
Redis словил ошибку Segmentation fault. Эта такая мутная тема, потому что нельзя однозначно сказать, из-за чего она возникает. Это могут быть как проблемы с железом, так и с самим софтом. Либо банально оперативной памяти на сервере не хватило.
У меня скорее всего последний вариант, так как в момент падения сервер реально сильно нагрузили, причём разносторонней нагрузкой. Рядом работающая СУБД в этот же момент скинула на диск свой пул и буферный кэш. Это осталось в её логе. Они это делают, чтобы освободить оперативную память, если её не хватает.
В настройках systemd юнита Redis указан параметр
Restart=always. Подробно на эту тему я делал отдельную заметку. Рекомендую ознакомиться, если не знаете. Данный параметр означает, что при любой причине завершения работы службы будет попытка поднять её. Я упоминал в той заметке, что не всегда это бывает полезно. И это как раз мой случай.Redis всю ночь поднимался и падал, постоянно записывая что-то на диск. Это видно по мониторингу. Забил весь ресурс дисков своей записью. Он писал свои трейсы в лог, но помимо них ещё какую-то информацию. Судя по всему своё состояние пытался скинуть, но не получалось. Я трейсы бегло посмотрел, но особо не вникал, так как там без должного понимания ничего особо не увидишь.
В общем случае с параметром
Restart=always служба должна подняться автоматически. Я потестировал немного на отдельной виртуалке. Если Редису дать команду SIGSEGV, то он так же, как у меня вышло, скидывает свой трейс в лог, завершает работу и запускается заново. Проверить можно так:# kill -SIGSEGV $(pidof redis-server)Но как я уже сказал, у меня что-то пошло не так. В данном случае было бы лучше, если бы он тихо помер и не мучал больше сервер. Помогло в итоге то, что я туром проснулся, вручную остановил его и запустил заново:
# systemctl stop redis-server# systemctl start redis-serverТак что сильно рассчитывать на systemd в таких вопросах не стоит. Очень желательно настраивать для критичных сервисов внешний мониторинг службы, чтобы она отвечала по настроенному TCP порту или Unix сокету. Отдавала какие-то данные или своё состояние передавала. И если не отвечает, то каким-то образом гарантированно перезапускать её, в зависимости от того, где она запущена, как служба на сервере или в отдельном контейнере.
Если бы это была СУБД, типа MySQL или Postgres, которая всю ночь пыталась подняться и падала, то даже не знаю, что бы стало с данными. Для этих баз данных такое поведение может быть фатальным, особенно если они упали из-за проблем с диском, а при старте запускали восстановление данных. Постоянные перезапуски их добьют. Так что аккуратнее с параметром
Restart.Я в итоге снизил потребление памяти у некоторых служб, чтобы избежать ситуаций, когда память вся закончится. Буду наблюдать. Надеюсь, что проблема не повторится.
#linux #systemd #ошибка
👍103👎3
Не смог пропустить знаменательное событие сегодняшнего дня. Не забыли о нём? Сделаем так, чтобы на нашем сервере костры рябин горели вечно. Кстати, купил на днях в питомнике 3 рябины. Так что у меня скоро будут гореть реальные костры рябин.
Я уже раньше подобное делал с помощью cron. Пришло время применить systemd timers.
Итак, настроим на сервере вечное 3-е сентября. Для этого первым делом надо отключить синхронизацию времени, в зависимости от того, как она настроена. В современных серверах скорее всего это сделает команда:
Далее нам нужно установить дату на 3-е сентября и добавить в планировщик. Можно сделать это в лоб вот так:
Но тогда устанавливается время на 00:00. Можно сделать аккуратнее и менять только день, не трогая часы. Для этого создадим очень простой скрипт:
Берём текущее время, текущий год и выставляем третье сентября текущего года с неизменным временем. Сохраняем скрипт в
Создаём systemd сервис -
Делаем таймер для службы
Перечитываем конфигурацию и запускаем таймер со службой:
Теперь у вас постоянно переворачивается календарь и каждый день 3-е сентября. Подобную заготовку можно использовать под любой свой скрипт.
#юмор #systemd
Я уже раньше подобное делал с помощью cron. Пришло время применить systemd timers.
Итак, настроим на сервере вечное 3-е сентября. Для этого первым делом надо отключить синхронизацию времени, в зависимости от того, как она настроена. В современных серверах скорее всего это сделает команда:
# timedatectl set-ntp falseДалее нам нужно установить дату на 3-е сентября и добавить в планировщик. Можно сделать это в лоб вот так:
# date -s "2025-09-03 00:00:00"Но тогда устанавливается время на 00:00. Можно сделать аккуратнее и менять только день, не трогая часы. Для этого создадим очень простой скрипт:
#!/bin/bash
now_date=$(date +%H:%M:%S)
now_year=$(date +%Y)
date -s "$now_year-09-03 $now_date"
Берём текущее время, текущий год и выставляем третье сентября текущего года с неизменным временем. Сохраняем скрипт в
/usr/local/bin/3sep.sh и делаем исполняемым:# chmod +x /usr/local/bin/3sep.shСоздаём systemd сервис -
/etc/systemd/system/3sep.service:[Unit]
Description=Set system date to September 3rd, po zavetam Shafutinskogo
[Service]
Type=oneshot
ExecStart=/usr/local/bin/3sep.sh
[Install]
WantedBy=multi-user.target
Делаем таймер для службы
/etc/systemd/system/3sep.timer:[Unit]
Description=Turn over the calendar every minute
[Timer]
OnCalendar=*:0/1
Unit=3sep.service
Persistent=false
[Install]
WantedBy=timers.target
Перечитываем конфигурацию и запускаем таймер со службой:
# systemctl daemon-reload# systemctl enable --now 3sep.serviceТеперь у вас постоянно переворачивается календарь и каждый день 3-е сентября. Подобную заготовку можно использовать под любой свой скрипт.
#юмор #systemd
3👍107👎14
Относительно недавно (2018 год) по меркам Linux в составе базовых системных утилит популярных дистрибутивов появилась утилита choom. Узнал о ней случайно. В Debian и Ubuntu она есть по умолчанию, отдельно ставить не надо. В других не проверял.
Забегая вперёд скажу, что лично я для неё применения не увидел, но решил всё равно написать для общего образования. Кому-то может пригодится. Не просто же так её написали и добавили в дистрибутивы. С помощью choom можно управлять таким параметром, как OOM score adjustment (oom_score_adj). На его основе OOM-killer принимает решение о том, какой процесс завершить при нехватке оперативной памяти в системе.
Choom работает с запущенными процессами на лету, используя их pid. Примерно так:
Посмотрели текущее значения
Проверяем:
Oom_score стал 0, а oom_score_adj, как и указали -1000. В данном примере pid 1994 - это процесс mariadbd. Удобней было бы сделать сразу вот так:
Вообще, принцип работы OOM-killer довольно замороченный. Как видно, у него есть два параметра oom_score и oom_score_adj. Первый показывает текущие накопленные баллы, которые динамически изменяются в зависимости от различных условий, а второй - это то, что задаётся вручную и тоже влияет на oom_score. Сделав oom_score_adj минимальным, то есть -1000, мы и oom_score уменьшили.
Вручную всё это менять имеет смысл только в каких-то отладочных целях. Для постоянной работы этими параметрами удобнее управлять через systemd. Просто указываем в unit файле сервиса нужные значения:
Перезапускаем сервис и проверяем. В случае с mariadb это будет выглядеть так. Делаем корректировку стандартного юнита:
Добавляем в конфигурацию:
Перечитываем параметры юнита и перезапускаем его.
Проверяем значение:
По сути choom удобен именно для просмотра. Смотреть значения с помощью утилиты быстрее и проще, чем напрямую:
Она по сути именно это и делает. И меняет значение тоже переопределяя именно эти параметры.
На практике я никогда не занимался настройкой
Исключение, наверное, для каких-то специфических случаев, когда целенаправленно нужно использовать всю память сервера, но при этом гарантированно иметь работающим какое-то приложение. Я не могу придумать таких примеров, но думаю, что они есть. Если кто-то знает такие истории, поделитесь в комментариях. Когда вам приходилось целенаправленно настраивать OOMScoreAdjust? В голову приходят агенты мониторинга. Желательно, чтобы они всегда работали, но на практике я не видел, чтобы их первым отключал OOM-killer.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#linux #terminal #systemd
Забегая вперёд скажу, что лично я для неё применения не увидел, но решил всё равно написать для общего образования. Кому-то может пригодится. Не просто же так её написали и добавили в дистрибутивы. С помощью choom можно управлять таким параметром, как OOM score adjustment (oom_score_adj). На его основе OOM-killer принимает решение о том, какой процесс завершить при нехватке оперативной памяти в системе.
Choom работает с запущенными процессами на лету, используя их pid. Примерно так:
# choom -p 1994pid 1994's current OOM score: 684pid 1994's current OOM score adjust value: 0Посмотрели текущее значения
oom_score и oom_score_adj. Для того, чтобы максимально уменьшить шанс для процесса быть убитыми, ему нужно присвоить параметр oom_score_adj -1000. Соответственно, параметр 1000 будет означать максимальный шанс. То есть там разбег от -1000 до 1000. И чем меньше значение, тем меньше шанса быть завершённым. # choom -p 1994 -n -1000Проверяем:
# choom -p 1994pid 1994's current OOM score: 0pid 1994's current OOM score adjust value: -1000Oom_score стал 0, а oom_score_adj, как и указали -1000. В данном примере pid 1994 - это процесс mariadbd. Удобней было бы сделать сразу вот так:
# choom -p $(pidof mariadbd) -n 1000Вообще, принцип работы OOM-killer довольно замороченный. Как видно, у него есть два параметра oom_score и oom_score_adj. Первый показывает текущие накопленные баллы, которые динамически изменяются в зависимости от различных условий, а второй - это то, что задаётся вручную и тоже влияет на oom_score. Сделав oom_score_adj минимальным, то есть -1000, мы и oom_score уменьшили.
Вручную всё это менять имеет смысл только в каких-то отладочных целях. Для постоянной работы этими параметрами удобнее управлять через systemd. Просто указываем в unit файле сервиса нужные значения:
[Service]............OOMScoreAdjust=-800............Перезапускаем сервис и проверяем. В случае с mariadb это будет выглядеть так. Делаем корректировку стандартного юнита:
# systemctl edit mariadbДобавляем в конфигурацию:
[Service]OOMScoreAdjust=-800Перечитываем параметры юнита и перезапускаем его.
# systemctl daemon-reload# systemctl restart mariadbПроверяем значение:
# choom -p $(pidof mariadbd)pid 2274's current OOM score: 152pid 2274's current OOM score adjust value: -800По сути choom удобен именно для просмотра. Смотреть значения с помощью утилиты быстрее и проще, чем напрямую:
# cat /proc/2274/oom_score# cat /proc/2274/oom_score_adjОна по сути именно это и делает. И меняет значение тоже переопределяя именно эти параметры.
На практике я никогда не занимался настройкой
OOMScoreAdjust. Если на сервере кончается память и приходит OOM-killer - это аварийная ситуация. Надо идти и разбираться, куда утекает память и почему её не хватает. Обычно после этого её должно хватать. Исключение, наверное, для каких-то специфических случаев, когда целенаправленно нужно использовать всю память сервера, но при этом гарантированно иметь работающим какое-то приложение. Я не могу придумать таких примеров, но думаю, что они есть. Если кто-то знает такие истории, поделитесь в комментариях. Когда вам приходилось целенаправленно настраивать OOMScoreAdjust? В голову приходят агенты мониторинга. Желательно, чтобы они всегда работали, но на практике я не видел, чтобы их первым отключал OOM-killer.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#linux #terminal #systemd
3👍83👎1