Rabbit Slide Show

systemd 再入門

2021-04-17

Description

[オンライン開催:東京エリア・関西合同Debian勉強会(2021/04/17(土))](https://debianjp.connpass.com/event/208924/)の発表資料です。 crontab の代わりに systemd-timer を使う、および user 権限での systemd の話です。

Text

Page: 1

systemd 再入門
Kazuhiro NISHIYAMA
東京エリア・関西合同Debian勉強会
2021-04-17
株式会社Ruby開発
Powered by Rabbit 2.2.1

Page: 2

自己紹介
西山 和広
Ruby のコミッター
twitter, github など: @znz
株式会社Ruby開発 www.ruby-dev.jp
1/24

Page: 3

systemd のおすすめ資料
systemdエッセンシャル / systemd-
intro - Speaker Deck
https://speakerdeck.com/moriwaka/
systemd-intro
2/24

Page: 4

agenda
crontab の代わりに systemd-timer
user 権限での systemd
3/24

Page: 5

systemd-timer の利点
systemctl start での動作確認と
timer での実行の環境が同じ
journald に自動でログが残る
他の unit との依存関係が設定できる
(DB バックアップなら DB 起動必須な
ど)
時刻指定が crontab より柔軟
4/24

Page: 6

systemd-timer の欠点
最低限の利用でも記述量が多い
service ファイルと timer ファイルが必
要で 1 行だけでは出来ない
時刻指定が独自
kubernetes の cronjob のような新しいも
のでも crontab 形式の時刻指定が使われて
いることが多い
5/24

Page: 7

シンプルな使い方
Type=oneshot の service ユニットを
作成
同名の timer ユニットを作成して
systemctl enable --now
foo.timer のように enable と
start をする
別の名前のユニットを start するなら
Unit= で指定
6/24

Page: 8

enable と start
foo.timer から起動する
foo.service は enable しない
foo.timer も enable を忘れるとマシ
ンの再起動後に動いていない (service
unit と同じ)
systemctl start foo.service で
timer を待たずに起動して動作確認可能
7/24

Page: 9

動作確認例
systemctl list-timers
systemctl status systemd-
tmpfiles-clean.timer
systemctl status systemd-
tmpfiles-clean.service
8/24

Page: 10

ログの例
ログ表示は systemd-journal グループに
所属するか sudo を使う
journalctl -u systemd-tmpfiles-
clean.timer
journalctl -u systemd-tmpfiles-
clean.service
Starting が実行開始時刻で Started が
実行終了時刻
9/24

Page: 11

service 作成例
# /etc/systemd/system/gitlab-backup.service
[Unit]
Description=Backup gitlab
After=gitlab-runsvdir.service
Requires=gitlab-runsvdir.service
[Service]
Type=oneshot
ExecStart=/opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1
10/24

Page: 12

service 作成例 (解説)
ExecStart が crontab での実行内容に相
当 (ARGV0 の部分はフルパス必須)
crontab 代わりで最低限必要なのは Type
と ExecStart
After や Requires で gitlab の
service unit が動いているときだけバック
アップを実行 (runsvdir 経由なので gitlab
全体が正常に動いているかどうかは未確認)
11/24

Page: 13

timer 作成例
# /etc/systemd/system/gitlab-backup.timer
[Unit]
Description=Backup gitlab
[Timer]
OnCalendar=*-*-* 2,14:00
Persistent=true
[Install]
WantedBy=timers.target
12/24

Page: 14

timer 作成例 (解説)
Persistent=true は anacron 相当
crontab 代わりで最低限必要なのは
OnCalendar と WantedBy
13/24

Page: 15

OnCalendar
systemd-analyze calendar '*-*-*
2,14:00' などで OnCalendar の指定内容
を確認可能
任意の時刻を基準にするには faketime コ
マンドと組み合わせて faketime
'2021-04-17 16:00' systemd-
analyze calendar '*-*-* 2,14:00'
14/24

Page: 16

at コマンド代わり
systemd-run --on-active=30 /bin/
touch /tmp/foo で30秒後
systemd-run --on-active="1h
30m" --unit foo.service で1時間半後
systemd-run --on-
calendar="2021-04-17 16:00" /
bin/touch /tmp/foo のように日時指定
も可能
15/24

Page: 17

user 権限での systemd
特に設定していなければ
pam_systemd.so で /lib/systemd/
systemd --user が起動して、ログアウト
時に終了
systemctl --user で操作
loginctl enable-linger someuser
で常に起動 (loginctl disable-
linger someuser で戻す)
16/24

Page: 18

動作確認
自ユーザーなら systemctl --user
status
別ユーザーなら sudo -u someuser
XDG_RUNTIME_DIR=/run/user/$(id -
u someuser) systemctl --user
status
sudo -u someuser systemctl --user
status だけだと Failed to connect to
bus: No such file or directory
17/24

Page: 19

unit ファイルの場所
普通は ~/.config/systemd/user/ に置
く
全ユーザー共通なら /etc/systemd/
user/ に置くのも可能
全パスは systemd.unit(5) 参照
18/24

Page: 20

Install の WantedBy
system の unit なら WantedBy=multi-
user.target を使うことが多い
user の unit は
WantedBy=default.target を代わりに
使う
19/24

Page: 21

unit ファイル例
# /home/chatuser/.config/systemd/user/weechat.service
[Unit]
Description=A WeeChat client and relay service using Tmux
After=network.target
[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/usr/bin/tmux -L weechat new -d -s weechat weechat
ExecStop=/usr/bin/tmux -L weechat kill-session -t weechat
[Install]
WantedBy=default.target
20/24

Page: 22

unit ファイル例 (解説)
マシン起動時に weechat を tmux の中で自
動起動
手抜きで tmux を手動終了したときの処理
は省略
終了してしまったときはマシンを再起動してい
る
21/24

Page: 23

動作確認例
sudo -u chatuser
XDG_RUNTIME_DIR=/run/user/$(id -
u chatuser) systemctl --user
status weechat
sudo -u chatuser
XDG_RUNTIME_DIR=/run/user/$(id -
u chatuser) journalctl --user -
u weechat
22/24

Page: 24

/etc にあった例
# ls /etc/systemd/user/sockets.target.wants/
dirmngr.socket gpg-agent-browser.socket gpg-agent-extra.socket
gpg-agent.socket gpg-agent-ssh.socket
# readlink /etc/systemd/user/sockets.target.wants/gpg-agent.socket
/usr/lib/systemd/user/gpg-agent.socket
# cat /etc/systemd/user/sockets.target.wants/gpg-agent.socket
[Unit]
Description=GnuPG cryptographic agent and passphrase cache
Documentation=man:gpg-agent(1)
[Socket]
ListenStream=%t/gnupg/S.gpg-agent
FileDescriptorName=std
SocketMode=0600
DirectoryMode=0700
[Install]
WantedBy=sockets.target
23/24

Page: 25

まとめ
crontab の代わりに timer unit + service
unit
systemd-run は at の代わりになる
user 権限での systemd は loginctl
enable-linger で常時起動
~/.config/systemd/user/ に unit ファ
イル
Powered by Rabbit 2.2.1
24/24

Other slides