Systemctlサービスを使用してSystemdサービスとユニットを管理する方法

はじめに

Systemdは、多くのLinuxディストリビューションの 新しい標準となったinitシステム兼システムマネージャーです。積極的に採用されているsystemdは、手間をかけてでも習得する価値があります。サーバー管理もかなり楽になるでしょう。systemdを構成するツールやデーモンについて学習すると、systemdに備わったパワー、柔軟性や機能の理解に役立ちます。少なくとも最小限の労力で仕事をこなすのに役立ちます。

このガイドでは、initシステムを制御する中央管理ツールであるsystemctlコマンドについて説明します。 サービスの管理方法、ステータスの確認方法、システム状態の変更方法、設定ファイルの操作方法を取り上げます。

systemdは多くのLinuxディストリビューションでデフォルトのinitシステムになりましたが、すべてのディストリビューションに共通して実装されたわけではないことに注意してください。このチュートリアルを進める中で、端末でエラーbash: systemctl is not installedが出力される場合、マシンに別のinitシステムがインストールされている可能性があります。

サービス管理

initシステムの基本目的は、Linuxカーネルのブート後に起動させるコンポーネント(従来「ユーザーランド」コンポーネントとして知られる)の初期化です。initシステムは、システム実行中のあらゆる時点でサーバーのサービスとデーモンの管理にも使用されます。  それを念頭に置いて、基本的なサービス管理操作から始めます。

systemdで、ほとんどのアクションのターゲットである「ユニット」は、systemdが管理方法を把握しているリソースです。ユニットは、それらが表すリソースのタイプによって分類され、ユニットファイルと呼ばれるファイルで定義されます。各ユニットのタイプは、ファイルの接尾辞から推測できます。

サービス管理タスクの場合、ターゲットユニットはサービスユニットとなり、ユニットファイルには接尾辞.serviceが付きます。ただし、サービス管理コマンドを使うときはサービスの操作がしたいのだろうとsystemdが賢く判断するので、実際ほとんどのサービス管理コマンドで接尾辞.serviceが省略できます。

サービスの起動と停止

systemdサービスを起動し、サービスのユニットファイル内の命令を実行するには、startコマンドを使用します。root以外のユーザーとして実行している場合、オペレーティングシステムの状態に影響を与えるコマンドなので、sudoを使用する必要があります。

  • sudo systemctl start application.service

前述のように、systemdはサービス管理コマンドの*.serviceファイルを探すと理解しているため、コマンドは次のように簡単に入力できます。

  • sudo systemctl start application

一般的な管理には上記の形式を使用できますが、わかりやすくするために、残りのコマンドに接尾辞.serviceを使用して、操作するターゲットを明示します。

現在実行中のサービスを停止するには、代わりにstopコマンドを使用します。

  • sudo systemctl stop application.service

再起動とリロード

実行中のサービスを再起動するには、restartコマンドを使用します。

  • sudo systemctl restart application.service

当該アプリケーションが(再起動せずに)設定ファイルをリロードできる場合は、reloadコマンドを発行してそのプロセスを開始できます

  • sudo systemctl reload application.service

サービスに設定のリロード機能があるかどうか不明な場合は、reload-or-restartコマンドを発行できます。これにより、リロードが可能であれば、設定が適切にリロードされます。それ以外の場合は、サービスを再起動し、新しい設定が反映されます。

  • sudo systemctl reload-or-restart application.service

サービスの有効化と無効化

上記のコマンドは、接続中のセッションでサービスを起動または停止するのに役立ちます。systemdに、ブート時にサービスを自動的に起動するように指示するには、それらを有効にします。

ブート時にサービスを起動するには、enableコマンドを使用します。

  • sudo systemctl enable application.service

これにより、システムのサービスファイル(通常は/lib/systemd/systemまたは/etc/systemd/system内)のコピーから、systemdがautostartファイルを探すディスク上の場所(通常は/etc/systemd/system/some_target.target.wants)に、シンボリックリンクが作成されます。 ターゲットについてはこのガイドの後半で説明します。

サービスの自動起動を無効にするには、次のように入力します。

  • sudo systemctl disable application.service

これにより、サービスの自動起動を示すシンボリックリンクが削除されます。

サービスを有効にしても、接続中のセッションでは起動しないことに注意してください。ブート時にサービスを起動して有効にする場合は、startenableの両コマンドを発行します。

サービスのステータスを確認する

システム上のサービスのステータスを確認するには、statusコマンドを使用します。

  • systemctl status application.service

これにより、サービスの状態、cgroup階層、および最初の数行のログが表示されます。

たとえば、Nginxサーバーのステータスを確認すると、次のような出力が表示されます。

Output● nginx.service - A high performance web server and a reverse proxy server    Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)    Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago  Main PID: 495 (nginx)    CGroup: /system.slice/nginx.service            ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;            └─496 nginx: worker process Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server... Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server. 

これにより、アプリケーションの現在のステータスの概要と、問題や必要なアクションが示されます。

特定の状態を確認する方法もあります。たとえば、ユニットが現在アクティブ(実行中)かどうかを確認するには、is-activeコマンドを使用します。

  • systemctl is-active application.service

これにより、現在のユニットの状態が返されます。通常はactiveまたはinactiveです。終了コードは、アクティブであれば「0」になり、シェルスクリプト内での結果の解析が簡単になります。

ユニットが有効かどうか確認するには、is-enabledコマンドを使用します。

  • systemctl is-enabled application.service

これにより、サービスがenabledかdisabledかが出力され、コマンドの質問への回答に応じて終了コードが「0」または「1」に再び設定されます。“

3番目に確認することは、ユニットが故障状態にあるかどうかです。これは、当該ユニットの起動に問題があったことを示しています。

  • systemctl is-failed application.service

これは、正常に実行されている場合はactiveを返し、エラーが発生した場合はfailedを返します。ユニットが意図的に停止された場合、unknownまたは inactiveを返すことがあります。終了ステータス「0」は障害が発生したことを示し、終了ステータス「1」はその他のステータスを示します。

システム状態の概要

これまでのコマンドは、単発のサービスを管理するのには役立ちますが、システムの現在の状態を調べるのにはあまり役立ちません。 こうした情報を提供するsystemctlコマンドは多数あります。

現在のユニット一覧

systemdが把握しているすべてのアクティブユニットを一覧表示するには、list-unitコマンドを使用します。

  • systemctl list-units

これにより、systemdがシステム上で現在アクティブにしているすべてのユニットが一覧表示されます。出力は次のようになります。

OutputUNIT                                      LOAD   ACTIVE SUB     DESCRIPTION atd.service                               loaded active running ATD daemon avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack dbus.service                              loaded active running D-Bus System Message Bus dcron.service                             loaded active running Periodic Command Scheduler dkms.service                              loaded active exited  Dynamic Kernel Modules System [email protected]                        loaded active running Getty on tty1 . . . 

出力には次の列があります。

  • UNIT: systemdユニット名
  • LOAD: ユニットの構成がsystemdによって解析されたかどうか。ロードされたユニットの設定はメモリに保持されます。
  • ACTIVE: ユニットがアクティブかどうかに関する状態概要。これは通常、ユニットが正常に起動したかどうかを判断する極めて基本的な方法です。
  • SUB: 低レベルの状態を表し、ユニットに関するより詳細な情報を示します。多くの場合、ユニットのタイプ、状態、および実際のユニットの実行方法によって異なります。
  • DESCRIPTION: ユニットの内容/実行内容の短いテキストによる説明。

list-unitsコマンドはデフォルトでアクティブなユニットのみを表示するため、上記のエントリはすべてLOAD列にloaded、ACTIVE列にactiveと表示されます。この表示は、追加コマンドなしで呼び出された場合の実際のsystemctlのデフォルトの動作です。したがって、引数なしでsystemctlを呼び出した場合も同じ表示になります。

  • systemctl

フラグを追加することで、さまざまな情報を出力するようにsystemctl に指示できます。たとえば、現在アクティブであるかどうかに関係なく、systemd がロードした(またはロードしようとした)ユニットをすべて表示するには、次のように--allフラグを使用します。

  • systemctl list-units --all

これは、システムの現在の状態に関係なく、systemdがロードした、またはロードしようとしたユニットを表示します。実行後に非アクティブになったユニットや、systemdがロードしようとしたもののディスク上で見つからなかったユニットがあるかもしれません。

他に、これらの結果をフィルタリングできるフラグがあります。たとえば、--state=フラグを使用して、表示したいLOAD、ACTIVE、またはSUB状態を示すことができます。systemctlが非アクティブなユニットでも表示するように、--allフラグを保持する必要があります。

  • systemctl list-units --all --state=inactive

他に一般的なフィルターとして、--type= があります。興味のあるタイプのユニットのみを表示するようにsystemctl に指示できます。たとえば、アクティブなサービスユニットのみを表示するには、次を使用できます。

  • systemctl list-units --type=service

すべてのユニットファイルの一覧化

list-unitsコマンドは、systemdが解析してメモリにロードしようとしたユニットのみを表示します。systemdは必要と判断したユニットしか読み込まないめ、必ずしもシステムで利用可能なユニットすべてが表示されるとは限りません。systemdがロードしないものを含め、systemdパス内の利用可能なユニットファイルをすべて表示するには、 list-unit-filesコマンドを使用します。

  • systemctl list-unit-files

ユニットは、systemdが把握するリソースを表します。systemdは必ずしもこのビューですべてのユニット定義を読み取るわけではないため、ファイル自体に関する情報のみを表示します。出力には、unit file(ユニットファイル)とstate(状態)の2つの列があります。

OutputUNIT FILE                                  STATE    proc-sys-fs-binfmt_misc.automount          static   dev-hugepages.mount                        static   dev-mqueue.mount                           static   proc-fs-nfsd.mount                         static   proc-sys-fs-binfmt_misc.mount              static   sys-fs-fuse-connections.mount              static   sys-kernel-config.mount                    static   sys-kernel-debug.mount                     static   tmp.mount                                  static   var-lib-nfs-rpc_pipefs.mount               static   org.cups.cupsd.path                        enabled . . . 

stateは、通常enableddisabledstatic、またはmaskedになります。このコンテキストでのstaticとは、そのユニットファイルにユニットを有効にするinstallセクションがないことを意味します。 そのため、これらのユニットは有効にできません。通常、これは、ユニットが1回限りのアクションを実行するか、別のユニットの依存関係としてのみ使用され、単独で実行されるものではないことを意味します。

maskの意味については、後で説明します。

ユニット管理

これまで、サービスを操作して、systemdが把握しているユニットとユニットファイルに関する情報を表示してきました。ただし、コマンドをいくつか追加すれば、ユニットに関してもっと具体的な情報が見つかります。

ユニットファイルの表示

systemdがシステムにロードしたユニットファイルを表示するには、catコマンドを使用できます( systemd バージョン209で追加)。たとえば、atdスケジューリングデーモンのユニットファイルを表示するには、次のように入力します。

  • systemctl cat atd.service
Output[Unit] Description=ATD daemon [Service] Type=forking ExecStart=/usr/bin/atd [Install] WantedBy=multi-user.target 

出力は、現在実行中のsystemdプロセスにとって既知のユニットファイルです。これは、ユニットファイルを変更したばかりの場合や、ユニットファイルフラグメントの特定オプションをオーバーライドする場合に、重要になります(これについては後で取り上げます)。

依存関係の表示

ユニットの依存関係ツリーを表示するには、list-dependenciesコマンドを使用します。

  • systemctl list-dependencies sshd.service

これにより、当該ユニットを起動するために処理すべき依存関係の階層マッピングが表示されます。この文脈では、依存関係には、上位のユニットから要求または必要とされるユニットが含まれます。

Outputsshd.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 . . . 

再帰的依存関係は、システムの状態を示す.targetユニットについてのみ表示されます。すべての再帰的依存関係を一覧表示するには、--allフラグを付けます。

逆依存関係(指定されたユニットに依存するユニット)を表示するには、コマンドに--reverseフラグを付けします。他に便利なフラグとして、--before--afterフラグがあります。これらのフラグはそれぞれ、指定したユニットより後続起動するユニット、先行起動するユニットを表示します。

ユニットプロパティの確認

ユニットの低レベルのプロパティを表示するには、showコマンドを使用します。これは、key=value形式を使用して、指定したユニットのプロパティ一覧を表示します。

  • systemctl show sshd.service
OutputId=sshd.service Names=sshd.service Requires=basic.target Wants=system.slice WantedBy=multi-user.target Conflicts=shutdown.target Before=shutdown.target multi-user.target After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice Description=OpenSSH server daemon . . . 

特定のプロパティだけを表示したい場合、プロパティ名とともに-pフラグを渡します。たとえば、sshd.serviceユニットにある競合を確認するには、次のように入力します。 

  • systemctl show sshd.service -p Conflicts
OutputConflicts=shutdown.target 

ユニットのマスキングとマスキング解除

サービス管理セクションではサービスを停止または無効にする方法を見ましたが、systemdにはユニットを/dev/nullにリンクすることで、自動または手動で完全に起動不能としてマークする機能もあります。これはユニットのマスキングと呼ばれ、maskコマンドで実行可能です。

  • sudo systemctl mask nginx.service

これで、Nginxサービスがマスクされている限り、自動でも手動でも起動できなくなります。

list-unit-filesを確認すると、サービスをマスクして表示するのがわかります。

  • systemctl list-unit-files
Output. . . kmod-static-nodes.service              static   ldconfig.service                       static   mandb.service                          static   messagebus.service                     static   nginx.service                          masked quotaon.service                        static   rc-local.service                       static   rdisc.service                          disabled rescue.service                         static . . . 

サービスを起動しようとすると、次のようなメッセージが表示されます。

  • sudo systemctl start nginx.service
OutputFailed to start nginx.service: Unit nginx.service is masked. 

ユニットのマスクを解除し、再び使用できるようにするには、unmaskコマンドを使用します。

  • sudo systemctl unmask nginx.service

これにより、ユニットが以前の状態に戻り、起動または有効化できるようになります。

ユニットファイルの編集

ユニットファイルの特定の形式についてはこのチュートリアルの範囲外ですが、systemctlには、調整が必要な場合にユニットファイルを編集・変更する組み込み機能があります。 この機能は、systemdバージョン218で追加されました。

editコマンドはデフォルトで、当該ユニットのユニットファイルスペニットを開きます。

  • sudo systemctl edit nginx.service

これは、ユニット定義にディレクティブをオーバーライドまたは追加するのに使用する空のファイルです。ユニット名に.dが追加されたディレクトリが、/etc/systemd/systemディレクトリ内に作成されます。たとえば、nginx.serviceの場合、nginx.service.dというディレクトリが作成されます。

このディレクトリ内に、override.conf というスニペットが作成されます。ユニットがロードされると、systemdはメモリ内でオーバーライドスニペットを完全なユニットファイルとマージします。スニペットのディレクティブは、元のユニットファイルにあるディレクティブよりも優先されます。

スニペットを作成せずに完全なユニットファイルを編集する場合は、--fullフラグを渡します。

  • sudo systemctl edit --full nginx.service

これにより、現在のユニットファイルがエディターにロードされ、そこで変更できます。エディターを終了すると、変更したファイルは/etc/systemd/systemに書き込まれ、システムのユニット定義(通常/lib/systemd/system内のどこかにあります)より優先されます。

加えた変更を削除するには、ユニットの.d設定ディレクトリまたは変更されたサービスファイルを/etc/systemd/systemから削除します。たとえば、スニペットを削除するには、次のように入力します。

  • sudo rm -r /etc/systemd/system/nginx.service.d

変更したユニットファイルを完全に削除するには、次のように入力します。

  • sudo rm /etc/systemd/system/nginx.service

ファイルまたはディレクトリの削除後、systemdプロセスをリロードして、削除したファイルが再び参照されないように、また元のシステムコピーが使用されるようにします。これを行うには、次のように入力します。

  • sudo systemctl daemon-reload

ターゲットを使用したシステム状態(ランレベル)の調整

ターゲットは、システム状態や同期ポイントを記述する特別なユニットファイルです。他のユニットと同様に、ターゲットを定義するファイルは、接尾辞(この場合は.target)で識別できます。ターゲットはそれ自体あまり機能せず、他のユニットのグループ化に使用されます。

これは、他のinitシステムがランレベルを使用するように、システムを一定の状態にするために使用します。 ターゲットは利用可能な特定の機能の参照先として使用されます。その状態にしたい個々のユニットを指定するのではなく、目的の状態を指定できます。

たとえば、スワップの使用準備ができていることを示す swap.targetがあります。このプロセスの一部であるユニットは、swap.targetから必要とされる(WantedBy=)または要求される(RequiredBy=)設定であることを示して、このターゲットと同期できます。スワップの使用を必要とするユニットは、Wants=Requires=、およびAfter=によりこの条件を指定して、関係性を示します。

デフォルトターゲットの取得と設定

systemdプロセスには、システム起動時に使用するデフォルトのターゲットがあります。その特定のターゲットが依存関係のカスケードを満たせば、システムは望ましい状態になります。システムのデフォルトターゲットを見つけるには、次のように入力します。

  • systemctl get-default
Outputmulti-user.target 

別のデフォルトターゲットを設定する場合は、set-defaultを使用します。たとえば、グラフィカルデスクトップがインストールされていて、システムをデフォルトで起動したい場合は、それに応じてデフォルトターゲットを変更できます。

  • sudo systemctl set-default graphical.target

利用可能なターゲットの一覧表示

システムで使用可能なターゲットの一覧を表示するには、次のように入力します。

  • systemctl list-unit-files --type=target

ランレベルとは異なり、複数のターゲットを一度にアクティブにできます。アクティブなターゲットは、systemd がターゲットに紐付いたすべてのユニットの起動を試み、紐付けを解除しようとはしていないことを示します。アクティブなターゲットをすべて表示するには、次を入力します。

  • systemctl list-units --type=target

ターゲットの分離

ターゲットに関連付けられているユニットをすべて起動し、依存関係ツリーに含まれないユニットをすべて停止することができます。 これを行うコマンドの正式な呼称をisolateといいます。 これは、他のinitシステムでランレベルを変更するのと似ています。

たとえば、graphical.targetがアクティブなグラフィカル環境で動作している場合、multi-user.targetを分離することにより、グラフィカルシステムをシャットダウンし、システムをマルチユーザー・コマンドラインモードにすることができます。graphical.targetmulti-user.targetに依存しますが、その逆ではないため、すべてのグラフィックユニットが停止します。

この手順を実行する前に、重要なサービスを停止しないように、分離するターゲットの依存関係を確認することをお勧めします。

  • systemctl list-dependencies multi-user.target

ユニットが停止しないことを確認できたら、次のように入力してターゲットを分離します。

  • sudo systemctl isolate multi-user.target

重要なイベントにショートカットを使用する

電源オフや再起動などの重要なイベントのために定義されたターゲットがあります。ただし、systemctlには、便利なショートカットを追加するショートカットもあります。‏

たとえば、システムをレスキュー(シングルユーザー)モードにするには、isolate rescue.targetの代わりにrescueコマンドを使用できます。

  • sudo systemctl rescue

これにより、ログインしているすべてのユーザーにイベントに関するアラートを表示する追加機能が提供されます。

システムを停止するには、haltコマンドを使用できます。

  • sudo systemctl halt

完全にシャットダウンするには、poweroffコマンドを使用できます。

  • sudo systemctl poweroff

再起動するにはrebootコマンドを使用できます。

  • sudo systemctl reboot

これらすべてのコマンドは、ログイン中のユーザーにイベント発生をアラートします。これはただターゲットを実行または隔離するだけでは行われないことです。ほとんどのマシンでは、systemdで適切に動作するように、より短く一般的なコマンドがこうした操作にリンクされていることに注意してください。

たとえば、システムを再起動するには、通常次のように入力します。

  • sudo reboot

まとめ

ここまでで、systemdインスタンスとやり取りして制御するsystemctlコマンドの基本機能がいくつか理解できたはずです。systemctlユーティリティは、サービスとシステムの状態管理のやり取りの要になります。

systemctlは主にコアのsystemdプロセスで動作しますが、他のユーティリティによって制御されるsystemdエコシステムには他のコンポーネントがあります。 ログ管理やユーザーセッションなど他の機能は、個別のデーモンと管理ユーティリティ(それぞれ journald/ journalctlおよびlogind/loginctl)によって処理されます。これらの他ツールやデーモンに慣れておくと、管理が楽になります。