Prometheus Agent Modeの紹介:効率的かつクラウドネイティブなメトリック転送の方法
2021年11月16日筆者: Bartlomiej Plotka (@bwplotka)
Bartek Płotkaは2019年からPrometheusのメンテナーであり、Red Hatのプリンシパルソフトウェアエンジニアです。CNCF Thanosプロジェクトの共同創設者でもあります。CNCFアンバサダーであり、CNCF TAG Observabilityのテックリードも務めています。時間のある時には、O'Reillyから「Efficient Go」というタイトルの本を執筆しています。個人の意見です。
Prometheusプロジェクトで私が個人的に気に入っている点、そしてチームに参加した多くの理由の一つは、プロジェクトの目標にレーザーフォーカスしていることです。Prometheusは常に、実用的で信頼性が高く、安価でありながらも非常に価値のあるメトリックベースの監視を提供するための境界線を押し広げてきました。Prometheusの超安定した堅牢なAPI、クエリ言語、および統合プロトコル(例:Remote WriteとOpenMetrics)は、Cloud Native Computing Foundation (CNCF) のメトリックエコシステムがこれらの強力な基盤の上に成長することを可能にしました。その結果、素晴らしいことが起こっています。
- コミュニティのエクスポーターにより、事実上あらゆるもの(例:コンテナ、eBPF、Minecraftサーバー統計、そしてガーデニングにおける植物の健康状態まで、メトリックを取得できます。
- 今日、ほとんどの人がクラウドネイティブソフトウェアに、PrometheusがスクレイピングできるHTTP/HTTPSの
/metricsエンドポイントがあると期待しています。これはGoogle内で秘密裏に開発され、Prometheusプロジェクトによって世界的に普及した概念です。 - オブザーバビリティのパラダイムは変化しました。SREや開発者が初日からメトリックに大きく依存するようになり、ソフトウェアの回復力、デバッグ可能性、データ駆動型の意思決定が向上しています。
結局のところ、Prometheusが実行されていないKubernetesクラスタを見ることはほとんどありません。
Prometheusコミュニティの強力な焦点は、他のオープンソースプロジェクトの成長も可能にし、Prometheusのデプロイメントモデルを単一ノードを超えて拡張すること(例:Cortex、Thanosなど)。クラウドベンダーがPrometheusのAPIとデータモデルを採用していること(例:Amazon Managed Prometheus、Google Cloud Managed Prometheus、Grafana Cloudなど)。Prometheusプロジェクトがこれほど成功している理由を一つ挙げるとすれば、それは「監視コミュニティを重要なことに集中させる」ことです。
この(長文の)ブログ記事では、「Agent」と呼ばれるPrometheusの新しい運用モードを紹介したいと思います。これはPrometheusバイナリに直接組み込まれています。AgentモードはPrometheusの通常の機能を一部無効にし、バイナリをスクレイピングおよびリモートロケーションへのリモート書き込みのために最適化します。機能数を減らすモードを導入することで、新しい使用パターンが可能になります。この記事では、CNCFエコシステムにおける特定のデプロイメントにとって、これがなぜゲームチェンジャーとなるかを説明します。私はこれに非常に興奮しています!
転送ユースケースの歴史
Prometheusのコア設計は、プロジェクトの全期間にわたって変更されていません。GoogleのBorgmon監視システムに触発され、監視したいアプリケーションの隣にPrometheusサーバーをデプロイし、Prometheusにそれらに到達する方法を指示し、定期的にメトリックの現在の値をスクレイピングすることができます。このような収集方法は、「プルモデル」としてしばしば参照され、Prometheusを軽量で信頼性の高いものにしている中核原則です。さらに、アプリケーションのインストルメンテーションとエクスポーターは、すべての追跡されているメトリックの現在の値を(OpenMetrics形式で)単に人間が読めるHTTPエンドポイントで提供するだけでよいため、非常にシンプルになります。複雑なプッシュインフラストラクチャや非自明なクライアントライブラリは不要です。全体として、典型的なPrometheus監視デプロイメントは以下のようになります。

これはうまく機能しており、何年もかけて数十億の成功したデプロイメントを見てきました。その中には、2年程度の長期保存のものもあります。すべて、クラスター管理者と開発者の両方にとって有用なメトリックをクエリ、アラート、記録することを可能にします。
しかし、クラウドネイティブの世界は絶えず成長し、進化しています。マネージドKubernetesソリューションの増加と、数秒でオンデマンドで作成されるクラスタにより、私たちはついにクラスタを「家畜」として扱い、「ペット」ではない(つまり、個々のインスタンスの重要度を低くする)ことができるようになりました。場合によっては、クラスタという概念さえもはや存在しません。例えば、kcp、Fargateなどのプラットフォームです。

もう一つの興味深いユースケースとして、エッジクラスタまたはネットワークという概念が浮上しています。通信、自動車、IoTデバイスなどの産業がクラウドネイティブ技術を採用するにつれて、リソースが制限された、はるかに小規模なクラスタが増加しています。これにより、ほとんど何もリモートノードに保存できないため、すべてのデータ(オブザーバビリティを含む)をリモートの、より大きな対抗物に転送する必要があります。
これは何を意味するのでしょうか?それは、監視データを何らかの方法で集約し、ユーザーに提示し、時にはグローバルレベルで保存する必要があることを意味します。これはしばしばグローバルビュー機能と呼ばれます。
単純に考えると、リモートネットワーク全体をスクレイピングするグローバルレベルのPrometheusをデプロイするか、監視目的でアプリケーションから直接中央ロケーションにメトリックをプッシュするかのどちらかでこれを実装できるかもしれません。どちらも一般的に非常に悪いアイデアである理由を説明します。
🔥 ネットワーク境界を越えたスクレイピングは、監視パイプラインに新しい未知の要素を追加する場合、課題となる可能性があります。ローカルプルモデルにより、Prometheusはターゲットがなぜ問題があり、いつ問題があるのかを正確に知ることができます。ダウンしているのか、設定ミスなのか、再起動したのか、メトリックを取得するのが遅すぎるのか(例:CPUが飽和している)、サービスディスカバリで発見できないのか、アクセス資格がないのか、あるいはDNS、ネットワーク、またはクラスタ全体がダウンしているのか。スクレイパーをネットワークの外に置くことで、個々のターゲットとは無関係なスクレイプに信頼性の低下を導入することによって、この情報の一部を失うリスクがあります。さらに、ネットワークが一時的にダウンした場合、重要な可視性を完全に失うリスクがあります。しないでください。それは価値がありません。(
🔥 アプリケーションから中央ロケーションに直接メトリックをプッシュすることも同様に悪いです。特に大規模なフリートを監視している場合、リモートアプリケーションからのメトリックが見えないと、何もわかりません。アプリケーションがダウンしているのか?受信パイプラインがダウンしているのか?アプリケーションの認証に失敗したのか?リモートクラスタのIPアドレスを取得できなかったのか?遅すぎるのか?ネットワークがダウンしているのか?さらに悪いことに、一部のアプリケーションターゲットからのデータが欠落していることにさえ気づかないかもしれません。そして、データを送信すべきすべての状態とステータスを追跡する必要があるため、あまり多くのメリットも得られません。このような設計は、失敗のレシピになりやすいため、慎重な分析が必要です。
注サーバーレス関数や短命なコンテナは、プッシュをアプリケーションからの救済策と考えることが多いケースです。しかし、この時点では、イベントまたは集約したいメトリックの断片を、より長命な時系列に変換することについて話しています。このトピックはここでで議論されています。自由に貢献して、これらのケースをより良くサポートするのを手伝ってください!
Prometheusは、グローバルビューケースをサポートするために3つの方法を導入しました。それぞれに長所と短所があります。それらを簡単に見てみましょう。以下の図ではオレンジ色で示されています。

- フェデレーションは、集約目的のために最初に導入された機能です。これにより、グローバルレベルのPrometheusサーバーは、リーフPrometheusからメトリックのサブセットをスクレイピングできます。このような「フェデレーション」スクレイプは、フェデレーションエンドポイントによって公開されるメトリックが元のサンプルのタイムスタンプを含むため、ネットワークを越えた未知の要素を一部削減します。それでも、通常はすべてのメトリックをフェデレーションできない、または長時間のネットワークパーティション(数分)中にデータを失うという問題があります。
- Prometheus Remote Readは、直接PromQLクエリなしで、リモートPrometheusサーバーのデータベースから生のメトリックを選択できます。グローバルレベルにPrometheusまたは他のソリューション(例:Thanos)をデプロイして、これらのデータに対してPromQLクエリを実行し、必要なメトリックを複数のリモートロケーションから取得できます。これは非常に強力で、データを「ローカル」に保存し、必要なときにのみアクセスできます。残念ながら、欠点もあります。Query Pushdownのような機能がない場合、単一のクエリに応答するために、極端なケースではGB単位の圧縮メトリックデータをプルします。また、ネットワークパーティションがある場合、一時的に何も見えなくなります。最後に、特定のセキュリティガイドラインでは、イングレストラフィックのみを許可し、エグレストラフィックは許可しません。
- 最後に、現在最も人気のある選択肢であるPrometheus Remote Writeがあります。Agentモードはリモート書き込みユースケースに焦点を当てているため、詳しく説明します。
リモート書き込み
Prometheus Remote Writeプロトコルを使用すると、Prometheusが収集したすべてのメトリックまたはそのサブセットをリモートロケーションに転送(ストリーミング)できます。Prometheusを、(必要であれば、すべてのメタデータとエクサンブルを含めて)Remote Write APIをサポートする1つ以上のロケーションに一部のメトリックを転送するように構成できます。実際、PrometheusはRemote Writeの取り込みと送信の両方をサポートしているため、グローバルレベルにPrometheusをデプロイしてそのストリームを受信し、クロス・クラスタでデータを集約できます。
公式のPrometheus Remote Write API仕様はレビュー段階ですが、エコシステムはRemote Writeプロトコルをデフォルトのメトリックエクスポートプロトコルとして採用しました。例えば、Cortex、Thanos、OpenTelemetry、そしてAmazon、Google、Grafana、Logz.ioなどのクラウドサービスはすべて、Remote Write経由でのデータ取り込みをサポートしています。
Prometheusプロジェクトは、APIの公式コンプライアンステストも提供しています。例えば、Remote Writeクライアント機能を提供するソリューション向けのremote-write senderコンプライアンスです。これは、このプロトコルを正しく実装しているかどうかを迅速に判断するための素晴らしい方法です。
このようなスクレイパーからのデータストリーミングは、メトリックデータを集中型ストレージに保存することを可能にし、グローバルビューユースケースを有効にします。また、関心の分離も可能になり、アプリケーションがオブザーバビリティまたは監視パイプラインとは異なるチームによって管理されている場合に便利です。さらに、顧客からできるだけ多くの作業をオフロードしたいベンダーがRemote Writeを選択する理由でもあります。
ちょっと待ってください、Bartek。あなたは先ほど、アプリケーションから直接メトリックをプッシュするのは最善のアイデアではないと言いました!
もちろんですが、素晴らしいのは、Remote Writeを使用しても、Prometheusは依然としてアプリケーションからメトリックを収集するためにプルモデルを使用していることです。これにより、これらのさまざまな障害モードを理解できます。その後、サンプルとシリーズをバッチ処理し、リモート書き込みエンドポイントにデータをエクスポート、レプリケート(プッシュ)し、中央ポイントが持つ監視の未知の要素の数を制限します!
信頼性の高い効率的なリモート書き込み実装は、簡単な問題ではないことに注意することが重要です。Prometheusコミュニティは、安定したスケーラブルな実装を考案するのに約3年を費やしました。WAL(write-ahead-log)を数回再実装し、内部キューイング、シャーディング、スマートバックオフなどを追加しました。これらすべてがユーザーからは隠されており、ユーザーはパフォーマンスの高いストリーミングや、集中型ストレージに保存された大量のメトリックを楽しむことができます。
実践的なRemote Writeの例:Katacodaチュートリアル
これらはすべてPrometheusにとって新しいものではありません。私たちの多くはすでにPrometheusを使用して必要なすべてのメトリックをスクレイピングし、それらの一部またはすべてをリモートロケーションにリモート書き込みしています。
リモート書き込み機能のハンズオン体験を試したい場合は、Prometheusからリモートロケーションにすべてのメトリックを転送するために必要なすべてのステップを説明している、Prometheusからのリモート書き込みメトリックのThanos Katacodaチュートリアルをお勧めします。これは無料です。アカウントにサインアップしてチュートリアルをお楽しみください!🤗
この例では、Thanosを受信モードでリモートストレージとして使用していることに注意してください。現在では、リモート書き込みAPIと互換性のある他の多くのプロジェクトを使用できます。
では、リモート書き込みがうまく機能するなら、なぜPrometheusに特別なAgentモードを追加したのでしょうか?
Prometheus Agent Mode
Prometheus v2.32.0(次のリリース)から、誰でも実験的な--enable-feature=agentフラグでPrometheusバイナリを実行できるようになります。リリース前に試したい場合は、Prometheus v2.32.0-beta.0を使用するか、quay.io/prometheus/prometheus:v2.32.0-beta.0イメージを使用してください。
Agentモードは、リモート書き込みユースケースのためにPrometheusを最適化します。クエリ、アラート、ローカルストレージを無効にし、カスタマイズされたTSDB WALに置き換えます。それ以外はすべて同じです:スクレイピングロジック、サービスディスカバリ、および関連する設定。リモートPrometheusサーバーまたは他のRemote-Write準拠プロジェクトにデータを転送したい場合、これはPrometheusのドロップイン置換として使用できます。本質的には次のようになります。

Prometheus Agentの最も良い点は、Prometheusに組み込まれていることです。同じスクレイピングAPI、同じセマンティクス、同じ設定とディスカバリメカニズム。
ローカルでクエリまたはアラートを行わず、メトリックを外部にストリーミングする場合、Agentモードを使用する利点は何でしょうか?いくつかあります。
まず、効率性です。カスタマイズされたAgent TSDB WALは、書き込みが成功した後すぐにデータを削除します。リモートエンドポイントに到達できない場合、リモートエンドポイントがオンラインに戻るまで一時的にディスクにデータを永続化します。これは現在、非Agent Prometheusと同様に2時間のバッファに制限されています。すぐに解除されることを期待しています。これは、メモリ内にデータのチャンクを構築する必要がないことを意味します。クエリ目的のために完全なインデックスを維持する必要もありません。本質的に、Agentモードは、同様の状況で通常のPrometheusサーバーが使用するリソースのごく一部を使用します。
この効率性は重要でしょうか?はい!前述したように、エッジクラスタでは、メモリのGB、CPUコアのすべてが一部のデプロイメントにとって重要です。一方で、メトリックを使用した監視のパラダイムは、現在かなり成熟しています。これは、同じコストでより多くのカーディナリティを持つ、より関連性の高いメトリックを送信できるほど良いことを意味します。
注Agentモードの導入により、元のPrometheusサーバーモードは引き続き推奨される、安定したメンテナンスされたモードとして残ります。リモートストレージを備えたAgentモードは、追加の複雑さをもたらします。注意して使用してください。
第二に、新しいAgentモードの利点は、取り込みの水平スケーリングを容易にすることです。これは私が最も興奮していることです。なぜか説明しましょう。
夢:自動スケーラブルなメトリック取り込み
スクレイピングのための真の自動スケーラブルソリューションは、メトリックターゲットの量とそれらが公開するメトリックの数に基づいている必要があります。スクレイピングするデータが多いほど、Prometheusのインスタンスを自動的にデプロイします。ターゲットの数やメトリックの数が減少した場合は、スケールダウンしてインスタンスをいくつか削除できます。これにより、Prometheusのサイジングを調整する手動の負担が軽減され、クラスタが一時的に小さい場合にPrometheusを過剰に割り当てる必要がなくなります。
サーバーモードのPrometheusだけでは、これは達成するのが困難でした。これは、サーバーモードのPrometheusがステートフルであるためです。収集されたものはすべて単一の場所にそのまま保持されます。これは、スケールダウン手順で、既存のインスタンスに収集されたデータをバックアップしてから終了する必要があることを意味します。その後、スクレイプの重複、誤解を招くステールネスマーカーなどの問題が発生します。
さらに、すべてのインスタンスのサンプルを(例:Thanos QueryまたはPromxy)集約できるグローバルビュークエリが必要になります。最後に、サーバーモードのPrometheusのリソース使用量は、取り込み以外の多くの要因に依存します。アラート、記録、クエリ、コンパクション、リモート書き込みなどがあり、メトリックターゲットの数とは無関係により多くの、またはより少ないリソースが必要になる場合があります。
Agentモードは、本質的にディスカバリ、スクレイピング、およびリモート書き込みを個別のマイクロサービスに移行します。これにより、取り込みのみに焦点を当てた運用モデルが可能になります。その結果、AgentモードのPrometheusは多かれ少なかれステートレスになります。はい、メトリックの損失を回避するために、エージェントのHAペアをデプロイし、それらに永続ディスクをアタッチする必要があります。しかし、技術的には、数千のメトリックターゲット(例:コンテナ)がある場合、複数のPrometheusエージェントをデプロイし、どのレプリカがどのターゲットをスクレイピングしているかを安全に変更できます。これは、最終的にすべてのサンプルが同じ中央ストレージにプッシュされるためです。
全体として、PrometheusのAgentモードは、メトリックターゲットの動的な変化に反応できる、Prometheusベースのスクレイピングの水平自動スケーリング機能を容易に実現します。これは間違いなく、Prometheus Kubernetes Operatorコミュニティとともに今後検討していくことです。
それでは、PrometheusにおけるAgentモードの現在の実装状態を見てみましょう。使用準備はできていますか?
Agentモードは大規模で実証済み
Prometheusの次のリリースには、Agentモードが実験的機能として含まれます。フラグ、API、およびディスク上のWAL形式は変更される可能性があります。しかし、Grafana Labs'のオープンソース作業のおかげで、実装のパフォーマンスはすでに実証済みです。
AgentのカスタムWALの初期実装は、現在のPrometheusサーバーのTSDB WALに触発され、19年にRobert Frattoによって、PrometheusメンテナーTom Wilkieの指導の下で作成されました。その後、2019年、PrometheusメンテナーTom Wilkieの指導の下で、オープンソースのGrafana Agentプロジェクトで使用され、その後多くのGrafana Cloudの顧客やコミュニティメンバーによって使用されてきました。ソリューションの成熟度を考慮すると、実装をPrometheusに寄贈してネイティブ統合とより大きな採用を促進する時期が来ました。Robert(Grafana Labs)は、Srikrishna(Red Hat)とコミュニティの助けを借りて、コードをPrometheusコードベースに移植し、2週間前にマージされました!
寄贈プロセスは非常にスムーズでした。一部のPrometheusメンテナーは以前Grafana Agentでこのコードに貢献しており、新しいWALはPrometheus自身のWALに触発されているため、現在のPrometheus TSDBメンテナーがそれを完全にメンテナンスするのは難しくありませんでした!RobertがPrometheusチームにTSDBメンテナーとして参加するのも大いに役立ちました(おめでとうございます!)。
それでは、使い方の説明です!(
Agentモードの詳細な使用方法
今後、Prometheusのヘルプ出力(--helpフラグ)を表示すると、概ね以下のようになります。
usage: prometheus [<flags>]
The Prometheus monitoring server
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
(... other flags)
--storage.tsdb.path="data/"
Base path for metrics storage. Use with server mode only.
--storage.agent.path="data-agent/"
Base path for metrics storage. Use with agent mode only.
(... other flags)
--enable-feature= ... Comma separated feature names to enable. Valid options: agent, exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver,
extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.dokyumento.jp/docs/prometheus/latest/feature_flags/ for more details.
Agentモードは前述の通りフィーチャーフラグで保護されているため、--enable-feature=agentフラグを使用してPrometheusをAgentモードで実行します。残りのフラグは、サーバーとAgentの両方、または特定のモードのみに使用されます。フラグのヘルプ文字列の最後の文を確認することで、どのフラグがどのモード用であるかを確認できます。「サーバーモードのみで使用」は、サーバーモード専用であることを意味します。これに該当する言及がない場合は、フラグは共有されています。
Agentモードは、同じスクレイプ設定と、同じディスカバリオプションおよびリモート書き込みオプションを受け入れます。
また、クエリ機能が無効になっているWeb UIを公開しますが、通常のPrometheusサーバーと同様に、ビルド情報、設定、ターゲット、およびサービスディスカバリ情報を表示します。
ハンズオンPrometheus Agentの例:Katacodaチュートリアル
Prometheusリモート書き込みチュートリアルと同様に、Prometheus Agentの機能のハンズオン体験を試したい場合は、Prometheus Agentを実行するのがいかに簡単かを説明している、Prometheus AgentのThanos Katacodaチュートリアルをお勧めします。
概要
この記事が興味深いものであったことを願っています!この記事では、次のような新しいケースを検討しました。
- エッジクラスタ
- アクセス制限のあるネットワーク
- 多数のクラスタ
- 一時的および動的なクラスタ
次に、スクレイピングされたメトリックをリモート書き込みエンドポイントに効率的に転送できる新しいPrometheus Agentモードを説明しました。
いつものように、問題やフィードバックがあれば、GitHubにチケットを提出するか、メーリングリストで質問してください。
この記事は、CNCF、Grafana、Prometheus間の協調リリースの一部です。ぜひ、CNCFの発表や、Prometheus Agentの基盤となっているGrafana Agentの視点も読んでみてください。