TT Lab
はじめる
学ぶ 学習パス コース

PCA — Prometheus認定アソシエイト

スクレイプ設定とリラベリング

TT Labで続きを見る

目標

Prometheusのスクレイプ設定を、最初から最後まで自分で書き、その設定が実際のクラスターのPodをどう選ぶかを確認します。終わると、他人のprometheus.ymlを見て、どのターゲットが残り、どのメトリクスが捨てられるかを説明できるようになります。

なぜ重要なのか

スクレイプ設定は、Prometheusで唯一「何を見るか」を決める場所です。その後のすべてのクエリとアラートは、ここで残ったデータだけを扱います。リラベルが難しく感じられる理由は、文法ではなく、2つの段階が別の時点で動作することにあります。relabel_configsはスクレイプの前にターゲットの一覧を扱い、metric_relabel_configsはスクレイプのあとに入ってきたメトリクスを扱います。前の段階で捨てたターゲットは、リクエスト自体が出ないのでコストが0で、後の段階で捨てたメトリクスは、すでにネットワークとパースのコストを払ったあとです。この違いが、大規模なクラスターでのPrometheusの生死を分けます。ガードレールも同じ文脈です。sample_limitがなければ、カーディナリティが爆発したサービス1つが、モニタリング全体を止めます。

ステップ

  1. /root/pca-scrape/prometheus.ymlを作成して、globalブロックを書きます。scrape_interval: 15s、evaluation_interval: 30s、scrape_timeout: 10sを設定し、さらにexternal_labelsの下にcluster: homelabを入れます。
  2. scrape_configsリストの1つ目の項目にjob_name: prometheus-selfを作成し、metrics_path: /metricsを設定し、static_configsのtargetsにlocalhost:9090を1つだけ入れます。
  3. 2つ目の項目にjob_name: checkout-apiを作成し、scrape_interval: 30s、scrape_timeout: 20s、sample_limit: 20000、label_limit: 24、label_value_length_limit: 256を入れます。
  4. 3つ目の項目にjob_name: kubernetes-podsを作成し、kubernetes_sd_configsにrole: podを指定してから、namespaces.namesにpca-scrapeだけを入れて、監視の範囲を絞ります。
  5. 3つ目のジョブのrelabel_configsに、3つのルールを入れます。(a) action: keep、source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]、regex: "true" (b) action: replace、source_labels: [__meta_kubernetes_pod_ip, __meta_kubernetes_pod_annotation_prometheus_io_port]、target_label: __address__、replacement: '$1:$2' (c) action: replace、source_labels: [__meta_kubernetes_namespace]、target_label: namespace。
  6. 同じジョブに、action: labelmap、regex: __meta_kubernetes_pod_label_(.+)のルールを追加し、metric_relabel_configsに2つのルールを入れます。(a) action: drop、source_labels: [__name__]、regex: 'go_gc_duration_seconds.*|python_gc_.*' (b) action: replace、source_labels: [__name__]、regex: 'http_requests_total'、target_label: user_id、replacement: ''。
  7. ネームスペースpca-scrapeを作成し、その中にConfigMapprometheus-configを作成します。キー名はprometheus.ymlで、値は今書いたファイルの内容です。
  8. ネームスペースpca-scrapeにPodcheckout-apiを作成します。ラベルはapp: checkout-api、アノテーションはprometheus.io/scrape: "true"、prometheus.io/port: "8080"、prometheus.io/path: "/metrics"で、コンテナポートは、名前metricsでcontainerPort: 8080にします。

参考

globalブロックを書く

/root/pca-scrape/prometheus.ymlを作成して、globalブロックを書きます。scrape_interval: 15s、evaluation_interval: 30s、scrape_timeout: 10sを設定し、さらにexternal_labelsの下にcluster: homelabを入れます。

prometheus.ymlの最上位のglobalの下に、scrape_interval、evaluation_interval、scrape_timeoutを入れます。external_labelsは、このPrometheusが出力するすべての時系列に付くラベルなので、フェデレーションやリモートストレージで、インスタンスを区別するのに使います。

static_configsのジョブを追加する

scrape_configsリストの1つ目の項目にjob_name: prometheus-selfを作成し、metrics_path: /metricsを設定し、static_configsのtargetsにlocalhost:9090を1つだけ入れます。

scrape_configsはリストです。1つ目の項目に、job_nameとstatic_configsを入れてください。static_configsは、targetsリストを持つ項目のリストなので、角括弧が2回入ります。metrics_pathには既定値がありますが、ここでは明示します。

ガードレールを設定するジョブ

2つ目の項目にjob_name: checkout-apiを作成し、scrape_interval: 30s、scrape_timeout: 20s、sample_limit: 20000、label_limit: 24、label_value_length_limit: 256を入れます。

sample_limitは、1つのターゲットが出すサンプル数の上限で、超えるとそのスクレイプが丸ごと失敗します。label_limitとlabel_value_length_limitも、同じ系統の防御線です。scrape_timeoutはscrape_intervalより大きくできない、という制約を思い出してください。

kubernetes_sdでPodを探す

3つ目の項目にjob_name: kubernetes-podsを作成し、kubernetes_sd_configsにrole: podを指定してから、namespaces.namesにpca-scrapeだけを入れて、監視の範囲を絞ります。

kubernetes_sd_configsもリストです。roleは、node/service/pod/endpoints/endpointslice/ingressのどれかで、Podのコンテナポートを直接スクレイプするにはpodです。namespaces.namesで監視の範囲を絞ると、大規模なクラスターでSDの負荷が大きく減ります。

keepで選び、アドレスを組み立て直す

3つ目のジョブのrelabel_configsに、3つのルールを入れます。(a) action: keep、source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]、regex: "true" (b) action: replace、source_labels: [__meta_kubernetes_pod_ip, __meta_kubernetes_pod_annotation_prometheus_io_port]、target_label: __address__、replacement: '$1:$2' (c) action: replace、source_labels: [__meta_kubernetes_namespace]、target_label: namespace。

keepは、正規表現にマッチ「しない」ターゲットを捨てます。アノテーションのメタラベル名は、ドットとスラッシュがアンダースコアに変わる、というルールを思い出してください。ソースラベルを2つ使うと、値がセミコロンでつながって正規表現に入ってくるので、replacementでキャプチャグループとして組み立て直します。

labelmapとmetric_relabel_configs

同じジョブに、action: labelmap、regex: __meta_kubernetes_pod_label_(.+)のルールを追加し、metric_relabel_configsに2つのルールを入れます。(a) action: drop、source_labels: [__name__]、regex: 'go_gc_duration_seconds.*|python_gc_.*' (b) action: replace、source_labels: [__name__]、regex: 'http_requests_total'、target_label: user_id、replacement: ''。

relabel_configsはスクレイプの前にターゲットを扱い、metric_relabel_configsはスクレイプのあとにメトリクスを扱います。labeldropはラベル「名」だけを見てマッチして、そのジョブのすべてのメトリクスから消してしまうので、特定のメトリクスからだけ消したいなら、replaceで空の値を入れます。空の値のラベルは、ないラベルと同じです。

設定をConfigMapとして上げる

ネームスペースpca-scrapeを作成し、その中にConfigMapprometheus-configを作成します。キー名はprometheus.ymlで、値は今書いたファイルの内容です。

kubectl create configmapの--from-fileは、키=경로(プレースホルダーはキー名とパスです)の形でキー名を指定できます。ファイルを直したあとは、ConfigMapを作り直さないと反映されません。実際の運用では、config-reloaderサイドカーがこの更新を検知して、Prometheusにリロードをトリガーします。

keepルールが生かすPodを作る

ネームスペースpca-scrapeにPodcheckout-apiを作成します。ラベルはapp: checkout-api、アノテーションはprometheus.io/scrape: "true"、prometheus.io/port: "8080"、prometheus.io/path: "/metrics"で、コンテナポートは、名前metricsでcontainerPort: 8080にします。

前に書いたkeepルールと、__address__の組み立て直しのルールが、このPodを通過させるかを考えながら、アノテーションの値を決めてください。値が文字列のtrueとまったく同じで、ポートのアノテーションの値がコンテナポートと一致する必要があります。labelmapルールが移すPodのラベルも1つ付けます。