<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Systemd on Шлакоблог</title><link>https://vodolaz095.ru/tags/systemd/</link><description>Recent content in Systemd on Шлакоблог</description><generator>Hugo -- 0.162.1</generator><language>ru-RU</language><lastBuildDate>Sat, 18 Jan 2025 13:31:12 +0300</lastBuildDate><atom:link href="https://vodolaz095.ru/tags/systemd/index.xml" rel="self" type="application/rss+xml"/><item><title>Systemd - скрипт для включения и выключения юнита одной командой</title><link>https://vodolaz095.ru/systemd_toggle/</link><pubDate>Sat, 18 Jan 2025 13:31:12 +0300</pubDate><author>Анатолий Остроумов</author><guid>https://vodolaz095.ru/systemd_toggle/</guid><description>В статье представлен образец скрипта, чтобы включать или выключать systemd unit одной командой.</description><content type="text/html" mode="escaped"><![CDATA[<p>Допустим, у вас есть OpenVPN соединение с работой (systemd-unit <code>openvpn-client@work.service</code>), и вы хотите включать
или выключать его одной командой:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ connect_work
</span></span></code></pre></div><p>Для этого можно написать такой скрипт (и разместить его, допустим, в <code>/usr/bin/connect_work</code>):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#75715e">#!/usr/bin/env bash
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>set -e
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>service<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openvpn-client@work.service&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>systemctl -q is-active <span style="color:#e6db74">&#34;</span>$service<span style="color:#e6db74">&#34;</span><span style="color:#f92672">)</span> <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>	echo <span style="color:#e6db74">&#34;Stopping </span>$service<span style="color:#e6db74">...&#34;</span>
</span></span><span style="display:flex;"><span>	sudo systemctl stop <span style="color:#e6db74">&#34;</span>$service<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>	echo <span style="color:#e6db74">&#34;Starting </span>$service<span style="color:#e6db74">...&#34;</span>
</span></span><span style="display:flex;"><span>	sudo systemctl start <span style="color:#e6db74">&#34;</span>$service<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>systemctl status <span style="color:#e6db74">&#34;</span>$service<span style="color:#e6db74">&#34;</span>
</span></span></code></pre></div><p>Чтобы sudo не спрашивало постоянно пароль для эскалации прав, пользователю можно разрешить выполнять эти команды
без запроса пароля, создав файл в <code>/etc/sudoers.d/vpn</code> с таким содержанием.</p>
<pre tabindex="0"><code>%vodolaz095 ALL=NOPASSWD: /usr/bin/systemctl start openvpn-client@work.service, /usr/bin/systemctl stop openvpn-client@work.service, /usr/bin/systemctl restart openvpn-client@work.service
</code></pre><p>Тут:</p>
<ul>
<li><code>%vodolaz095</code> - группа пользователя, которому можно совершать данные действия</li>
<li><code>ALL=NOPASSWD:</code> выключает проверку пароля при вызове sudo для этих команд</li>
<li><code>/usr/bin/systemctl start openvpn-client@work.service, ...</code> - список комманд, которые может вводить пользователь с эскалацией прав</li>
</ul>
<p>Совет - файл можно создать любым текстовым редактором, но лучше всего использовать
<a href="https://man7.org/linux/man-pages/man8/visudo.8.html">visudo</a> - оно проверяет корректность синтаксиса.</p>
<p>Создать разрешения для использования vpn можно этой командой</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ sudo visudo /etc/sudoers.d/vpn 
</span></span></code></pre></div><p>Как итог, любой пользователь из группы <code>vodolaz095</code> может вызвать команду <code>$ connect_work</code> и включить или выключить
systemd юнит <code>openvpn-client@work.service</code>.</p>
<p>Образец скрипта также опубликован тут:
<a href="https://gist.github.com/vodolaz095/484efe4fbd385185d50c0e454d32eabe">https://gist.github.com/vodolaz095/484efe4fbd385185d50c0e454d32eabe</a></p>
]]></content></item><item><title>systemd - как работать с NodeJS сервисом, у которого утекает память?</title><link>https://vodolaz095.ru/systemd-memleaky-nodejs/</link><pubDate>Thu, 18 Feb 2021 18:26:27 +0300</pubDate><author>Анатолий Остроумов</author><guid>https://vodolaz095.ru/systemd-memleaky-nodejs/</guid><description>В статье рассмотрен один из вариантов борьбы с утечками памяти в приложении на NodeJS, которые начинаются после нескольких часов работы</description><enclosure url="https://vodolaz095.ru/images/systemd_memleaky_node.png" length="" type="image/png"/><media:thumbnail url="https://vodolaz095.ru/images/systemd_memleaky_node.png" width="1073" height="736"/><media:content url="https://vodolaz095.ru/images/systemd_memleaky_node.png" medium="image" type="image/png" width="1073" height="736"><media:title type="html">/images/systemd_memleaky_node.png</media:title></media:content><content type="text/html" mode="escaped"><![CDATA[<p><img src="/images/systemd_memleaky_node.png" alt="systemd_memleaky_node.png"></p>
<p>Всем хороша среда выполнения Javascript NodeJS, но у неё есть три недостатка.</p>
<ul>
<li>Первый недостаток - много низкокачественных NPM модулей, включая те, в которых происходят утечки памяти.</li>
<li>Второй недостаток - обычная программа требует множество модулей, и обязательно среди них будет несколько, в которых утекает память.</li>
<li>Третий недостаток - иногда утечки памяти начинаются после часов, а то и суток работы программы.</li>
</ul>
<p>Что с этим делать?
Можно потратить много времени, разобраться, где утекает память, написать исправление к модулю и послать Pull-Request разработчикам модуля,
который они скорее всего проигнорируют, так как у них проблема не воспроизводится, или же они, как обычно, не видят в этом проблему.
А можно просто перезапустить программу через несколько часов работы, когда начинают появляться утечки памяти.</p>
<p>Для примера, рассмотрим почтовый сервер на основе <a href="https://haraka.github.io/">https://haraka.github.io/</a>, который, после запуска
потребляет 56.8 мегабайт памяти, а через несколько суток - уже 180 мегабайт.</p>
<p>Данный сервер запускается с помощью systemd, используя этот unit файл:</p>
<pre tabindex="0"><code>[Unit]
Description=Haraka inbound STMP server
After=network.target

[Service]
Type=simple

User=haraka
Group=haraka

WorkingDirectory=/opt/haraka/haraka-inbound
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=1s
Environment=NODE_ENV=production

# Hardening
ProtectHome=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
</code></pre><p>Как его можно перезапустить, допустим, раз в час, используя systemd?</p>
<p>Для этого достаточно почитать документацию к systemd, и найти этот параметр конфигурации:</p>
<p><a href="https://www.freedesktop.org/software/systemd/man/systemd.service.html#RuntimeMaxSec">https://www.freedesktop.org/software/systemd/man/systemd.service.html#RuntimeMaxSec</a></p>
<pre tabindex="0"><code>RuntimeMaxSec=

Configures a maximum time for the service to run. If this is used 
and the service has been active for longer than the specified time it is terminated 
and put into a failure state. Note that this setting does not have any effect 
on Type=oneshot services, as they terminate immediately after activation 
completed. Pass &#34;infinity&#34; (the default) to configure no runtime limit.
</code></pre><p>То есть, задав этот параметр равным 3600, мы добьёмся того, что systemd будет автоматически останавливать, и
снова запускать почтовый сервер каждый час. Так как Haraka написан неожиданно хорошо для nodejs приложений,
он не только быстро перезагружается, он ещё знает, как закончить все транзакции перед перезапуском, и поэтому
ни одно письмо не пропадёт.</p>
<p>Такой unit файл был в итоге создан для почтового сервера:</p>
<pre tabindex="0"><code>
[Unit]
Description=Haraka inbound STMP server
After=network.target

[Service]
Type=simple

User=haraka
Group=haraka

WorkingDirectory=/opt/haraka/haraka-inbound
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=1s
Environment=NODE_ENV=production

# Gracefully restart service every hour to prevent memleaks
RuntimeMaxSec=3600

# Hardening
ProtectHome=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
</code></pre><p>Теперь почтовый сервер перезапускается раз в час, и в среднем потребляет около 60 мегабайт памяти.</p>
]]></content></item></channel></rss>