Table of Contents
URL: https://www.progressiverobot.com/how-to-use-systemctl-to-manage-systemd-services-and-units-ja/
はじめに
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
これにより、サービスの自動起動を示すシンボリックリンクが削除されます。
サービスを有効にしても、接続中のセッションでは起動しないことに注意してください。ブート時にサービスを起動して有効にする場合は、start 、enableの両コマンドを発行します。
サービスのステータスを確認する
システム上のサービスのステータスを確認するには、statusコマンドを使用します。
systemctl status <^>application<^>.service
これにより、サービスの状態、cgroup階層、および最初の数行のログが表示されます。
たとえば、Nginxサーバーのステータスを確認すると、次のような出力が表示されます。
[secondary_label 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がシステム上で現在アクティブにしているすべてのユニットが一覧表示されます。出力は次のようになります。
[secondary_label Output]
UNIT 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
getty@tty1.service 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つの列があります。
[secondary_label Output]
UNIT 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は、通常enabled、disabled、static、またはmaskedになります。このコンテキストでのstaticとは、そのユニットファイルにユニットを有効にするinstallセクションがないことを意味します。 そのため、これらのユニットは有効にできません。通常、これは、ユニットが1回限りのアクションを実行するか、別のユニットの依存関係としてのみ使用され、単独で実行されるものではないことを意味します。
maskの意味については、後で説明します。
ユニット管理
これまで、サービスを操作して、systemdが把握しているユニットとユニットファイルに関する情報を表示してきました。ただし、コマンドをいくつか追加すれば、ユニットに関してもっと具体的な情報が見つかります。
ユニットファイルの表示
systemdがシステムにロードしたユニットファイルを表示するには、catコマンドを使用できます( systemd バージョン209で追加)。たとえば、atdスケジューリングデーモンのユニットファイルを表示するには、次のように入力します。
systemctl cat atd.service
[secondary_label 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
これにより、当該ユニットを起動するために処理すべき依存関係の階層マッピングが表示されます。この文脈では、依存関係には、上位のユニットから要求または必要とされるユニットが含まれます。
[secondary_label Output]
sshd.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
[secondary_label Output]
Id=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
[secondary_label Output]
Conflicts=shutdown.target
ユニットのマスキングとマスキング解除
サービス管理セクションではサービスを停止または無効にする方法を見ましたが、systemdにはユニットを/dev/nullにリンクすることで、自動または手動で*完全に*起動不能としてマークする機能もあります。これはユニットのマスキングと呼ばれ、maskコマンドで実行可能です。
sudo systemctl mask nginx.service
これで、Nginxサービスがマスクされている限り、自動でも手動でも起動できなくなります。
list-unit-filesを確認すると、サービスをマスクして表示するのがわかります。
systemctl list-unit-files
[secondary_label 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
[secondary_label Output]
Failed 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
[secondary_label Output]
multi-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.targetはmulti-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)によって処理されます。これらの他ツールやデーモンに慣れておくと、管理が楽になります。