Systemdユニットの理解: サービス設定の深掘り

Linuxサービスの構成の基盤であるsystemdユニットファイルについて深く掘り下げます。`.service` ファイルの読み取り、変更、作成方法を学び、`[Unit]`、`[Service]`、`[Install]`のようなセクションを理解します。このガイドでは、`systemctl` を使用したカスタムサービスの管理や`journalctl` でのログ表示に関する実践的な例を取り上げ、システム管理者や開発者にとって不可欠な知識を提供します。

47 ビュー

Systemdユニットの理解:サービス設定の詳細解説

Systemdは、最新のLinuxディストリビューションにおいて、サービスの初期化と管理の事実上の標準となりました。Systemdの根幹は、サービス、デバイス、マウントポイントなど、さまざまなシステムリソースを定義および制御するためのユニットファイルに依存しています。これらのユニットファイルの構造と構文を理解することは、システム管理者と開発者の両方にとって不可欠であり、既存のサービスを効果的に管理し、特定のニーズに合わせてカスタムサービスを作成することを可能にします。

この記事では、主にサービスユニット(.serviceファイル)に焦点を当てた、systemdユニットファイルの詳細な解説を提供します。その基本的な構造、一般的なディレクティブ、およびそれらを読み取り、変更し、作成するための実践的な例を探ります。このガイドの終わりまでに、systemdのパワーを活用して自信を持ってシステムのサービスを管理するための強固な基盤が得られるでしょう。

Systemdユニットファイルとは?

Systemdユニットファイルは、特定のユニットの設定ディレクティブを含む単純なテキストファイルです。ユニットは、systemdによって管理されるリソースを表します。最も一般的なタイプはサービスユニットであり、バックグラウンドプロセスまたはアプリケーションを起動、停止、再起動、および管理する方法を定義します。

ユニットファイルはセクションに整理されており、各セクションは角括弧([])で区切られます。サービスユニットで最も重要なセクションは次のとおりです。

  • [Unit]: ユニットに関するメタデータ、依存関係、および順序付けが含まれます。
  • [Service]: 実行方法を含む、サービス自体の動作を定義します。
  • [Install]: ユニットを有効または無効にする方法を指定し、通常はターゲットユニットにリンクします。

Systemdはいくつかの標準ディレクトリでユニットファイルを探しますが、最も一般的なのは次のとおりです。

  • /etc/systemd/system/: ローカルで設定されたユニット用。デフォルトのユニットを上書きします。
  • /usr/lib/systemd/system/: パッケージによってインストールされたユニット用。

.serviceユニットファイルの構造

典型的な.serviceユニットファイルのコンポーネントを理解するために、それを分解してみましょう。

[Unit]セクション

このセクションは、記述情報を提供し、ユニット間の関係を定義します。

  • Description=: サービスの人間に読みやすい説明。
  • Documentation=: サービスのドキュメントへのURLまたはパス。
  • After=: 指定されたユニットの起動が完了した後にこのユニットが起動することを指定します。
  • Requires=: After=に似ていますが、指定されたユニットが必須であることも意味します。必須ユニットの起動に失敗した場合、このユニットも失敗します。
  • Wants=: より弱い依存関係。このユニットは、要求されたユニットを起動しようとしますが、それらが失敗してもこのユニットの起動は妨げられません。
  • Conflicts=: このユニットと同時に実行できないユニットを指定します。

[Unit]セクションの例:

[Unit]
Description=My Custom Web Server
Documentation=https://example.com/docs/my-web-server
After=network.target

これは、カスタムWebサーバーがネットワークが利用可能になった後に起動する必要があることを示しています。

[Service]セクション

サービスを実行するためのコアロジックがここにあります。

  • Type=: プロセスの起動タイプを定義します。一般的なタイプには次のものがあります。
    • simple (デフォルト): メインプロセスはExecStart=によって起動されたプロセスです。Systemdは、ExecStart=プロセスがフォークされた直後にサービスが開始されたと見なします。
    • forking: 子プロセスをフォークして終了する従来のデーモンに使用されます。Systemdは親プロセスの終了を待ちます。
    • oneshot: 単一のコマンドを実行してから終了するタスク用。
    • notify: サービスが起動を完了したときにsystemdに通知を送信します。
    • dbus: D-Bus名を取得するサービス用。
  • ExecStart=: サービスを起動するために実行するコマンド。
  • ExecStop=: サービスを停止するために実行するコマンド。
  • ExecReload=: サービスを再起動せずに設定をリロードするために実行するコマンド。
  • Restart=: サービスがいつ再起動されるかを定義します。オプションには、no (デフォルト)、on-successon-failureon-abnormalon-watchdogon-abort、およびalwaysがあります。
  • RestartSec=: サービスを再起動する前に待機する時間。
  • User= / Group=: サービスを実行するユーザーとグループ。
  • WorkingDirectory=: 実行されるプロセスの作業ディレクトリ。
  • Environment= / EnvironmentFile=: サービス用の環境変数を設定します。

[Service]セクションの例:

[Service]
Type=simple
ExecStart=/usr/local/bin/my-web-server --config /etc/my-web-server.conf
User=www-data
Group=www-data
Restart=on-failure
RestartSec=5

この構成は、Webサーバーを起動し、www-dataユーザーとグループとして実行し、失敗した場合は5秒遅延して自動的に再起動します。

[Install]セクション

このセクションは、ユニットを有効または無効にする場合に使用されます。ユニットがsystemdのターゲットユニットとどのように統合されるかを定義します。

  • WantedBy=: ユニットが有効になったときに「要求」すべきターゲットを指定します。起動時に起動すべきサービスの場合、multi-user.targetが一般的に使用されます。

[Install]セクションの例:

[Install]
WantedBy=multi-user.target

systemctl enable my-custom-service.serviceを実行すると、systemdは/etc/systemd/system/multi-user.target.wants/からサービスファイルへのシンボリックリンクを作成し、システムがマルチユーザーランレベルに達したときに起動することを保証します。

カスタムサービスユニットの作成と管理

カスタムサービスユニットを作成するプロセスを順を追って説明します。

ステップ1:ユニットファイルの作成

/etc/systemd/system/.service拡張子を持つ新しいファイルを作成します。例として、/etc/systemd/system/my-app.serviceを作成しましょう。

[Unit]
Description=My Custom Application Service
After=network.target

[Service]
Type=simple
ExecStart=/opt/my-app/bin/run-app --port 8080
User=appuser
Group=appgroup
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

重要な考慮事項:

  • ExecStartコマンドが、アクセス可能で実行権限を持つ実行可能スクリプトまたはバイナリを指していることを確認してください。
  • 指定されたUserGroupが存在しない場合は作成してください(sudo useradd -r -s /bin/false appusersudo groupadd appgroupsudo usermod -a -G appgroup appuser)。
  • アプリケーションが指定されたコマンドを使用して正しく起動および停止できることを確認してください。

ステップ2:Systemd設定のリロード

ユニットファイルを作成または変更した後、systemdに設定をリロードするように指示する必要があります。

sudo systemctl daemon-reload

このコマンドは、新しいまたは変更されたユニットファイルをスキャンし、systemdの内部状態を更新します。

ステップ3:サービスの有効化と起動

サービスをすぐに起動し、起動時に起動するように構成するには、次のようにします。

sudo systemctl enable my-app.service  # 起動時のシンボリックリンクを作成します
sudo systemctl start my-app.service   # 今すぐサービスを起動します

ステップ4:サービスの管理

systemctlコマンドを使用してサービスを管理します。

  • ステータスを確認する:
    bash sudo systemctl status my-app.service
    これにより、サービスがアクティブかどうか、そのプロセスID、最近のログエントリなどが表示されます。

  • サービスを停止する:
    bash sudo systemctl stop my-app.service

  • サービスを再起動する:
    bash sudo systemctl restart my-app.service

  • サービスをリロードする(ExecReload=が定義されている場合):
    bash sudo systemctl reload my-app.service

  • サービスを無効にする(起動時に起動しないようにする):
    bash sudo systemctl disable my-app.service

ステップ5:journalctlでのログ表示

Systemdはロギングのためにjournaldと緊密に連携しています。journalctlを使用してサービスのログを表示できます。

  • 特定のサービスのログを表示する:
    bash sudo journalctl -u my-app.service

  • ログをリアルタイムでフォローする:
    bash sudo journalctl -f -u my-app.service

  • 前回の起動以降のログを表示する:
    bash sudo journalctl -b -u my-app.service

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

  • 最新のアプリケーションにはType=notifyを使用する: アプリケーションがサポートしている場合、Type=notifyはsystemdとの統合が向上し、サービスの準備状況を正確に追跡できます。
  • 非rootユーザーでサービスを実行する: セキュリティリスクを最小限に抑えるために、常に[Service]セクションでUser=Group=を指定してください。
  • 依存関係を慎重に定義する: After=Requires=Wants=を使用して、サービスが正しい順序で起動し、重要な依存関係が満たされていることを確認してください。
  • Restart=を活用する: サービスの可用性を確保するために、適切な再起動ポリシーを構成してください。
  • ユニットファイルをシンプルに保つ: 複雑な起動シーケンスの場合は、ユニットファイルに直接複雑なコマンドを記述するのではなく、ExecStart=によって呼び出されるラッパー ใช้を検討してください。
  • systemctl cat <unit>を使用する: systemdが見たユニットファイルの完全な内容(オーバーライドを含む)を表示します。
  • systemctl edit <unit>を使用する: このコマンドは、既存のユニットのオーバーライドファイルを作成するためのエディタを開きます。これは、デフォルトのユニットファイルを直接編集するよりもクリーンな方法です。

結論

Systemdユニットファイル、特に.serviceファイルは、最新のLinuxシステムにおけるサービス管理のバックボーンです。その構造([Unit][Service][Install]セクション)を理解し、systemctlおよびjournalctlコマンドを習得することで、システムのプロセスを強力に制御できるようになります。既存のサービス構成を適応させる場合でも、カスタムデーモンを構築する場合でも、ユニットファイルに関する確かな知識は、システムをより効率的、信頼性高く、安全に管理することを可能にします。