インフラ・サービス監視ツールの新顔「Prometheus」入門

サーバーやインフラなどの監視ツールの1つとして最近注目されているのが「Prometheus」だ。Prometheusはインストールや設定が容易で、かつ十分な機能を持ち管理しやすいという特徴を持つ。本記事ではこのPrometheusの導入方法、基本的な監視設定の流れを紹介する。

クラウド時代の監視管理ツール

ネットサービスを運営する場合、そのサービスを運営するソフトウェアやサーバー、ネットワーク機器などの状況を監視する手段を用意するのが一般的だ。監視を行い、意図しない状況になったら自動的にメールなどで通知を行うシステムを構築することで、問題をいち早く解決できるようになる。さらに、サービスやマシンの稼働ログを適切に記録することで潜在的な問題を事前に見つけたり、最適化に向けた分析を行うといったことも可能になる。

監視や問題発覚時の通知などを行うオープンソースのツールとしては、過去にElasticsearchZabbixCactiHinemosなどを紹介したが、今回紹介するのは最近注目されている新しい監視・通知ツールである「Prometheus(プロメテウス)」だ(図1)。

図1 PrometheusのWebサイト

Prometheusは2016年7月にバージョン1.0がリリースされた、比較的新しいソフトウェアだ。音楽共有サービスを手がけるSoundCloudが開発したもので、現在は独立したプロジェクトとしてLinux Foundationのクラウド関連オープンソースプロジェクト「Cloud Native Computing Foundation」の支援の下活発な開発が続けられており、2017年11月9日にはメジャーアップデート版となるバージョン2.0がリリースされている。

Prometheusが注目される理由としては、構造がシンプルでセットアップが容易な点がまず挙げられる。外部ライブラリなどに依存せず、バイナリと設定ファイルを用意するだけで利用できるほか、データを格納するデータベースを別途用意する必要もない。また、DockerやKubernetesといったコンテナ/クラスタ管理ツールとの連携機能もあり、容易に監視対象を設定できる。

それに加えて、柔軟なクエリ機能やデータの視覚化機能を備えており、取得したデータを加工して表示したり、そのデータからグラフを作成するといった操作が簡単に行える。もちろん、問題発生時に通知を行うアラート機能も備えている。

いっぽうで、Prometheusはモニタリングを定期的に行うことを重視しており、その精度については100%を保証していない。そのため、たとえば課金のために正確にリクエスト数を記録する、といった用途には適していないという。

Prometheusのアーキテクチャ

Prometheusでは、データの収集・保存・管理を行う「Prometheus Server」が監視対象にアクセスを行って各種データを取得することで監視を行う「プル(Pull)型」のアーキテクチャを採用している(図2)。

図2 Prometheusによる監視アーキテクチャ

このようなアーキテクチャでは、Prometheusからのリクエストに応じて監視対象のデータを送信する仕組みを用意する必要がある。これを行うコンポーネントは「exporter」と呼ばれており、サーバーのリソースを収集して送信する「Node/system metrics exporter」やMySQLサーバーの情報を収集・送信する「MySQL exporter」など、すでにさまざまなexporterが開発されている。

また、ネイティブでPrometheusに対応するソフトウェアも登場しており、たとえばEtcdやKubernetes、Dockerデーモンといったソフトウェアでは別途exporterを用意することなしに、直接Prometheus Serverがこれらにアクセスしてデータを取得できるようになっている。

もちろん、独自にPrometheusからのリクエストを処理する仕組みを実装することも可能だ。これを支援するClient Librariesと呼ばれるライブラリも用意されているほか、独自に適切な処理を返すような機構を実装することもできる。Prometheus Serverとexporterとのやり取りにはHTTPが使われているため、こういった機構はさまざまな言語で比較的容易に実装できるだろう。

プル型のアーキテクチャでは一時的にしか実行されない、たとえばバッチ処理などの処理については監視しにくい。こういった一時的に実行される処理の実行結果などを保持しておく「Pushgateway」という機構も用意されている。これを利用することで、監視対象が自発的に監視用のデータを送信する「プッシュ(Push)型」のような監視も可能になっている。

通知(アラート)に関しては、Prometheusでは「Alertmanager」というコンポーネントを使用して実装されている。Prometheus Serverはアラートを生成すると、その情報をAlertmanagerに送信し、Alertmanagerが設定に応じてそれをメールやインスタントメッセージなどさまざまな形式でユーザーに送信する処理を実行するという仕組みだ。

外部のアプリケーションからAPI経由でPrometheus Serverに接続し、収集した監視データにアクセスすることもできる。これを利用し、Prometheus Serverが収集したデータを視覚的に表示できる「Grafana」と呼ばれるツールも登場している。

Prometheusのインストールと設定

それでは、Prometheusを実際にインストールし、基本的な設定を行う流れを紹介していこう。前述のとおり、PrometheusはPrometheus ServerやAlertmanager、各種exporterといったコンポーネントごとに個別に配布されており、必要に応じてそれぞれをインストールする必要がある。これらコンポーネントのインストール方法は複数があるが、代表的なのは次の4つだ。

  • OSのパッケージマネージャ経由でインストールする
  • Docker経由で実行する
  • Prometheusが公式にビルドして配布しているバイナリを利用する
  • 自分でソースコードからビルドする

まずパッケージマネージャ経由でのインストールだが、Debianではバージョン9(stretch)以降、Ubuntuでは16.04 LTS(xenial)以降で公式パッケージが提供されている。設定ファイルも同時にインストールされるため、DebianやUbuntuではこの方法でのインストールをおすすめする。ただし、パッケージで提供されているPrometheusは若干古いバージョンの場合があるので注意したい。たとえばDebian 9では記事執筆時点で提供されているバージョンは1.5.2(「stretch-backports」リポジトリでは1.8.1)、Ubuntu 16.04 LTSではバージョン0.16.2、17.04(zesty)では1.5.2、17.10(artful)では1.7.1となっている。

Docker経由のインストールについては、Prometheusの開発者らが公式にDocker向けイメージをDockerHubで提供しており、そちらを利用できる。こちらの場合、インストール作業については簡単ではあるが、設定ファイルなどの用意は必要だ。

Prometheusの開発者らが公式に配布しているバイナリは、公式Webサイトのダウンロードページから入手できる。このページではLinux(対応アーキテクチャは386およびamd64、armv6/v7/ppc64/ppc64le)、Mac OS X(Darwin、対応アーキテクチャは386およびamd64)、FreeBSDおよびNetBSD(386、amd64、armv6/v7)、OpenBSD(386およびamd64)、Windows(386およびamd64)向けのバイナリが公開されている。これらのインストール方法については後述する。

ソースコードからのビルドは、Go環境の構築などが必要であり、またアップデート時にその都度作業が必要であるためあまりおすすめしない。もし興味がある方は、公式ドキュメントや各コンポーネントのリポジトリなどを参照して欲しい。

なお、Prometheusでは設定ファイルなどのフォーマットにYAML形式を採用している。YAML形式について本記事内では解説しないので、適宜「プログラマーのための YAML 入門 (初級編)」などを参照して欲しい。

「node_exporter」を使ってマシンの状況を監視する

前述のとおり、Prometheusでは「exporter」と呼ばれるコンポーネントを使って監視対象のデータを取得する。まずはシンプルな例として、インストールしたホストのリソース使用状況を取得する「Node/system metrics exporter(node_exporter)」を使った監視環境の構築例を紹介しよう。手順としては以下のようになる。

  1. 監視対象マシンにnode_exporterをインストール
  2. Prometheus Serverのインストールおよび設定
  3. Alertmanagerのインストールおよび設定

まずnode_exporterのインストールだが、DebianやUbuntuの場合は次のようにapt-getコマンドでインストールするのが簡単だ。

# apt-get install prometheus-node-exporter

この場合、systemdには「prometheus-node-expoter」というサービス名で登録され、systemctlコマンド経由で起動や停止、ステータスの確認などが行える。

# systemctl status prometheus-node-exporter
● prometheus-node-exporter.service - Prometheus exporter for machine metrics
   Loaded: loaded (/lib/systemd/system/prometheus-node-exporter.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2017-10-11 19:39:55 JST; 36s ago
     Docs: https://github.com/prometheus/node_exporter
 Main PID: 21512 (prometheus-node)
   CGroup: /lxc/sd-test/system.slice/prometheus-node-exporter.service
           mq21512 /usr/bin/prometheus-node-exporter -collector.diskstats.ignored-devices=^(ram|loop|fd)d+$ -collector.filesys
  
  

node_exporterは9100番ポートでPrometheus Serverとのやり取りを行うので、Prometheus Serverからこのポートにアクセスできるようファイアウォールの設定なども確認しておこう。

パッケージが提供されていない環境や、より新しいバージョンのものを利用したいという場合は、Dockerを利用すると簡単に利用できる。次のように「prom/node-exporter」というイメージをダウンロードし、このイメージを使ってコンテナを起動すれば良い。

# docker pull prom/node-exporter
# docker run -d --name node_exporter -p 9100:9100 prom/node-exporter

また、Prometheusのダウンロードページで公開されているnode_exporterを利用する場合は、ダウンロードしたアーカイブを適当なディレクトリで展開し、含まれる「node_exporter」バイナリファイルを適当なディレクトリにコピーすれば良い。下記では、/usr/local/binディレクトリにコピーを行っている。

$ wget https://github.com/prometheus/node_exporter/releases/download/v0.15.0/node_exporter-0.15.0.linux-amd64.tar.gz
$ tar xvfz node_exporter-0.15.0.linux-amd64.tar.gz
$ cd node_exporter-0.15.0.linux-amd64
# mkdir -p /usr/local/bin
# cp -a node_exporter /usr/local/bin/

直接シェルからnode_exporterを実行することもできるが、systemdなどでサービスとして実行して管理するほうが良いだろう。たとえば以下のような内容のファイルを「/etc/systemd/system/prometheus-node-exporter.service」として作成することで、systemd経由でnode_exporterを管理できるようになる。起動オプションについては後述するが、特に指定しなくとも構わない。

[Unit]
Description=node_exporter for Prometheus

[Service]
Restart=always
User=prometheus
ExecStart=/usr/local/bin/node_exporter <起動オプション>
ExecReload=/bin/kill -HUP $MAINPID
TimeoutStopSec=20s
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

ここではnode_exporterを実行するユーザーとして「prometheus」ユーザーを指定しているので、次のようにしてサービスの起動前にこのユーザーを作成しておく必要がある。

# useradd -U -s /sbin/nologin -M -d / prometheus

最後にsystemctl daemon-reloadコマンドでsystemdの設定を再読込させると、systemctl startコマンドでサービスを起動できるようになる。また、Prometheus Serverから9100番ポートにアクセスできるようファイアウォールの設定も確認しておこう。

# systemctl daemon-reload

node_exporterの設定

node_exporterでは特に設定を行わずとも、単に起動するだけでホストのCPU統計やディスクI/O統計などさまざまなデータを取得できるようになっている。また、起動オプションで取得する項目をカスタマイズすることも可能だ。詳しくはドキュメントを確認して欲しいが、デフォルトで取得される統計情報の中で不要なものがあれば、「--no-collector.<名前>」オプションを指定すれば取得対象から除外できる。また、デフォルトでは収集されない情報を取得対象に加えたい場合は「--collector.<名前>」オプションを指定すれば良い。

ちなみに、Debian/Ubuntuでパッケージ経由でインストールした場合は/etc/default/prometheus-node-exporterファイルで設定されている「ARGS」環境変数で起動オプションが設定されているので、設定を行う際はここを編集しよう。

Prometheus Serverのインストール

次に、Prometheusの本体であるPrometheus Serverをインストールする。Debian/Ubuntuでは、次のようにパッケージをインストールすれば良い。

# apt-get install prometheus

なお、現行のDebian安定版であるバージョン9系(strech)や、Ubuntu 16.04 LTS(xenial)で提供されているPrometheusは若干バージョンが古い。Debianの場合、「strech-backports」リポジトリでより新しいバージョンのものが提供されているので、可能であればこちらを利用することをお勧めする。

Dockerを利用する場合、設定ファイルであるprometheus.ymlを用意し、次のようにdockerコマンドを実行することでPrometheus Serverを起動できる。

$ docker pull prom/prometheus
$ docker run -d --name prometheus -p 9090:9090 -v <データ保存ディレクトリ>:/prometheus -v <設定ファイル>:/etc/prometheus/prometheus.yml prom/prometheus

prometheus.ymlファイルについてはサンプルファイルが公開されているので、まずはこれを利用すると良いだろう。

Prometheusのダウンロードページで公開されているバイナリを直接インストールする場合は、node_exporterの場合と同様、ダウンロードしたアーカイブを適当なディレクトリで展開し、含まれるファイルを適当なディレクトリにコピーすれば良い。下記では、/usr/localディレクトリ以下に「prometheus」というディレクトリを作成し、そこにコピーしている。設定ファイルは/etc/prometheusディレクトリを作成してそこにコピーしている。

$ wget https://github.com/prometheus/prometheus/releases/download/v1.8.0/prometheus-1.8.0.linux-amd64.tar.gz
$ tar xvzf prometheus-1.8.0.linux-amd64.tar.gz
# cp -a prometheus-1.8.0.linux-amd64 /usr/local/prometheus
# cd /usr/local/prometheus
# mkdir /etc/prometheus
# cp -a prometheus.yml /etc/prometheus/

また、exporterの場合と同様、シェルから直接prometheusバイナリを実行するのではなく、systemdのサービスとして管理する方が良いだろう。ここでは「/etc/systemd/system/prometheus.service」として次のような設定ファイルを作成している。

[Unit]
Description=Prometheus - Monitoring system and time series database

[Service]
Restart=always
User=prometheus
ExecStart=/usr/local/prometheus/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.local.path=/var/lib/prometheus/metrics
ExecReload=/bin/kill -HUP $MAINPID
TimeoutStopSec=20s
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

実行ユーザーには「prometheus」というユーザーを指定しているので、必要に応じてこのユーザーを作成しておこう。また、ここでは収集したデータを「/var/lib/prometheus/metrics」ディレクトリに格納するよう指定しているので、こちらも事前に作成しておく。

# mkdir -p /var/lib/prometheus
# chown prometheus:prometheus /var/lib/prometheus

なお、ここではPrometheus 1.8.0を使用しているが、Prometheusバージョン2系では「-storage.local.path」オプションが「-storage.tsdb.path」に改名されている。そのため、Prometheus 2系を利用する場合は「-storage.local.path」部分を「-storage.tsdb.path」に置き換えてほしい。

最後にsystemdの設定の再読込を行っておく。

systemctl daemon-reload

Prometheus Serverの設定

Prometheus Serverでは、起動時にコマンドラインオプションで指定した設定ファイルで各種データの収集対象などを指定する。デフォルトで用意されている設定ファイルは以下のようになっている。

# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'codelab-monitor'

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first.rules"
  # - "second.rules"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ['localhost:9090']

ここでまず確認しておきたいのが、「global:」セクションの「scrape_interval」パラメータだ。Prometheus Serverはここで指定した頻度で監視対象にアクセスしてデータを取得する。頻繁なデータ取得が不要であれば、この値を大きくすることでPrometheus Serverや監視対象への負荷を下げることができる。

また、監視対象は「scrape_configs:」セクション以下で、次のような形式で指定する。

  - job_name: '<ジョブ名>'
    static_configs:
      - tagets: ['<対象のホスト名>:<ポート番号>']

デフォルトでは、「prometheus」というジョブ名で「localhost:9090」という対象が指定されている。これはPrometheus Server自身を指しており、Prometheus Serverの稼働データをPrometheus Serverで取得するという設定内容になっている。

たとえば先に設定したnode_exporterを監視対象として追加したい場合、scrape_configs:セクション以下に次のような項目を追加すれば良い。

  - job_name: node
    static_configs:
      - targets: ['<対象ホスト>:9100']

ちなみにPrometheusをDebianパッケージでインストールした場合、デフォルトでnode_exporterについての設定が含まれた設定ファイルが/etc/prometheus/prometheus.ymlとしてインストールされているので、必要に応じてその部分のホスト名を変えるだけでnode_exporter経由でのマシン情報収集が行える。

設定ファイルの変更後は、Prometheus Serverを再起動することでその設定が反映される。

Webブラウザからコンソールにアクセスする

PrometheusではWebブラウザからアクセスできるコンソール(「Web UI」などとも呼ばれる)が用意されており、ここから取得した監視データを確認できる。デフォルトではPrometheus Serverを起動したホストの9090番ポートにWebブラウザでアクセスすることで、このコンソールを利用できる。

Prometheusの起動後、Webブラウザで「http://<Prometheusが起動するホスト>:9090」にアクセスすると、図2のようなコンソール画面が表示されるはずだ。

図2 Prometheusのコンソール画面

このコンソールでは収集したデータのグラフ表示やアラート設定、各種ステータスの表示が行える。まずグラフ表示だが、「- insert metric at cursor -」と表示されているドロップダウンで表示したい項目を選択し、「Execute」をクリックするとそのグラフが表示される(図3)。

図3 ドロップダウンでグラフ表示したい項目を選び、「Execute」をクリックする

続いて「Graph」タブをクリックすると、そのグラフが表示される(図4)。

図4 「Graph」タブでグラフが表示される

ちなみに、「Console」タブでは取得した最新のデータをそのままリスト形式で確認できる(図5)。

図5 「Console」タブでは取得されているデータを確認できる

下部に表示される「Add Graph」ボタンをクリックすれば、複数のグラフを同時に表示することもできる。また、グラフ上側左のテキストボックスでデータの表示範囲、真ん中のテキストボックスで表示開始時刻を設定可能だ(図6)。

図6 複数のグラフの表示や、時系列の変更なども行える

「Status」メニューではPrometheus Serverの設定を確認できる。たとえば「Targets」を選択すると、設定されているデータ取得対象一覧が表示され、おのおのの最終データ取得時刻やステータス、エラー状況などを確認できる(図7)。

図7 「Status」メニューから表示できる「Targets」画面ではデータ取得先の状況を確認できる

インストールや設定は容易、パッケージの提供が待たれる

さて、本記事ではPrometheusの基本的なインストール方法について紹介した。Prometheusの特徴の1つとしてインストールや設定の容易さを挙げたが、実際かなり手軽に導入できることが分かる。ただ、Red Hat Enteprise LinuxやCentOSなどのその互換OS、Fedoraなどでは公式パッケージが提供されていないため、サービスとして利用するための設定ファイルを用意しなければならない。こちらについては、今後ディストリビューション側でのサポートに期待した。

また、インストールや設定が容易な理由の1つには別途データベースを用意する必要がないという点があるが、逆にいうと仮想マシンの削除とともにストレージも削除されてしまうようなクラウド環境の場合、データが消失しないよううまく管理を行う必要がある点には注意したい。

次回は、コンソールでのクエリについてより詳しい解説をするとともに、アラートの設定方法についても紹介する。