はじめに
プロセスとは、実行中のプログラムです。サービスとは、定義とライフサイクルポリシーに従って管理される、長時間実行されるシステム機能です。Ubuntu では、systemd が unit 定義を読み込み、サービスの開始と停止、状態の追跡を行い、出力を system journal に記録します。
この実験では、分離された labex-heartbeat 練習用サービスを使用します。unit の内容を確認し、実行時状態を制御し、起動時の有効化を設定します。さらに、journal と従来のテキストログを検索し、リアルタイム出力を追跡し、意図的に発生させた障害を診断して、正常な状態に復旧します。unit ファイルを編集したり、SSH サービスを操作したりすることはありません。
systemd とサービス unit を確認する
このステップでは、systemd が利用可能であることを確認し、実行中の unit とインストール済みの unit ファイルを区別します。
実験用の作業ディレクトリに移動します。
cd /home/labex/project/service-lab
systemd のバージョンを表示します。識別には最初の行だけで十分です。
systemctl --version | head -n 1
systemd 全体の状態を確認します。
systemctl is-system-running || true
running は、必要なすべての unit が正常であることを示します。トレーニング用 VM では、関係のないオプションの unit が失敗しているため、degraded と表示されることがあります。この場合でも、systemd が応答していることは確認できます。
現在実行中のサービスの一部を一覧表示します。
systemctl list-units --type=service --state=running --no-pager | head -n 12
unit は、systemd が管理するオブジェクトです。サービス unit の名前は .service で終わります。unit ファイルには、現在実行されていないものも含め、管理可能な対象が定義されています。
systemctl list-unit-files --type=service --no-pager | head -n 12
systemd の概要を簡潔に保存します。コマンド置換 $(...) を使うと、printf が書き込むテキスト内にコマンドの出力を挿入できます。
printf 'systemd=%s\nstate=%s\n' "$(systemctl --version | head -n 1)" "$(systemctl is-system-running)" > systemd-summary.txt
cat systemd-summary.txt
サービスの定義と状態を確認する
このステップでは、準備済みの練習用サービスを開始する前に、その定義と状態を確認します。
systemctl status は、読み込まれた unit のパス、有効化状態、実行時状態、プロセス情報、最近のログ行をまとめて表示します。
cd /home/labex/project/service-lab
systemctl status labex-heartbeat.service --no-pager
サービスは inactive (dead) かつ disabled になっているはずです。inactive は現在実行されていないことを意味し、disabled は起動時に install target を通じて開始するよう設定されていないことを意味します。これらは別々の状態です。
unit の定義を表示します。
systemctl cat labex-heartbeat.service
[Unit] セクションには識別情報と起動順序、[Service] セクションにはプロセス、[Install] セクションには有効化の設定が定義されています。ここでは準備済みの unit を確認するだけで、unit を作成する必要はありません。
機械的に処理しやすいプロパティを systemctl show で表示します。
systemctl show labex-heartbeat.service -p LoadState -p ActiveState -p SubState -p UnitFileState
確認用に、これらのプロパティを保存します。
systemctl show labex-heartbeat.service -p LoadState -p ActiveState -p SubState -p UnitFileState > service-properties.txt
cat service-properties.txt
サービスを開始、停止、再起動する
このステップでは、練習用サービスの実行時状態を変更し、その結果を毎回確認します。
システムサービスの開始と停止には、権限の昇格が必要です。サービスを開始します。
sudo systemctl start labex-heartbeat.service
簡潔なアクティブ状態を確認します。
systemctl is-active labex-heartbeat.service
出力は active になるはずです。より詳しい状態を表示します。
systemctl status labex-heartbeat.service --no-pager
状態にメイン PID が表示されるようになります。サービスを停止して、結果を確認します。
sudo systemctl stop labex-heartbeat.service
systemctl is-active labex-heartbeat.service || true
期待される状態は inactive です。もう一度開始してから、restart を使って実行中のプロセスを 1 回の操作で入れ替えます。
sudo systemctl start labex-heartbeat.service
sudo systemctl restart labex-heartbeat.service
systemctl show labex-heartbeat.service -p ActiveState -p SubState -p MainPID
このステップの最後には、ActiveState=active と SubState=running になっているはずです。
起動時の有効化を設定する
このステップでは、サービスの現在の実行時状態と、次回以降の起動時に有効になる設定を区別します。
前のステップでサービスはアクティブになっていますが、セットアップでは unit ファイルが無効になっています。有効化状態を確認します。
systemctl is-enabled labex-heartbeat.service || true
サービスを有効化します。
sudo systemctl enable labex-heartbeat.service
systemctl is-enabled labex-heartbeat.service
有効化すると、サービスを起動 target に関連付けるリンクが作成されます。すでに実行中のサービスを再起動する必要はありません。
これらの起動用リンクを削除する操作も実践します。
sudo systemctl disable labex-heartbeat.service
systemctl is-enabled labex-heartbeat.service || true
出力が disabled になっても、サービスはアクティブなままの場合があります。実験の最終状態に戻すため、サービスを再度有効化します。
sudo systemctl enable labex-heartbeat.service
独立した 2 つのプロパティを確認します。
systemctl is-active labex-heartbeat.service
systemctl is-enabled labex-heartbeat.service
journalctl でサービスログを検索する
このステップでは、systemd journal からサービスの最近の出力を読み取り、対象を絞ったスナップショットを保存します。
systemd が管理するサービスは通常、標準出力と標準エラー出力を journal に送ります。練習用 unit だけを対象に検索します。
sudo journalctl -u labex-heartbeat.service -n 10 --no-pager
-u オプションは対象の unit を選択し、-n 10 は最新の 10 件に制限し、--no-pager はページャーを使わず直接表示します。最近の heartbeat 記録が表示されるはずです。サービスが動作し続けている間に、起動メッセージがこの件数制限の外へ流れている場合があります。
最近の時間範囲に結果を制限します。
sudo journalctl -u labex-heartbeat.service --since "5 minutes ago" --no-pager
warning 以上の priority に絞り込みます。サービスが warning を記録していない場合、何も出力されないことは正常で有効な結果です。
sudo journalctl -u labex-heartbeat.service -p warning --since "5 minutes ago" --no-pager
最近の unit 固有のスナップショットを、プロジェクトの作業ディレクトリに保存します。
cd /home/labex/project/service-lab
sudo journalctl -u labex-heartbeat.service -n 20 --no-pager > service-journal.txt
tail -n 5 service-journal.txt
従来のテキストログを追跡する
このステップでは、/var/log を確認し、新しい記録が追加されるテキストログを追跡します。
/var/log 階層には、従来のシステムログやアプリケーションログが多数保存されています。少数の例を一覧表示します。
ls -lh /var/log | head -n 12
練習用サービスの最新の記録を読み取ります。
tail -n 5 /var/log/labex-heartbeat.log
-f オプションを使うと、ファイルを追跡し、別のプロセスが追加した新しい行を表示できます。
tail -f /var/log/labex-heartbeat.log
新しい heartbeat 行が少なくとも 2 行表示されるまで待ち、その後 Ctrl+C を押します。これにより tail は中断されますが、ログを書き込んでいるサービスは停止しません。
heartbeat 行だけを抽出し、最新の 3 行を表示します。
grep '^heartbeat ' /var/log/labex-heartbeat.log | tail -n 3
5 行分のサンプルをプロジェクトの作業ディレクトリに保存します。
cd /home/labex/project/service-lab
tail -n 5 /var/log/labex-heartbeat.log > traditional-log-sample.txt
cat traditional-log-sample.txt
失敗したサービスを診断して復旧する
このステップでは、意図的に設定エラーを作成し、サービスの状態とログから原因を特定して、正常な動作に復旧します。
練習用サービスを停止し、簡単な設定ファイルをバックアップします。
sudo systemctl stop labex-heartbeat.service
sudo cp /etc/labex-heartbeat.conf /etc/labex-heartbeat.conf.bak
数値の間隔を無効な値に置き換えます。これにより、練習用サービスだけが意図的に壊れます。
sudo sed -i 's/^INTERVAL=2$/INTERVAL=invalid/' /etc/labex-heartbeat.conf
サービスの開始を試みます。失敗メッセージが表示されるのは想定どおりです。
sudo systemctl start labex-heartbeat.service || true
失敗した状態を確認します。
systemctl status labex-heartbeat.service --no-pager || true
systemctl is-failed labex-heartbeat.service
状態表示からプロセスが終了したことを確認できますが、アプリケーション固有の原因は journal に記録されています。
sudo journalctl -u labex-heartbeat.service -n 10 --no-pager
configuration error: INTERVAL must be a positive integer を探してください。正常な設定を復元し、記録された失敗状態をクリアしてから、サービスを再度開始します。
sudo mv /etc/labex-heartbeat.conf.bak /etc/labex-heartbeat.conf
sudo systemctl reset-failed labex-heartbeat.service
sudo systemctl start labex-heartbeat.service
復旧したことを確認します。
systemctl is-active labex-heartbeat.service
cat /etc/labex-heartbeat.conf
サービスは active になり、設定には再び INTERVAL=2 が含まれているはずです。
まとめ
プロセス、サービス、アクティブ状態、起動時の有効化の違いを確認しました。systemd unit を調べ、systemctl で安全な練習用サービスを制御し、journalctl でその記録を検索しました。
さらに、/var/log を確認し、tail -f でテキスト出力をリアルタイムに追跡しました。状態とログを組み合わせて意図的に発生させた障害の原因を説明し、サービスを復旧しました。このように、まず状態を確認し、次にログを調べる手順は、初心者がサービスのトラブルシューティングを行うための実践的な基礎になります。



