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

提供:Dev Guides
移動先:案内検索

序章

systemdは、Linuxディストリビューションの新しい標準に広くなっているinitシステムおよびシステムマネージャーです。 systemdは広く採用されているため、サーバーの管理が非常に簡単になるため、問題を解決する価値があります。 systemdが提供するパワー、柔軟性、機能をよりよく理解できるようになります。

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

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

サービス管理

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

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

サービス管理タスクの場合、ターゲットユニットはサービスユニットであり、.serviceのサフィックスが付いたユニットファイルがあります。 ただし、ほとんどのサービス管理コマンドでは、実際には.serviceサフィックスを省略できます。これは、systemdは、サービス管理コマンドを使用するときにサービスを操作する可能性があることを認識できるほど賢いためです。

サービスの開始と停止

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が自動起動ファイルを探すディスク上の場所(通常は[ X189X]。 このガイドの後半で、ターゲットが何であるかについて説明します)。

サービスが自動的に開始されないようにするには、次のように入力します。

sudo systemctl disable application.service

これにより、サービスを自動的に開始する必要があることを示すシンボリックリンクが削除されます。

サービスを有効にしても、現在のセッションではサービスが開始されないことに注意してください。 サービスを開始し、起動時にも有効にする場合は、startコマンドとenableコマンドの両方を発行する必要があります。

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

システム上のサービスのステータスを確認するには、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-unitsコマンドを使用できます。

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

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

  • UNITsystemdユニット名
  • 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

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

systemctl list-units --type=service

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

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

systemctl list-unit-files

単位は、systemdが認識しているリソースの表現です。 systemdは、このビューのすべてのユニット定義を必ずしも読み取っていないため、ファイル自体に関する情報のみを表示します。 出力には、ユニットファイルと状態の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
. . .

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

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

ユニット管理

これまで、サービスを利用して、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

これは、ユニット定義にディレクティブをオーバーライドまたは追加するために使用できる空白のファイルになります。 /etc/systemd/systemディレクトリ内に、.dが追加されたユニットの名前を含むディレクトリが作成されます。 たとえば、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があります。 このプロセスの一部であるユニットは、構成でWantedBy=またはRequiredBy= swap.targetであることを示すことにより、このターゲットと同期できます。 スワップを使用可能にする必要があるユニットは、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

結論

これで、systemctlコマンドの基本的な機能のいくつかに精通しているはずです。これにより、systemdインスタンスを操作および制御できます。 systemctlユーティリティは、サービスおよびシステム状態管理の主要な対話ポイントになります。

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