Prometheusを使わずにメトリクスをPrometheus Remote Writeのエンドポイントに送る – OpenTelemetry

By 清水 孝郎 - AUGUST 25, 2021

SHARE:

本文の内容は、2021年8月24日にCarlos Tolonが投稿したブログ(https://sysdig.com/blog/prometheus-remote-write-opentelemetry/)を元に日本語に翻訳・再構成した内容となっております。

Prometheus remote write は、ほぼすべてのデバイスから Prometheus サーバーにメトリクスを送信することができる素晴らしい機能です。デバイスにサービスPrometheusインスタンスをインストールし、remote_writeを有効にすればOKです。

しかし、時には、アプリケーションを完全にインストルメンタライズ 化する必要がない場合や、カスタムのメトリクスを送信する必要がある場合もあります。そのような場合には、Prometheus の代わりに OpenTelemetry を使うことができます。

OpenTelemetryとは

OpenTelemetry は、Jaeger や Prometheus のようなオープンソースプロジェクトをサポートする、トレース、メトリクス、ログを管理するためのベンダーを問わない実装を提供する、SDK、API、ツール、インテグレーションのセットです。

OpenTelemetry Collectorは、データを受信し、処理し、エクスポートするための標準的で不可知論的な方法を提供します。これにより、Prometheus サーバーを管理することなく、remote_write を有効にした外部の Prometheus サーバーにメトリクスをプッシュするための簡単なシナリオを作成することができます。

すべてのバッチジョブは、Prometheus Remote Writeの代わりに、すぐにこのサービスにメトリクスを送ることができます。

OpenTelemetryコレクターの設定

この目的のために、Prometheus Remote Write用のOpenTelemetry Collectorエクスポーターを使うことができます。

OpenTelemetry Collectorは以下のように構成する必要があります:

レシーバー
OpenCensus用のOpenTelemetry Collector Receiverを設定します。これにより、OpenCensus Metric Format でメトリクスを直接プッシュできるエンドポイントができます。

エクスポーター
Prometheus remote writeエンドポイント用のエクスポーターと、それに接続するために必要な環境変数(Bearer Token を含む認可ヘッダーなど)です。

サービス
OpenTelemetryでは、レシーバーとエクスポーターが接続されているサービスパイプラインを介して、任意のプロセスを有効にする必要があります。


このプロセスには次のようなステップがあります。
  1. バッチジョブはOpenCensus Metric Formatを使ってOpenTelemetry Collectorにメトリクスをプッシュします。
  2. OpenTelemetryは、Prometheus Remote Write エクスポーターで設定した外部ラベルを追加します。
  3. OpenTelemetry CollectorはメトリクスをRemote Writeバックエンドに送信します。

ベアラートークンを設定するには、デプロイメントの環境変数としてマウントされたシークレットを使用します。

OpenTelemetry Collectorに必要なのは、アプリケーションを定義したKubernetes Deploymentと、このアプリケーションと通信するためのService、そしてプロセスを設定するためのConfigMapだけです。

OpenTelemetry Collectorの最新リリースはこちらで、最新のDocker Imageも入手できます。

クラスターにOpenTelemetry Collectorをデプロイする

これは、Kubernetes Deployment、Service、ConfigMapを使ってOpenTelemetry Collectorをデプロイする方法です。また、OpenTelemetry Operatorを使ってCollectorを実行することもできます。

デプロイメント
Kubernetes Deploymentを使ってコレクターを1つのレプリカでデプロイします。ここでは、利用可能な最新のバージョンを使用しています。DockerHubでotel/opentelemetry-collectorの利用可能なすべてのイメージバージョンを確認してください。

Prometheus remote writeエンドポイントで認証を行う必要がある場合は、シークレットを作成する必要があります:

kubectl create secret generic remote-write-api-token --from-literal=remote-write-api-token="Remote Write Token”

そして、それを設定に追加します:

env:
       - name: BEARER_TOKEN
         valueFrom:
           secretKeyRef:
             name: remote-write-api-token
             key: remote-write-api-token

Service
ここでは、OpenTelemetry Collectorにメトリクスを送信するためのOpenCensusポートのみを定義します。OpenTelemetry Collectorのデフォルトポートは、他のレシーバーエクスポーター用にも用意されています。

ConfigMap
Collectorのエクスポーターをprometheusremotewriteタイプで設定します。必要に応じて、デプロイメントにBEARER_TOKEN変数を追加します。この例では、OpenTelemetryコレクターがすべてのメトリクスに含める追加のラベルも含めています。

# otel-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
 labels:
   app: opentelemetry
   component: otel-collector-conf
 name: otel-collector-conf
data:
 otel-collector-config: |
   receivers:
     opencensus:
   processors:
     batch:
   exporters:
     prometheusremotewrite:
       endpoint: "https://remote-endpoint/prometheus/remote/write"
       headers:
         Authorization: "Bearer ${BEARER_TOKEN}"
       external_labels:
         server: otel
   service:
     extensions: [health_check]
     pipelines:
       metrics:
         receivers: [opencensus]
         processors: [batch]
         exporters: [prometheusremotewrite]

Kubernetesクラスターにデプロイする場合は、自身のネームスペースですべての設定を適用する必要があります。


メトリクスをOpenTelemetryに送る

これはOpenCensusのメトリクスフォーマットで、ジョブがOpenTelemetryにメトリクスを送信するために使用する必要があります。1つのクエリで複数のメトリクスを送ることができ、必要なラベルを付けることができます。

{
   "node": {
     "identifier": {
       "host_name": "HOSTNAME",
       "pid": 123,
       "start_timestamp": "TIMESTAMP"
     }
   },
   "metrics": [
     {
       "metric_descriptor": {
         "name": "my_custom_metric",
         "description": "Build has been correctly executed",
         "unit": "1",
         "type": "GAUGE_INT64",
         "label_keys": [
           {
             "key": "environment",
             "description": "Representing the environment"
           },
           {
               "key": "kernel",
               "description": "Kernel version"
             }
         ]
       },
       "timeseries": [
         {
           "start_timestamp": "TIMESTAMP",
           "label_values": [
             {
               "value": "ENVIRONMENT",
               "has_value": true
             },
             {
               "value": "KERNEL",
               "has_value": true
             }
           ],
           "points": [
             {
               "timestamp": "TIMESTAMP",
               "int64_value": "VALUE"
             }
           ]
         }
       ]
     }
   ]
 }

前述のメトリクステンプレートをbashスクリプトで使用することにより、1分ごとに1つのメトリクスを送信することができます。例えば、バッチジョブが終了したときに、1つのRANDOM番号が付きます。

#!/bin/bash

...my custom batch job...

query=`cat query-body-example-template.json`
value=$((1 + $RANDOM % 10))
hostname=`hostname`
timestamp=`date -u +%FT%TZ`
kernel=`uname -r`

query=$(sed -e "s/HOSTNAME/$hostname/g" -e "s/TIMESTAMP/$timestamp/g" -e "s/ENVIRONMENT/dev/g" -e "s/KERNEL/$kernel/g" -e "s/VALUE/$value/g" :55678/v1/metrics --data "$query"


OpenTelemetryの設定で、あなたのメトリクスが表示されます:


curlを使って直接メトリクスを送信したい場合は、次のようなクエリを実行します。

curl -H "Content-Type: application/json" <otel-collector-url>:55678/v1/metrics --data "$query"

$queryは先ほどのJSONの内容です。

まとめ

この記事では、OpenTelemetry が Prometheus remote writeエンドポイントにメトリクスを送信するための優れたソリューションであることを、サービス Prometheus インスタンスのインストールと設定を必要とせずに学ぶことができました。

これは、ビジネスにおけるバッチプロセスを監視するための迅速かつシンプルな方法です。

SysdigのPrometheusマネージドプラットフォームなら、さらに簡単です。数分でサインアップして、すぐにPrometheus remote write 対応エンドポイントにメトリクスをプッシュしましょう!