今年5月に出版された「入門 Prometheus」を読んだ.本書は Prometheus の仕組みから,実際に本番環境で運用するときに必要になるデプロイの観点まで解説されているため「Prometheus に興味のある幅広い読者層」にオススメできる1冊だった.僕自身も Prometheus を本番環境で運用した経験はなく,Kubernetes や Microservices のハンズオンを試しながら,合わせて Prometheus と Grafana を使う場面が多く,本書の読者層に合っていた.
本書は O'Reilly Japan 様より献本を頂き,ありがとうございます!そして,本書の監訳者である @superbrothers さん,出版おめでとうございます!本書を読んでいたら,多くのページに「監訳注」が入っていて本当に素晴らしかった!原著出版後に追加された Prometheus API も紹介されていて,とても読みやすくなっていた.予想以上に本書のボリュームが大きく,さらに実際に Prometheus 環境を構築し,試しながら読み進めたり,個人的に忙殺されていた時期もあり,書評記事の公開が予定よりも遅れてしまったという点は反省点と言える.
目次
- 第Ⅰ部 : イントロダクション
- 1章 : Prometheusとは何か
- 2章 : 初めてのPrometheus
- 第Ⅱ部 : アプリケーションのモニタリング
- 3章 : インストルメンテーション
- 4章 : 開示
- 5章 : ラベル
- 6章 : Grafanaによるダッシュボードの作成
- 第Ⅲ部 : インフラストラクチャのモニタリング
- 7章 : Node exporter
- 8章 : サービスディスカバリ
- 9章 : コンテナとKubernetes
- 10章 : よく使われるexporter
- 11章 : ほかのモニタリングシステムとの連携
- 12章 : exporterの書き方
- 第Ⅳ部 : PromQL
- 13章 : PromQL入門
- 14章 : 集計演算子
- 15章 : 二項演算子
- 16章 : 関数
- 17章 : レコーディングルール
- 第V部 : アラート
- 18章 : アラート
- 19章 : Alertmanager
- 第Ⅵ部 : デプロイ
Prometheus とは?
まず「1章 : Prometheusとは何か」を読むと Prometheus の基本を学べる.SoundCloud 社によって開発された話 / CNCF (Cloud Native Computing Foundation) / モニタリングの必要性もまとまっている.そして Prometheus のアーキテクチャを整理し,本書に出てくる様々な Prometheus 用語の概要も学べる.具体的には以下など.
- exporter
- サービスディスカバリ
- スクレイプ(プル型)
- インストルメンテーション
- Alertmanager
- PromQL
- Grafana
そして「2章 : 初めてのPrometheus」では,さっそく Prometheus を実行し,Prometheus 自体のメトリクスを取得する.次に Prometheus コンソール http://xx.xx.xx.xx:9090
にアクセスし,PromQL を使って up
や process_resident_memory_bytes
や rate(prometheus_tsdb_head_samples_appended_total[1m])
などのクエリを体験する.さらに Node exporter を実行し,Linux メトリクスを取得する.もし Prometheus を試したことがなければ,最初に検証用の Prometheus 環境を構築し,雰囲気を掴んでから本書を読み進めると効率的に学べると思う.
なお,今回は「Prometheus 2.12.0」を検証環境にした.
prometheus.io
Prometheus クライアントライブラリ
「3章 : インストルメンテーション」では,アプリケーションのメトリクスを Prometheus でスクレイプする.本書では Python のクライアントライブラリである prometheus_client
を使って,アプリケーションを実装する.以下のサンプルコードはスクレイプする HTTP Server を実行している.なお,本書に載っているサンプルコードは GitHub に公開されているため,写経しても良いし,GitHub からコピーもできる.
github.com
import http.server
from prometheus_client import start_http_server
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b"Hello World")
if __name__ == "__main__":
start_http_server(8000)
server = http.server.HTTPServer(('localhost', 8001), MyHandler)
server.serve_forever()
Python コードを実行したら,prometheus.yml
に以下の定義をする.Prometheus を再起動をしておく.
scrape_configs:
- job_name: example
static_configs:
- targets:
- localhost:8000
すると,HTTP Server をスクレイプし,PromQL を使って python_info
のメトリクスを取得できるようになる.実際にアプリケーションに組み込む場合は「カウンタ」や「ゲージ」や「サマリ」や「ヒストグラム」などを実装し,より価値のあるメトリクスを取得する.さらに「メトリクス名のサフィックス」に慣習があるという話もコラムにあって参考になった.
python_info{implementation="CPython",instance="localhost:8000",job="example",major="3",minor="7",patchlevel="4",version="3.7.4"}
Pushgateway とは?
バッジジョブなど,スクレイプできないターゲットからメトリクスを取得する場合に「Pushgateway」を使う.注意点として Pushgateway は Prometheus をプル型からプッシュ型に変えるものではなく,Prometheus は Pushgateway をスクレイプする.よって,Pushgateway も exporter と言える.今まで Pushgateway を使ったことがなく,本書を参考に試した.
まず,Pushgateway を実行する.
$ wget https://github.com/prometheus/pushgateway/releases/download/v0.9.1/pushgateway-0.9.1.linux-amd64.tar.gz
$ tar -xzf pushgateway-0.9.1.linux-amd64.tar.gz
$ cd pushgateway-0.9.1.linux-amd64
$ ./pushgateway
次に prometheus.yml
に以下の定義をする.Prometheus を再起動をしておく.
scrape_configs:
- job_name: pushgateway
honor_labels: true
static_configs:
- targets:
- localhost:9091
今度は prometheus_client
の push_to_gateway()
を実装し,Python コードを実行すると,メトリクスを Pushgateway に送信できる.
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
registry = CollectorRegistry()
g = Gauge('job_last_success_unixtime', 'Last time a batch job successfully finished', registry=registry)
g.set_to_current_time()
push_to_gateway('localhost:9091', job='batchA', registry=registry)
最後は Pushgateway コンソール http://xx.xx.xx.xx:9091
にアクセスすると,スクレイプされたメトリクスを確認できるようになる.
サービスディスカバリ
Auto Scaling を前提にすると,毎回 prometheus.yml
に static_configs
を定義するのは運用的に難しく「サービスディスカバリ」を検討する必要がある.「8章 : サービスディスカバリ」では,Prometheus における「サービスディスカバリ」の仕組みを学べる.サービスディスカバリも本書を参考に試した.
まず,最初に「ファイルサービスディスカバリ」を試す.下のように prometheus.yml
に file_sd_configs
を定義し,JSON もしくは YAML を指定すると,Prometheus の再起動をせず,自動的に読み込まれるようになる.Dynamic な環境だと運用的に難しいけど,prometheus.yml
との依存度を減らせるメリットがある.
scrape_configs:
- job_name: file
file_sd_configs:
- files:
- '*.yml'
そして,任意の YAML ファイルを作成し,targets
の中にターゲットを指定すると,Prometheus 側で確認できるようになる.今回は検証のために 10.10.10.10
は意図的に存在しないターゲットにしている.
- targets:
- 10.0.1.84:9100
- 10.0.2.104:9100
- 10.10.10.10:9100
labels:
service: web
より Dynamic に Amazon EC2 を対象にする場合,prometheus.yml
に ec2_sd_configs
を定義する.さらに relabel_configs
に Tag を定義し,タグによる絞り込みを定義できる.Prometheus で非常に重要な機能である「ラベル」に関しても,本書に多く解説があり,参考になった.実際に Dynamic な環境で Prometheus を運用するときに,もう1度読み直そうと思う.
scrape_configs:
- job_name: ec2
ec2_sd_configs:
- region: ap-northeast-1
access_key: xxx
secret_key: xxx
port: 9100
relabel_configs:
- source_labels: [__meta_ec2_tag_environment]
regex: prd
action: keep
- source_labels: [__meta_ec2_tag_role]
regex: web
action: keep
デプロイ
最後の章「20章 : 本番システムへのデプロイ」では,Prometheus を本番環境で運用することを前提に,理解しておくべき知識を整理できる.特に Prometheus を階層化する「フェデレーション」や,時系列データを長期保存するために Prometheus API から「スナップショット」を取得する機能は今まで使ったことがなく,参考になった.個人的に「ダウンサンプリング」など,Prometheus のメトリクスを意図的に中長期に残していく話にも興味があったけど,本書にはメトリクス数を減らす設定と scrape_interval
と evaluation_interval
を変更する設定などが載っていた.Thanos の事例など,別途調べてみようと思う.
prometheus.io
誤植
O'Reilly のサイトにまだ「正誤表」がなく,気付いた誤植を載せておこうと思う.今回読んだのは「初版第1刷」となる.
www.oreilly.co.jp
まとめ
- 「入門 Prometheus」を読んだ(献本ありがとうございます!)
- 「Prometheus に興味のある幅広い読者層」にオススメできる1冊だった
- 実際に Prometheus 環境を構築し,試しながら読み進めると効率的に学べると思う