Если вам нужно ограничить процессу потребление памяти, то с 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