Prometheus を本番環境に導入した話

f:id:hacomono-tech:20210302090157p:plain

こんにちは、hacomonoの工藤です。

以前の記事でもご紹介しましたが、hacomono では uptimerobot というサービスを使って外形監視を実現しています。今回はさらにCPU・メモリ・ディスク容量などの監視ポイントを強化するために Prometheus を導入した話を書きたいと思います。

以前の記事は↓です。

note.com

Prometheus とは

f:id:hacomono-tech:20210302085529p:plain

Prometheus は OSS のメトリクス監視ツールで、以下のような特徴があります。

  • 監視対象サーバーに exporter と呼ばれるエージェントを配置
  • Prometheus Server から exporter が出力するメトリクスをプルする
  • PromQL でメトリクスを柔軟に抽出、閾値を超えたらアラート
  • サービスディスカバリで監視対象を自動検知
  • Grafana と組み合わせてメトリクスをダッシュボードで見やすく表示

なぜ Prometheus を採用するのか

hacomono では現在、AWS 上にお客様毎に分離された EC2/RDS/VPC リソースを構築するシングルテナント構成を採用しています。導入社数の増加に伴い管理対象サーバーの台数がかなり増えてきており (執筆時点で300台ほど)、外形監視以外の部分の監視の強化が課題となっておりました。

監視のための SaaS サービスとして Datadog などの導入も検討しましたが、どのサービスもサーバー台数ベースでの価格体系になっており採用が難しく、今後のサーバー台数増加にも柔軟に耐えられるよう、サービスディスカバリ機能を持つ Prometheus を導入することにしました。

1) Prometheus をインストール

今回は Amazon Linux 2 環境にインストールします。単に Prometheus を起動するだけならとても簡単です。

$ cd /usr/local/src
$ wget https://github.com/prometheus/prometheus/releases/download/v2.23.0/prometheus-2.23.0.linux-amd64.tar.gz
$ tar -xzvf prometheus-2.23.0.linux-amd64.tar.gz
$ cd prometheus-2.23.0.linux-amd64/
$ ./prometheus

次に Prometheus を systemctl へ登録して自動起動するようにします。以下の要領で /usr/lib/systemd/system/prometheus.service を作成します。

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/src/prometheus/prometheus \
 --config.file=/usr/local/src/prometheus/prometheus.yml \

[Install]
WantedBy=multi-user.target

systemctl で自動起動を有効にします。

$ systemctl enable prometheus.service
$ systemctl start prometheus.service

次に設定ファイル prometheus.yml を編集します。

この後にインストールする Alertmanager の設定、アラートルール設定ファイルのパス、メトリックス収集対象となるサーバーを自動検出するためのサービスディスカバリ設定を追加しています。サービスディスカバリの部分は、事前に EC2 ロールに AmazonEC2ReadOnlyAccess 権限を付与しておくことで、監視対象の EC2 サーバーの情報を参照可能としています。

global:
 scrape_interval: 1m
 evaluation_interval: 1m

# Alertmanager 設定
alerting:
 alertmanagers:
 - static_configs:
   - targets:
     - localhost:9093

# アラートルール設定
rule_files:
 - "rules.yml"

# メトリクス収集設定
scrape_configs:
 - job_name: 'prometheus'
   static_configs:
   - targets: ['localhost:9090']

 # 監視対象ノード設定
 - job_name: 'node'
   # HTTPS 通信で証明書エラーを無視する
   tls_config:
     insecure_skip_verify: true

   # サービスディスカバリ設定、EC2 ロールの権限範囲で参照する
   ec2_sd_configs:
     - region: ap-northeast-1
       filters:
         - name: tag:Role
           values:
             - app
             - admin-app
   # パブリックIPでメトリックスを取得できるよう、ラベルの設定を行う
   relabel_configs:
     - source_labels: [__meta_ec2_public_ip]
       regex: '(.*)'
       target_label: __address__
       replacement: '${1}'
     - source_labels: [__meta_ec2_tag_Name]
       target_label: instance

最後にアラートルール設定ファイルを、prometheus.yml と同じ階層に rules.yml として作成します。今回はサーバーダウン・メモリ使用率が90%以上を検知できるような設定を追加しました。

groups:
 - name: alert
   rules:
     - alert: InstanceDown
       expr: up == 0
       for: 1m
       labels:
         severity: critical
       annotations:
         description: '{{ $labels.instance }} of {{ $labels.description }} has been down for more than 1 minutes.'
         summary: 'Instance {{ $labels.instance }} down'

     - alert: MemoryUsed
       expr: 100 * (1 - node_memory_MemFree_bytes{job="node"} / node_memory_MemTotal_bytes{job="node"}) > 90
       for: 5m
       labels:
         severity: critical
       annotations:
         summary: "Memory {{ $labels.instance }} used over 90%"
         description: "Memory of {{ $labels.instance }} has been used over 90% for more than 5 minutes."

ここまでの設定で Prometheus を起動させてみると、監視対象サーバーが自動で検出されていることが確認できます。

f:id:hacomono-tech:20210302085734p:plainf:id:hacomono-tech:20210302085734p:plain

2) Alertmanager をインストールする

次に Alertmanager と呼ばれる、アラートルールの閾値を超えた際にメール送信・Slack 通知などの処理を行うサービスをインストールします。インストールの仕方は Prometheus とほぼ同じノリです。

$ cd /usr/local/src
$ wget https://github.com/prometheus/alertmanager/releases/download/v0.21.0/alertmanager-0.21.0.linux-amd64.tar.gz
$ tar -xzvf alertmanager-0.21.0.linux-amd64.tar.gz
$ cd alertmanager-0.21.0.linux-amd64
$ ./alertmanager

次に alertmanager.yml を変更してアラート通知設定を行います。今回は Slack 通知の設定を追加しました。

global:
 resolve_timeout: 5m

route:
 group_by: ['alertname']
 group_wait: 10s
 group_interval: 10s
 repeat_interval: 1h
 receiver: 'notification'
receivers:
 - name: 'notification'
   slack_configs:
     - api_url: 'https://hooks.slack.com/services/xxxx'
       text: "{{ .CommonAnnotations.summary }}"
       send_resolved: true
inhibit_rules:
 - source_match:
     severity: 'critical'
   target_match:
     severity: 'warning'
   equal: ['alertname', 'dev', 'instance']

3) 監視対象サーバーに node_exporter をインストールする

次に監視対象となるサーバーに node_exporter という CPU・メモリ・ディスク・I/O・ネットワークなどのマシンレベルのメトリクスを提供する exporter をインストールします。この exporter は沢山の種類があり、また独自の exporter を用意することも可能となっています。

監視対象サーバーに SSH して、以下の要領で node_exporter をインストールします。

$ cd /usr/local/src
$ wget https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-amd64.tar.gz
$ tar -xzvf node_exporter-1.0.1.linux-amd64.tar.gz
$ cd node_exporter-1.0.1.linux-amd64
$ ./node_exporter

デフォルトでは 9100 ポートで起動し、http://xxx.hacomono.jp:3000/metrics にアクセスすると実際のメトリクスを確認することができます。

実際の運用では、Prometheus サーバーからのみこのポートにアクセス可能なよう、セキュリティグループの編集を行う必要があります。弊社の場合は監視対象のサーバーがかなり多いので、この辺りの設定も踏まえて Ansible で一括でセットアップを実施しました。

4) Grafana をインストールする

Prometheus 単体でもグラフは表示可能なのですが、より見やすいダッシュボードを利用できる Grafana をインストールしました。Grafana は yum コマンドでインストール可能です。

$ yum install https://dl.grafana.com/oss/release/grafana-7.3.6-1.x86_64.rpm
$ systemctl enable grafana-server
$ systemctl start grafana-server

起動後、ブラウザでアクセスしてまずは Prometheus をデータソースとして登録します。

f:id:hacomono-tech:20210302085919p:plainf:id:hacomono-tech:20210302085919p:plain

登録後は自分でダッシュボードをぽちぽち作っていきます。使用できるメトリックスも候補が表示されるので、どんな数値が取れているかを確認しながらグラフを追加していくことができました。

f:id:hacomono-tech:20210302085938p:plain

ここで AWS からマネージド Prometheus/Grafana が発表...

と、ここまで作業してしまいましたが、昨年 AWS からマネージド Prometheus の発表がありましたね。。まだプレビュー版ですが、なるべくマネージドサービスに寄せたい気持ちがあるので、そのうちこちらにリプレイスすることになりそうです 😇

aws.amazon.com