Kubernetesの監視はPrometheusがデファクトスタンダードになっており、インストールもk8sクラスタ上に行うのが一般的です。が、今回はPrometheusをざっくり理解するために普通のサーバに入れてみようという、今更だけど自分用メモです。
Prometheusとは
ちゃんとした解説は世の中に色々転がっていると思うので、そちらを見てください。自分的には
- Prometheus server/Prometheus Web UI/Alertmanager/Push Gateway/Exporter/Grafanaなど複数のコンポーネントで構成
- 構造がシンプルでバイナリ+設定ファイルだけで動く
- DockerやKubernetesとの連携も可能
というイメージです。
コンポーネントが細かく別れていることと、UIがコンポーネントごとに別だったり、他の外部UIコンポーネント(grafanaとか)も現実的に必要になったり、ということで全貌が見えにくい印象があります。が、Promethes本体はあくまでも各監視対象のメトリクスを保存しておく単なる時系列データベースであり、周辺ツールがここにアクセスすることで一つの監視システムを構成していると考えています。
なので、各コンポーネントが何をしているのか、というところからまず整理します。
- Prometheus Server
- 本体。時系列データベース、それにアクセスするためのAPI、監視対象からメトリクスを収集
- Exporter
- いわゆるエージェント。監視対象システム上でメトリクスを収集、Prometheus Serverからの取得要求に答える
- Push Gateway
- 監視対象側からメトリクスをpushしたい場合に待ち受けている。Prometheus Serverはここをポーリングしてメトリクスを拾うので、pushとpullの中間層的なイメージ。
- AlertManager
- Promethes本体は通知機能を持たない。AlertManagerにpushして通知を行う。そのためのWeb UIも持つ。
- Prometheus web UI/Grafana
- Prometheus ServerのAPIにアクセスして、メトリクスの抽出、視覚化を行う。PromQLというクエリ言語でアクセスする。
ま、ざっとこんな感じかなと。このあたりをアーキテクチャ図と見比べると理解しやすいかと思います。他にもサービスディスカバリ等でkubernetesと連携したりしますが、そこはちょっと置いときましょう。
Prometheusのインストール
では早速やっていきましょう。Prometheusサーバと監視対象サーバの2台のサーバを用意してやってみます。
インストール方法は色々あるようですが、ubuntuなので素直にパッケージ使いたいと思います。
Prometheusサーバ
インストール
$ sudo apt-get install -y prometheus
設定ファイルは/etc/prometheus/prometheus.yaml
# Sample config for Prometheus. global: scrape_interval: 15s # By default, scrape targets every 15 seconds. evaluation_interval: 15s # By default, scrape targets every 15 seconds. # 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: 'example' # Load and evaluate rules in this file every 'evaluation_interval' seconds. 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' # Override the global default and scrape targets from this job every 5 seconds. scrape_interval: 5s scrape_timeout: 5s # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ['localhost:9090'] - job_name: node # If prometheus-node-exporter is installed, grab stats about the local # machine by default. static_configs: - targets: ['localhost:9100']
- 15秒間隔で監視対象からデータを引っ張る
- 15秒間隔で引っ張ったデータとルールの比較を行う
- アラートルールの設定はなし
- scrape_configs.[].job_nameで監視対象の設定を行う。デフォルトでは以下が含まれている。
- ローカルのprometheusサーバ自身
- ローカルのnode-exporter(prometheusのインストールで自動で入る)
とりあえずこのままでも動きそうなので起動します。node-exporterも起動しておきましょう。
$ sudo systemsctl start prometheus $ sudo systemsctl start prometheus-node-exporter
では、ブラウザでprometheusサーバの9090版ポートにアクセスします。
はい、prometheusの管理画面が表示されていますね。ではメトリクスを表示してみます。ドロップダウンリストから適当なメトリクスを選択して"Execute"をクリックします。今回は「node_cpu」を選択してみます。
こんな感じでメトリクスが表示されます。次に、Graphタブをクリックしてみてください。
時系列でメトリクスが時系列でグラフ表示されます。つまり先程数値で表示されていたのは最新のメトリクスということですね。
監視対象サーバ
こちらはprometheus-node-exporterをインストールしてプロセスを上げておくだけです。
$ sudo apt-get install -y prometheus-node-exporter $ sudo systemctl start prometheus-node-exporter
で、あとはprometheusサーバ側で監視対象に追加してあげます。/etc/prometheus/prometheus.yamlに以下を追加します。
... snip ... scrape_configs: ... snip ... - job_name: prometheus-client static_configs: - targets: ['10.240.0.41:9100']
反映します。
$ sudo systemctl restart prometheus
先ほどと同じように「node_cpu」のグラフを見てみましょう。新しく追加した監視対象サーバが下の方に追加されているのが見えるでしょうか?
ここまでがprometheusの基本になります。
AlertManagerのインストール
上でも述べたとおり、Prometheus自体は通知の機能を持たず、通知はAlertManagerの仕事になります。ということでAlertManagerをPrometheusサーバ上にインストールします。
$ apt-get install -y prometheus-alertmanager
アラートの条件やしきい値はPrometheus Server側で設定します(なのでAlertManagerはほんと通知だけですね。)/etc/prometheus/prometheus.yaml に以下を追加します。別ファイルで切り出している形です。
... snip ... rule_files: - "/etc/prometheus/alert.rules" ... snip ...
/etc/prometheus/alert.rulesを記載します。で、prometheusのアラートルールを色々紹介しているサイトがあるみたいなので、そこからルールを持ってたいと思います。
groups: - name: prometheus-client rules: - alert: PrometheusTargetMissing expr: up == 0 for: 5m labels: severity: critical annotations: summary: "Prometheus Target missing (instance {{ $labels.instance }})" description: "A Prometheus Target has disappeared\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" - alert: HostHighCpuLoad expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80 for: 5m labels: severity: warning annotations: summary: "Host high CPU load (instance {{ $labels.instance }})" description: "CPU load is > 80%\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
ノードが死んだ場合とcpuが80%を超えた場合を試しに設定してみました。
反映します。
sudo systemctl restart prometheus
prometheusの管理画面にあるAlertメニューを開くと追加したルールが表示されていますね。
では試しに監視対象サーバを落としてみましょう。Prometheusのalertを開くと、ちゃんと状態が変化していることを検出できています。
この状態でしばらく待つと、さらに状態が変わり「FIRING」となります。これがalertmanagerにpushされる状態です。
では、通知の設定を行います。色々通知の方法はありますが、今回はSlackに投げてみましょう。/etc/prometheus/alertmanager.ymlを以下のように修正します。
global: slack_api_url: "https://hooks.slack.com/services/XXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXX" route: receiver: 'slack-notification' receivers: - name: 'slack-notification' slack_configs: - channel: '#general' text: "<!channel> \nsummary: {{ .CommonAnnotations.summary }}\ndescription: {{ .CommonAnnotations.description }}"
シンプルにslackだけに投げてます。グループは使ってません。あとはテキストにアラート設定側のannotationsを含めるようにしてます。通知のテンプレは以下も参考にしてください。
そして、Prometheus serverからalert manager似pushするように設定します。/etc/prometheus/prometheus.yaml に以下を追加します。
alerting: alertmanagers: - static_configs: - targets: - localhost:9093
でAlert Managerを起動、Prometheus Serverも再起動して反映しましょう。
$ sudo systemctl start prometheus-alertmanager $ sudo systemctl restart prometheus-alertmanager
AlertManagerのWeb画面を見てみるとこちらでも検出しています。
そしてslackにも通知が来ました!
まとめ
とりあえず一通り動きました。あとはgrafana入れればよくあるprometheus構成になると思いますが、ちょっとそこは割愛します。次回はこれをkubernetesでやってみたいと思います。