「Systemd」の版間の差分
(→ユニットを使う: 翻訳を更新) |
(→電源管理: 情報を更新) |
||
146行目: | 146行目: | ||
=== 電源管理 === |
=== 電源管理 === |
||
+ | 非特権ユーザーでの電源管理には、[[polkit]] が必要です。ローカルの ''systemd-logind'' ユーザーセッションで、他のセッションがアクティブでない場合、以下のコマンドは root 権限がなくても動作します。そうでない場合(例えば、他のユーザーが tty にログインしているなど)、''systemd'' は自動的に root パスワードを要求します。 |
||
− | 電源管理には {{ic|polkit}} が必要です。 |
||
− | ローカルの {{ic|systemd-logind}} のユーザーセッション中で、他のセッションがアクティブでなければ、ルート権限なしで以下のコマンドが使えます。そうでなければ (他のユーザが tty でログインしている場合など)、systemd は自動的に root のパスワードを要求するでしょう。 |
||
+ | {| class="wikitable" |
||
− | 再起動: |
||
+ | ! アクション|コマンド |
||
− | |||
+ | |- |
||
− | $ systemctl reboot |
||
+ | | システムをシャットダウンして再起動する || {{ic|systemctl reboot}} |
||
− | |||
+ | |- |
||
− | シャットダウンしてパワーオフ: |
||
+ | | システムをシャットダウンして電源を切る || {{ic|systemctl poweroff}} |
||
− | |||
+ | |- |
||
− | $ systemctl poweroff |
||
+ | | システムを一時停止する || {{ic|systemctl suspend}} |
||
− | |||
+ | |- |
||
− | サスペンド(待機): |
||
+ | | システムをハイバネーションにする || {{ic|systemctl hibernate}} |
||
− | |||
+ | |- |
||
− | $ systemctl suspend |
||
+ | | システムをハイブリッドスリープ状態にする (または suspend-to-both) にする || {{ic|systemctl hybrid-sleep}} |
||
− | |||
+ | |- |
||
− | ハイバネート(休止): |
||
+ | |} |
||
− | |||
− | $ systemctl hibernate |
||
− | |||
− | ハイブリッドスリープ (もしくは suspend-to-both): |
||
− | |||
− | $ systemctl hybrid-sleep |
||
== ユニットファイル == |
== ユニットファイル == |
2022年3月3日 (木) 17:22時点における版
関連記事
プロジェクトウェブページ より:
- systemd は Linux 環境の基本構成スイートであり、SysV や LSB init スクリプトと互換性のある、Linux 用のシステム・サービスマネージャです。systemd はサービスの起動を積極的に並行化します。また、ソケットや D-Bus のアクティベーションを使用してサービスを起動し、必要なデーモンの開始を行うことができ、Linux の cgroups によるプロセス管理ができます。システム状態のスナップショット作成と復元、(自動) マウントポイントの管理、煩雑な依存関係に基づいたサービスのコントロールを処理します。systemd は sysvinit の代替として SysV や LSB init スクリプトをサポートしています。init としての機能以外にも、ログデーモンやホストネーム・時刻・ロケールなどシステムの基本設定を制御するユーティリティ、ログイン中のユーザーから実行中のコンテナや仮想マシン、システムアカウントまで管理する機能、ネットワーク設定や時刻同期あるいは名前解決などを管理するシンプルなデーモンも含まれています。
systemctl の基本的な使い方
systemd を管理したり内部情報を見るために使うメインのコマンドが systemctl
です。システムの状態を確かめたりシステムやサービスを管理するために使うのは使い方の一部です。詳しくは systemctl(1) を見て下さい。
システムの状態を分析する
システムの状態を表示:
$ systemctl status
実行中のユニットを一覧する:
$ systemctl
または:
$ systemctl list-units
失敗したユニットを一覧する:
$ systemctl --failed
実行可能なユニットファイルは /usr/lib/systemd/system/
や /etc/systemd/system/
にあります (後者が優先的に使われます)。インストールされたユニットを一覧するには:
$ systemctl list-unit-files
ユニットを使う
ユニットには、例えば、サービス (.service
) やマウントポイント (.mount
)、デバイス (.device
)、ソケット (.socket
) などがあります。
systemctl
を使うとき、一般的には拡張子 (suffix) を含むユニットファイルの完全な名前を指定する必要があります。例えば、sshd.socket
のように。しかし、以下のような場合には省略形が存在します:
- 拡張子が指定されない場合、systemctl は
.service
とみなします。例えばnetctl
とnetctl.service
は同じように扱われます。 - マウントポイントは自動的に対応する
.mount
ユニットとして扱われます。例えば、/home
を指定することはhome.mount
の指定と同じです。 - マウントポイントと同じく、デバイスも自動的に対応する
.device
ユニットとして扱われます。従って、/dev/sda2
の指定はdev-sda2.device
と同じです。
詳細は systemd.unit(5) を見てください。
以下の表のコマンドは、systemctl の暗黙のデフォルトである --system
から、system unit' を操作するものです。代わりに、ユーザー単位 で操作するには、root 権限なしで systemctl --user を使ってください。全てのユーザーに対してユーザーユニットを有効・無効にするには systemd/ユーザー#基本設定 も見て下さい。
アクション | コマンド | 注意 |
---|---|---|
システム状態の分析 | ||
システムステータスを表示する | systemctl status |
|
実行中のユニット リスト | systemctl orsystemctl list-units |
|
失敗したユニット 一覧 | systemctl --failed |
|
インストールされているユニット 一覧1 | systemctl list-unit-files |
|
PID のプロセスステータス を表示 | systemctl status pid |
cgroup slice, メモリ と 上位プロセス |
ユニットの状態を確認する | ||
ユニットに関連付けられている マニュアルページを表示する | systemctl help unit |
ユニットでサポートされています |
ユニットの ステータス | systemctl status unit |
実行されているかどうかを含む |
ユニットが有効かどうかを チェック する | systemctl is-enabled unit |
|
本体の起動、再起動、再読み込み | ||
ユニットを即座に スタート する | systemctl start unit as root |
|
ユニットを即座に ストップ する | systemctl stop unit as root |
|
ユニットを 再起動 する | systemctl restart unit as root |
|
ユニットとその設定を 再読み込み する | systemctl reload unit as root |
|
systemd マネージャーの再読み込み 設定2 | systemctl daemon-reload as root |
ユニットスキャン |
ユニットの有効化 | ||
ブート時に自動的に起動するユニットを 有効 にする | systemctl enable unit as root |
|
起動時に自動起動するユニットを 有効 にして、すぐに 起動 する | systemctl enable --now unit as root |
|
無効 にすると、ブート時に起動しなくなります | systemctl disable unit as root |
|
ユニット3を 再有効化 する | systemctl reenable unit as root |
つまり、無効化して新たに有効化する |
ユニットのマスキング | ||
mask して起動不能にするユニット4 | systemctl mask unit as root |
|
unmask ユニット | systemctl unmask unit as root |
- 利用可能なユニットファイルがあるディレクトリは systemd.unit(5) § UNIT FILE LOAD PATH を参照してください。
- これは変更されたユニットに設定の再読み込みを要求しません (アクション Reload を参照して下さい)。
- 例えば、最後に有効化してからその
[インストール]
セクションが変更された場合。 - 手動でも依存関係としても、マスクは危険です。既存のマスクされたユニットをチェックします。
# systemctl list-unit-files --state=masked
電源管理
非特権ユーザーでの電源管理には、polkit が必要です。ローカルの systemd-logind ユーザーセッションで、他のセッションがアクティブでない場合、以下のコマンドは root 権限がなくても動作します。そうでない場合(例えば、他のユーザーが tty にログインしているなど)、systemd は自動的に root パスワードを要求します。
コマンド | |
---|---|
システムをシャットダウンして再起動する | systemctl reboot
|
システムをシャットダウンして電源を切る | systemctl poweroff
|
システムを一時停止する | systemctl suspend
|
システムをハイバネーションにする | systemctl hibernate
|
システムをハイブリッドスリープ状態にする (または suspend-to-both) にする | systemctl hybrid-sleep
|
ユニットファイル
systemd の ユニットファイル の構文は XDG の Desktop Entry Specification である .desktop から影響を受けています。そして .desktop は Microsoft Windows の .ini ファイルからインスパイアされています。ユニットファイルは複数の場所に配置されます (配置場所のリストを確認するには systemctl show --property=UnitPath
を実行してください)。優先度が低い方から説明すると:
/usr/lib/systemd/system/
: インストールしたパッケージに含まれているユニット/etc/systemd/system/
: システムの管理者がインストールしたユニット
依存関係を解決する
systemd ではユニットファイルを適切に書くことで依存関係を解決します。一番典型的なケースは、ユニット A
が走る前に、ユニット A
がユニット B
を必要としている場合です。この場合、A
の [Unit]
セクションに Requires=B
と After=B
を加えます。依存が必然ではない場合、代わりに Wants=B
と After=B
を加えます。Wants=
と Requires=
は After=
を含まないことに注意してください、もし After=
を明記しなかったときは、2つのユニットは並行して実行されます。
基本的に、依存関係はターゲットではなくサービスに記述します。例えば、network.target
はネットワークインターフェースを設定する全てのサービスによって使われるので、カスタムユニットを起動させる順番は network.target
が起動し終わってからにする必要があります。
タイプ
カスタムサービスファイルを書くときにどのスタートアップタイプを使うべきか考える必要があります。タイプは [Service]
セクションの Type=
パラメータで設定します。より詳しい説明は systemd.service(5) を見て下さい。
Type=simple
(デフォルト): systemd はプロセスを起動した時点でサービスが立ち上がったとみなします。プロセスをフォークすることはできません。ソケットアクティベーション以外で他のサービスが必要な場合に、このタイプを使ってはいけません。Type=forking
: 起動したプロセスが一旦フォークし、親プロセス側が終了したときに、 systemd はサービスが立ち上がったとみなします。このタイプでなくてもかまわないとき以外は、古典的なデーモンにはこのタイプを使って下さい。またPIDFile=
を指定することで systemd はメインプロセスの情報を追い続けます。Type=oneshot
: シングルジョブを行い終了するスクリプト用のタイプです。またRemainAfterExit=yes
を設定することで systemd はプロセスが終了した後もサービスがアクティブだとみなします。Type=notify
:Type=simple
と同じですが、利用可能になったときにデーモンが systemd に信号を送るように条件がつけられます。この通知のリファレンス実装はlibsystemd-daemon.so
によって提供されています。Type=dbus
: 指定のBusName
が DBus のシステムバスに乗ったときに使うことができるサービス。Type=idle
: idle の挙動はType=simple
と非常に似ています。ただし、サービスバイナリの実行は全てのジョブが処理されるまで待たされます。これを使えば、コンソールに状態を出力するシェルサービスで、出力が混じってしまうのを避けることができます。
ユニットファイルの編集
パッケージに入っているユニットファイルを編集する方法は2つあります: 新しいユニットファイルで完全に置き換えるか、ドロップインファイルを作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。systemctl edit
でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:
# systemctl daemon-reload
ユニットファイルを置換する
ユニットファイル /usr/lib/systemd/system/unit
を置き換えたいときは、/etc/systemd/system/unit
ファイルを作成してユニットを再有効することでシンボリックリンクをアップデートします:
# systemctl reenable unit
もしくは、次を実行:
# systemctl edit --full unit
このコマンドはテキストエディタで /etc/systemd/system/unit
を開いて (ファイルが存在しない場合はインストールされているユニットがコピーされます)、編集を終えた時に自動的にユニットをリロードします。
ドロップインファイル
ユニットファイル /usr/lib/systemd/system/unit
のドロップインファイルを作成するには、/etc/systemd/system/unit.d/
という名のディレクトリ (例: /etc/systemd/system/httpd.service.d/
) を作成してその中に *.conf
を配置します。このファイルを使ってオプションを上書きしたり追加してください。systemd が *.conf
ファイルをパースして元のユニットファイルの一番上に設定を適用します。
ドロップインファイルを作成する一番簡単な方法は次のコマンドを実行することです:
# systemctl edit unit
テキストエディタで /etc/systemd/system/unit.d/override.conf
ファイルが開かれ (必要であればファイルが作成されます)、編集を終えた時に自動でユニットがリロードされます。
初期状態にリバート
systemctl edit
を使って変更したユニットを元に戻したい場合、以下のコマンドを実行:
# systemctl revert unit
サンプル
例えば、ユニットに依存するデーモンを追加したい場合、以下のファイルを作成することができます:
/etc/systemd/system/<unit>.d/customdependency.conf
[Unit] Requires=<new dependency> After=<new dependency>
oneshot
タイプでないユニットの ExecStart
ディレクティブを置き換えるには、以下のファイルを作成します:
/etc/systemd/system/unit.d/customexec.conf
[Service] ExecStart= ExecStart=new command
サービスが自動的に再起動されるようにするには:
/etc/systemd/system/unit.d/restart.conf
[Service] Restart=always RestartSec=30
ターゲット
Systemd ではランレベルに似たものとしてターゲットを使っています。ただしその挙動には少し違いがあります。それぞれのターゲットはナンバリングされる代わりに名前がつけられ、ある特定の目的のために作られ、複数のターゲットを同時に有効にできるようになっています。ターゲットによっては、他のターゲットのサービスを全て引継ぎ、そこにサービスを追加するよう実装されています。一般的な SystemVinit ランレベルに擬態する systemd ターゲットもあり、親しみのある telinit RUNLEVEL
コマンドを使って使用するターゲットを切り替えることが可能です。
現在のターゲットを獲得
systemd では runlevel
の代わりに次のコマンドが使われます:
$ systemctl list-units --type=target
カスタムターゲットを作る
標準の Fedora インストールではランレベルごとに特定の目的が設定されています; 0, 1, 3, 5, 6 のランレベルには特定の sytemd ターゲットと一対一の対応関係が存在します。残念ながら、ユーザー定義のランレベル (2 や 4 など) で同じことをする良い方法はありません。もしあなたがそうしたいならば、既に存在しているランレベルをベースに新しい systemd ターゲットを /etc/systemd/system/<your target>
として作り (/usr/lib/systemd/system/graphical.target
がサンプルになるかもしれません)、/etc/systemd/system/<your target>.wants
ディレクトリを作って、有効にしたいサービスに /usr/lib/systemd/system/
からシンボリックリンクを貼ることが示唆されています。
SysV ランレベルと systemd ターゲットの対応表
SysV ランレベル | systemd ターゲット | 説明 |
---|---|---|
0 | runlevel0.target, poweroff.target | システムを停止。 |
1, s, single | runlevel1.target, rescue.target | シングルユーザーモード。 |
2, 4 | runlevel2.target, runlevel4.target, multi-user.target | ユーザー定義・サイト指定ランレベル。デフォルトでは、3 と同一。 |
3 | runlevel3.target, multi-user.target | マルチユーザー、非グラフィカル。一般的にマルチコンソールやネットワークを介してログインするのに使われます。 |
5 | runlevel5.target, graphical.target | マルチユーザー、グラフィカル。通常、ランレベル 3 の全てのサービスにグラフィカルログインを付加。 |
6 | runlevel6.target, reboot.target | 再起動 |
emergency | emergency.target | 緊急シェル |
現在のターゲットを変更する
systemd ではターゲットは"ターゲットユニット"を通して扱うことができます。ターゲットを変えるには次のようにします:
# systemctl isolate graphical.target
これは現在のターゲットを変えるだけで、次の起動時には影響がありません。SysVinit での、telinit 3
や telinit 5
のようなコマンドと同じです。
起動するデフォルトターゲットを変更
標準のターゲットは default.target
で、これは graphical.target
へのシンボリックリンクです。これは、古いランレベル5にほぼ対応します。
systemctl を使用して現在のターゲットを確認するには、次の手順に従います。
$ systemctl get-default
ブート先のデフォルトターゲットを変更するには、default.target
シンボリックリンクを変更します。systemctl の場合
# systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target. Created symlink /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target.
または、次の カーネルパラメータ のいずれかをブートローダに追加します。
systemd.unit=multi-user.target
(これは、古いランレベル3にほぼ対応しています)systemd.unit=rescue.target
(これは、古いランレベル1にほぼ対応しています)
デフォルトのターゲット順序
systemd は、次の順序に従って default.target
を選択します。
- 上記のカーネルパラメータ
/etc/systemd/system/default.target
への Symlink/usr/lib/systemd/system/default.target
への Symlink
systemd の構成要素
systemd のコンポーネントをいくつか(網羅的ではない)紹介します。
- systemd-boot - シンプルな UEFI boot manager です。
- systemd-firstboot - 最初のブートの前に基本的なシステム設定を初期化します。
- systemd-homed - ポータブル human-user accounts です。
- systemd-logind(8) - セッション管理
- systemd-networkd - ネットワーク設定 管理。
- systemd-nspawn - 軽量なネームスペースコンテナ。
- systemd-resolved - ネットワークの 名前解決
- systemd-sysusers(8) - パッケージのインストール時または起動時に、システムユーザーとグループを作成し、ユーザーをグループに追加します。
- systemd-timesyncd - ネットワーク上で システム時刻 を同期します。
- systemd/ジャーナル - システムのログを記録します。
- systemd/タイマー - ファイルやイベントを制御するための単調またはリアルタイムのタイマー .service cron の代替。
- systemd-stub(7) - [Unified カーネルイメージ] を作成するために使用される UEFI ブートスタブです。
systemd.mount - マウンティング
systemd は /etc/fstab
で指定されたパーティションとファイルシステムのマウントを担当します。systemd-fstab-generator(8) は /etc/fstab
の全てのエントリを systemd 単位に変換します; これは起動時とシステムマネージャの設定が再ロードされた時に実行されます。
systemd は通常の fstab 機能を拡張し、追加のマウントオプションを提供します。これらのオプションはマウントユニットの依存関係に影響を与えます。例えば、ネットワークが立ち上がった時だけマウントするようにしたり、他のパーティションがマウントされた時だけマウントするようにすることができます。特定の systemd マウントオプションの完全なリストは、通常 x-systemd.
で始まり、 systemd.mount(5) § FSTAB で詳細に説明されています。
これらのマウントオプションの例として、自動マウントがあります。これは、ブート時に自動的にマウントするのではなく、リソースが必要な時にだけマウントすることを意味します。これは fstab#Automount with systemd で提供されています。
GPT パーティションの自動マウント
UEFI で起動したシステムでは、特定の条件が満たされると systemd-gpt-auto-generator(8) は Discoverable Partitions Specification に従って GPT パーティションを自動マウントし、fstab から省略することができるようになります。
前提条件は以下の通りです。
- ブートローダは LoaderDevicePartUUID EFI 変数を設定し、使用する EFI システムパーティションが特定できるようにする必要があります。これは systemd-boot, systemd-stub(7) と rEFInd (not enabled by default) でサポートされています。これは
bootctl
を実行してBoot loader sets ESP information
の状態をチェックすることによって確認できます。 - ルートパーティションは、使用する EFI システムパーティションと同じ物理ディスク上になければなりません。オートマウントされる他のパーティションは、ルートパーティションと同じ物理ディスク上になければなりません。これは基本的に、オートマウントされる全てのパーティションは ESP と同じ物理ディスクを共有していなければならないことを意味します。
/var
/var
の自動マウントが動作するためには、PARTUUID がパーティションタイプの UUID (4d21b016-b534-45c2-a9fb-5c16e091fd2d
) の SHA256 HMAC ハッシュにマシン ID でキーを付けたものと一致している必要があります。必要な PARTUUID は、以下の方法で取得できます。
$ systemd-id128 -u --app-specific=4d21b016-b534-45c2-a9fb-5c16e091fd2d machine-id
systemd-sysvcompat
systemd-sysvcompat の主な役割は以下の通りです。(base で必要) は伝統的な linux init バイナリを提供することです。systemd -controlled systems では、init
はその systemd
実行ファイルへのシンボリックリンクに過ぎません。
さらに、SysVinit のユーザーが慣れ親しんでいるであろう4つの便利なショートカットも提供されています。便利なショートカットは halt(8), poweroff(8), reboot(8), shutdown(8) です。これら4つのコマンドはそれぞれ systemctl
へのシンボリックリンクであり、systemd の動作に支配されます。そのため、#電源管理 での議論が適用されます。
systemd ベースのシステムは init=
を使うことでこれらの System V 互換の方法を諦めることができます。boot parameter (例えば、/bin/init is in systemd-sysvcompat ?) と systemd ネイティブ systemctl
コマンド引数を見てください。
systemd-tmpfiles - 一時ファイル
systemd-tmpfiles は揮発性ファイルや一時ファイル、ディレクトリの作成、削除、クリーンアップを行います。systemd-tmpfiles は /etc/tmpfiles.d/
と /usr/lib/tmpfiles.d/
にある設定ファイルを読んで、実行するアクションを決めます。前者のディレクトリにある設定ファイルは後者のディレクトリにある設定ファイルより優先されます。
設定ファイルは通常サービスファイルと一緒に提供され、/usr/lib/tmpfiles.d/program.conf
というスタイルで命名されます。例えば、Samba デーモンはディレクトリ /run/samba
が存在し、正しいパーミッションを持っていることを期待します。そのため、samba パッケージはこの設定で出荷されます。
/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root
設定ファイルは、起動時に特定のファイルに値を書き込むために使用することもできます。例えば、/etc/rc.local
で USB デバイスからの wakeup を無効にするために echo USBE > /proc/acpi/wakeup
を使った場合、代わりに以下の tmpfile を使用することができます。
/etc/tmpfiles.d/disable-usb-wake.conf
# Path Mode UID GID Age Argument w /proc/acpi/wakeup - - - - USBE
詳しくは systemd-tmpfiles(8) および tmpfiles.d(5) のマニュアルページを参照してください。
ヒントとテクニック
GUI 設定ツール
- systemadm — systemd ユニット用のグラフィカルブラウザ。ユニットのリストを表示することができ、タイプでフィルタリングすることもできます。
- SystemdGenie — systemd KDE 技術に基づく管理ユーティリティ。
ネットワークが稼働した後にサービスを実行する
ネットワークが立ち上がった後までサービスを遅らせるには、以下の依存関係を .service ファイルに含めます。
/etc/systemd/system/foo.service
[Unit] ... Wants=network-online.target After=network-online.target ...
ネットワークを管理する特定のアプリケーションのネットワーク待ち受けサービスも有効にして、network-online.target
がネットワークの状態を適切に反映するようにする必要があります。
- NetworkManager を利用している場合、
NetworkManager-wait-online.service
も一緒に有効になっています。systemctl is-enabled NetworkManager-wait-online.service
で確認してください。有効になっていない場合は、再有効化を実行してください。NetworkManager.service
です。 - netctl の場合、
netctl-wait-online.service
を 有効化 して下さい。 - systemd-networkd を利用している場合,
systemd-networkd-wait-online.service
と共に有効にします.systemctl is-enabled systemd-networkd-wait-online.service
でこの状態にあるかどうか確認してください。有効になっていない場合は、再有効化 をしてください。systemd-networkd.service
です。
より詳しい説明は freedesktop.org の systemd wiki にある Running services after the network is up をご覧ください。
サービスが DNS クエリを実行する必要がある場合、追加で nss-lookup.target
の後に命令する必要があります。
/etc/systemd/system/foo.service
[Unit] ... Wants=network-online.target After=network-online.target nss-lookup.target ...
systemd.special(7) § Special Passive System Units を参照してください。
Wants=nss-lookup.target
が効果を発揮するためには、 Before=nss-lookup.target
でその前に自分自身を命令するサービスが必要です。通常、これはローカルの DNSリゾルバ によって行われます。
もしあれば、どのアクティブなサービスが nss-lookup.target
で引っ張っているのかを確認してください。
$ systemctl list-dependencies --reverse nss-lookup.target
インストールされたユニットをデフォルトで有効にする
Arch Linux の /usr/lib/systemd/system-preset/99-default.preset
には disable *
と記述されています。systemctl プリセットがデフォルトで全てのユニットを無効化するようになり、新しいパッケージがインストールされたときも、ユーザーが手動でユニットを有効化する必要があります。
自動的に有効化させたい場合、/etc/systemd/system-preset/99-default.preset
から /dev/null
にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが有効化されるようになります。詳しくは systemd.preset(5) の man ページを参照。
アプリケーション環境のサンドボックス化
ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。systemd は名前空間やケイパビリティのホワイトリスト・ブラックリスト、Cgroups を活用して 実行環境を設定 しプロセスをコンテナ化します。
既存の systemd ユニットファイルを使ってアプリケーションをサンドボックス化するには strace, stderr, journalctl などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。
CapabilityBoundingSet
では許可されるケイパビリティのホワイトリストを定義できますが、特定のケイパビリティをブラックリストに追加する用途で使うこともできます。例: CapabilityBoundingSet=~ CAP_SYS_ADMIN
。
サービスの失敗を通知する
サービス障害を通知するためには、OnFailure=
ディレクティブを、例えば ドロップイン設定ファイル を使用して、該当するサービスファイルに追加する必要があります。このディレクティブを各サービスユニットに追加するには、トップレベルのドロップイン設定ファイルを使用します。トップレベルのドロップインについて詳しくは systemd.unit(5) を参照してください。
サービス用のトップレベルのドロップインを作成します。
/etc/systemd/system/service.d/toplevel-override.conf
[Unit] OnFailure=failure-notification@%n
これにより、すべてのサービスファイルに OnFailure=failure-notification@%n
が追加されます。some_service_unit が失敗すると、failure-notification@some_service_unit
が開始されて通知(または実行するよう設定された任意のタスク)を処理するようになります。
テンプレートユニット failure-notification@
を作成します。
/etc/systemd/system/failure-notification@.service
[Unit] Description=Send a notification about a failed systemd unit After=network.target [Service] Type=simple ExecStart=/path/to/failure-notification.sh %i
failure-notification.sh
スクリプトを作成し、何をするか、どのように通知するか(メール、gotify、xmpp など)を定義します。%i
は失敗したサービスユニットの名前で、スクリプトの引数として渡されます。
起動に失敗した場合に、何度も failure-notification@.service
のインスタンスを起動する再帰を防ぐために、トップレベルのドロップインと同じ名前の空のドロップイン設定ファイルを作成します(空のサービスレベルのドロップイン設定ファイルはトップレベルのドロップインより優先され、後者をオーバーライドします。)
# mkdir -p /etc/systemd/system/failure-notification@.service.d # touch /etc/systemd/system/failure-notification@.service.d/toplevel-override.conf
トラブルシューティング
systemd のエラーを調査する
例えば、systemd-modules-load
サービスのエラーを調べるとします:
1. 起動に失敗している systemd サービスを探しましょう:
$ systemctl --state=failed
systemd-modules-load.service loaded failed failed Load Kernel Modules
もしくは systemd のライブログメッセージを確認します:
$ journalctl -fp err
2. Ok, systemd-modules-load
サービスに問題が発生していることがわかりました。詳しく見てみましょう:
$ systemctl status systemd-modules-load
systemd-modules-load.service - Load Kernel Modules Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static) Active: failed (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago Docs: man:systemd-modules-load.service(8). man:modules-load.d(5) Process: 15630 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)
Process ID
が載っていない場合は、systemctl restart systemd-modules-load
で失敗したサービスを再実行してください。
3. エラーを細かく調べるためのプロセス ID (PID) を入手しました。Process ID
を使って (ここでは: 15630) 以下のコマンドを実行してください:
$ journalctl _PID=15630
-- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. -- Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'blacklist usblp' Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'install usblp /bin/false'
4. カーネルモジュールに間違った設定がなされているようです。よって /etc/modules-load.d/
下の設定を見てみましょう:
$ ls -Al /etc/modules-load.d/
... -rw-r--r-- 1 root root 79 1. Dez 2012 blacklist.conf -rw-r--r-- 1 root root 1 2. Mär 14:30 encrypt.conf -rw-r--r-- 1 root root 3 5. Dez 2012 printing.conf -rw-r--r-- 1 root root 6 14. Jul 11:01 realtek.conf -rw-r--r-- 1 root root 65 2. Jun 23:01 virtualbox.conf ...
5. エラーメッセージ Failed to find module 'blacklist usblp'
はおそらく blacklist.conf
内に間違った設定があることを示しています。手順 3 で見つけたオプションの前に # を挿入して無効化してみましょう:
/etc/modules-load.d/blacklist.conf
# blacklist usblp # install usblp /bin/false
6. では、systemd-modules-load
を起動してみることにします:
$ systemctl start systemd-modules-load
成功した場合、何も表示されないはずです。何かエラーが表示される場合は、手順 3 に戻って下さい。そして新しい PID を使って残った問題を解決してください。
全て問題ないならば、サービスが正しく起動したか次のコマンドで確認することができます:
$ systemctl status systemd-modules-load
systemd-modules-load.service - Load Kernel Modules Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static) Active: active (exited) since So 2013-08-25 12:22:31 CEST; 34s ago Docs: man:systemd-modules-load.service(8) man:modules-load.d(5) Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS) Aug 25 12:22:31 mypc systemd[1]: Started Load Kernel Modules.
この種の問題は上のように解決できます。より詳しい調査をする場合は次のブート問題の診断を見て下さい。
ブート問題の診断
カーネルコマンドラインに次のパラメータをつけて起動してください: systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M
。
特定のサービスの問題を診断
ある systemd サービスが上手く動作せず、どうなっているのか詳しい情報が欲しい場合、環境変数 SYSTEMD_LOG_LEVEL
を debug
に設定してください。以下は systemd-networkd デーモンをデバッグモードで動かす例です:
# systemctl stop systemd-networkd # SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd
もしくは同じようにサービスファイルを修正してください:
/lib/systemd/system/systemd-networkd.service
[Service] ... Environment=SYSTEMD_LOG_LEVEL=debug ....
シャットダウン/再起動にものすごく時間がかかる
シャットダウンに非常に長い時間がかかる(もしくはフリーズする)場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。なにが原因か知るには この記事 を見て下さい。
短いプロセスがログを出力しない
journalctl -u foounit.service
が短いプロセスについてなにも表示しない場合、かわりに PID を見て下さい。例えば、systemd-modules-load.service
が失敗したとき、systemctl status systemd-modules-load
によってそれが PID 123 として動いているとわかったら、その PID の journal の出力を見ることができます、journalctl -b _PID=123
。journal の _SYSTEMD_UNIT
や _COMM
などのメタデータは非同期に収集され /proc
ディレクトリにプロセスが存在している時だけ表示されます。これを修正するには、SCM_CREDENTIALS
のように、ソケット接続を使ってデータを流すようカーネルを変更する必要があります。
クラッシュしたアプリケーションのダンプのジャーナルを無効にする
/etc/systemd/coredump.conf
ファイルを編集して次の行を追加してください:
Storage=none
そして設定をリロードしてください:
# systemctl daemon-reload
少しづつ起動時間が長くなっている
systemd-analyze
を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。systemd-analyze blame
を使って NetworkManager が起動するのに異常に長い時間かかるようになったという報告もあります。
問題の原因として /var/log/journal
が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズをここに書かれているように制限するよう設定すれば解決します(できればファイルを削除する前に、どこかに一時的にバックアップしてください)。
起動時に systemd-tmpfiles-setup.service の実行に失敗する
systemd 219 から、/usr/lib/tmpfiles.d/systemd.conf
は /var/log/journal
下のディレクトリに対して ACL 属性を指定しており、それによって、ジャーナルが存在するファイルシステムで ACL のサポートを有効にしなくてはならなくなっています。
/var/log/journal
が存在するファイルシステムで ACL を有効化する方法はアクセス制御リスト#ACL の有効化を見て下さい。
systemctl enable で /etc/systemd/system にシンボリックリンクが作成されない
/etc/systemd/system/foo.service
がシンボリックリンクの場合、systemctl enable foo.service
を実行しても以下のエラーで失敗します:
Failed to issue method call: No such file or directory
これは systemd の 仕様 です。絶対パスで有効にすることで回避できます:
# systemctl enable /absolute/path/foo.service
リモートマシンで緊急モードを無効化
リモートマシン (例えば Azure や Google Cloud でホストしている仮想マシン) の緊急モードは無効化すると良いでしょう。緊急モードが起動すると、ネットワークからマシンに接続できなくなってしまうからです。無効化するには以下のコマンドを実行:
# systemctl mask emergency.service # systemctl mask emergency.target
参照
- 公式ウェブサイト
- Wikipedia の記事
- Manual Pages
- systemd Optimizations
- FAQ
- Tips And Tricks
- systemd for Administrators (PDF)
- Fedora プロジェクトによる systemd の説明
- systemd の問題をデバッグする方法
- [3] [4] The H Open マガジンに記載された二部からなる紹介記事
- Lennart のブログ記事
- ステータスアップデート
- ステータスアップデート 2
- ステータスアップデート 3
- 近況
- Fedora の SysVinit と systemd のチートシート
- Emacs の Systemd ファイルのシンタックスハイライト
- digital ocean のチュートリアル