ブログ

Amazon CloudWatch向けのPrometheusエクスポーターの改善

Amazon CloudWatch向けのPrometheusエクスポーターの改善

本文の内容は、2020年5月20日に David de Torres Huertaが投稿したブログ(https://sysdig.com/blog/improving-prometheus-cloudwatch-exporter/)を元に日本語に翻訳・再構成した内容となっております。

Prometheus CloudWatchエクスポーターは、AWS CloudWatchを監視したい人にとって重要な要素です。CloudWatchメトリクスをPrometheusサーバーにエクスポートすると、PromQLクエリーの能力を活用し、AWSメトリクスを他のアプリケーションまたはクラウドプロバイダーのメトリクスと統合し、問題を掘り下げるための高度なダッシュボードを作成できます。

しかし、誰がウォッチャーを監視しますか?これらの利点にもかかわらず、誤ったエクスポーターまたは誤った構成を使用すると、実稼働環境で悪影響が生じる可能性があります。AWS APIをスロットリングすると、運用でそれがブロックされ、過剰なメトリクスまたはクエリが追加の請求コストを引き起こし、誤った構成が時系列のデータの欠落につながる可能性があります。

スケーラブルなPrometheusモニタリングエクスペリエンスを提供する過程で、私たちはプロダクショングレードのPrometheus CloudWatchエクスポーターを提供する必要があることに気付きました。

これを実現するために、ゼロから始める代わりに、YACE(Yet Another CloudWatch Exporter)を選択し、このオープンソースプロジェクトに貢献しました。AWS CloudWatchメトリクスの使用にかかるコストを削減するために、API呼び出しを抑制および最適化して、安定性を大幅に改善しました。

このPrometheus CloudWatchエクスポーターを適切な構成で使用して、本番環境に安全にデプロイできます。このようにして、AWS APIの可用性に影響を与えたり、AWS CloudWatchサービスのコストを制御したりせずに、AWS CloudWatchをモニタリングしてそのメトリクスをPrometheusサーバーに統合することができます。

この記事では、最初にPrometheusがAWS CloudWatchを拡張する方法と、既存のエクスポーターの問題を学びます。次に、API呼び出しの数を減らして安定性を向上させた方法の技術的な詳細を詳しく調べることができます。最後に、まとめと関連リソースをお見逃しなく。

CloudWatchとPrometheusの相乗効果

クラウドへの移行において、多くの企業にとって、AWSマネージドサービスが推奨されるオプションです。AWSは、Kubernetesクラスター、サーバーレス、データベース、ストレージ、オンデマンド機能などの価値の高いサービスを提供し、インフラストラクチャー、スケーラビリティ、ソフトウェアまたはハードウェアの更新の管理から組織を解放します。これは、特に新興企業やクラウドの初心者にとって大きな利点です。これにより、コアビジネスの開発に労力と人員を集中させることができます。

ただし、マネージドサービスであることは、監視されるべきではないという意味ではありません。クラウドベースのサービスとアプリケーションのパフォーマンスメトリクスは、基盤となるインフラストラクチャーを所有していないため、より価値があります。このデータは、アプリケーションのトラブルシューティングと最適化のために、管理対象インフラストラクチャーへの唯一のウィンドウを提供する場合があります。

しかし、それらのサービスからどのようにしてメトリクスを取得するのでしょうか?仮想マシンとは異なり、ほとんどの場合、マネージドサービスにPrometheusサーバーとエクスポーターをインストールできません。ここで、AWS CloudWatchの出番です。

20200521-1.png

サービスを管理すればするほど、プラットフォームへの依存度が高くなります。

赤い線の右側にいる場合、メトリクスを取得するにはおそらくCloudWatchが必要です。

この時点で、多くの人々は、PrometheusでCloudWatchメトリクスを使用できるかどうか疑問に思っています。彼らが尋ねるべき質問は「なぜ両方を組み合わせないのですか?」です。

CloudWatchは、AWSが管理するサーバーレスサービス用の非常に価値の高いメトリクスのセットを提供します。一方、Prometheusには強力なクエリー言語(PromQL)があります。PromQLを使用すると、独自のサービスレベルインジケーターを作成し、メトリクスを自由に組み合わせて集計できます。Prometheusでは、システムの他の部分と独自のコードをインストルメント化して、カスタムメトリクスを提供することもできます。

AWS CloudWatchとPrometheus の関係は競争ではなく、相乗効果です。AWS CloudWatchをPrometheusでモニタリングすると、それぞれを個別に使用するよりも多くの機能と可観測性が得られます。

このユニオンの利点を理解したので、問題が見つかりました。AWS CloudWatchは、APIとAWSコンソールUIでメトリクスを提供しますが、Prometheusが取り込める形式でそれらを公開しません。

解決策は、Prometheus CloudWatchエクスポーターを使用することです。これは、AWS APIを介してCloudWatchメトリクスを取得し、Prometheusと互換性のある形式でhttpエンドポイントに公開するように構成できるアプリケーションです。このようにして、PrometheusはCloudWatchメトリクスをスクレイピングし、それらをシステム内の他のサービスおよびアプリケーションからの残りのメトリクスと統合できます。

20200521-2.png

AWS APIを壊したエクスポーター

そこで、PrometheusでAWS CloudWatchをモニタリングすることにしました。クイック検索により、公式の Prometheus CloudWatch Exporterが表示されます。そのドキュメントには、AWSアクセス許可を設定する手順と、さまざまなサービスの設定ファイルのいくつかの例が含まれています。リポジトリのクローンを作成した後、EC2インスタンスからのメトリクスの受信を開始するために、IAM、権限、設定ファイルを準備します。

しかし、エクスポーターを起動し、Prometheusサーバーを起動してそれを削ると、何か問題が発生します。

エクスポーターは、コード400とThrottlingExceptionで複数のエラーを取得し始めます。エクスポーターが行うAPI呼び出しが多すぎるようです(そのリージョンにあるEC2インスタンスの数が原因である可能性があります)。

このスロットリングは、CloudWatchサービスへの呼び出しをブロックするだけではありません。このアカウントのAWS APIがブロックされているため、さまざまな操作スクリプトが一部のAPI呼び出しで失敗しています。

害のないエクスポーターはどのようにしてAWS APIを壊すことができますか?

エクスポーターのコードを詳しく調べると、関数-GetMetricStatistics-がすべてのリソースの各メトリクスに対してAPI呼び出しを行っていることがわかります。エクスポーターをデプロイすると、Prometheusはそれを毎分でスクレイピングします。つまり、そのAWSリージョンに約200のインスタンスがあり、インスタンスごとに10のメトリクスを設定した場合、エクスポーターは60秒ごとに2,000のAPI呼び出しを試行します(Prometheusがエクスポーターをスクレイプするたびに)。それは多すぎます。これがAPIのスロットリングと最終的なブロックを引き起こしたものです。

しかし、それだけではありません。CloudWatchに対するこれらすべてのメトリクスクエリーのコストの計算をすると、Prometheus CloudWatchエクスポーターで必要なすべてのサービスとリソースを監視することは非常に高価になることに気づきます。

幸いなことに、Yet Another CloudWatch Exporter(YACE)と呼ばれる公式のPrometheus CloudWatchエクスポーターに代わるものがあります。

このエクスポーターの構成は他のエクスポーターと似ていますが、1 回の呼び出しで最大500個のメトリクスを照会できる別のAPI関数を使用しています。これにより、API呼び出しの数が2,000から約12に減り、スロットルのリスクがなくなります

YACEエクスポーターは良い候補のようですが、本番環境の準備をするために対処しなければならないいくつかの問題がありました。

最初のものは、クラッシュする可能性でした。APIが利用できない場合、またはスロットルによって引き起こされたエラーがAPIから返された場合はいつでも、エクスポーターがクラッシュしました。これにより、エクスポーターがデプロイされていたコンテナも継続的に再起動されました。

パフォーマンスに影響を与えたもう1つの問題は、エクスポーターの待ち時間が長いことでした。リソースの量が多いシナリオでは、スクレイピング時間が60秒を超える場合があります。これによりタイムアウトエラーが発生し、一部のシナリオでは、新しいスクレイプが以前の未完成のスクレイプと重複していました。これにより、API呼び出しの数が増加し、スロットルのリスクが増加しました。

また、一部のメトリクスでは、利用可能なデータがあることを知っていても、CloudWatchが何も返さないことがあります。スクレイピングは成功したように見えましたが、一部のメトリクスが欠落しており、メトリクスグラフのデータギャップに変換されました。

次のセクションでは、SysdigチームがオープンソースのYACEエクスポーターリポジトリに行ったコントリビュートがこれらの問題にどのように対処したかを説明します。

プロキシーを使用したCloudWatch呼び出しの制御

YACEエクスポーターは、GetMetricData API呼び出しを使用して、1つのリクエストで複数のメトリクスを要求します。ただし、エクスポーターの同時または高頻度のスクレイピングにより、APIのスロットルとAWS CloudWatchの追加請求コストの両方が発生する可能性があるというリスクは依然としてあります。

高頻度のスクレイピングは、10秒などの短いスクレイピング間隔でのPrometheusの設定、または複数のPrometheusサーバーがエクスポーターに独立してスクレイピングを行う高可用性デプロイメントによって引き起こされる可能性があります。

これらのシナリオを回避するために、メトリクスの提供とCloudWatchへの新しいデータのクエリを分離するようにYACEエクスポーターを変更しました。このようにして、エクスポーターはプロキシーとして機能し、特定の頻度(通常は300秒)で新しいデータを要求します。Prometheusサーバーがエクスポーターをスクレイピングするたびに、CloudWatchに照会する必要なく、最後に回復されたデータを提供します。

20200521-3.png

メトリクスのプロキシーがある場合と、ない場合の動作のフローチャート

データ更新に300秒間隔を使用するのでしょうか? AWS CloudWatchは、無料利用枠で、300秒の粒度。そして有料利用において最大60秒の粒度でかなりの量のメトリクスを提供します。

異なるスクレイピング頻度 が必要な場合は、データ更新間隔を設定できます。デカップリングを無効にして、エクスポーターのすべてのスクレイプに新しいメトリクスを要求することもできます。

異なるデータ更新間隔 を使用する1つのケースは、S3バケットの日次メトリクスです。これらのメトリクスは1日に1回しか変更されないため、5分ごとに要求しても意味がありません。これらの2つのメトリクスが無料で提供されている場合でも、クエリーを実行するとAWS CloudWatchサービスの請求が行われます。これにより、バケット数が多いアカウントで大きな違いが生じる可能性があります。

それを知っていれば、データ更新間隔を4時間に設定できます。200個のS3バケットを持つアカウントでこの設定を使用すると、Prometheusサーバーのスクレイピング間隔に関係なく、1日あたり115,200メトリクスから約2,400になります。これは、メトリクスが約60分の1に削減されます。メメトリクスのプロキシが設定されておらず、デフォルトのスクレイピング時間が60秒である場合、1日あたりのAWS CloudWatchメトリクスの数は最大576,000になることに注意してください。

別のデータ更新間隔を使用すると、エクスポーターに2つの追加の影響がありました。1つ目は、スクレイピング時間の大幅な短縮で、数十秒(場合によっては60を超える)から1秒未満に短縮されました。また、設計上、APIへの複数の同時呼び出しを回避して、2つのスクレイプが時間的にオーバーラップすることは不可能でした。

AWS API呼び出しを削減してコストを削減し、スロットルを回避する

YACEエクスポーターで行われた別の最適化は、行われたAPI呼び出しの数に関連しています。エクスポーターはAWS CloudWatchメトリクスを要求する必要があるだけでなく、利用可能なリソースとメトリクスのリストを取得するために行われる他のAPI呼び出しがあります。これらのAPI呼び出しも課金に含まれます。

YACEエクスポーターは、地域とタグによる優れたフィルタリングサポートを備えています。この機能を利用して、本番環境のデプロイから、または特定のリソース(開発、ステージング、本番などとしてタグ付け)からメトリクスを収集できます。

これを可能にするために、エクスポーターはすべてのスクレイプでリソースのメタデータをAWSに要求し、それらをフィルター処理してから、それらすべての設定済みメトリクスを要求する必要があります。

そして、ここでは、どこでもそうであるように、悪魔は細部にいます。

まず、すべてのリソースがすべての設定済みメトリクスを持つとは限りません。200個のS3バケットがあるAWSアカウントの前の例を見てみましょう。無料で提供される2つの1日のメトリクスとは別に、頻度が60秒で16のメトリクスがあります。これらを明示的に有効にする必要があり、それらは無料ではないため、何かがうまくいかない場合に警告したいような最も重要なバケットでのみ有効にします。10個のバケットが重要であるため、それらのバケットでのみ追加のメトリクスを有効にするとします。

このシナリオでは、YACEエクスポーターは、利用可能なメトリクスを要求する3,600 API呼び出しを行います。これらは同時に行われるため、AWS APIサーバーでスロットルを引き起こします。そのため、さらに多くの利用可能なメトリクスとデータを要求する次のリクエストはすべてエラーを返します。それだけでなく、これらのAPI呼び出しはAWS CloudWatchの請求にも影響を与えます。

これは良いシナリオではありません。

これを修正するために、YACEエクスポーターのロジックを変更して、メトリクスが使用可能なすべての使用可能なリソースと特定のメトリクスのディメンションを要求するようにしました。この新しい動作により、この例では、エクスポーターは以前の3,600ではなく、18のAPI呼び出し(設定されたメトリクスごとに1つ)のみを実行します。

これにより、データが利用可能なリソースのみのメトリクスを要求することもできます。200個のS3バケットすべてで3,600メトリクスを要求する代わりに、エクスポーターは、それらのメトリクスを有効にした10個のバケット(10個のリソースで16個のメトリクス)のみで160個のメトリクスを要求します。

20200521-4.png

Yaceエクスポーターは、リソースの青いセクションの指標を求めていました。

ロジックを変更して、赤いセクションの質問のみを要求するようにしました。

また、この最適化の作業中に修正された他の 2つのエッジケースがありました。

AWS ALBサービスのアプリケーションロードバランサーでは、リソースはロードバランサーまたはターゲットグループのいずれかです。それらのメトリクスは、単独で使用されるロードバランサーとターゲットグループと組み合わせられるロードバランサーによって異なります。この特別なケースは、ロードバランサーとターゲットグループの可能な組み合わせごとにAPI呼び出しを行わないように最適化されました。

バグにより、エクスポーターは特定の状況下で現在の設定を無視し、最後の120秒でのみ生成されたデータを要求するように制限しました。これにより、CloudWatchが不足しているデータを収集に使用できると想定されていたため、イライラしていたいくつかのデータギャップが発生しました。これが修正されたため、エクスポーターはより長い時間(600秒など)のデータを要求できるようになり、これらのデータのギャップが解消されました。

安定性とAPI呼び出しの他の改善

YACEエクスポーターのオープンソースリポジトリにこれらの最適化を実装する際に、パフォーマンスと安定性を向上させるためにいくつかのコントリビュートも行いました。

API呼び出しの数の最適化に直接関連する1つのコントリビュートは、GetMetricsDataごとのメトリクスの増加です。この機能が最初にエクスポーターに実装されたとき、AWSには、このAPI呼び出しのリクエストごとに100 メトリクスの制限がありました。その後、AWSはその制限を500メトリクスに増やしましたが、これはエクスポーターコードで更新されませんでした。これを更新しただけでなく、フラグで構成できるようにしたので、このAPI呼び出しの制限が再び変更された場合に、YACEエクスポーターをすばやく適応させることができます。

APIからのエラー処理の改善に焦点を当てた別のコントリビュートもあります。エクスポーター、スロットルシナリオ、または接続エラーによるAWS APIからのエラーでの致命的なエラーを防止することにより、より信頼性が高く、本番環境に対応できるようにしました。

最後に重要なことですが、AWS Farateのメトリクスの統合にコントリビュートし、AWS namespace ECS/ContainerInsightsを介してメトリクスを利用できるようにしました。これにより、PromCat.ioオープンソースプロジェクトでAWS Fargateのリソースを作成できるようになりました。

まとめ

AWS CloudWatchとPrometheusのモニタリングは相乗的に機能します。AWS CloudWatchをPrometheusでモニタリングすると、promQLのすべての機能を使用し、AWSメトリクスを他のアプリケーションやクラウドのメトリクスと統合できます。

これらのメトリクスにアクセスするには、Prometheus CloudWatchエクスポーターが必要ですが、本番環境に対して十分な信頼性があり、適切に構成されている必要があります。

これを実現するために、SysdigチームはYACE CloudWatchエクスポーターにコントリビュートし、その安定性を向上させ、AWS API呼び出しとCloudWatchメトリクスの使用を最適化しました。

PromCat.ioでは、YACEエクスポーターを活用してさまざまなAWSサービスのAWS CloudWatchメトリクスを抽出するAWSサービスのキュレーションされた構成、ダッシュボード、アラート、レコーディングルールのコレクションを見つけることができます。AWSサービスを使用している場合は、ぜひお試しください。ローカルインストールとKubernetesの両方ですぐに使える設定とデプロイを準備しました。

詳細を確認しますか?AWSオープンソースブログを読む:PrometheusおよびPromCatを使用して、Kubernetesで使用されるAWSサービスを監視する

また、Sysdig Monitorは、CloudWatchエクスポーターによって提供されるものを含む、プロダクショングレードのPrometheusメトリクスを統合および拡張します。是非、無料トライアルをお試しください!

最近の投稿

カテゴリー

アーカイブ

ご質問・お問い合わせはこちら

top