systemd

最終更新: 2024-04-14 21:45:03 +0800 +0800
tags: Linux | Systemd
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

systemd は、サービスマネージャーであり、Linux のシステム管理コンポーネント群です。 システムマネージャーは PID 1 として実行され、ユーザーマネージャーは systemd --user として実行されます。 両方のマネージャーはユニットを読み込み、ジョブのトランザクションを計算し、 Linux のコントロールグループを通じてプロセスグループを監視します。

ユニット、ジョブ、ライフサイクル状態 #

ユニットは、マネージャーが認識するリソースを表します。一般的なユニットの種類は次のとおりです。

サフィックスリソース
.serviceプロセスまたはデーモン
.socketアクティベーションに使用する IPC またはネットワークソケット
.target同期およびグループ化のポイント
.mount、.automount、.swapストレージ構成
.device、.path、.timerデバイスまたはイベントベースのアクティベーション
.slice、.scopecgroup の編成および外部から開始されたプロセス

ジョブは、start、stop、reload など、要求されたユニット状態の変更です。1 つのユニットを開始すると、他のジョブが取り込まれることがあります。マネージャーはそれらを 1 つのトランザクションにまとめ、順序付けの循環と競合するジョブを検査した後、独立した処理を並列にディスパッチします。

ユニットの状態には複数の側面があります。LoadState は定義が読み込まれたかどうかを記録し、ActiveState は inactive、activating、active、deactivating、failed などの高レベル状態を示し、SubState は種類固有の詳細を提供します。読み込み済みのサービスが必ずしも実行中とは限らず、enable されたサービスが必ずしも読み込み済みまたは active とは限りません。enable はブートまたはアクティベーション用のリンクを変更し、start は実行時ジョブを作成します。

sh
systemctl show sshd.service \
  --property=LoadState,ActiveState,SubState,UnitFileState
systemctl status sshd.service
systemctl list-jobs
systemctl --failed

要件依存関係と順序依存関係 #

要件エッジは、どのユニットをトランザクションに含めるかを決定します。

  • Requires= は別のユニットを取り込み、選択された start の失敗または stop を伝播します。
  • Wants= は、要求されたユニットが失敗しても要求元が失敗しない可能性があるため、より弱い関係です。
  • Requisite= は、他のユニットがすでに active でなければ失敗します。
  • BindsTo= は、消失するリソースに対してアクティビティをより強く結び付けます。
  • Conflicts= は、競合するユニットの stop をスケジュールします。

順序エッジは実行順序を決定します。After= と Before= は別のユニットをトランザクションに取り込まず、Requires= と Wants= は順序を確立しません。両方の関係が必要な場合は、両方を記述します。

ini
[Unit]
Wants=network-online.target
After=network-online.target

シャットダウン時には順序が異なる方法で評価されます。同じトランザクションで、あるユニットが別のユニットの後に順序付けられていて stop される場合、前者が先に stop されます。

マネージャーは、ユニットの種類と設定に基づいて、暗黙的およびデフォルトの依存関係を追加します。たとえば、mount ユニットは親マウントとの関係を取得し、多くの service ユニットは基本的な起動およびシャットダウンの target に対するデフォルトの順序付けを受け取ります。generator はマネージャーの起動初期にユニット定義を作成または変更します。systemd-fstab-generator は /etc/fstab を変換し、他の generator はカーネルコマンドラインおよび互換性入力を処理します。すべてのエッジが 1 つのファイルに文字どおり現れると仮定せず、計算済みのグラフを検査してください。

sh
systemctl list-dependencies example.service
systemctl list-dependencies --reverse example.service
systemctl show example.service --property=Wants,Requires,Before,After
systemd-analyze critical-chain

検出、命名、オーバーライド #

ユニット名はサフィックスに種類をエンコードします。パスから派生した名前では systemd のエスケープが使用されます。/var/lib は var-lib.mount になり、/ は -.mount になります。worker@.service のようなテンプレート名は、worker@blue.service のようなインスタンスを作成します。%i はエスケープ済みインスタンスに展開され、%I はエスケープされていない形式に展開されます。

マネージャーは、コンパイル時に定義されたユニットロードパスを検索します。 /etc/systemd/system の管理者定義は、通常 /usr/lib/systemd/system または /lib/systemd/system にインストールされるベンダー定義より優先されます。一時的および生成されたディレクトリも、同じ検索順序の中で定義された位置を持ちます。ディストリビューションによって異なる可能性があるため、実行中のマネージャーに問い合わせてください。

sh
systemd-analyze unit-paths
systemd-analyze --user unit-paths
systemctl cat example.service
systemctl list-unit-files 'example*'

alias は、シンボリックリンクまたは enable 時の Alias= によって実装された、別の有効なユニット名です。.wants/ および .requires/ ディレクトリは依存関係リンクをエンコードします。WantedBy= や RequiredBy= などの [Install] 設定は、systemctl enable に対して作成するリンクを指示します。マネージャーは、ユニットの start 中に [Install] を解釈しません。

ローカルポリシーのために、パッケージ化されたベンダーファイルを編集しないでください。drop-in を作成します。

sh
systemctl edit example.service
systemctl daemon-reload
systemctl restart example.service
systemd-delta

*.conf という名前の drop-in は辞書順にマージされます。スカラー設定は以前の値を置き換えますが、リスト設定は蓄積される可能性があり、置き換える前に空の代入が必要になることがあります。

ini
[Service]
ExecStart=
ExecStart=/usr/local/bin/example --foreground

systemctl revert は、ユニット用に作成されたローカルオーバーライドを削除します。本番サービスを restart する前に、systemctl cat でマージ後の定義を確認してください。

サービス追跡と cgroup #

systemd はサービスプロセスをユニットの cgroup に配置します。二重 fork 後も子孫プロセスはサービスに関連付けられたままになるため、PID ファイルは基本的な追跡メカニズムではありません。slice はサービスおよび scope の cgroup を階層的に編成します。CPUWeight=、MemoryMax=、TasksMax= などのリソース設定は、ホストで利用可能なカーネル cgroup コントローラーを通じて適用されます。

sh
systemctl status example.service
systemd-cgls
systemctl show example.service --property=ControlGroup,MainPID,TasksCurrent

Type=simple は ExecStart プロセスをメインプロセスとして扱い、readiness プロトコルを待機しません。Type=exec は実行が成功するまで待機します。Type=notify は、通知プロトコルを実装するサービスからの READY=1 を待機します。Type=forking は従来型の自分自身をデーモン化するプログラムをサポートし、Type=oneshot はコマンドが終了するまで待機します。デーモンに適合する readiness 契約を選択してください。simple サービスの後に順序付けても、そのプロセスが起動されたことしか保証されません。

target、ブート、互換性 #

default.target は通常のブート目標です。カーネルの systemd.unit= 引数は、1 回のブートで別の target を選択できます。それ以外の場合は、構成されたデフォルトが使用されます。

sh
systemctl get-default
systemctl set-default multi-user.target
systemctl isolate rescue.target

isolate は target に必要とされないユニットを stop し、セッションを終了させる可能性があるため、リモートで使用する前に target の依存関係を確認してください。emergency.target と rescue.target は、制限された復旧環境を提供します。

target は作業をグループ化しますが、それ自体では順序を強制しません。そのため、ブート性能と障害診断では、ジョブグラフとタイムスタンプの両方を使用します。

sh
systemd-analyze time
systemd-analyze blame
systemd-analyze critical-chain
journalctl -b -p warning

SysV 互換性はディストリビューションに依存します。generator は従来の init スクリプトを service ユニットとしてラップできます。また、shutdown などの使い慣れたコマンドが systemd ツールへのリンクになっている場合があります。ネイティブユニットは、より精密な依存関係、cgroup 追跡、アクティベーション、サンドボックス化を提供します。init スクリプトがすべてのネイティブサービスセマンティクスを受け取るとは仮定しないでください。

logind とユーザーマネージャー #

systemd-logind は、カーネルおよびユーザー空間のデバイス/セッション情報を使用して、seat、ログインセッション、ユーザー、inhibitor lock を追跡します。loginctl はその状態を検査します。

sh
loginctl list-sessions
loginctl session-status
loginctl user-status "$USER"

PAM ログインでは通常、ユーザーマネージャーを実行する user@UID.service が開始されます。ユーザーユニットは個別のロードパスに従い、systemctl --user で制御します。デフォルトでは、マネージャーのライフタイムはログインポリシーに従います。loginctl enable-linger USER は、ブート時の起動と最後のセッション終了後の永続化を要求します。対話的なログインがなくても lingering 中のユーザーサービスはリソースを消費するため、意図的に使用してください。

システムマネージャーとユーザーマネージャーでは、権限とバスが分離されています。ユーザーサービスは、ユニットオプションを宣言するだけでシステムマネージャーの権限を取得できません。また、システムサービスは、その結合が意図的でない限り、一時的なデスクトップセッションに依存すべきではありません。

運用時の検査 #

ファイルだけから状態を推測するのではなく、マネージャー自身のインターフェースを使用してください。

sh
systemctl list-units --all
systemctl list-unit-files
systemctl cat example.service
systemctl show example.service
systemd-analyze verify /etc/systemd/system/example.service
journalctl --unit=example.service --boot

systemctl edit 以外でユニットファイルを変更した後は、systemctl daemon-reload を実行してください。これは定義を再解析しますが、サービスは restart しません。まず検証し、reload し、マージ後のユニットを検査してから、影響を受ける最小のユニットを restart または reload してください。上流マニュアルの systemd.unit(5)、systemd.service(5)、systemd.special(7)、systemd.generator(7) は、ホストにインストールされたバージョンの仕様を定義します。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)