コンテンツにスキップ

systemd本番サービス運用パターン:実践的設定とトラブル回避

この記事の対象者

  • 本番環境でsystemdサービス運用を行っている中級者(基本的なsystemctl操作ができる方)

この記事のポイント

  1. 本番運用で頻出する依存関係エラーの予防設定
  2. メモリ・CPU制限による安定運用の実装
  3. 障害時の自動復旧とログ管理パターンの構築

なぜこの問題が今重要か

本番環境では、サービス停止・メモリリーク・依存関係エラーが業務継続に直結します。systemdの基本的な作成方法は理解していても、実際の運用で遭遇する「サービス間の起動順序問題」「リソース枯渇による障害」「ログ管理の煩雑さ」を解決できずに困るケースが多発しています。

解決ステップ概要

ステップ内容到達指標
1依存関係の明示的設定他サービスとの順序保証
2リソース制限の実装メモリ・CPU使用量制御
3自動復旧・ログ管理の設定障害時の自動回復動作

ステップ1: 依存関係の明示的設定

Webアプリケーション + データベースの典型パターンで実装します。

[Unit]
Description=Web Application Service
After=network.target postgresql.service
Wants=postgresql.service
Requires=network.target

[Service]
Type=forking
User=webapp
Group=webapp
ExecStart=/opt/webapp/bin/start.sh
ExecStop=/opt/webapp/bin/stop.sh
PIDFile=/var/run/webapp/webapp.pid
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

重要設定の解説: - After=: 指定サービス起動後に開始(順序保証) - Wants=: 依存サービスの起動を試行(失敗時も継続) - Requires=: 必須依存関係(失敗時は当サービスも停止)

ステップ2: リソース制限の実装

メモリリークやCPU使いすぎを防ぐ制限設定:

[Unit]
Description=Resource-Limited Web Service
After=network.target

[Service]
Type=simple
User=webapp
ExecStart=/opt/webapp/app
Restart=always
RestartSec=5

# リソース制限
MemoryLimit=512M
CPUQuota=50%
TasksMax=100

# セキュリティ強化
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=/var/log/webapp /var/lib/webapp

[Install]
WantedBy=multi-user.target

効果: メモリ512MB超過時の自動killによりシステム全体の安定性確保。

ステップ3: 自動復旧・ログ管理の設定

障害時の自動復旧と構造化ログ出力:

[Unit]
Description=Self-Healing API Service
After=network.target

[Service]
Type=simple
User=apiuser
ExecStart=/usr/local/bin/api-server
StandardOutput=journal
StandardError=journal
SyslogIdentifier=api-service

# 自動復旧設定
Restart=on-failure
RestartSec=10
StartLimitIntervalSec=300
StartLimitBurst=5

# 環境変数でログレベル制御
Environment=LOG_LEVEL=INFO
Environment=LOG_FORMAT=json

[Install]
WantedBy=multi-user.target

ログ確認コマンド:

# リアルタイム監視
journalctl -u api-service -f

# 構造化ログ検索
journalctl -u api-service -o json-pretty | grep ERROR

よくある落とし穴と対処

症状原因即時対処
サービス起動失敗依存サービス未起動After=に依存関係追加
メモリ不足でkillリソース制限未設定MemoryLimit=設定
ログが見つからない出力先が標準出力StandardOutput=journal追加
高度な運用パターン(大規模環境向け) ### マルチインスタンス管理
# /etc/systemd/system/webapp@.service
[Unit]
Description=Web App Instance %i
After=network.target

[Service]
Type=simple
User=webapp
ExecStart=/opt/webapp/start.sh %i
Environment=INSTANCE_ID=%i
PrivateTmp=yes

[Install]
WantedBy=multi-user.target
**使用方法**:
# インスタンス別起動
systemctl start webapp@1.service webapp@2.service
systemctl enable webapp@{1..3}.service
### 条件起動(環境別設定)
[Unit]
Description=Production Only Service
ConditionPathExists=/etc/production.flag
ConditionKernelCommandLine=!rescue

[Service]
ExecStart=/opt/service/prod-service

次に読む(関連記事)