これは、なにをしたくて書いたもの?
systemdのユニット定義ファイルですが、どこに置くものだったかよく忘れるので。
ちょっと調べて、メモしておこうかなと。
manを見る
まずは、systemdのマニュアルを見てみます。
systemd(1) - Linux manual page
DIRECTORIESに、説明が書いてあります。
System Unit Directoryと、User Unit Directoryの2つがあるようです。
完全なディレクトリのリストは、systemd.unitを見てください、と。
Full list of directories is provided in systemd.unit(5).
User Unitってなんでしょう?
どうやら、systemdにはシステムモードとユーザーモードの2つがあるようです。
--system, --user
it shall operate in system or per-user mode,
ユーザーモードは、ユーザーがログインした時にユーザーごとのサービスを実行するモードのようです。ユーザーセッションが
残っている限り動作し続け、ユーザーのセッションがなくなると終了する、と。知らなかったです。
一方で、サーバー用途でのsystemdで馴染みがあるのはシステムモードだと思います。
というわけで、以降は基本的にはシステムモードの話でいきます。
systemd.unit
さて、systemd.unitのドキュメントを見るように書かれていたので、見てみましょう。
systemd.unit(5) - Linux manual page
システムモード、ユーザーモードそれぞれでsystemdが参照するパスは、以下のようです。
- System Unit Search Path
- /etc/systemd/system.control/*
- /run/systemd/system.control/*
- /run/systemd/transient/*
- /run/systemd/generator.early/*
- /etc/systemd/system/*
- /etc/systemd/system.attached/*
- /run/systemd/system/*
- /run/systemd/system.attached/*
- /run/systemd/generator/*
- ...
- /usr/lib/systemd/system/*
- /run/systemd/generator.late/*
- User Unit Search Path
- ~/.config/systemd/user.control/*
- $XDG_RUNTIME_DIR/systemd/user.control/*
- $XDG_RUNTIME_DIR/systemd/transient/*
- $XDG_RUNTIME_DIR/systemd/generator.early/*
- ~/.config/systemd/user/*
- $XDG_CONFIG_DIRS/systemd/user/*
- /etc/systemd/user/*
- $XDG_RUNTIME_DIR/systemd/user/*
- /run/systemd/user/*
- $XDG_RUNTIME_DIR/systemd/generator/*
- $XDG_DATA_HOME/systemd/user/*
- $XDG_DATA_DIRS/systemd/user/*
- ...
- /usr/lib/systemd/user/*
- $XDG_RUNTIME_DIR/systemd/generator.late/*
システムモードの方のパスを見ると、/etc/systemd/system/*、/usr/lib/systemd/system/*とよく見るパスが出てきたと思います。
それぞれのパスの説明は、UNIT FILE LOAD PATHに書かれています。
systemd.unit / UNIT FILE LOAD PATH
抜粋してみましょう。
/usr/lib/systemd/system… System units installed by the distribution package manager(パッケージマネージャーによってインストールされたシステムユニット)/etc/systemd/system… System units created by the administrator(管理者によって作成されたシステムユニット)
この説明を見て、パッケージが使うのは/usr/lib/systemd/system、利用者(サーバーの管理者)が使うのは
/etc/systemd/systemということがなんとなくわかりますが、EXAMPLESにもう少し具体的に書かれています。
たとえば、ベンダー(パッケージ提供者)の設定をオーバーライドするには/usr/lib/systemd/systemにあるユニット定義ファイルを
/etc/systemd/systemにコピーして変更します、と。
files: copying the unit file from /usr/lib/systemd/system to /etc/systemd/system and modifying the chosen settings.
または、unit.dディレクトリを作ってもよいみたいですが…こちらは今回は置いておきます。
Alternatively, one can create a directory named unit.d/ within /etc/systemd/system and place a drop-in file name.
usr/lib/systemd/systemから/etc/systemd/systemにコピーして変更した場合、ファイルは完全に上書きになり、
それ以降ベンダー側のユニット定義ファイルは読まれません。
The advantage of the first method is that one easily overrides the complete unit, the vendor unit is not parsed at all anymore.
つまり、/etc/systemd/systemの方が優先度が高いことになります。
というわけで、/usr/lib/systemd/systemと/etc/systemd/systemの使い分けはわかった気がします。
あと、知っておいた方が良さそうなのは/run/systemd/systemという実行時に自動的に作成されるユニット定義ファイルを
配置するディレクトリですね。
参考までに、Ret Hat Enterprise Linuxのsystemd ユニット定義ファイルのドキュメントも見ておいた方が良さそうです。
第17章 systemd ユニットファイルでの作業 Red Hat Enterprise Linux 8 | Red Hat Customer Portal
ここまでドキュメントをいろいろ見てきたので、少し実際に確認してみるとしましょう。
次の2つのパターンを試してみたいと思います。
- パッケージをインストールして、そのユニット定義ファイルをカスタマイズする
- 独自のユニット定義ファイルを作成する
環境
今回の環境は、こちらです。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.2 LTS Release: 20.04 Codename: focal $ uname -srvmpio Linux 5.4.0-74-generic #83-Ubuntu SMP Sat May 8 02:35:39 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Ubuntu Linux 20.04 LTSです。
Apacheをパッケージインストールして、カスタマイズしてみる
パッケージインストールの例として、Apacheを使ってみましょう。
まずはインストール。
$ sudo apt install apache2
ところでApacheをインストールしているとsystemctl enableのログらしきものが出てきますが、この時のシンボリックリンク
作成先は/lib/systemd/systemとなっています。
Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service → /lib/systemd/system/apache2.service. Created symlink /etc/systemd/system/multi-user.target.wants/apache-htcacheclean.service → /lib/systemd/system/apache-htcacheclean.service.
Ubuntu Linuxの場合だと/usr/lib/systemd/systemディレクトリではなく、/lib/systemd/systemディレクトリを見るようです。
第598回 systemdユニットの設定を変える:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
といっても、/libディレクトリを確認すると/usr/libディレクトリにリンクされているだけなので、結局のところ
/usr/lib/systemd/systemディレクトリにファイルはあるわけですが。
$ ll /lib lrwxrwxrwx 1 root root 7 May 26 19:39 /lib -> usr/lib/ $ ll /usr/lib/systemd/system/apache2.service -rw-r--r-- 1 root root 395 Apr 13 2020 /usr/lib/systemd/system/apache2.service
ステータスを確認してみます。
$ systemctl status apache2
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-06-06 10:47:38 UTC; 8min ago
Docs: https://httpd.apache.org/docs/2.4/
Main PID: 1641 (apache2)
Tasks: 55 (limit: 2280)
Memory: 5.5M
CGroup: /system.slice/apache2.service
├─1641 /usr/sbin/apache2 -k start
├─1642 /usr/sbin/apache2 -k start
└─1643 /usr/sbin/apache2 -k start
Jun 06 10:47:38 ubuntu2004.localdomain systemd[1]: Starting The Apache HTTP Server...
Jun 06 10:47:38 ubuntu2004.localdomain apachectl[1640]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using ubuntu2004.localdomain. Set>
Jun 06 10:47:38 ubuntu2004.localdomain systemd[1]: Started The Apache HTTP Server.
今回、ここで表示されているDescriptionのThe Apache HTTP Serverを書き換えて、カスタマイズしてみましょう。
まずは、/usr/lib/systemd/systemから/etc/systemd/systemへユニット定義ファイルをコピー。
$ sudo cp /usr/lib/systemd/system/apache2.service /etc/systemd/system/apache2.service
ユニット定義ファイルの、Descriptionを変更します。
/etc/systemd/system/apache2.service
[Unit] Description=The Apache HTTP Server(Customized) After=network.target remote-fs.target nss-lookup.target Documentation=https://httpd.apache.org/docs/2.4/ [Service] Type=forking Environment=APACHE_STARTED_BY_SYSTEMD=true ExecStart=/usr/sbin/apachectl start ExecStop=/usr/sbin/apachectl stop ExecReload=/usr/sbin/apachectl graceful PrivateTmp=true Restart=on-abort [Install] WantedBy=multi-user.target
そして、systemctl daemon-reloadを実行。
$ sudo systemctl daemon-reload
systemctl statusを見ると、ロードされているユニット定義ファイルが変更されていることと、Descriptionの変更が
反映されていることが確認できます。
$ systemctl status apache2
● apache2.service - The Apache HTTP Server(Customize)
Loaded: loaded (/etc/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-06-06 11:04:18 UTC; 38s ago
Docs: https://httpd.apache.org/docs/2.4/
Main PID: 3081 (apache2)
Tasks: 55 (limit: 2280)
Memory: 5.2M
CGroup: /system.slice/apache2.service
├─3081 /usr/sbin/apache2 -k start
├─3082 /usr/sbin/apache2 -k start
└─3083 /usr/sbin/apache2 -k start
Jun 06 11:04:18 ubuntu2004.localdomain systemd[1]: Starting The Apache HTTP Server...
Jun 06 11:04:18 ubuntu2004.localdomain apachectl[3064]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using ubuntu2004.localdomain. Set>
Jun 06 11:04:18 ubuntu2004.localdomain systemd[1]: Started The Apache HTTP Server.
ちなみに、/etc/systemd/system/multi-user.target.wantsから参照されているのは、/lib/systemd/systemから実は変わって
いなかったりします。
$ ll /etc/systemd/system/multi-user.target.wants/apache2.service lrwxrwxrwx 1 root root 35 Jun 6 11:03 /etc/systemd/system/multi-user.target.wants/apache2.service -> /lib/systemd/system/apache2.service
ちょっと不思議な感じはしますが、systemctl daemon-reloadで反映させる、で合ってはいるみたいです。
ここでsystemctl enableを実行すると、シンボリックリンクも貼り替えてくれます。
$ sudo systemctl enable apache2 Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable apache2 Removed /etc/systemd/system/multi-user.target.wants/apache2.service. Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service → /etc/systemd/system/apache2.service.
ここまでやった方がいいのでしょうか?
$ systemctl status apache2
● apache2.service - The Apache HTTP Server(Customize)
Loaded: loaded (/etc/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-06-06 11:07:09 UTC; 6min ago
Docs: https://httpd.apache.org/docs/2.4/
Main PID: 670 (apache2)
Tasks: 55 (limit: 2280)
Memory: 8.0M
CGroup: /system.slice/apache2.service
├─670 /usr/sbin/apache2 -k start
├─671 /usr/sbin/apache2 -k start
└─672 /usr/sbin/apache2 -k start
Jun 06 11:07:09 ubuntu2004.localdomain systemd[1]: Starting The Apache HTTP Server(Customize)...
Jun 06 11:07:09 ubuntu2004.localdomain apachectl[654]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using ubuntu2004.localdomain. Set >
Jun 06 11:07:09 ubuntu2004.localdomain systemd[1]: Started The Apache HTTP Server(Customize).
独自のユニット定義ファイルを作成する
最後に、自分でユニット定義ファイルを作成してみます。
お題は、Prometheusにしましょう。
Prometheus用のユーザーを作成。
$ sudo useradd -r prometheus
インストール先は、/opt/prometheusにしましょう。
$ cd /opt $ sudo curl -OLs https://github.com/prometheus/prometheus/releases/download/v2.27.1/prometheus-2.27.1.linux-amd64.tar.gz $ sudo tar xf prometheus-2.27.1.linux-amd64.tar.gz $ sudo mv prometheus-2.27.1.linux-amd64 prometheus $ sudo chown -R prometheus.prometheus prometheus
データ保存用のディレクトリを作成。
$ sudo mkdir -p /var/lib/prometheus $ sudo chown prometheus.prometheus /var/lib/prometheus
Prometheus用のユニット定義ファイルを作成。
/etc/systemd/system/prometheus.service
[Unit] Description=Prometheus - systems monitoring and alerting toolkit Documentation=https://prometheus.io/docs/ After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data ExecReload=/bin/kill -HUP $MAINPID User=prometheus [Install] WantedBy=multi-user.target
systemdのサービスとして、有効化。
$ sudo systemctl enable prometheus Created symlink /etc/systemd/system/multi-user.target.wants/prometheus.service → /etc/systemd/system/prometheus.service.
起動。
$ sudo systemctl start prometheus
確認。
$ sudo systemctl status prometheus
● prometheus.service - Prometheus - systems monitoring and alerting toolkit
Loaded: loaded (/etc/systemd/system/prometheus.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-06-06 11:57:57 UTC; 13s ago
Docs: https://prometheus.io/docs/
Main PID: 5399 (prometheus)
Tasks: 7 (limit: 2280)
Memory: 18.7M
CGroup: /system.slice/prometheus.service
└─5399 /opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.047Z caller=head.go:755 component=tsdb msg="On-disk memory mappable chunks replay compl>
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.047Z caller=head.go:761 component=tsdb msg="Replaying WAL, this may take a while"
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.052Z caller=head.go:813 component=tsdb msg="WAL segment loaded" segment=0 maxSegment=1
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.053Z caller=head.go:813 component=tsdb msg="WAL segment loaded" segment=1 maxSegment=1
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.053Z caller=head.go:818 component=tsdb msg="WAL replay completed" checkpoint_replay_dur>
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.054Z caller=main.go:828 fs_type=EXT4_SUPER_MAGIC
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.054Z caller=main.go:831 msg="TSDB started"
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.054Z caller=main.go:957 msg="Loading configuration file" filename=/opt/prometheus/prome>
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.055Z caller=main.go:988 msg="Completed loading of configuration file" filename=/opt/pro>
Jun 06 11:57:58 ubuntu2004.localdomain prometheus[5399]: level=info ts=2021-06-06T11:57:58.055Z caller=main.go:775 msg="Server is ready to receive web requests."
なんとなく、リロードも対応しておきました。
$ sudo systemctl reload prometheus
停止。
$ sudo systemctl stop prometheus
こんなところでしょうか。
まとめ
systemdのユニット定義ファイルの置き場所をあらためて調べ直して、まとめておきました。
いつも雰囲気で見ていた気がするので、こういう機会も良いかな、と。