Русский
Русский
English
Статистика
Реклама

Systemd

Почему хабражители предпочитают велосипеды, вместо готовых решений? Или о systemd, part 0

01.01.2021 18:11:05 | Автор: admin

С Новым Годом Хабр!
Первого января все нормальные люди занимаются прокрастинацией, уничтожением стратегического запаса оливье и прочими, не связанными с физической или интеллектуальной нагрузкой вещами. Вот и я планировал присоединиться к этой новогодней армии, но не тут-то было!

Во всём виноват Хабр!

. Точнее хабражители! А, если ещё точнее, всему виной предновогодние статьи, в которых два никак не связанных между собой юзера изобрели два почти одинаковых велосипеда. Итак, встречайте моих сегодняшних героев!

Как создавался новогодний Хабрачат в этом году

Скачивается бинарник под нужную платформу изрелизов на github. Можно положить его, например, в/usr/bin. Далее пишем простой скрипт, который будет перезапускать сервер, в случае падения.

(пропущен башизм с бесконечным циклом и прочими sleep-ами)

оригинал

Безумный дом

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

(пропущены башизм, на пару с кронтабом)

Теперь каждые 5 минут будет запускаться скрипт, который проверит, работает ли Domoticz и перезапустит его, если это необходимо

оригинал

Что с этим делать и как дальше жить?

Я совершенно не планировал писать статью освещающую самые основы systemd, у меня в планах, цикл статей из разряда systemd для продолжающих, но жизнь, как видно, вносит свои коррективы, в результате пусть моя сегодняшняя, коротенькая статья будет своеобразным прологом к планируемуму циклу. Но так как про написание сервисных юнитов systemd написано 100500 хаутушек, то мы осветим только параметры относящиеся к автоматическому перезапуску сервисов, на конкретных примерах (и на затравку кое что ещё ;-), в применении к статьям двух уважаемых хабровчан.

Делаем всё по фен-шую

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

Как создавался Хабрачат в этом году

Юнит(/etc/systemd/system/ssh-chat.service):

[Unit]Description=SSH Chat ServiceAfter=network.target network-online.target[Service]# Пользователь и группа с правами которых будет запускаться сервисUser=ssh-chatGroup=ssh-chatType=SimpleExecStart=/usr/local/bin/ssh-chat --admin=/etc/ssh-chat/admins --bind=0.0.0.0:22 --log /var/log/ssh-chat.log --motd=/etc/ssh-chat/motd# В каких случаях сервис будет автоматически перезагружаться.# on-failure  в случае выхода с ненулевым кодом возврата.Restart=on-failure# Таймаут перед загрузкой сервиса, после падения.RestartSec=1# Capablities для сервиса. В данном случае - разрешение сервису# биндиться на привилегированные порты (< 1000)AmbientCapablities=CAP_NET_BIND_SERVICE[Install]WantedBy=multiuser.target

Конфиг для systemd-sysusers.service(/etc/sysusers.d/ssh-chat.conf):

u ssh-chat - "SSH Chat user" /etc/ssh-chat# Поля записи:# u : создаём пользователя# ssh-chat : username# - : или UID[:GID] в данном случае автоматически занять свободные UID/GID < 1000# "SSH Chat user" : Описание, или "-", если не нужно.# /etc/ssh-chat : Home Directory# Может быть ещё одно поле -- login shell. По умолчанию /usr/bin/nologin

Инсталляция и запуск:

sudo systemctl restart systemd-sysusers.service && sudo systemctl enable --now ssh-chat

Безумный дом

Юнит(/etc/systemd/system/domoticz.service):

[Unit]Description=Domoticz DaemonAfter=network.target[Service]User=httpGroup=http# Эта директива позволяет выполнять подготовительные действия перед# запуском сервиса. Модификатор "+" указывает выполнять их от рута.ExecStartPre=+/usr/bin/install -d -m 0700 -o http -g http /var/run/domoticzExecStart=/opt/domoticz/domoticz -www 8080 -pidfile /var/run/domoticz/domoticz.pidPIDFile=/var/run/domoticz/domoticz.pidWorkingDirectory=/opt/domoticz# Всё то же самое, что и в случае "хабрачата", только таймаут 5 секунд.RestartSec=5Restart=on-failure[Install]WantedBy=multi-user.target

Инсталляция и запуск:

sudo systemctl enable --now domoticz

Что дальше?

Возможности systemd, кратко освещённые в этой статье, а так-же многие другие, более подробно будут разобраны в следующих статьях цикла. Триггеры, поддержка бинарных форматов, прозрачные(transient) юниты, встроенная контейнеризация and more, more... Но нетерпеливые могут уже вот прям щаз заняться чтением одной из лучших документаций в мире линукс. Маны которые можно почитать по сегодняшней теме:

man systemd.unitman systemd.serviceman systemctlman sysusers.dman systemd-sysusers

И на закуску маленький секрет. Один из моих любимых манов: man systemd.directives - путеводитель по всем директивам конфигурации которые могут встретиться вам в процессе изучения systemd.

Ещё раз С новым Годом Хабр! И используйте правильные инструменты! ;-)

Подробнее..

Systemd для продолжающих. Part 1 Запуск юнитов по временным событиям

02.01.2021 20:04:09 | Автор: admin

Всем привет! В последнее время я вплотную занимаюсь исследованием возможностей systemd и решил поделиться результатом исследований с сообществом, в виде небольшого (или большого, как пойдёт ;-) цикла статей. Итак первым (уже нет) номером нашей программы будет запуск юнитов по различным событиям происходящим во время работы ОС. В качестве исследовательской платформы будет выступать Manjaro Linux c systemd v247.2. И... да. Некоторые события, вынудили меня написать внеочередную статью, которая взлетела на вершину хит-парада, а опрос показал, что тема актуальна и вызывает интерес, так что погнали!

Пролог

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

pacman -Ql $(pacman -Qsq systemd|xargs)|egrep '^systemd\s|^systemd-sysvcompat\s'|egrep "man/man[1|5|8]/[[:print:]]*\.gz"|wc -l278

И это только маны описывающие конфиги, пользовательские и администраторские утилиты systemd. Если же не ограничивать поиск практической частью, то цифра будет ещё более устрашающей:

pacman -Ql $(pacman -Qsq systemd|xargs)|egrep '^systemd\s|^systemd-sysvcompat\s'|wc -l1852

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

Disclamer: Хоть в официальной документации и манах почти не используется такое понятие как триггеры (хотя и используется triggered by), но все те штуки которые описаны в этой и следующей статье, по сути, именно ими и являются. Это сущности которые срабатывают по каким-либо событиям, поэтому не удивляйтесь, если я, авторским произволом, буду использовать этот термин.

Часть первая, очевидная. Таймеры.

Все мы знаем старый, добрый cron, во всех его проявлениях. Созданный ещё в 80-х, он, в том или ином виде, дожил до нашего времени облачных сервисов. Так-же мы все знаем его ограничения. Например одной строчкой невозможно заставить крон запускать произвольный бинарник/скрипт раз в полтора часа, начная с часа ночи, приходится описывать такое событие двумя строчками. Что-бы обойти ограничения классического крона, в systemd были придуманы такие триггеры как таймеры (юниты с окончанием *.timer) умеющие запускать произвольные сервисы или группы сервисов (*.target) периодически; по наступлении какого-либо времени; по выходу системы из спящего режима; по календарному событию (наподобие того как это делает другой ветеран Unix утилит, команда at), а так-же по другим событиям, не связанными, напрямую, со временем.

Для начала что запускаем. Возьмём, для примера, таймер man-db.timer из комплекта поставки одноимённого пакета:

$ cat /usr/lib/systemd/system/man-db.timer[Unit]Description=Daily man-db regenerationDocumentation=man:mandb(8)[Timer]OnCalendar=dailyAccuracySec=12hPersistent=true[Install]WantedBy=timers.target

Простой, коротенький таймер. Но в чём-же дело, почему не указано что мы запускаем? Всё нормально! По умолчанию, если в секции [Timer] отсутствует параметр Unit=, с указанием запускаемого юнита, systemd будет искать одноимённый *.service юнит. Проверяем!

$ cat /usr/lib/systemd/system/man-db.service[Unit]Description=Daily man-db regenerationDocumentation=man:mandb(8)ConditionACPower=true[Service]Type=oneshot# Recover from deletion, per FHS.ExecStart=+/usr/bin/install -d -o root -g root -m 0755 /var/cache/man# Expunge old catman pages which have not been read in a week.ExecStart=/usr/bin/find /var/cache/man -type f -name *.gz -atime +6 -delete# Regenerate man database.ExecStart=/usr/bin/mandb --quietUser=rootNice=19IOSchedulingClass=idleIOSchedulingPriority=7

Да, вот он сервис который ежедневно пересоздаёт базу данных страниц руководства. Сервис стартует начиная с 00:00 (OnCalendar=daily) , с точностью 12 часов (AccuracySec=12h), то-есть он может сработать в любой момент между полуночью и полднем, в зависимости от загрузки системы:

$ systemctl status man-db.timer  man-db.timer - Daily man-db regeneration     Loaded: loaded (/usr/lib/systemd/system/man-db.timer; disabled; vendor preset: disabled)     Active: active (waiting) since Thu 2020-12-31 23:18:59 MSK; 1 day 19h ago    Trigger: Sun 2021-01-03 00:00:00 MSK; 5h 30min left   Triggers:  man-db.service       Docs: man:mandb(8)дек 31 23:18:59 dell-lnx systemd[1]: Started Daily man-db regeneration.

Минимальная точность у параметра AccuracySec= 1us! Чем больше этот параметр, тем меньше нагрузка на систему. Если параметр отсутствует, то по умолчанию (указано в /etc/systemd/system.conf: DefaultTimerAccuracySec=) он равен одной минуте. Ладно, это всё лирика, давайте быстренько пробежимся по другим возможным параметрам секции [Timer], а на сладкое оставим параметры задания времени в OnCalendar= и других временнх параметрах.

Монотонные таймеры, для периодических событий

  • OnBootSec= Таймер сработает через указанное время после старта системы.

  • OnStartupSec= Для системных таймеров действие аналогично предыдущему, для пользовательских таймеров, это время после первого логина пользователя в систему.

  • OnActiveSec= Один из параметров для периодического запуска. Через какое время, после реального времени срабатывания таймера, запускать юнит.

  • OnUnitActiveSec= Триггер будет ориентироваться на время последнего запуска целевого юнита.

  • OnUnitInactiveSec= Триггер будет ориентироваться на последнее время завершения работы целевого юнита. Хорошо для долгоиграющих сервисов. Бэкапы и вот это вот всё. Все эти таймеры можно комбинировать между собой и с таймером OnCalendar=.

Прочие параметры

  • RandomizedDelaySec= Этакий рандомный джиттер. Перед срабатыванием добавляется случайный таймаут от нуля, до заданного значения. По умолчанию -- отключено.

  • OnClockChange=, OnTimezoneChange= Булевые параметры, определяющие будет-ли таймер реагировать на перевод системных часов или смену временной зоны. По умолчанию, оба параметра, false.

  • Persistent= Записывать-ли на диск состояние таймера сразу после запуска юнита. Актуально для параметра OnCalendar=. По умолчанию false.

  • WakeSystem= Ещё один логический параметр. Действует на монотонные таймеры. По умолчанию отключён. Логика следующая. При отключённом параметре все монотонные таймеры запоминают своё состояние, перед уходом системы в спящий режим и встают на паузу. После выхода системы из спящего режима, отсчёт продолжается с того момента с которого система ушла в спячку. Если-же параметр поставить в true, то таймеры продолжают работать и в спящем режиме (должно поддерживаться и железом) и по наступлении события выводят систему из спячки и запускают юнит.

  • RemainAfterElapse= Последняя крутилка, по умолчанию true Смысл этого параметра примерно следующий, После срабатывания таймера он остаётся загруженным, но если поставить false, то после срабатывания таймер выгружается и перестаёт отслеживать время. Хорошо для одноразовых юнитов (Transient Units) о которых мы поговорим в одной из следующих статей. Или для таймеров которые должны сработать один раз, как это делают задания старой, доброй at.

Таймстампы, диапазоны, тестирование, примеры

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

[Unit]Description=Test timer[Timer]OnCalendar=01:00OnActiveSec=1.5h

Ну это слишком просто. Например мы хотим что-б наш юнит запускался каждую пятницу 13-е OnCalendar=Fri *-*-13 12:00:00 Полный формат календарной формы выглядит так: Mon 2025-12-01 00:00:00.000000 Europe/Moscow Поэтому мы можем запускать таймер по времени другого часового пояса (по умолчанию текущий) Например хотим что-б таймер прислал нам уведомление, что Камчатка уже отпраздновала Новый год: OnCalendar=yearly Asia/Kamchatka Нормализованная форма будет выглядеть так(эти строчки указывают на одно и то-же время):
OnCalendar=*-01-01 00:00:00 Asia/Kamchatka Алиасы (и их эквиваленты в нормализованной форме) могут быть такими:

                       minutely  *-*-* *:*:00                         hourly  *-*-* *:00:00                          daily  *-*-* 00:00:00                        monthly  *-*-01 00:00:00                         weekly  Mon *-*-* 00:00:00                         yearly  *-01-01 00:00:00                      quarterly  *-01,04,07,10-01 00:00:00                                                                         semiannually  *-01,07-01 00:00:00

Примеры валидных таймстампов:

таймстамп с @ epoch time
        Fri 2012-11-23 11:12:13  Fri 2012-11-23 11:12:13            2012-11-23 11:12:13  Fri 2012-11-23 11:12:13        2012-11-23 11:12:13 UTC  Fri 2012-11-23 19:12:13                     2012-11-23  Fri 2012-11-23 00:00:00                       12-11-23  Fri 2012-11-23 00:00:00                       11:12:13  Fri 2012-11-23 11:12:13                          11:12  Fri 2012-11-23 11:12:00                            now  Fri 2012-11-23 18:15:22                          today  Fri 2012-11-23 00:00:00                      today UTC  Fri 2012-11-23 16:00:00                      yesterday  Fri 2012-11-22 00:00:00                       tomorrow  Fri 2012-11-24 00:00:00      tomorrow Pacific/Auckland  Thu 2012-11-23 19:00:00                       +3h30min  Fri 2012-11-23 21:45:22                            -5s  Fri 2012-11-23 18:15:17                      11min ago  Fri 2012-11-23 18:04:22                    @1395716396  Tue 2014-03-25 03:59:56

Здесь представлены таймстампы как для OnCalendar=, так и для монотонных таймеров.

Перечисления и диапазоны:

Боольшой список примеров
      Sat,Thu,Mon..Wed,Sat..Sun  Mon..Thu,Sat,Sun *-*-* 00:00:00          Mon,Sun 12-*-* 2,1:23  Mon,Sun 2012-*-* 01,02:23:00                        Wed *-1  Wed *-*-01 00:00:00               Wed..Wed,Wed *-1  Wed *-*-01 00:00:00                     Wed, 17:48  Wed *-*-* 17:48:00    Wed..Sat,Tue 12-10-15 1:2:3  Tue..Sat 2012-10-15 01:02:03                    *-*-7 0:0:0  *-*-07 00:00:00                          10-15  *-10-15 00:00:00            monday *-12-* 17:00  Mon *-12-* 17:00:00      Mon,Fri *-*-3,1,2 *:30:45  Mon,Fri *-*-01,02,03 *:30:45           12,14,13,12:20,10,30  *-*-* 12,13,14:10,20,30:00                12..14:10,20,30  *-*-* 12..14:10,20,30:00      mon,fri *-1/2-1,3 *:30:45  Mon,Fri *-01/2-01,03 *:30:45                 03-05 08:05:40  *-03-05 08:05:40                       08:05:40  *-*-* 08:05:40                          05:40  *-*-* 05:40:00         Sat,Sun 12-05 08:05:40  Sat,Sun *-12-05 08:05:40               Sat,Sun 08:05:40  Sat,Sun *-*-* 08:05:40               2003-03-05 05:40  2003-03-05 05:40:00     05:40:23.4200004/3.1700005  *-*-* 05:40:23.420000/3.170001                 2003-02..04-05  2003-02..04-05 00:00:00           2003-03-05 05:40 UTC  2003-03-05 05:40:00 UTC                     2003-03-05  2003-03-05 00:00:00                          03-05  *-03-05 00:00:00                         hourly  *-*-* *:00:00                          daily  *-*-* 00:00:00                      daily UTC  *-*-* 00:00:00 UTC                        monthly  *-*-01 00:00:00                         weekly  Mon *-*-* 00:00:00        weekly Pacific/Auckland  Mon *-*-* 00:00:00 Pacific/Auckland                         yearly  *-01-01 00:00:00                       annually  *-01-01 00:00:00                          *:2/3  *-*-* *:02/3:00

Да. Микро и наносекунды тоже поддерживаются, а ещё очень удобная функция конца месяца и счётчик:

  • *-*~01 Первый день с конца каждого месяца (он-же последний день месяца).

  • *-05~05 27-e мая каждого года (31-5).

  • Mon *-12~07/1 Последний понедельник декабря.

  • Mon *-12-01/3 Третий понедельник декабря.

Проверять таймстампы на валидность можно при помощи утилиты systemd-analyze:

$ systemd-analyze calendar 'Mon *-12-01/1'  Original form: Mon *-12-01/1              Normalized form: Mon *-12-01/1 00:00:00         Next elapse: Mon 2021-12-06 00:00:00 MSK       (in UTC): Sun 2021-12-05 21:00:00 UTC       From now: 11 months 2 days left$ systemd-analyze timespan 1.5hOriginal: 1.5h            s: 5400000000   Human: 1h 30min$ systemd-analyze timestamp 01:00:30.9999  Original form: 01:00:30.9999              Normalized form: Sat 2021-01-02 01:00:30 MSK       (in UTC): Fri 2021-01-01 22:00:30 UTC   UNIX seconds: @1609538430.999900                From now: 18h ago 

Вот так, в принципе, всё просто, логично и красиво. И разумеется напочитать:

man systemd.timerman systemd.timeman systemd-system.confman systemd-analyzeman tzselect

Список статей серии

  1. Почему хабражители предпочитают велосипеды, вместо готовых решений? Или о systemd, part 0

  2. Systemd для продолжающих. Part 1 Запуск юнитов по временным событиям

Подробнее..

Systemd для продолжающих. Part 2 Триггеры на различные события

14.01.2021 10:07:09 | Автор: admin

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

Systemd.path триггер на события в файловой системе

Как известно, linux имеет большое количество системных вызовов, среди которых имеется замечательный вызов inotify() , позволяющий вешать обработчики на события в файловой системе на создание, удаление, изменение etc, файлов и каталогов. Наиболее распространёнными утилитами, использующими inotify() являются утилиты inotifywait и inotifywatch из пакета inotify-tools, которые хорошо использовать в скриптах, а так-же проект incron cron для файловой системы, о котором уже писали на Хабре. Systemd тоже имеет специальные юниты, которые хоть и ограничены по функционалу (я надеюсь пока), по сравнению с incron и тем более с inotify-tools , но зато умеют запускать юниты systemd.

Практическое применение systemd.path

Вот такой триггер пришлось ваять одному товарищу, когда он захотел использовать дискретную видеокарту, в качестве основной, на своём ноутбуке (предвидя вопрос... Нет, параметра ядра для этой фигувины нет):

$ cat /etc/systemd/system/enable-radeon.path[Unit]Description=Enable radeon path[Path]PathExists=/sys/kernel/debug/vgaswitcheroo/switch[Install]WantedBy=multi-user.target

Всё то-же самое, как и в случае с таймерами. Если в основной секции, в данном случае [Path], не указана директива Unit=, ищем и запускаем одноимённый *.service:

$ cat /etc/systemd/system/enable-radeon.service[Unit]Description=Enable radeon service[Service]Type=oneshotRemainAfterExit=yesExecStart=/usr/bin/sh -c "echo DDIS > /sys/kernel/debug/vgaswitcheroo/switch"[Install]WantedBy=multi-user.target

Итак всё просто. Энейблим *.path sudo systemctl enable enable-radeon.path и, во время загрузки, как только в дереве файловой системы появляется файл (PathExists=) /sys/kernel/debug/vgaswitcheroo/switch, запускаем соответствующий сервис.

Возможные директивы слежения для systemd.path

К сожалению их мало, но базовые потребности для старта каких-либо юнитов они, в принципе, покрывают:

  • PathExists= Триггерится на появление файла или директории, в файловой системе.

  • PathExistsGlob= То же самое что и предыдущая директива, но можно использовать файлы / каталоги по маске.

  • PathChanged= Если в файле или каталоге произошли изменения, при этом он не будет реагировать на каждый вызов write(), а сработает только после первого close()

  • PathModified= Подобно предыдущему, только в этом случае не ждём close(), а сразу реагируем на первый попавшийся write().

  • DirectoryNotEmpty= Как понятно из названия срабатывает только в отношении директорий, когда в директории появляется хотя-бы один файл.

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

Дополнительные параметры

  • Unit= Юнит для запуска. Важное замечание, о котором я забыл в предыдущей статье. В параметре Unit= не обязательно может быть *.service, но и любой другой (кроме *.path) юнит. Например *.mount.

  • MakeDirectory= Булевый параметр. Создавать-ли каталоги слежения. По умолчанию false.

  • DirectoryMode= Связанный с предыдущим параметром параметр раздачи прав на создаваемую директорию. По умолчанию 0755.

Сравнение функционала systemd.path c incron и inotify-tools

В таблице пропущено парочка специфичных для incron параметров.

Функция

systemd.path

inotify-tools

incron

read

access

IN_ACCESS

write

PathModified=

modify

IN_MODIFY

attrib

attrib

IN_ATTRIB

close & write

PathChanged=

close_write

IN_CLOSE_WRITE

close

close_nowrite

IN_CLOSE_NOWRITE

open

open

IN_OPEN

moved to watched

moved_to

IN_MOVED_TO

moved from watched

moved_from

IN_MOVED_FROM

moved self

moved_self

IN_MOVE_SELF

create

PathExist= PathExistGlob= DirectoryNotEmpty=

create

IN_CREATE

delete

delete

IN_DELETE

delete self

delete_self

IN_DELETE_SELF

unmount

unmount

systemd support

yes

И да, чуть не забыл. Все утилиты использующие inotify() работают только и исключительно на локальных файловых системах. То-есть, например, на SMB / NFS они работать не будут, но при этом спокойно будут работать в /run, /sys, /proc!

Systemd.automount триггеры автомонтирования ФС

Очень простые юниты позволяющие как сэкономить немного времени, при загрузке системы, так и немного обезопасить критические (не все, с корнем такой трюк не пройдёт) файловые системы, от повреждения в случае, например, пропадания питания.

Практика

Сразу два примера. Для автомонтирования локальной и удалённой файловой системы. Два *.automount и два *.mount юнита к ним в пару. В отличие от *.timer и *.path юнитов в случае автомаунта отсутствует директива Unit=, поэтому используется или одноимённый persistent *.mount, что предпочтительнее, либо *.mount автоматически сгенерированный из содержимого /etc/fstab.

Первый пример: Локальная файловая система, смонтированная в /boot. По большому счёту, содержимое каталога /boot практически не нужно при работе системы. Исключение обновление ядра и соответственно обновление initrd образов и конфигурации загрузчика, что бывает, не сказать что-бы часто. Поэтому, мы спокойно можем выслать раздел /boot в автомонтирование.

$ cat /etc/systemd/system/boot.automount[Unit]Description=Automount boot partition when needed.[Automount]Where=/boot## Time to automatic umount of inactivityTimeoutIdleSec=120[Install]WantedBy=multi-user.target

И в пару к нему одноимённый *.mount файл:

$ cat /etc/systemd/system/boot.mount[Unit]Description=Boot partition (running by automount) /dev/sda1Documentation=man:systemd.mount(5)After=blockdev@dev-disk-by\x2duuid-ea65285a\x2d01da\x2d451c\x2da93a\x2d4b155c46aeeb.target[Mount]Where=/bootWhat=/dev/disk/by-uuid/ea65285a-01da-451c-a93a-4b155c46aeebType=ext4Options=rw,relatimeDirectoryMode=0755

Всё практически как в fstab, только раскидано по нескольким строчкам. Что происходит в автомаунте: Когда какой-либо процесс пытается прочитать/записать что-то в каталоге /boot или получить его листинг, автомаунт запускает одноимённый юнит *.mount и начинает мониторить обращения к /boot. Через 2 минуты после последнего обращения (TimeoutIdleSec=), раздел будет автоматически отмонтирован.

И второй пример, который я всё никак не соберусь перевести на rclone автомонтирование облака яндекса, когда я к нему обращаюсь.

$ cat /etc/systemd/system/home-oxyd-Clouds-yadisk.automount[Unit]Description=Automount yandex disc when needed.[Automount]Where=/home/oxyd/Clouds/yadiskDirectoryMode=0777## Time to automatic umount of inactivityTimeoutIdleSec=300[Install]WantedBy=multi-user.target

И ответочка к нему:

$ cat /etc/systemd/system/home-oxyd-Clouds-yadisk.mount[Unit]Description=Yandex disk automounted driveDocumentation=man:systemd.mount(8) [Mount]Where=/home/oxyd/Clouds/yadiskWhat=https://webdav.yandex.ru/Type=davfsOptions=noauto,user

Тут тоже всё прозрачно, единственно добавлен параметр раздачи прав для создания директории, если таковой не окажется на законном месте. Да у автомаунта ровно три параметра:

  • Where= Путь который мониторим.

  • TimeoutIdleSec= Таймаут перед автоотмонтированием, если параметр отсутствует, или равен 0 (по умолчанию) раздел не автоотмонтируется.

  • DirectoryMode= права на создание каталога для мониторинга, по умолчанию 0755.

Вот, вкратце, как-то примерно так. И, как всегда, какие маны почитать:

man systemd.pathman 7 inotifyman inotifywaitman inotifywatchman systemd.automountman systemd.mountman systemd-mountman 5 fstabman systemd.time

Список статей серии

  1. Почему хабражители предпочитают велосипеды, вместо готовых решений? Или о systemd, part 0

  2. Systemd для продолжающих. Part 1 Запуск юнитов по временным событиям

  3. Systemd для продолжающих. Part 2 Триггеры на различные события

Ресурсы

  • systemd.io Статьи по внутренней кухне systemd. Частенько упоминается в манах.

  • systemd @ freedesktop.org Основная страница с манами, документацией, видео, блогами и прочими ссылками на ресурсы.

  • @ru_systemd Русскоязычный чат в Telegram. У нас тепло и лампово.

Подробнее..

Настраиваем Restic с systemd на Linux

31.01.2021 02:12:47 | Автор: admin

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


Поставим задачу следующим образом:


  1. Автоматический бэкап запускается ежедневно.
  2. Бэкап хранит только важные файлы и данные.
  3. Бэкап также включает в себя содержимое баз PostgreSQL, которое можно восстановить psql -f.

TL;DR поста

Пишем два юнита / таймера для systemd, запускаем restic под выделенным пользователем с CAP_DAC_READ_SEARCH, для PostgreSQL архивируем результат pg_dumpall.


Здесь предполагается, что бэкап производится на машине с Ubuntu Server 20.04 и выполняется на rest-server, работающий на 192.168.1.200. Тем не менее, конфигурация тривиально адаптируется к любому облачному провайдеру. Также предполагается, что репозиторий уже проинициализирован командой restic -r rest:http://192.168.1.200/your-repo/ init.


Бэкапим файлы/директории


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


# useradd -m -N -s /usr/sbin/nologin restic

Нам понадобится следующий сервис systemd с параметром и таймер к нему:


/etc/systemd/system/restic@.service:


[Unit]# юнит активируется с параметром после @, то есть в#   systemctl start restic@your-repo.service# %I означает "your-repo"Description=Restic backup on %IAfter=syslog.targetAfter=network-online.target[Service]Type=oneshotUser=restic# читать список файлов к бэкапу будем из /etc/restic/your-repo.filesExecStart=/usr/local/bin/restic backup --files-from /etc/restic/%I.files# считаем репозиторий и пароль из /etc/restic/your-repo.envEnvironmentFile=/etc/restic/%I.env# выполняем restic с capability DAC_READ_SEARCH, дающей право# обходить права доступа ФС в Linux, это нужно для бэкапа# директорий, которые могут читать только другие пользователи# или суперпользовательAmbientCapabilities=CAP_DAC_READ_SEARCH[Install]WantedBy=multi-user.target

/etc/systemd/system/restic@.timer:


[Unit]# таймер, будучи запущенным с параметром после @# (restic@your-repo.timer), запустит restic@your-repo.serviceDescription=Run Restic at 12:00 AM[Timer]# запускаем restic ежедневно в 12 часов ночиOnCalendar=*-*-* 12:00:00[Install]WantedBy=timers.target

Адрес репозитория и пароль от него подаются на вход через файл с переменными среды в /etc/restic/your-repo.env. systemd читает их при старте юнита с правами root, поэтому имеет смысл задать разрешения директории /etc/restic/ соответствующим образом (т.е. 700 и владельцем установить root):


RESTIC_PASSWORD=your_repo_passwordRESTIC_REPOSITORY=rest:http://192.168.1.200/your-repo/

Нам также понадобится список файлов/директорий к бэкапу в /etc/restic/your-repo.files:


/var/lib/docker/etc/postgresql/etc/restic...

Бэкап PostgreSQL


Restic позволяет подачу данных для бэкапа через стандартный вход, так что мы можем скормить ему дамп, полученный pg_dumpall. Так как systemd запускает указанное директивой ExecStart вызовом execve(3), для использования перенаправления вывода и сжатия нам понадобится отдельный скрипт /usr/local/bin/pgdump.sh:


#!/usr/bin/env bashset -euo pipefail/usr/bin/sudo -u postgres pg_dumpall --clean \    | gzip --rsyncable \    | /usr/local/bin/restic backup --host $1 --stdin \        --stdin-filename postgres-$1.sql.gz

Сервис /etc/systemd/system/restic-pg@.service достаточно тривиален:


[Unit]Description=Restic PostgreSQL backup on %IAfter=syslog.targetAfter=network-online.targetAfter=postgresql.serviceRequires=postgresql.service[Service]Type=oneshotUser=resticExecStart=/usr/local/bin/pgdump.sh %IEnvironmentFile=/etc/restic/%I.env[Install]WantedBy=multi-user.target

Таймер /etc/systemd/system/restic-pg@.timer не отличается от виденного выше:


[Unit]Description=Run Restic on PostgreSQL at 12:00 AM[Timer]OnCalendar=*-*-* 0:00:00[Install]WantedBy=timers.target

Завершаем


Запустим таймеры и включим их автозагрузку:


# systemctl enable --now restic@your-repo.timer restic-pg@your-repo.timer

Проверим, работает ли построенная система:


# systemctl start restic@your-repo.service# systemctl start restic-pg@your-repo.service

Данный набор юнитов позволяет бэкапиться в неограниченное количество репозиториев, нужно лишь создать соответствующие /etc/restic/repo-name.{env,files}.


Ссылки


Подробнее..

Бесплатный онлайн-курс Основы Ansible, шпаргалка по GNU Screen, запись Red Hat Summit и многое другое

06.05.2021 14:05:14 | Автор: admin

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

Узнать новое:

Скачать:

Что еще интересного:

Мероприятия:

Вебинары:

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru