【Linux】systemdでpostfixを自動起動設定する

2021年3月21日

こんにちは、キクです。

本記事ではLinux学習シリーズとして、僕が学んだ内容をアウトプットしていこうと思います。

少し前までWeb制作に関する学習にハマっていましたが、本業の方で力不足を感じることも多く「このままではダメだ」と感じて以来Linuxの学習に力を入れるようになっている今日この頃。
今回はその中でもLinuxの大切な技術となる「systemd」の自動起動に関して学んだことを整理していこうと思います。

自動起動設定自体は簡単ですが、その裏では複数のファイル同士が連携して動いています。

本記事でsystemdの全体像までは把握できませんが、一部分でも理解することで少しずつ理解の視野を広げることができればと思います。

それでは、よろしくお願いします。

動作環境

本記事の内容は、下記の環境で実施したものになります。
・CentOS7 on VirtualBox on macOS

注意事項

本記事は僕が経験した内容をもとに記載しておりますが、実行環境や設定内容によっては動作が異なる場合があります。
そのため『参考程度』にお読みいただけますと幸いです。

ユニット / ターゲットについて

自動起動について触れる前に、まずはsystemdの基本的な概念である「ユニット」と「ターゲット」について簡単に書いていこうと思います。

ユニット

まずは「ユニット」について。

ユニットとはsystemdが管理する処理の単位のことです。
以下のようなさまざまなユニットの種類が存在する

主なユニット

Serviceユニット:システムサービス
Targetユニット:Serviceユニットのグループ
Automountユニット:ファイルシステムの自動マウント
Deviceユニット:カーネルが認識するデバイスファイル
Mountユニット:ファイルシステムのマウント
Pathユニット:ファイルシステムのファイルやディレクトリ
Scopeユニット:外部プロセス
Sliceユニット:システムプロセスを管理するために階層的に組織化された一連のユニット
Socketユニット:通信用のソケット
Swapユニット:スワップデバイスとスワップファイル
Timerユニット:システムタイマー

たくさんあってお腹が一杯になりそうですが、本記事で扱うのは「Serviceユニット」と「Targetユニット」の2つになります。

とはいえ、せっかくなので少しだけ全体像を見ていきます。
これらは「実行型」「起動型」「構造型」「管理型」に分類することができます。

実行型は「Serviceユニット」「Mountユニット」「 Swapユニット」などが該当し、実際に処理を行うユニットタイプになります。
起動型は「Socketユニット」「Timerユニット」「 Pathユニット」などが該当し、処理のタイミングを制御するユニットタイプです。

例えば、Timerユニットであればcronのように時刻起動の制御などが可能です。
従って、起動型のユニットで起動のタイミングを制御し、実際の処理はServiceユニットなどの実行型が行う流れになります。

構造型は「Targetユニット」「Sliceユニット」などが該当し、実行型や起動型のユニットをまとめて管理する用途で使用されます。
管理型は「Deviceユニット」「 Scopeユニット」などが該当します。

他の型と違う点として、管理型以外はユニット定義ファイルで定義されるのに対して管理型ではsystemdが自動生成する点にあります。

ターゲット

続いて「ターゲット」について。

前節の「ユニット」の中に「Targetユニット」というのがあったかと思いますが、本節での「ターゲット」とはそれを指しています。
前述の通り、ターゲットとはユニットのグループ化をしたり順序関係や依存関係を定義するために使用されます。

本記事のテーマである「自動起動」もこのターゲットという概念に大きく絡んでいます。
ユニットにもいくつか種類があるように、ターゲットにもいくつか種類があります。
その中でもランレベルの概念に相当するターゲットを以下に示します。

ランレベルとターゲット

ランレベル0
 └ poweroff.target(別名:runlevel0.target)

ランレベル1
 └ rescue.target(別名:runlevel1.target)

ランレベル2
 └ multi-user.target(別名:runlevel2.target)

ランレベル3
 └ multi-user.target(別名:runlevel3.target)

ランレベル4
 └ multi-user.target(別名:runlevel4.target)

ランレベル5
 └ graphical.target(別名:runlevel5.target)

ランレベル6
 └ reboot.target(別名:runlevel6.target)

本記事で取り扱うのはランレベル2, 3, 4に該当する「multi-user.target」になります。

自動起動に関連するファイル / ディレクトリ

続いて実際に自動起動を行う上で関連のあるファイルについて見ていきたいと思います。
なお、本記事では自動起動の対象として「postfix.service」を例にお話します。

全体像のイメージ

具体的な内容に入る前に図を用いて簡単に全体像をイメージしておきましょう。
この段階では意味が分からないかもしれませんが、最後までお読みいただければ「なるほどね」となっているかと思います。

図の内容を簡単に書くと次のようになります。

①default.targetはmulti-user.targetへのシンボリックリンク
②multi-user.targetに紐付くユニットはmulti-user.target.wants配下にある
③postfix.serviceを自動起動設定するとmulti-user.target.wants配下にシンボリックリンクが設置される

/etc/systemd/system/default.target

このdefault.targetというのは、システムがブート時に起動するユニットグループになります。
実際にdefaullt.targetを確認した結果を以下に示します。

[root@host ~]# ll /etc/systemd/system/default.target
lrwxrwxrwx 1 root root 41  2月 23 14:01 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target

この結果からも分かるように、default.targetの実態はシンボリックリンクです。
通常は「multi-user.target」や「graphical.target」に向かっています。

/usr/lib/systemd/system/multi-user.target

今の僕の理解で本ファイルについて語れる内容は、default.targetのシンボリックリンクとしての向け先のひとつということぐらいしかありません。

すみません。

しかし「default.target」-「multi-user.target」-「multi-user.target.wants(次項)」は関連性が高いファイル・ディレクトリなので、本項を記載しました。

/etc/systemd/system/multi-user.target.wants

default.targetの向け先がmulti-user.targetとなっている場合には、本ディレクトリ配下のユニットが起動されます。
言葉だけだと難しいので、後ほど実際に自動起動設定した際に改めて触れたいと思います。

/usr/lib/systemd/system/postfix.service

こちらが今回自動起動設定を行うユニットになります。
少し中身を見てみましょう。

[root@host ~]# cat /usr/lib/systemd/system/postfix.service
[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service

[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop

[Install]
WantedBy=multi-user.target

いろいろ書いてありますが本記事で扱いたい部分は最後の「WantedBy=multi-user.target」の部分になります。
WantedBy属性は「弱い依存関係」で自動起動を設定することができる紐付けることができます。

どういうことかというと以下になります。

①postfix.serviceを自動起動設定した場合にはmulti-user.targetに紐付く
②仮にpostfix.serviceの起動に失敗してもmulti-user.target全体の起動には影響はない

「弱い依存関係」が関係している部分は②ですね。

反対に「強い依存関係」というのもあり、この場合は「RequiredBy」で指定することになります。
しかし、依存関係が強い場合には、そのサービスの起動に失敗するとシステム全体の起動ができなくなることにも繋がるので、設定には注意が必要です。

話が少し逸れましたが、ここでお伝えしたかったのはpostfix.serviceが紐付くターゲットとしてはmulti-user.targetが紐付いているということです。

自動起動設定してみる

それでは実際にpostfix.serviceの自動起動設定を行ってみたいと思います。
これまで登場したファイル/ディレクトリがすべて関係してくるのでイメージしながら読んでみてください。

1. default.targetの確認

先程も記載していますが、改めてdefault.targetがどこへのシンボリックリンクになっているのか確認してみます。

[root@host ~]# ll /etc/systemd/system/default.target
lrwxrwxrwx 1 root root 41  2月 23 14:01 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target

multi-user.targetへのシンボリックリンクになっていることを確認できました。

2. 既に自動起動設定されているユニットを確認

multi-user.target.wantsを確認して、既に自動起動が設定されているユニットを確認してみます。

[root@host ~]# ll /etc/systemd/system/multi-user.target.wants/
合計 0
lrwxrwxrwx. 1 root root 46  2月 21 16:32 NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service
lrwxrwxrwx. 1 root root 38  2月 21 16:33 auditd.service -> /usr/lib/systemd/system/auditd.service
lrwxrwxrwx  1 root root 39  2月 21 18:56 chronyd.service -> /usr/lib/systemd/system/chronyd.service
lrwxrwxrwx. 1 root root 37  2月 21 16:32 crond.service -> /usr/lib/systemd/system/crond.service
lrwxrwxrwx. 1 root root 42  2月 21 16:33 irqbalance.service -> /usr/lib/systemd/system/irqbalance.service
lrwxrwxrwx. 1 root root 37  2月 21 16:33 kdump.service -> /usr/lib/systemd/system/kdump.service
lrwxrwxrwx  1 root root 36  2月 24 00:18 ntpd.service -> /usr/lib/systemd/system/ntpd.service
lrwxrwxrwx. 1 root root 40  2月 21 16:32 remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
lrwxrwxrwx. 1 root root 39  2月 21 16:33 rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root 36  2月 21 16:33 sshd.service -> /usr/lib/systemd/system/sshd.service
lrwxrwxrwx. 1 root root 37  2月 21 16:33 tuned.service -> /usr/lib/systemd/system/tuned.service

postfix.serviceが含まれていません。

先程「multi-user.target.wants」の説明を先送りにしてしまいましたが、このディレクトリ配下には上記のようにいくつかの「.service」や「.target」などのユニットが含まれていることが分かります。
ここにあるユニットたちがmulti-user.targetとして自動起動設定が済んでいるユニットになります。

つまり、ここに存在しないpostfix.serviceはまだ自動起動設定ができていないことが分かります。

3. postfix.serviceに自動起動設定する

それでは本題の自動起動をしてみたいと思います。

設定方法は以下のコマンドです。

[root@host ~]# systemctl enable postfix.service
Created symlink from /etc/systemd/system/multi-user.target.wants/postfix.service to /usr/lib/systemd/system/postfix.service.

実行結果を見てみると「/usr/lib/systemd/system/postfix.servide」へのシンボリックリンクとして「/etc/systemd/system/multi-user.target.wants」配下に「postfix.service」というファイルが追加されているのが分かります。

念の為、改めてmulti-user.target.wants配下を確認してみましょう。

[root@host ~]# ll /etc/systemd/system/multi-user.target.wants/
合計 0
lrwxrwxrwx. 1 root root 46  2月 21 16:32 NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service
lrwxrwxrwx. 1 root root 38  2月 21 16:33 auditd.service -> /usr/lib/systemd/system/auditd.service
lrwxrwxrwx  1 root root 39  2月 21 18:56 chronyd.service -> /usr/lib/systemd/system/chronyd.service
lrwxrwxrwx. 1 root root 37  2月 21 16:32 crond.service -> /usr/lib/systemd/system/crond.service
lrwxrwxrwx. 1 root root 42  2月 21 16:33 irqbalance.service -> /usr/lib/systemd/system/irqbalance.service
lrwxrwxrwx. 1 root root 37  2月 21 16:33 kdump.service -> /usr/lib/systemd/system/kdump.service
lrwxrwxrwx  1 root root 36  2月 24 00:18 ntpd.service -> /usr/lib/systemd/system/ntpd.service
lrwxrwxrwx  1 root root 39  2月 28 12:57 postfix.service -> /usr/lib/systemd/system/postfix.service
lrwxrwxrwx. 1 root root 40  2月 21 16:32 remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
lrwxrwxrwx. 1 root root 39  2月 21 16:33 rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root 36  2月 21 16:33 sshd.service -> /usr/lib/systemd/system/sshd.service
lrwxrwxrwx. 1 root root 37  2月 21 16:33 tuned.service -> /usr/lib/systemd/system/tuned.service

無事にpostfix.serviceが追加されていました。
これで自動起動設定は完了です。

default.targetがmulti-user.targetであれば、システム起動時にpostfix.serviceユニットも自動的に起動されるようになりました。

4. 自動起動設定を解除してみる

最後におまけとして自動起動の解除もやってみましょう。
ここまで読んでくださった方であれば、どのような動きになるかはイメージできるのではないでしょうか?

[root@host ~]# systemctl disable postfix.service
Removed symlink /etc/systemd/system/multi-user.target.wants/postfix.service.

解除の場合には「/etc/systemd/system/multi-user.target.wants」からpostfix.serviceが削除する処理が実行されましたね。
これは自動起動設定時の逆の処理が行われたことになります。
イメージ通りの結果でしたでしょうか?

おわりに

いかがだったでしょうか。

今回はsystemdの自動起動設定について整理しました。
systemdについての理解が全然ないときには「自動起動設定はできるけど裏で何してるかは知らない」という状態でしたが、
ひとつひとつ紐解いてみると意外とシンプルな動作であることを知ることができました。
systemdの全貌を理解するには程遠いですが、こういう小さな積み重ねで少しずつ理解を広げていけたらなと思いながらこれからも学んでいきましょう!

本記事を最後まで読んでいただき、ありがとうございました。
ではでは!

 

-Linux
-