はじめに
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サーバーのステータスを確認すると、次のような出力が表示されます。
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は、通常enabled
、disabled
、static
、または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.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
)によって処理されます。これらの他ツールやデーモンに慣れておくと、管理が楽になります。