PrometheusでSystemdを監視する:サーバーが「生存」していてもアプリが「死んでいる」状態を防ぐ

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

課題:ダッシュボードは「正常」なのに、顧客からエラーの連絡が来る

GrafanaでサーバーのCPUやメモリが安定しているのを確認して安心していたら、顧客から「サイトに繋がらない」とクレームの電話が鳴り止まない……そんな経験はありませんか?原因は単純です。サーバー自体は生きていても、NginxやMySQL、あるいはsystemd unitとして実行しているPythonのボットなどのコアサービスがfailed状態になったりフリーズしたりしているからです。

Node Exporterでもデフォルトでsystemdを監視できますが、それはあくまで表面的なものです。各ユニットの正確な稼働時間(uptime)を把握したり、重要なサービスだけをフィルタリングしたりするには、Systemd Exporterこそが真の解決策です。これにより、サービスの状態をより詳細かつ効率的に管理できるようになります。

5分で完了するSystemd Exporterの導入

複雑な手順は不要です。Linuxサーバーにバイナリをインストールし、すぐにPrometheusと接続しましょう。

ステップ1:バイナリのダウンロードとインストール

# GitHub Prometheus Communityで最新バージョンを確認
export VERSION="0.6.0"
wget https://github.com/prometheus-community/systemd_exporter/releases/download/v${VERSION}/systemd_exporter-${VERSION}.linux-amd64.tar.gz
tar -xvf systemd_exporter-${VERSION}.linux-amd64.tar.gz
sudo cp systemd_exporter-${VERSION}.linux-amd64/systemd_exporter /usr/local/bin/

ステップ2:Exporter用のSystemdサービス設定

Exporterをroot権限で実行するのはセキュリティ上のリスクがあります。ログイン権限のない専用ユーザーを作成して実行するのがベストプラクティスです。

sudo useradd --no-create-home --shell /bin/false systemd_exporter
sudo nano /etc/systemd/system/systemd_exporter.service

以下の設定内容を貼り付けます:

[Unit]
Description=Systemd Exporter
After=network-online.target

[Service]
User=systemd_exporter
Group=systemd_exporter
ExecStart=/usr/local/bin/systemd_exporter \
    --collector.unit-include="(nginx|mysql|docker|ssh).*" \
    --web.listen-address=":9101"

[Install]
WantedBy=multi-user.target

Tips: --collector.unit-include フラグは非常に重要です。これにより、必要なサービスのメトリクスのみを取得し、何百もの不要なシステムサービスでPrometheus의データベースが溢れるのを防ぐことができます。

ステップ3:有効化

sudo systemctl daemon-reload
sudo systemctl enable --now systemd_exporter

# 結果を素早くテスト
curl http://localhost:9101/metrics | grep node_systemd_unit_state

なぜSystemd Exporterを導入すべきなのか?

「Node Exporterがあるのに、なぜわざわざ追加でインストールするのか?」と疑問に思うかもしれません。実際、Systemd Exporterは非常に軽量(メモリ消費量わずか10〜15MB程度)でありながら、Node Exporterでは不十分な以下の3つのメリットを提供します。

  • Regexフィルタリング: ダッシュボードに表示させるサービスを正確に選択できます。
  • 正確な稼働時間: サービスが起動してから何秒経過したかを把握できます。この数値が頻繁にリセットされる場合は、アプリがクラッシュループに陥っている証拠です。
  • 多様なステータス: activating(起動中)とfailed(停止)の微妙な境界線を明確に区別できます。

Prometheusでのデータ収集設定

prometheus.yml ファイルに以下の設定を追加します。IPアドレスは実際の環境に合わせて変更してください。

scrape_configs:
  - job_name: 'systemd_nodes'
    static_configs:
      - targets: ['192.168.1.10:9101']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        replacement: 'app-server-01'

実践的なヒント:アラート疲れ(Alert Fatigue)を解消する

以前、50台のノードを管理していた際、すべての通知を有効にするという「初心者」特有のミスを犯しました。ログ掃除のタイマーが停止しただけで通知が飛び、結局ノイズが多すぎて重要なアラートを無視するようになってしまいました。これを解決するために、アラートを以下の2つのカテゴリに分けましょう。

1. クリティカルアラート(サービスの完全停止)

最重要サービスのみに適用します。failed 状態が2分以上続いた場合にのみアラートを飛ばします。

- alert: ServiceDown
  expr: node_systemd_unit_state{state="failed"} == 1
  for: 2m
  labels:
    severity: critical
  annotations:
    summary: "サービス {{ $labels.name }} が {{ $labels.instance }} で停止しています"

2. ワーニングアラート(頻繁な再起動)

これは最も厄介な「サイレント」エラーです。サービスは active と表示されますが、30秒ごとに再起動を繰り返しているようなケースです。この場合、node_systemd_unit_start_time_seconds メトリクスを使用して検知します。

- alert: ServiceFlapping
  expr: (time() - node_systemd_unit_start_time_seconds) < 60
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "サービス {{ $labels.name }} が頻繁に再起動しています"

ダッシュボードと運用

ダッシュボードをゼロから作成する必要はありません。**Grafana ID: 7539** を使用してください。システム全体の正常・異常(緑/赤)を俯瞰できます。稼働時間のグラフを確認し、右肩上がりの線が突然垂直に落下していたら、すぐにログを確認すべきタイミングです。

最後にいくつか注意点です。ポート9101をインターネットに公開するのは厳禁です。ファイアウォールを使用して、Prometheusサーバーからのアクセスのみを許可してください。また、NginxとPHP-FPMをソケット経由で連携させている場合は、.socket ユニットも監視対象に加えることで、処理の詰まりを未然に防ぐことができます。

systemdレベルでの詳細な監視により、夜も安心して眠れるようになりました。顧客から苦情が来る前に、サービスが不安定になった瞬間に対応できるからです。皆さんもぜひ、自社システムの完璧なコントロールを目指してください!

Share: