systemd本番サービス運用パターン:実践的設定とトラブル回避¶
この記事の対象者
- 本番環境でsystemdサービス運用を行っている中級者(基本的なsystemctl操作ができる方)
この記事のポイント¶
- 本番運用で頻出する依存関係エラーの予防設定
- メモリ・CPU制限による安定運用の実装
- 障害時の自動復旧とログ管理パターンの構築
なぜこの問題が今重要か¶
本番環境では、サービス停止・メモリリーク・依存関係エラーが業務継続に直結します。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