注目の記事

はじめてのsystemdサービス管理ガイド

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

MarketplaceでCentOS 7 AMIがリリースされましたね!(ex. Amazon EC2 CentOS 7 AMIファーストインプレッション)

ということで、これはもう本格的にsystemdを学ばないとあかん、という危機感に駆られた次第です。systemdは"system and service manager"なので、電源やロケールなどのシステム部分の管理も可能ですが、差し当たってEC2で使う上で最低限押さえとかなければいかないのはサービス管理になるでしょう。そこでsystemdを操作するためのコマンドであるsystemctlを使って、サービスを管理する方法についてまとめました。

systemdサービス管理

systemdでは、これまでサービス起動スクリプトで定義されていたものがUnitという形で定義されますので、サービスの管理=Unitの管理となります。

有効化されているUnitの一覧表示(list-units)

systemctlコマンドのdefaultオプションがsystemctl list-unitsなので、オプションを付けないとlist-unitsの結果が表示されます。

ちなみにsystemctlコマンドでは--no-pagerオプションを付与するとページ送りされず一気に全て表示されます。

$ systemctl list-units
UNIT                                             LOAD   ACTIVE SUB       DESCRIPTION
proc-sys-fs-binfmt_misc.automount                loaded active waiting   Arbitrary Executable File Formats File System Automount Point
sys-devices-platform-serial8250-tty-ttyS1.device loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS1
sys-devices-platform-serial8250-tty-ttyS2.device loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS2
sys-devices-platform-serial8250-tty-ttyS3.device loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS3
sys-devices-pnp0-00:09-tty-ttyS0.device          loaded active plugged   /sys/devices/pnp0/00:09/tty/ttyS0
(--snip--)
LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

96 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

インストールされているUnitファイルの一覧表示(list-unit-files)

$ systemctl list-unit-files
UNIT FILE                              STATE
proc-sys-fs-binfmt_misc.automount      static
dev-hugepages.mount                    static
sys-kernel-debug.mount                 static
tmp.mount                              masked
var-lib-nfs-rpc_pipefs.mount           static
brandbot.path                          disabled
arp-ethers.service                     disabled
auditd.service                         enabled
(--snip--)
207 unit files listed.

例えばyum install httpdでApacheをインストールしてみると、こんな感じでUnitファイルが登録されます。

$ systemctl list-unit-files | grep httpd
httpd.service                          disabled

Unitの有効化(enable)

有効化すると、以下のようにシステム起動時に立ち上がるサービスとして登録されます。systemctl enable httpdchkonfig httpd onと同等です。

$ sudo systemctl enable httpd
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'

ちなみにmulti-userというのは以前で言うrunlevel 2 or 3 or 4相当です。以下のような割り当てになっています。

  • runlevel0 -> poweroff
  • runlevel1 -> rescue
  • runlevel2 -> multi-user
  • runlevel3 -> multi-user
  • runlevel4 -> multi-user
  • runlevel5 -> graphical
  • runlevel6 -> reboot

有効にすると、インストールした直後はdisableだったものがenableになります。

$ systemctl list-unit-files --no-pager | grep httpd
httpd.service                          enabled

Unitの無効化(disable)

無効化すると、以下のようにシステム起動時に立ち上がるサービス対象から削除されます。systemctl disable httpdchkonfig httpd offと同等です。

$ sudo systemctl disable httpd
rm '/etc/systemd/system/multi-user.target.wants/httpd.service'

無効にしてlist-unit-filesで確認するとdisableになります。

$ systemctl list-unit-files --no-pager | grep httpd
httpd.service                          disabled

Unitの有効/無効の確認(is-enable)

有効の場合はenabledを、無効の場合はdisabledを返します。

$ sudo systemctl is-enabled httpd
disabled
$ sudo systemctl enable httpd
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
$ sudo systemctl is-enabled httpd
enabled

Unitの再有効化(reenable)

再有効化すると、一度disableにした上でenableになります。起動スクリプトのシンボリックリンクが貼り直される動作となります。

$ sudo systemctl reenable httpd
rm '/etc/systemd/system/multi-user.target.wants/httpd.service'
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'

Unitの起動(start)

serviceコマンドの場合は起動の経過が表示されたのですが、systemctlの場合は起動しても特にメッセージは表示されません。

$ sudo systemctl start httpd
$ ps aux | grep httpd
root      7977  0.3  0.4 213704  4880 ?        Ss   01:02   0:00 /usr/sbin/httpd -DFOREGROUND
apache    7978  0.0  0.2 213704  2872 ?        S    01:02   0:00 /usr/sbin/httpd -DFOREGROUND

Unitの起動状態確認(status)

$ sudo systemctl status httpd
httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
   Active: active (running) since 金 2014-10-10 01:06:07 UTC; 8s ago
 Main PID: 7998 (httpd)
   Status: "Processing requests..."
   CGroup: /system.slice/httpd.service
           ├─7998 /usr/sbin/httpd -DFOREGROUND
           ├─7999 /usr/sbin/httpd -DFOREGROUND
           ├─8000 /usr/sbin/httpd -DFOREGROUND
           ├─8001 /usr/sbin/httpd -DFOREGROUND
           ├─8002 /usr/sbin/httpd -DFOREGROUND
           └─8003 /usr/sbin/httpd -DFOREGROUND

10月 10 01:06:07 ip-172-31-7-131 systemd[1]: Starting The Apache HTTP Server...
10月 10 01:06:07 ip-172-31-7-131 systemd[1]: Started The Apache HTTP Server.

Unitの詳細確認(show)

Unitの詳細情報が表示されます。目視にはstatusのほうが便利ですが、スクリプトなどで処理したい場合にはshowのほうが使い勝手が良いです。

$ sudo systemctl show httpd
Id=httpd.service
Names=httpd.service
Requires=basic.target
Wants=system.slice
Conflicts=shutdown.target
Before=shutdown.target
After=network.target remote-fs.target nss-lookup.target systemd-journald.socket basic.target system.slice
Description=The Apache HTTP Server
LoadState=loaded
ActiveState=active
...

Unitの停止(stop)

停止の場合も同じく、特にメッセージは表示されません。

$ sudo systemctl stop httpd

Unitの設定ファイル再読み込み(reload)

再読み込みが可能かどうかはUnitによります。

$ sudo systemctl reload httpd

Unitの再起動(restart)

startstopと同じく、特にメッセージは表示されません。

$ sudo systemctl restart httpd

Unitの再起動試行(try-restart)

Unitが起動している場合には再起動します。Unitが停止している場合には何もしません。

$ sudo systemctl try-restart httpd

Unitの再読み込みまたは再起動(reload-or-restart)

Unitが再読み込み可能であればreloadを、再読み込みに対応していなければrestartを行います。またUnitが停止している場合は起動します。

$ sudo systemctl reload-or-restart httpd

Unitの再読み込みまたは再起動試行(reload-or-try-restart)

reload-or-restartと同等ですが、Unitが停止している場合には起動しません。

$ sudo systemctl reload-or-try-restart httpd

$ sudo systemctl stop httpd
$ sudo systemctl reload-or-try-restart httpd
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.

Unitの強制終了(kill)

$ sudo systemctl kill httpd

Unitのマスキング(mask/unmask)

Unitが無効化(disable)になっていてもサービスの起動は可能ですが、maskすることでサービスの起動自体が出来なくなります。

$ sudo systemctl mask httpd
ln -s '/dev/null' '/etc/systemd/system/httpd.service'
$ sudo systemctl start httpd
Failed to issue method call: Unit httpd.service is masked.

マスキングされた場合、is-enabledではmaskedが返ります。

$ sudo systemctl is-enabled httpd
masked

マスキングの解除はunmaskで行います。

$ sudo systemctl unmask httpd
rm '/etc/systemd/system/httpd.service'

Unitの起動状態の確認(is-active)

is-activeでは、Unitが起動しているとactiveが返ります。

$ sudo systemctl start httpd
$ sudo systemctl is-active httpd
active

起動していないとunknownが返ります。

$ sudo systemctl stop httpd
$ sudo systemctl is-active httpd
unknown

Unitの異常状態の確認(is-failed)

is-failedUnitが正常に起動している場合はactiveが返ります。

$ sudo systemctl is-failed httpd
active

Unitが正常に起動せず異常となっている場合、failedが返ります。

$ sudo mv /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
$ sudo systemctl restart httpd
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
$ sudo systemctl is-failed httpd
failed

Unitの異常状態のリセット(reset-failed)

systemdが認識している異常状態をリセットします。

$ sudo systemctl is-failed httpd
failed
$ sudo systemctl reset-failed httpd
$ sudo systemctl is-failed httpd
unknown

Unitの依存関係の確認(list-dependencies)

そのUnitが依存しているUnitを一覧表示します。

$ sudo systemctl list-dependencies httpd
httpd.service
├─system.slice
└─basic.target
  ├─microcode.service
  ├─rhel-autorelabel-mark.service
  ├─rhel-autorelabel.service
  ├─rhel-configure.service
  ├─rhel-dmesg.service
  ├─rhel-loadmodules.service
  ├─paths.target
  ├─slices.target

さいごに

すっかりSysvinitに慣れ親しんだ身としては、新しい仕組みを覚えるのはなかなかしんどいものがありますが、今後はsystemdが主流になっていくと思いますので、ガシガシ使って慣れていきたいと思います。