インフラエンジニアの羅針盤

インフラエンジニア1〜3年目のための技術ガイド

AlmaLinux 10 総合ガイド 第5章: systemdによるサービス管理と自動化

公開更新

AlmaLinux 10 総合ガイド
第5章: systemdによるサービス管理と自動化

【この章で学ぶこと】 systemdでサービスを制御し、定期実行を設定する
【なぜ重要か】 サーバーで動くサービスの起動・停止は日常業務
【前提知識】 第4章完了、基本的なシステム理解
【所要時間】 約3時間

サーバーの本質は「サービスを提供すること」です。Webサーバー、データベースサーバー、メールサーバーなど、サーバーはさまざまなサービスを24時間365日動かし続けます。この章では、それらのサービスを管理する仕組みであるsystemdについて学びます。

「サービスが起動しない」「なぜか再起動すると動いていない」といったトラブルは、サーバー運用で頻繁に遭遇する問題です。systemdの仕組みを理解すれば、これらの問題に適切に対処できるようになります。

目次
  1. 5.1 systemdとは
    1. 5.1.1 init systemの役割
    2. 5.1.2 systemdの登場背景(SysVinitからの進化)
    3. 5.1.3 systemdが管理するもの
    4. 5.1.4 ユニットの種類(service, timer, mount, target等)
    5. 5.1.5 ユニットファイルの場所
  2. 5.2 systemctlコマンドの基本
    1. 5.2.1 systemctl statusでサービス状態確認
    2. 5.2.2 systemctl startでサービス起動
    3. 5.2.3 systemctl stopでサービス停止
    4. 5.2.4 systemctl restartで再起動
    5. 5.2.5 systemctl reloadで設定再読み込み
    6. 5.2.6 startとreloadの使い分け
  3. 5.3 サービスの自動起動設定
    1. 5.3.1 systemctl enableで自動起動有効化
    2. 5.3.2 systemctl disableで自動起動無効化
    3. 5.3.3 systemctl is-enabledで状態確認
    4. 5.3.4 enabledとstartedの違い
    5. 5.3.5 マスクとアンマスク
  4. 5.4 サービス一覧と依存関係
    1. 5.4.1 systemctl list-unitsで稼働中のユニット一覧
    2. 5.4.2 systemctl list-unit-filesで全ユニットファイル一覧
    3. 5.4.3 systemctl list-dependenciesで依存関係確認
    4. 5.4.4 サービスのフィルタリング
  5. 5.5 ログの確認 – journalctl
    1. 5.5.1 systemdのログシステム(journald)
    2. 5.5.2 journalctlの基本的な使い方
    3. 5.5.3 特定サービスのログ表示(-uオプション)
    4. 5.5.4 リアルタイムログ監視(-fオプション)
    5. 5.5.5 時間範囲指定(–since, –until)
    6. 5.5.6 優先度フィルタ(-pオプション)
    7. 5.5.7 ログの永続化設定
  6. 5.6 実践: httpdサービスの管理
    1. 5.6.1 Apache HTTPサーバーのインストール
    2. 5.6.2 サービスの起動
    3. 5.6.3 自動起動設定
    4. 5.6.4 ステータス確認
    5. 5.6.5 ログ確認
    6. 5.6.6 設定変更後のリロード
    7. 5.6.7 トラブルシューティング実践
  7. 5.7 カスタムサービスの作成
    1. 5.7.1 ユニットファイルの基本構造
    2. 5.7.2 [Unit], [Service], [Install]セクション
    3. 5.7.3 簡単なサービスの作成例
    4. 5.7.4 systemctl daemon-reloadで反映
    5. 5.7.5 カスタムサービスの起動テスト
  8. 5.8 定期実行 – cronとsystemd timer
    1. 5.8.1 定期実行が必要な理由
    2. 5.8.2 cronの基本
    3. 5.8.3 systemd timerの基本
    4. 5.8.4 cronとtimerの使い分け
  9. 5.9 実践: ログのバックアップ自動化
    1. 5.9.1 バックアップスクリプトの作成
    2. 5.9.2 cronで毎日深夜に実行
    3. 5.9.3 動作確認と検証
    4. 5.9.4 エラーハンドリング
    5. 【コラム4】サービス起動失敗で障害対応、原因はtypoだった話
  10. 章末まとめ
  11. 練習問題
  12. 次章への橋渡し

5.1 systemdとは

まず、systemdとは何か、なぜ必要なのかを理解しましょう。

5.1.1 init systemの役割

Linuxが起動するとき、最初に起動するプロセスがあります。これをinit(イニット)プロセスと呼びます。initは「PID 1」(プロセスID 1番)として動作し、他のすべてのプロセスの親となります。

init system(イニットシステム)とは、このinitプロセスを中心としたシステム管理の仕組みです。主な役割は以下の通りです。

  • システムの起動: OSの起動時に、必要なサービスを順番に起動する
  • サービスの管理: 各サービスの起動、停止、再起動を制御する
  • 依存関係の処理: 「Aが起動してからBを起動する」といった順序を管理する
  • システムの終了: シャットダウン時に、サービスを適切な順序で停止する

5.1.2 systemdの登場背景(SysVinitからの進化)

systemdが登場する前は、SysVinit(シスファイブ・イニット)というinit systemが広く使われていました。SysVinitはシンプルで理解しやすい反面、いくつかの限界がありました。

項目 SysVinit systemd
起動方式 順次起動(1つずつ) 並列起動(同時に複数)
起動速度 遅い 高速
依存関係 手動で管理 自動で解決
サービス監視 基本的になし 自動再起動など高度な制御
ログ管理 別システム(syslog) 統合(journald)
設定形式 シェルスクリプト INI形式の設定ファイル

systemdは2010年に開発が始まり、現在ではRHEL系、Debian系を含むほとんどの主要なLinuxディストリビューションで採用されています。AlmaLinux 10ではsystemd 257が搭載されています。

5.1.3 systemdが管理するもの

systemdは単なるサービス管理ツールではありません。以下のようなシステム全体のさまざまな機能を統合的に管理します。

  • サービス: Webサーバー、データベースなどのバックグラウンドプロセス
  • マウント: ファイルシステムのマウント処理
  • デバイス: ハードウェアデバイスの検出と初期化
  • ソケット: ネットワーク接続の待ち受け
  • タイマー: 定期実行のスケジューリング(cronの代替)
  • ターゲット: システムの状態(マルチユーザーモードなど)

5.1.4 ユニットの種類(service, timer, mount, target等)

systemdでは、管理対象をすべてユニット(Unit)という単位で扱います。ユニットにはいくつかの種類があり、ファイル名の拡張子で区別します。

拡張子 種類 説明
.service サービス デーモン(バックグラウンドプロセス) httpd.service
.timer タイマー 定期実行のスケジュール logrotate.timer
.mount マウント ファイルシステムのマウント home.mount
.target ターゲット ユニットのグループ化 multi-user.target
.socket ソケット ソケットアクティベーション sshd.socket
.path パス ファイル/ディレクトリの監視 cups.path

この章では主に.service(サービスユニット)と.timer(タイマーユニット)を扱います。

5.1.5 ユニットファイルの場所

ユニットファイルは、主に2つの場所に配置されます。

ディレクトリ 用途 編集可否
/usr/lib/systemd/system/ パッケージが提供するユニットファイル 編集しない(上書きされる)
/etc/systemd/system/ 管理者が作成・カスタマイズするユニットファイル 編集可能

/etc/systemd/system/にあるファイルは/usr/lib/systemd/system/より優先されます。つまり、システム標準の設定をカスタマイズしたい場合は、/etc/systemd/system/にファイルを配置します。

💡 覚えておこう: カスタムのユニットファイルを作成する場合は、必ず/etc/systemd/system/に配置します。/usr/lib/systemd/system/のファイルは、パッケージのアップデート時に上書きされる可能性があります。

5.2 systemctlコマンドの基本

systemctlは、systemdを操作するための主要なコマンドです。サービスの状態確認、起動、停止など、日常的なサーバー管理のほとんどはこのコマンドで行います。

5.2.1 systemctl statusでサービス状態確認

サービスの状態を確認するには、systemctl statusを使います。これは最も頻繁に使うコマンドです。

[実行ユーザー: 一般ユーザー]

$ systemctl status sshd
● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-01-15 10:30:00 JST; 2h 15min ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1234 (sshd)
      Tasks: 1 (limit: 23456)
     Memory: 5.2M
        CPU: 123ms
     CGroup: /system.slice/sshd.service
             └─1234 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Jan 15 10:30:00 almalinux systemd[1]: Starting sshd.service - OpenSSH server daemon...
Jan 15 10:30:00 almalinux sshd[1234]: Server listening on 0.0.0.0 port 22.
Jan 15 10:30:00 almalinux systemd[1]: Started sshd.service - OpenSSH server daemon.

出力の各項目の意味を説明します。

  • ●(緑の丸): サービスが正常に動作中。赤い丸ならエラー状態
  • Loaded: ユニットファイルの読み込み状態
    • loaded: 正常に読み込み済み
    • 括弧内のenabled: 自動起動が有効(後述)
  • Active: 現在の動作状態
    • active (running): 実行中
    • inactive (dead): 停止中
    • failed: 起動失敗
  • Main PID: メインプロセスのプロセスID
  • Tasks: 実行中のタスク数
  • Memory: メモリ使用量
  • CPU: CPU使用時間
  • CGroup: コントロールグループ(プロセスのグループ化)

下部にはサービスの最近のログが表示されます。トラブル時にはこの部分が重要な手がかりになります。

簡潔に状態だけ確認したい場合は、以下のコマンドも便利です。

[実行ユーザー: 一般ユーザー]

# サービスが動作中かどうかだけ確認
$ systemctl is-active sshd
active

# サービスが自動起動設定されているか確認
$ systemctl is-enabled sshd
enabled

5.2.2 systemctl startでサービス起動

サービスを起動するには、systemctl startを使います。システム管理操作なのでsudoが必要です。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl start sshd

成功した場合は何も出力されません。これはLinuxの「沈黙は成功」という慣習に基づいています。起動できたか確認するには、続けてstatusを実行します。

$ systemctl status sshd
● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-01-15 12:45:00 JST; 5s ago
...

5.2.3 systemctl stopでサービス停止

サービスを停止するには、systemctl stopを使います。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl stop sshd

⚠️ 注意: サービスを停止すると、そのサービスを利用しているユーザーに影響が出ます。本番環境では、停止前に影響範囲を確認し、必要に応じてユーザーへの告知を行ってください。特にSSHを停止すると、リモートからの接続ができなくなります。

5.2.4 systemctl restartで再起動

サービスを再起動(停止→起動)するには、systemctl restartを使います。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl restart sshd

再起動は、設定ファイルを変更した後や、サービスの動作がおかしくなったときに使います。ただし、再起動中はサービスが一時的に停止するため、ユーザーへの影響があります。

5.2.5 systemctl reloadで設定再読み込み

多くのサービスは、設定ファイルを変更しただけでは反映されず、「設定の再読み込み」が必要です。systemctl reloadは、サービスを停止せずに設定だけを再読み込みします。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl reload sshd

reloadはサービスを停止しないため、ユーザーへの影響を最小限に抑えられます。ただし、すべてのサービスがreloadに対応しているわけではありません。対応していないサービスではrestartを使う必要があります。

5.2.6 startとreloadの使い分け

これらのコマンドの使い分けを整理します。

操作 コマンド サービス停止 用途
起動 start 停止中のサービスを起動
停止 stop あり サービスを停止
再起動 restart あり(一時的) 設定変更後、または異常時の復旧
再読み込み reload なし 設定変更後(対応サービスのみ)
条件付き再起動 try-restart あり(一時的) 動作中の場合のみ再起動
再読み込みまたは再起動 reload-or-restart 場合による reloadを試し、非対応ならrestart

設定変更後は、まずreloadを試し、それでも反映されない場合やreloadに対応していない場合はrestartを使う、というのが基本的な方針です。

5.3 サービスの自動起動設定

サービスを起動しても、サーバーを再起動すると停止してしまいます。サーバー起動時に自動的にサービスを起動するには、「自動起動設定」が必要です。

5.3.1 systemctl enableで自動起動有効化

サービスの自動起動を有効にするには、systemctl enableを使います。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl enable sshd
Created symlink /etc/systemd/system/multi-user.target.wants/sshd.service → /usr/lib/systemd/system/sshd.service.

このコマンドは、ユニットファイルへのシンボリックリンクを作成することで、システム起動時にサービスが自動的に起動するよう設定します。

5.3.2 systemctl disableで自動起動無効化

自動起動を無効にするには、systemctl disableを使います。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl disable sshd
Removed "/etc/systemd/system/multi-user.target.wants/sshd.service".

これはシンボリックリンクを削除するだけなので、現在動作中のサービスには影響しません。サービスは引き続き動作しますが、次回のシステム起動時には自動的に起動しなくなります。

5.3.3 systemctl is-enabledで状態確認

自動起動が設定されているかどうかを確認するには、systemctl is-enabledを使います。

[実行ユーザー: 一般ユーザー]

$ systemctl is-enabled sshd
enabled

$ systemctl is-enabled httpd
disabled

5.3.4 enabledとstartedの違い

初学者がよく混乱するポイントです。enablestartは全く別の操作です。

操作 コマンド 意味 効果
起動 start 今すぐ起動する 今この瞬間にサービスが動き始める
自動起動有効化 enable 次回起動時から自動起動 次回以降のシステム起動時に自動で起動する

つまり、以下の4つの状態がありえます。

状態 is-active is-enabled 説明
動作中・自動起動ON active enabled 今動いていて、再起動後も自動起動
動作中・自動起動OFF active disabled 今動いているが、再起動後は起動しない
停止中・自動起動ON inactive enabled 今は停止しているが、再起動後は自動起動
停止中・自動起動OFF inactive disabled 今も停止していて、再起動後も起動しない

新しいサービスをインストールして使い始めるときは、通常enablestartの両方が必要です。これを1つのコマンドで行うオプションがあります。

[実行ユーザー: 一般ユーザー(sudo使用)]

# enableとstartを同時に実行
$ sudo systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.

--nowオプションを付けると、enableと同時にstartも実行されます。同様に、disable --nowで無効化と停止を同時に行えます。

5.3.5 マスクとアンマスク

サービスを完全に無効化したい場合は、maskを使います。disableとの違いは、maskされたサービスは手動でも起動できなくなる点です。

[実行ユーザー: 一般ユーザー(sudo使用)]

# サービスをマスク(完全無効化)
$ sudo systemctl mask httpd
Created symlink /etc/systemd/system/httpd.service → /dev/null.

# マスクされたサービスは起動できない
$ sudo systemctl start httpd
Failed to start httpd.service: Unit httpd.service is masked.

# マスクを解除
$ sudo systemctl unmask httpd
Removed /etc/systemd/system/httpd.service.

maskは、誤って起動されては困るサービス(セキュリティ上の理由で無効にしたいサービスなど)に使用します。

5.4 サービス一覧と依存関係

システムで動作しているサービスの一覧を確認したり、サービス間の依存関係を調べたりする方法を学びます。

5.4.1 systemctl list-unitsで稼働中のユニット一覧

systemctl list-unitsは、現在読み込まれているユニットの一覧を表示します。

[実行ユーザー: 一般ユーザー]

$ systemctl list-units
  UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
  proc-sys-fs-binfmt_misc.automount  loaded active waiting Arbitrary...
  sys-devices-...                    loaded active plugged /sys/devices...
  -.mount                            loaded active mounted Root Mount
  boot.mount                         loaded active mounted /boot
● chronyd.service                    loaded failed failed  NTP client...
  crond.service                      loaded active running Command Scheduler
  dbus.service                       loaded active running D-Bus System...
  firewalld.service                  loaded active running firewalld...
  sshd.service                       loaded active running OpenSSH server...
...

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

出力の各列の意味は以下の通りです。

  • UNIT: ユニット名
  • LOAD: ユニットファイルの読み込み状態(loaded/not-found/error)
  • ACTIVE: 動作状態(active/inactive/failed)
  • SUB: 詳細な状態(running/dead/failed等)
  • DESCRIPTION: ユニットの説明

5.4.2 systemctl list-unit-filesで全ユニットファイル一覧

list-unit-filesは、インストールされているすべてのユニットファイルを表示します。動作中でないものも含まれます。

[実行ユーザー: 一般ユーザー]

$ systemctl list-unit-files --type=service
UNIT FILE                                  STATE           PRESET
auditd.service                             enabled         enabled
chronyd.service                            enabled         enabled
crond.service                              enabled         enabled
dbus-broker.service                        alias           -
firewalld.service                          enabled         enabled
httpd.service                              disabled        disabled
sshd.service                               enabled         enabled
...

STATE列の意味は以下の通りです。

  • enabled: 自動起動が有効
  • disabled: 自動起動が無効
  • static: 単体では有効/無効にできない(他のユニットから呼び出される)
  • masked: 完全に無効化(マスク)されている
  • alias: 別のユニットへのエイリアス

5.4.3 systemctl list-dependenciesで依存関係確認

サービス間には依存関係があります。例えば、「ネットワークが起動してからWebサーバーを起動する」といった関係です。依存関係を確認するには、list-dependenciesを使います。

[実行ユーザー: 一般ユーザー]

$ systemctl list-dependencies sshd
sshd.service
● ├─system.slice
● ├─sshd-keygen.target
● │ ├─sshd-keygen@ecdsa.service
● │ ├─sshd-keygen@ed25519.service
● │ └─sshd-keygen@rsa.service
● └─sysinit.target
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
...

逆に、あるサービスに依存しているユニットを確認するには、--reverseオプションを使います。

$ systemctl list-dependencies sshd --reverse
sshd.service
● └─multi-user.target
●   └─graphical.target

5.4.4 サービスのフィルタリング

特定の種類のユニットだけを表示するには、--typeオプションを使います。また、特定の状態でフィルタリングすることもできます。

[実行ユーザー: 一般ユーザー]

# サービスユニットのみ表示
$ systemctl list-units --type=service

# 失敗したユニットのみ表示
$ systemctl list-units --failed

# 動作中のサービスのみ表示
$ systemctl list-units --type=service --state=running

5.5 ログの確認 – journalctl

サービスが正常に動作しているか、エラーが発生していないかを確認するには、ログを見ることが不可欠です。systemdにはjournaldという統合ログシステムが含まれており、journalctlコマンドでログを確認できます。

5.5.1 systemdのログシステム(journald)

journaldは、systemdに統合されたログ収集・管理システムです。従来のsyslogと比較して、以下のような特徴があります。

  • 構造化されたログ: タイムスタンプ、ユニット名、優先度などのメタデータが付与
  • 高速な検索: インデックスによる効率的な検索
  • 完全性の保証: ログの改ざん検出機能
  • 統一されたインターフェース: すべてのサービスのログを1つのコマンドで確認

5.5.2 journalctlの基本的な使い方

オプションなしでjournalctlを実行すると、すべてのログが時系列で表示されます。

[実行ユーザー: 一般ユーザー]

$ journalctl
-- Logs begin at Wed 2026-01-01 00:00:00 JST, end at Wed 2026-01-15 14:30:00 JST. --
Jan 01 00:00:00 almalinux kernel: Linux version 6.12.0-55.9.1.el10_0.x86_64...
Jan 01 00:00:00 almalinux kernel: Command line: BOOT_IMAGE=(hd0,gpt2)/vmlinuz...
Jan 01 00:00:00 almalinux kernel: x86/fpu: Supporting XSAVE feature 0x001:...
...

ログはページャー(lessコマンド)で表示されます。qで終了、/キーワードで検索、Gで最後に移動できます。

最新のログだけを見たい場合は、-eオプションで最後にジャンプします。

$ journalctl -e

5.5.3 特定サービスのログ表示(-uオプション)

特定のサービスのログだけを表示するには、-uオプションを使います。これはトラブルシューティングで最もよく使うオプションです。

[実行ユーザー: 一般ユーザー]

$ journalctl -u sshd
-- Logs begin at Wed 2026-01-01 00:00:00 JST, end at Wed 2026-01-15 14:30:00 JST. --
Jan 15 10:30:00 almalinux systemd[1]: Starting sshd.service - OpenSSH server daemon...
Jan 15 10:30:00 almalinux sshd[1234]: Server listening on 0.0.0.0 port 22.
Jan 15 10:30:00 almalinux sshd[1234]: Server listening on :: port 22.
Jan 15 10:30:00 almalinux systemd[1]: Started sshd.service - OpenSSH server daemon.
Jan 15 12:15:30 almalinux sshd[5678]: Accepted publickey for developer from 192.168.1.100...
Jan 15 12:15:30 almalinux sshd[5678]: pam_unix(sshd:session): session opened for user developer...

5.5.4 リアルタイムログ監視(-fオプション)

サービスの動作をリアルタイムで監視するには、-fオプション(follow)を使います。新しいログが追加されると、自動的に表示されます。

[実行ユーザー: 一般ユーザー]

$ journalctl -u sshd -f
-- Logs begin at Wed 2026-01-01 00:00:00 JST. --
Jan 15 14:30:00 almalinux sshd[5678]: Received disconnect from 192.168.1.100...
# 新しいログが発生すると自動的に表示される
# Ctrl+C で終了

これは、設定変更後の動作確認や、問題発生時のリアルタイム監視に非常に便利です。

5.5.5 時間範囲指定(–since, –until)

特定の時間範囲のログだけを表示するには、--since--untilオプションを使います。

[実行ユーザー: 一般ユーザー]

# 今日のログ
$ journalctl --since today

# 昨日のログ
$ journalctl --since yesterday --until today

# 特定の日時以降
$ journalctl --since "2026-01-15 10:00:00"

# 1時間前から現在まで
$ journalctl --since "1 hour ago"

# 30分前から現在まで
$ journalctl --since "30 minutes ago"

# 組み合わせ
$ journalctl -u sshd --since "2026-01-15 10:00:00" --until "2026-01-15 12:00:00"

5.5.6 優先度フィルタ(-pオプション)

ログには優先度(重要度)があります。エラーだけを見たい場合など、優先度でフィルタリングできます。

優先度 数値 意味
emerg 0 システムが使用不能
alert 1 即座に対処が必要
crit 2 致命的な状態
err 3 エラー
warning 4 警告
notice 5 通常だが重要
info 6 情報
debug 7 デバッグ

[実行ユーザー: 一般ユーザー]

# エラー以上(err, crit, alert, emerg)を表示
$ journalctl -p err

# 警告以上を表示
$ journalctl -p warning

# 特定サービスのエラーのみ
$ journalctl -u httpd -p err

5.5.7 ログの永続化設定

デフォルトでは、journaldのログは/run/log/journal/に保存され、再起動すると消えてしまいます。ログを永続化するには、/var/log/journal/ディレクトリを作成します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# ログ保存用ディレクトリを作成
$ sudo mkdir -p /var/log/journal

# journaldを再起動
$ sudo systemctl restart systemd-journald

または、/etc/systemd/journald.confで設定することもできます。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo vi /etc/systemd/journald.conf
[Journal]
Storage=persistent

Storageの設定値は以下の通りです。

  • volatile: メモリ上のみ(再起動で消える)
  • persistent: ディスクに永続化
  • auto: /var/log/journal/があれば永続化、なければメモリ上(デフォルト)
  • none: ログを保存しない

💡 実務のヒント: トラブルシューティングの基本は「まずログを見る」です。サービスが起動しない、動作がおかしいと思ったら、まずjournalctl -u サービス名 -eでログを確認する習慣をつけましょう。

5.6 実践: httpdサービスの管理

ここまで学んだ内容を、実際のサービス管理で実践してみましょう。Apache HTTPサーバー(httpd)をインストールし、起動から動作確認、ログ確認まで一連の操作を行います。

5.6.1 Apache HTTPサーバーのインストール

まず、httpdパッケージをインストールします。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo dnf install httpd
Last metadata expiration check: 0:45:00 ago on Wed Jan 15 14:00:00 2026.
Dependencies resolved.
================================================================================
 Package                Arch       Version              Repository        Size
================================================================================
Installing:
 httpd                  x86_64     2.4.62-1.el10        appstream         52 k
Installing dependencies:
 apr                    x86_64     1.7.4-1.el10         appstream        128 k
 apr-util               x86_64     1.6.3-1.el10         appstream         95 k
 httpd-core             x86_64     2.4.62-1.el10        appstream        1.5 M
 httpd-filesystem       noarch     2.4.62-1.el10        appstream         16 k
 httpd-tools            x86_64     2.4.62-1.el10        appstream         84 k
 mailcap                noarch     2.1.54-1.el10        baseos             31 k
 mod_http2              x86_64     2.0.29-1.el10        appstream        171 k
 mod_lua                x86_64     2.4.62-1.el10        appstream         62 k

Transaction Summary
================================================================================
Install  9 Packages

Total download size: 2.1 M
Installed size: 5.8 M
Is this ok [y/N]: y
...
Complete!

5.6.2 サービスの起動

インストール直後は、サービスは停止しています。状態を確認してから起動しましょう。

[実行ユーザー: 一般ユーザー]

# まず状態を確認
$ systemctl status httpd
○ httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; preset: disabled)
     Active: inactive (dead)
       Docs: man:httpd.service(8)

inactive (dead)と表示され、サービスが停止していることがわかります。起動しましょう。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl start httpd

5.6.3 自動起動設定

サーバー再起動後も自動的に起動するよう、自動起動を有効にします。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl enable httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.

または、enable --nowで起動と自動起動設定を同時に行うこともできます。

# 起動と自動起動設定を同時に
$ sudo systemctl enable --now httpd

5.6.4 ステータス確認

サービスが正常に起動しているか確認します。

[実行ユーザー: 一般ユーザー]

$ systemctl status httpd
● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: active (running) since Wed 2026-01-15 15:00:00 JST; 1min ago
       Docs: man:httpd.service(8)
   Main PID: 12345 (httpd)
     Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/Sec: 0; Bytes/Second: 0; Bytes/Request: 0"
      Tasks: 213 (limit: 23456)
     Memory: 25.6M
        CPU: 234ms
     CGroup: /system.slice/httpd.service
             ├─12345 /usr/sbin/httpd -DFOREGROUND
             ├─12346 /usr/sbin/httpd -DFOREGROUND
             ├─12347 /usr/sbin/httpd -DFOREGROUND
             ├─12348 /usr/sbin/httpd -DFOREGROUND
             └─12349 /usr/sbin/httpd -DFOREGROUND

Jan 15 15:00:00 almalinux systemd[1]: Starting httpd.service - The Apache HTTP Server...
Jan 15 15:00:00 almalinux httpd[12345]: AH00558: httpd: Could not reliably determine...
Jan 15 15:00:00 almalinux systemd[1]: Started httpd.service - The Apache HTTP Server.

active (running)enabledが確認できれば成功です。

5.6.5 ログ確認

サービスのログを確認してみましょう。

[実行ユーザー: 一般ユーザー]

$ journalctl -u httpd -e
-- Logs begin at Wed 2026-01-01 00:00:00 JST, end at Wed 2026-01-15 15:05:00 JST. --
Jan 15 15:00:00 almalinux systemd[1]: Starting httpd.service - The Apache HTTP Server...
Jan 15 15:00:00 almalinux httpd[12345]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
Jan 15 15:00:00 almalinux systemd[1]: Started httpd.service - The Apache HTTP Server.

警告メッセージ(AH00558)が出ていますが、これはServerNameが設定されていないという警告で、動作には問題ありません。本番環境では適切に設定します。

5.6.6 設定変更後のリロード

Apacheの設定ファイルを変更した後は、設定を反映させる必要があります。

[実行ユーザー: 一般ユーザー(sudo使用)]

# 設定ファイルの構文チェック
$ sudo apachectl configtest
Syntax OK

# 設定の再読み込み(サービスを停止せずに反映)
$ sudo systemctl reload httpd

構文チェック(apachectl configtest)を先に行うことで、設定ミスによるサービス停止を防げます。

5.6.7 トラブルシューティング実践

サービスが起動しない場合のトラブルシューティング手順を確認しておきましょう。

手順1: ステータスの確認

[実行ユーザー: 一般ユーザー]

$ systemctl status httpd
× httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: failed (Result: exit-code) since Wed 2026-01-15 15:30:00 JST; 10s ago
       Docs: man:httpd.service(8)
    Process: 23456 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
   Main PID: 23456 (code=exited, status=1/FAILURE)
        CPU: 15ms

Jan 15 15:30:00 almalinux systemd[1]: Starting httpd.service - The Apache HTTP Server...
Jan 15 15:30:00 almalinux httpd[23456]: AH00526: Syntax error on line 42 of /etc/httpd/conf/httpd.conf:
Jan 15 15:30:00 almalinux httpd[23456]: Invalid command 'ServrName', perhaps misspelled...
Jan 15 15:30:00 almalinux systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Jan 15 15:30:00 almalinux systemd[1]: httpd.service: Failed with result 'exit-code'.
Jan 15 15:30:00 almalinux systemd[1]: Failed to start httpd.service - The Apache HTTP Server.

手順2: ログの詳細確認

$ journalctl -u httpd -e --no-pager

手順3: 原因の特定と修正

上記の例では、設定ファイルの42行目にServrNameというタイプミスがあることがわかります。正しくはServerNameです。

# 設定ファイルを修正
$ sudo vi /etc/httpd/conf/httpd.conf
# ServrName を ServerName に修正

# 構文チェック
$ sudo apachectl configtest
Syntax OK

# サービスを再起動
$ sudo systemctl start httpd

💡 トラブルシューティングの基本:

  1. systemctl statusで状態とエラーメッセージを確認
  2. journalctl -u サービス名 -eで詳細なログを確認
  3. エラーメッセージを手がかりに原因を特定
  4. 修正後、構文チェックしてから再起動

5.7 カスタムサービスの作成

自分で作成したスクリプトをsystemdのサービスとして登録すると、起動・停止・自動起動の管理が容易になります。ここでは、簡単なスクリプトをサービス化する方法を学びます。

5.7.1 ユニットファイルの基本構造

ユニットファイルは、INI形式のテキストファイルです。基本的な構造は以下の通りです。

[Unit]
# ユニットの説明と依存関係

[Service]
# サービスの動作定義

[Install]
# インストール時の設定

5.7.2 [Unit], [Service], [Install]セクション

各セクションの主要なディレクティブを説明します。

[Unit]セクション

ディレクティブ 説明
Description サービスの説明 Description=My Custom Service
After このユニットより先に起動するユニット After=network.target
Requires 必須の依存ユニット Requires=postgresql.service
Wants あれば起動する依存ユニット Wants=network-online.target

[Service]セクション

ディレクティブ 説明
Type サービスの種類 Type=simple
ExecStart 起動時に実行するコマンド ExecStart=/usr/local/bin/myapp
ExecStop 停止時に実行するコマンド ExecStop=/usr/local/bin/myapp –stop
ExecReload リロード時に実行するコマンド ExecReload=/bin/kill -HUP $MAINPID
Restart 再起動ポリシー Restart=on-failure
User 実行ユーザー User=myuser
WorkingDirectory 作業ディレクトリ WorkingDirectory=/opt/myapp

Typeの値:

  • simple: ExecStartのプロセスがメインプロセス(デフォルト)
  • forking: 起動後にフォークしてバックグラウンドで動作
  • oneshot: 1回実行して終了
  • notify: 起動完了をsystemdに通知

[Install]セクション

ディレクティブ 説明
WantedBy このターゲットの起動時に一緒に起動 WantedBy=multi-user.target
RequiredBy このターゲットに必須 RequiredBy=graphical.target

5.7.3 簡単なサービスの作成例

実際にカスタムサービスを作成してみましょう。定期的に現在時刻をファイルに書き込むスクリプトをサービス化します。

手順1: スクリプトの作成

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo vi /usr/local/bin/time-logger.sh
#!/bin/bash
# 10秒ごとに現在時刻をログファイルに書き込むスクリプト

LOG_FILE="/var/log/time-logger.log"

while true; do
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Time logger is running" >> "$LOG_FILE"
    sleep 10
done
# 実行権限を付与
$ sudo chmod +x /usr/local/bin/time-logger.sh

手順2: ユニットファイルの作成

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo vi /etc/systemd/system/time-logger.service
[Unit]
Description=Time Logger Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/time-logger.sh
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

5.7.4 systemctl daemon-reloadで反映

ユニットファイルを作成・変更した後は、systemdにその変更を認識させる必要があります。

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo systemctl daemon-reload

⚠️ 重要: ユニットファイルを新規作成したり編集したりした後は、必ずsystemctl daemon-reloadを実行してください。これを忘れると、変更が反映されません。

5.7.5 カスタムサービスの起動テスト

サービスを起動して動作を確認します。

[実行ユーザー: 一般ユーザー(sudo使用)]

# サービスを起動
$ sudo systemctl start time-logger

# 状態を確認
$ systemctl status time-logger
● time-logger.service - Time Logger Service
     Loaded: loaded (/etc/systemd/system/time-logger.service; disabled; preset: disabled)
     Active: active (running) since Wed 2026-01-15 16:00:00 JST; 15s ago
   Main PID: 34567 (time-logger.sh)
      Tasks: 2 (limit: 23456)
     Memory: 1.2M
        CPU: 12ms
     CGroup: /system.slice/time-logger.service
             ├─34567 /bin/bash /usr/local/bin/time-logger.sh
             └─34570 sleep 10

Jan 15 16:00:00 almalinux systemd[1]: Started time-logger.service - Time Logger Service.

# ログファイルを確認
$ cat /var/log/time-logger.log
2026-01-15 16:00:00 - Time logger is running
2026-01-15 16:00:10 - Time logger is running
2026-01-15 16:00:20 - Time logger is running

正常に動作していることが確認できたら、自動起動を有効にしましょう。

$ sudo systemctl enable time-logger
Created symlink /etc/systemd/system/multi-user.target.wants/time-logger.service → /etc/systemd/system/time-logger.service.

テストが終わったら、サービスを停止しておきます。

$ sudo systemctl disable --now time-logger

5.8 定期実行 – cronとsystemd timer

サーバー運用では、バックアップやログのローテーションなど、定期的に実行したいタスクがあります。Linuxでは、従来からcronが使われてきましたが、systemdのtimerも選択肢として増えています。

5.8.1 定期実行が必要な理由

定期実行が必要な典型的なタスクには以下のようなものがあります。

  • バックアップ: 毎日深夜にデータベースやファイルをバックアップ
  • ログローテーション: 古いログファイルを圧縮・削除
  • 監視: 定期的にシステムの状態をチェック
  • レポート: 毎朝、前日の統計レポートを生成
  • クリーンアップ: 一時ファイルの定期削除

5.8.2 cronの基本

cron(クロン)は、Unix/Linuxで長く使われてきた定期実行の仕組みです。シンプルで広く普及しているため、情報も豊富です。

cronのインストール確認

AlmaLinux 10では、cronieパッケージとしてcronが提供されています。

[実行ユーザー: 一般ユーザー]

$ rpm -q cronie
cronie-1.7.2-1.el10.x86_64

# インストールされていない場合
$ sudo dnf install cronie

crontabの編集

ユーザーごとの定期実行設定は、crontab -eで編集します。

[実行ユーザー: 一般ユーザー]

$ crontab -e
# エディタが開く

cron構文(5つのフィールド)

crontabのエントリは、以下の形式で記述します。

分 時 日 月 曜日 コマンド
フィールド 値の範囲 説明
0-59 実行する分
0-23 実行する時(24時間表記)
1-31 実行する日
1-12 実行する月
曜日 0-7 実行する曜日(0と7は日曜日)

特殊文字も使えます。

  • *: すべての値(毎分、毎時など)
  • */n: n間隔で(*/5 = 5分ごと)
  • n,m: 複数指定(1,15 = 1日と15日)
  • n-m: 範囲指定(1-5 = 月曜から金曜)

よく使うパターン

# 毎日午前3時に実行
0 3 * * * /path/to/script.sh

# 毎時0分に実行
0 * * * * /path/to/script.sh

# 5分ごとに実行
*/5 * * * * /path/to/script.sh

# 月曜から金曜の午前9時に実行
0 9 * * 1-5 /path/to/script.sh

# 毎月1日の午前0時に実行
0 0 1 * * /path/to/script.sh

# 毎週日曜日の午前2時に実行
0 2 * * 0 /path/to/script.sh

設定の確認

[実行ユーザー: 一般ユーザー]

# 現在のcrontab設定を表示
$ crontab -l
0 3 * * * /home/developer/backup.sh
*/5 * * * * /home/developer/check-disk.sh

実行結果の確認

cronの実行ログは、journalctlで確認できます。

$ journalctl -u crond

5.8.3 systemd timerの基本

systemd timerは、cronの代替として使える定期実行の仕組みです。systemdと統合されているため、サービス管理と同じ方法で管理できます。

timerとserviceの組み合わせ

systemd timerでは、以下の2つのユニットファイルが必要です。

  • .timer ファイル: いつ実行するかを定義
  • .service ファイル: 何を実行するかを定義

timerユニットの例

[実行ユーザー: 一般ユーザー(sudo使用)]

$ sudo vi /etc/systemd/system/my-backup.timer
[Unit]
Description=Run backup daily

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
$ sudo vi /etc/systemd/system/my-backup.service
[Unit]
Description=Backup Service

[Service]
Type=oneshot
ExecStart=/home/developer/backup.sh
User=developer

OnCalendar構文

OnCalendarは、crontabに似た形式で時刻を指定します。

# 毎日午前3時
OnCalendar=*-*-* 03:00:00

# 毎時0分
OnCalendar=*-*-* *:00:00

# 毎週月曜日の午前9時
OnCalendar=Mon *-*-* 09:00:00

# 毎月1日の午前0時
OnCalendar=*-*-01 00:00:00

# 5分ごと(別の方法)
OnCalendar=*:0/5

便利な省略形もあります。

OnCalendar=daily      # 毎日00:00
OnCalendar=weekly     # 毎週月曜00:00
OnCalendar=monthly    # 毎月1日00:00
OnCalendar=hourly     # 毎時00分

timerの有効化と確認

[実行ユーザー: 一般ユーザー(sudo使用)]

# daemon-reloadを忘れずに
$ sudo systemctl daemon-reload

# timerを有効化・起動
$ sudo systemctl enable --now my-backup.timer

# timerの一覧を表示
$ systemctl list-timers
NEXT                        LEFT          LAST                        PASSED       UNIT                         ACTIVATES
Wed 2026-01-16 03:00:00 JST 11h left      Wed 2026-01-15 03:00:00 JST 12h ago      my-backup.timer              my-backup.service
...

timerの利点

  • ログ統合: journalctlで実行ログを確認できる
  • 依存関係: 他のサービスとの依存関係を定義できる
  • Persistent: システム停止中に逃したジョブを起動後に実行
  • 精度: 秒単位での指定が可能
  • リソース制御: CPUやメモリの制限を設定できる

5.8.4 cronとtimerの使い分け

cronとsystemd timerには、それぞれ利点があります。

観点 cron systemd timer
学習コスト 低い やや高い
情報量 豊富 増加中
設定の簡潔さ 1行で完結 2ファイル必要
ログ管理 別途設定が必要 journaldと統合
依存関係 なし 定義可能
逃したジョブ 実行されない Persistentで実行可能

使い分けの指針

  • cronを使う場合: 簡単な定期実行、既存のcron設定がある場合、チームがcronに慣れている場合
  • timerを使う場合: サービスとの連携が必要な場合、詳細なログ管理が必要な場合、リソース制御が必要な場合

初学者には、まずcronで定期実行の概念を理解し、その後必要に応じてtimerを学ぶことをお勧めします。

5.9 実践: ログのバックアップ自動化

cronを使って、実際にログファイルのバックアップを自動化してみましょう。

5.9.1 バックアップスクリプトの作成

[実行ユーザー: 一般ユーザー]

$ mkdir -p ~/scripts
$ vi ~/scripts/backup-logs.sh
#!/bin/bash
#
# ログファイルのバックアップスクリプト
# 毎日深夜に実行し、7日分のバックアップを保持する
#

# 設定
BACKUP_DIR="/home/developer/backups/logs"
SOURCE_DIR="/var/log"
DATE=$(date +%Y%m%d)
BACKUP_FILE="logs-${DATE}.tar.gz"
KEEP_DAYS=7

# バックアップディレクトリの作成
mkdir -p "$BACKUP_DIR"

# バックアップの実行
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting backup..."

# /var/logから主要なログをバックアップ
# (sudo権限が必要なファイルは除外)
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" \
    --ignore-failed-read \
    -C / \
    var/log/messages \
    var/log/secure \
    var/log/cron \
    2>/dev/null

if [ $? -eq 0 ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup completed: ${BACKUP_FILE}"
else
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup completed with warnings"
fi

# 古いバックアップの削除
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Cleaning up old backups..."
find "$BACKUP_DIR" -name "logs-*.tar.gz" -mtime +${KEEP_DAYS} -delete

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Done."
# 実行権限を付与
$ chmod +x ~/scripts/backup-logs.sh

# バックアップディレクトリを作成
$ mkdir -p ~/backups/logs

5.9.2 cronで毎日深夜に実行

作成したスクリプトを毎日午前3時に実行するよう設定します。

[実行ユーザー: 一般ユーザー]

$ crontab -e

以下の行を追加します。

# ログバックアップ - 毎日午前3時に実行
0 3 * * * /home/developer/scripts/backup-logs.sh >> /home/developer/backups/logs/backup.log 2>&1

設定を確認します。

$ crontab -l
# ログバックアップ - 毎日午前3時に実行
0 3 * * * /home/developer/scripts/backup-logs.sh >> /home/developer/backups/logs/backup.log 2>&1

5.9.3 動作確認と検証

設定を待たずに、手動で実行して動作を確認しましょう。

[実行ユーザー: 一般ユーザー]

# 手動でスクリプトを実行
$ ~/scripts/backup-logs.sh
[2026-01-15 16:30:00] Starting backup...
[2026-01-15 16:30:01] Backup completed: logs-20260115.tar.gz
[2026-01-15 16:30:01] Cleaning up old backups...
[2026-01-15 16:30:01] Done.

# バックアップファイルの確認
$ ls -la ~/backups/logs/
total 24
drwxr-xr-x 2 developer developer 4096 Jan 15 16:30 .
drwxr-xr-x 3 developer developer 4096 Jan 15 16:25 ..
-rw-r--r-- 1 developer developer 8765 Jan 15 16:30 logs-20260115.tar.gz

# 内容の確認
$ tar -tzf ~/backups/logs/logs-20260115.tar.gz
var/log/messages
var/log/secure
var/log/cron

5.9.4 エラーハンドリング

cronジョブが失敗した場合に備えて、エラーハンドリングを追加することも重要です。

改良版のスクリプトでは、以下のような対策を行っています。

  • 終了ステータスの確認: $?でコマンドの成否を確認
  • 標準エラー出力のリダイレクト: 2>&1でエラーもログファイルに記録
  • ログへの記録: 実行時刻と結果を記録

より本格的なスクリプトでは、以下のような機能を追加することも検討してください。

  • メール通知(エラー時に管理者にメール送信)
  • ロック機構(同時実行の防止)
  • ディスク容量チェック(バックアップ先の空き容量確認)

【コラム4】サービス起動失敗で障害対応、原因はtypoだった話

ある日の深夜2時、アラートが鳴りました。「Webサーバー応答なし」。

慌ててサーバーにログインし、まずsystemctl status httpdを確認。

× httpd.service - The Apache HTTP Server
     Active: failed (Result: exit-code)

「failed」の赤い表示に嫌な予感がしました。続けてjournalctl -u httpd -eでログを確認。

AH00526: Syntax error on line 127 of /etc/httpd/conf/httpd.conf:
Invalid command 'DocumnetRoot'

「DocumnetRoot」…?

数時間前に設定を変更したことを思い出しました。バーチャルホストの追加です。確認すると、確かにDocumentRootDocumnetRootと書いていました。「e」と「n」の順番が逆です。

修正してapachectl configtestで構文チェック、「Syntax OK」を確認してからsystemctl start httpd。無事に復旧しました。

この経験から学んだこと:

  1. 設定変更後は必ず構文チェック: apachectl configtestnginx -tなど、各サービスには構文チェック機能がある
  2. エラーメッセージをよく読む: 「Invalid command ‘DocumnetRoot’」と、問題の箇所がそのまま表示されていた
  3. コピペも慎重に: 既存の設定をコピペしたつもりでも、手打ちした部分でミスが起きやすい
  4. 変更前にバックアップ: 設定ファイルは変更前にコピーを取っておく

たった一文字のtypoでサービスが停止し、深夜に叩き起こされる。サーバー管理者なら誰もが経験する「あるある」です。だからこそ、設定変更は慎重に、そしてログを読む習慣を身につけましょう。


章末まとめ

この章では、systemdによるサービス管理について学びました。

systemdの基本概念

  • systemdはLinuxのinit systemであり、サービスの起動・停止・監視を統合的に管理する
  • 管理対象は「ユニット」という単位で扱い、.service、.timer、.mountなどの種類がある
  • ユニットファイルは/usr/lib/systemd/system/(システム標準)と/etc/systemd/system/(カスタム)に配置

systemctlコマンド

  • systemctl status: サービスの状態確認(最も重要)
  • systemctl start/stop/restart: サービスの起動・停止・再起動
  • systemctl reload: 設定の再読み込み(停止せずに反映)
  • systemctl enable/disable: 自動起動の有効化・無効化
  • systemctl enable --now: 自動起動設定と起動を同時に

enabledとstartedの違い

  • enabled: 次回起動時に自動的に起動する設定
  • started(active): 今この瞬間に動作している状態
  • 新しいサービスを使い始めるときは、通常両方の設定が必要

journalctlによるログ確認

  • journalctl -u サービス名: 特定サービスのログを表示
  • journalctl -f: リアルタイム監視
  • journalctl --since/--until: 時間範囲でフィルタ
  • journalctl -p err: エラー以上の優先度でフィルタ

カスタムサービスの作成

  • ユニットファイルは[Unit]、[Service]、[Install]の3セクションで構成
  • 作成・変更後はsystemctl daemon-reloadが必須

定期実行

  • cron: 従来からの定期実行ツール、シンプルで情報が豊富
  • systemd timer: systemdと統合、ログ管理や依存関係に優れる
  • 初学者はまずcronで慣れ、必要に応じてtimerを使う

練習問題

問題1: 以下のsystemctl status出力を読み、各項目の意味を説明してください。

● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled)
     Active: active (running) since Wed 2026-01-15 10:00:00 JST; 3h ago
   Main PID: 1234 (nginx)
  1. 「enabled」は何を意味しますか?
  2. 「active (running)」は何を意味しますか?
  3. このサービスはシステム再起動後も自動的に起動しますか?
解答例を見る

a) enabledは、システム起動時に自動的にサービスが起動する設定になっていることを意味します。

b) active (running)は、現在サービスが動作中であることを意味します。

c) はい、自動的に起動します。enabledになっているため、システム再起動後も自動的に起動します。

問題2: 新しくインストールしたhttpdサービスを、今すぐ起動し、かつシステム再起動後も自動起動するようにするコマンドを書いてください。

解答例を見る
# 方法1: 2つのコマンドを実行
$ sudo systemctl start httpd
$ sudo systemctl enable httpd

# 方法2: 1つのコマンドで同時に実行(推奨)
$ sudo systemctl enable --now httpd

問題3: sshdサービスの過去1時間のエラーログだけを確認するコマンドを書いてください。

解答例を見る
$ journalctl -u sshd --since "1 hour ago" -p err

または

$ journalctl -u sshd --since "1 hour ago" -p 3

問題4: 毎日午前2時30分に/home/developer/scripts/cleanup.shを実行するcrontabエントリを書いてください。

解答例を見る
30 2 * * * /home/developer/scripts/cleanup.sh

crontabの形式は「分 時 日 月 曜日 コマンド」です。30分、2時、毎日(*)、毎月(*)、毎曜日(*)なので、「30 2 * * *」となります。

問題5: 以下の要件を満たす簡単なユニットファイル(/etc/systemd/system/hello.service)を作成してください。

  • 説明: “Hello World Service”
  • ネットワーク起動後に開始
  • 実行コマンド: /usr/local/bin/hello.sh
  • 失敗時に自動再起動
  • multi-user.targetで自動起動
解答例を見る
[Unit]
Description=Hello World Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/hello.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

次章への橋渡し

この章では、systemdによるサービス管理の基礎を学びました。サービスの起動・停止・状態確認ができるようになり、ログの確認方法も習得しました。これらはサーバー運用の基本中の基本です。

次の第6章では、ネットワーク設定と時刻同期について学びます。サーバーがネットワークに接続されていなければ、「サーバー」としての役割を果たせません。IPアドレスの設定、ファイアウォールの設定、そして見落としがちな時刻同期について詳しく解説します。

この章で学んだhttpdサービスも、次章でファイアウォールを適切に設定しなければ外部からアクセスできません。サービス管理とネットワーク設定は、車の両輪のような関係です。両方を理解することで、実用的なサーバー構築ができるようになります。

前の記事
次の記事