Systemdターゲットの理解:必須概念を解説

Linuxでシステム状態を定義・管理する強力なsystemdユニットであるsystemdターゲットの謎を解き明かします。この包括的なガイドでは、ターゲットがサービスや他のユニットをどのようにグループ化し、ブートプロセスをオーケストレーションし、従来のランレベルに代わるモダンな選択肢を提供するのかを解説します。`multi-user.target`や`graphical.target`などの一般的なターゲット、デフォルトターゲットの表示・変更方法、実行時のターゲット切り替え、さらにはアプリケーション用のカスタムターゲットの作成方法を学びます。実用的なコマンドとベストプラクティスが含まれており、systemd搭載Linux環境を効果的に管理するのに役立ちます。

40 ビュー

Systemdターゲットを理解する:必須の概念を解説

Systemdは、ほとんどのLinuxディストリビューションにおいて事実上のinitシステムとなり、サービスとプロセスの管理方法を一変させました。systemdの洗練されたシステム初期化と状態管理能力の中核にあるのが、ターゲットの概念です。単なるサービスの集合体にとどまらず、ターゲットは望ましいシステムの状態を定義する特殊なsystemdユニットであり、起動プロセス中やそれ以降の同期ポイントとして機能します。

この記事では、systemdターゲットの謎を解き明かし、他のユニットをグループ化し、システム全体の状態を制御する上でのその基本的な役割を解説します。ターゲットが従来のランレベルとどのように関連しているかを探り、遭遇する最も一般的なターゲットを詳述し、それらと対話・管理するための実用的なコマンドを提供します。この記事を読み終える頃には、ターゲットが電源投入から完全に動作する環境に至るまでのシステムの道のりをどのように調整しているのかを明確に理解できるようになるでしょう。

Systemdターゲットとは?

Systemdエコシステムにおいて、ターゲットは、組織化という重要な目的を果たす特殊なタイプのユニットファイル(.serviceファイルや.socketファイルなど)です。特定のプロセスの開始方法や停止方法を定義するサービスユニットとは異なり、ターゲットユニットは、システムの状態、または一緒にアクティブになるべきユニットの集合体を定義します。これらは、他のsystemdユニットの論理的なグループ化ポイントおよび同期ポイントとして機能します。

ターゲットは、システムの運用における道のりのマイルストーンだと考えてください。systemdが起動する際、単にサービスのリストを任意に起動するのではなく、特定のターゲットの達成に向けて動作します。このターゲットは、その状態を満たすために必要なすべてのサービス、ソケット、マウントポイント、および他のターゲットを取り込みます。この依存関係駆動型のアプローチにより、予測可能で効率的な起動プロセスが保証されます。

SysVinitのような古いLinux initシステムに詳しい方にとって、systemdターゲットはランレベルの現代版にあたります。SysVinitには固定されたランレベルのセット(例:マルチユーザーテキストモードのランレベル3、マルチユーザーグラフィカルモードのランレベル5)がありましたが、systemdターゲットはより柔軟です。これらは番号ではなく名前が付けられており、カスタムターゲットを定義することもでき、より高い粒度と拡張性を提供します。

ターゲットの動作原理:グループ化と依存関係

ターゲットは、ユニットファイル内で定義された明示的な依存関係を通じて、グループ化および状態定義の機能を実現します。このために使用される主要なディレクティブは、Wants=Requires=After=、およびBefore=です。

  • Wants=: 「弱い」依存関係を指定します。もしtarget Aunit BWants=する場合、systemdはtarget Aがアクティブ化される際にunit Bを起動しようとします。しかし、unit Bの起動に失敗してもtarget Aは起動します。これは、望ましいが付随的であり、厳密には必須ではない関連サービスをグループ化するためによく使用されます。
  • Requires=: 「強い」依存関係を指定します。もしtarget Aunit BRequires=する場合、target Aがアクティブ化されるにはunit Bが正常に起動しなければなりません。unit Bが失敗した場合、target Aも失敗するか、起動しません。これは重要な依存関係に使用されます。
  • After=: 順序依存関係を定義します。もしtarget Aunit Bに対してAfter=を持つ場合、target Aunit Bが起動したにのみ起動します。これは成功に対する依存関係ではなく、単に順序を意味します。
  • Before=: After=の逆です。もしtarget Aunit Bに対してBefore=を持つ場合、unit Btarget Aが起動したにのみ起動します。
  • Conflicts=: 特定のユニットが同時にアクティブにならないようにします。もしtarget Aunit BConflicts=する場合、target Aをアクティブ化すると、実行中のunit Bは停止され、その逆も同様です。

これらのディレクティブにより、ターゲットは堅牢なオーケストレーターとして機能し、必要に応じてサービスや他のターゲットを取り込み、それらが起動すべき順序を定義します。例えば、multi-user.targetは通常、network.targetや他の様々なサービスをWants=し、システムがマルチユーザー状態に達したときにそれらがアクティブであることを保証します。

ターゲットユニットファイルの内容を検査して、その依存関係を確認することができます:

systemctl cat multi-user.target

このコマンドは、multi-user.targetユニットファイルの内容を出力し、そのDescriptionDocumentation、そしてとりわけ、マルチユーザー状態を構成する要素を定義するWants=Requires=After=、その他のディレクティブを表示します。

一般的なSystemdターゲットの解説

Systemdは、それぞれが特定のシステムの状態または機能に対応する、様々な事前定義されたターゲットを提供します。これらを理解することは、システム管理にとって非常に重要です。

  • default.target: これは、システムが起動するデフォルトの状態を定義するため、最も重要なターゲットです。通常、graphical.target(デスクトップ向け)またはmulti-user.target(サーバー向け)へのシンボリックリンクです。
  • graphical.target: このターゲットは、通常、グラフィカルデスクトップ環境を持つシステムに使用されます。これはmulti-user.targetを取り込み、その後、グラフィカルログインマネージャーとディスプレイサーバー(例:GDM、LightDM、Xorg、Wayland)に必要なサービスを追加します。
  • multi-user.target: これは、グラフィカルインターフェースを持たないマルチユーザーシステムの標準的な状態です。サーバーで一般的であり、コマンドラインアクセス、ネットワーク、およびほとんどのデーモン操作に必要なすべてのサービスを提供します。
  • basic.target: 基本的な操作に必要な基本的なシステムサービスを含む最小限の状態ですが、multi-user.targetよりも前に到達します。通常、sysinit.targetやその他の必須サービスを取り込みます。
  • sysinit.target: このターゲットは、起動プロセスの非常に早い段階で到達します。これは、/etc/fstabファイルシステム(リモートを除く)のマウント、スワップの設定、その他のハードウェア関連の初期化など、コアシステムの初期化タスクを担当します。
  • local-fs.target: /etc/fstabで指定されたすべてのローカルファイルシステムがマウントされていることを保証します。
  • remote-fs.target: /etc/fstabで指定されたすべてのリモートファイルシステム(例:NFS、CIFS)がマウントされていることを保証します。
  • network.target: 基本的なネットワーク接続が利用可能であることを示します(例:ネットワークインターフェースが起動している)。完全なインターネット接続やIPアドレスの割り当ては保証しません。
  • network-online.target: より堅牢なネットワークターゲットであり、割り当てられたIPアドレスや、到達可能なゲートウェイを含む、システムが完全なネットワーク接続を持っていることを示します。アクティブなインターネットアクセスを必要とするサービスは、After=network-online.targetを持つべきです。
  • rescue.target: 最小限のサービスが実行され、ローカルファイルシステムがマウントされたシングルユーザーシェルを提供します。システムの復旧やトラブルシューティングに役立ちます。
  • emergency.target: rescue.targetよりもさらに最小限の環境です。通常は読み取り専用でマウントされたルートファイルシステム上のシェルを提供します。他のサービスは起動しません。重大な緊急事態向けです。
  • poweroff.targetreboot.targethalt.target: これらのターゲットは、それぞれシステムのシャットダウン、再起動、停止に使用されます。アクティブ化されると、ほとんどのサービスを停止し、システムを目的の電源状態に備えさせます。

Systemdターゲットの管理

Systemdターゲットとのやり取りは、主にsystemctlコマンドラインユーティリティを介して行われます。

アクティブなターゲットとデフォルトターゲットの表示

システムが現在実行されているターゲットを確認するには:

systemctl get-default

現在ロードされているすべてのターゲットユニットを一覧表示するには:

systemctl list-units --type=target

このコマンドは、アクティブ、ロード済み、静的なターゲットと、それらの説明を表示します。

デフォルトのブートターゲットの変更

システムがデフォルトで起動するターゲットを変更できます。例えば、multi-user.targetをデフォルトとして設定するには:

sudo systemctl set-default multi-user.target

graphical.targetに戻すには:

sudo systemctl set-default graphical.target

このコマンドは、/etc/systemd/system/default.targetから目的のターゲットファイルへのシンボリックリンクを作成します。

一時的に異なるターゲットで起動する

トラブルシューティングなど、特定のターゲットで一度だけ起動する必要がある場合があります。これは、起動時にカーネルパラメータを追加することで実現できます。GRUBブートメニューが表示されたら、ブートエントリを編集し(通常はeキーを押す)、カーネルコマンドラインにsystemd.unit=target_name.targetを追加します。

例えば、レスキューモードで起動するには:

systemd.unit=rescue.target

実行中のターゲットの切り替え

システム実行中に、systemctl isolateコマンドを使用して別のターゲットに切り替えることができます。このコマンドは、新しいターゲットに必要ないすべてのサービスを停止し、それによって要求されるすべてのサービスを開始します。

警告: systemctl isolateを使用すると、特にデスクトップマシンでgraphical.targetからmulti-user.targetのようなはるかに低レベルのターゲットに切り替える場合、システムの動作が中断される可能性があります。注意して使用してください。

graphical.targetからmulti-user.targetに切り替えるには:

sudo systemctl isolate multi-user.target

(以前の状態であったと仮定して)graphical.targetに戻るには:

sudo systemctl isolate graphical.target

カスタムターゲットの作成

Systemdは多くの有用なターゲットを提供していますが、カスタムターゲットを作成することが有益な状況があるかもしれません。これは、常に一緒に起動および停止する必要がある複数のサービスをグループ化する場合や、アプリケーション用に特定の環境を定義する必要がある複雑なアプリケーションデプロイメントで特に当てはまります。

カスタムターゲットを作成するには:

  1. .targetファイルを作成する: /etc/systemd/system/に配置します。例:my-application.target
    ini # /etc/systemd/system/my-application.target [Unit] Description=My Custom Application Target Wants=my-database.service my-webserver.service After=my-database.service my-webserver.service
    • Description: 人間が判読できる説明。
    • Wants=: このターゲットが取り込むべきサービスまたは他のターゲットをリストします。
    • After=: 順序を定義します。ターゲットはこれらのユニットの後に起動します。
  2. サービスを作成する: my-database.serviceおよびmy-webserver.service(またはリストしたサービス)が存在し、適切に構成されていることを確認します。
  3. systemdをリロードする: 新しいユニットファイルについてsystemdに通知します。
    bash sudo systemctl daemon-reload
  4. 有効化と起動: これでカスタムターゲットを有効化して起動でき、それに応じて目的のサービスが起動します。
    bash sudo systemctl enable my-application.target sudo systemctl start my-application.target

これにより、関連するサービスのグループを単一の論理ユニットとして管理できるようになり、複雑なアプリケーションのデプロイメントが簡素化されます。

ターゲットを使用したトラブルシューティング

ターゲットは、起動の問題やサービス障害のトラブルシューティングにも非常に役立ちます。

  • 依存関係の特定: サービスが起動に失敗した場合、それが属するターゲットを検査することで、不足している、または失敗している依存関係が明らかになることがあります。systemctl status <service_name> および systemctl list-dependencies <target_name> を使用してください。
  • 最小限のターゲットでの起動: システムがgraphical.targetまたはmulti-user.targetで起動できない場合は、カーネルパラメータの方法を使用してrescue.targetまたはemergency.targetで起動してみてください。これにより、多くの実行中のサービスの複雑さなしに問題を診断できる最小限の環境が提供されます。
  • ログの確認: ターゲットまたはサービスを起動しようとした後、必ずjournalctlログでエラーを確認してください。
    bash journalctl -b -u <target_or_service_name>

ベストプラクティスとヒント

  • network-online.targetを優先する: サービスがアクティブなネットワーク接続(例:外部APIにアクセスするため)を必要とする場合は、単にnetwork.targetや特定のネットワークサービスではなく、After=network-online.targetを持つようにしてください。これにより、ネットワーク設定時間の変動に対してサービスがより堅牢になります。
  • 起動順序を理解する: sysinit.targetからbasic.target、そしてmulti-user.target/graphical.targetへの一般的な流れに慣れてください。これは、起動プロセスの早い段階で失敗するサービスのデバッグに役立ちます。
  • default.targetには注意する: default.targetを変更すると、システムの起動動作が大幅に変わる可能性があります。カスタム構成は必ず非本番環境で最初にテストしてください。
  • 重要ではない依存関係にはWants=を使用する: ターゲットが「起動している」と見なされるために有用ではあるが厳密には必須ではないサービスには、Requires=ではなくWants=を使用してください。これにより、単一のオプションのサービス障害が連鎖し、ターゲット全体の有効化を妨げるのを防ぎます。

結論

Systemdターゲットは、現代のLinuxシステム管理の基礎であり、システムの状態を定義、制御、調整するための柔軟で強力なメカニズムを提供します。ターゲットがどのようにユニットをグループ化し、依存関係を管理し、起動プロセスを定義するかを理解することで、管理者と開発者はシステムの動作を大幅に制御できるようになります。multi-user.targetのような一般的なターゲットから、カスタムのアプリケーション固有のターゲットまで、これらの概念を習得することは、効果的なシステム管理、トラブルシューティング、および堅牢で保守性の高いLinux環境の構築に不可欠です。

Systemdの旅を続けるにあたり、ターゲットはユニットの依存関係とシステム初期化の複雑な状況をナビゲートするための地図であり、サービスが予測どおりに起動し、システムが意図した動作状態を達成することを保証することを忘れないでください。