NodeGroup単位でのメトリクス収集

こんにちは。
インフラグループKubernetesチームの福田です。
先日、こちらでPrometheus Stackを使った監視構成の概要を紹介させていただきました。
本記事はそれに関連して、NodeGroup単位でのメトリクスの取得に関してハマりポイントがあったので、それを紹介できればと思います。

NodeGroupとは

EKSにはNodeGroupという機能があります。
これは名前の通り、Nodeをグループとしてまとめる機能で、NodeGroup単位でマシンスペックを指定したりすることが可能です。
NodeGroupの詳細はこちらの記事が特に参考になります。
また、NodeGroupの名前等の情報は各nodeにラベルとして付与することが可能です。

やりたいこと

我々の場合、EKS上に複数のプロジェクトをホスティングしており、これらのプロジェクトに1:1でNodeGroupが存在しています。
そして、プロジェクト単位(NodeGroup単位)でnodeに関するメトリクスを収集したい要件があります。
例えば、あるプロジェクトのnodeの負荷を収集して、そのプロジェクトが設定しているEC2(Kubernetes node)マシンスペックが適切かどうか判断したい場合です。
言い換えると、あるnodeに関するメトリクスがどのNodeGroupに属するものか知りたいのです。

問題点

Prometheus metricsにはラベルが付いていて、このラベルを使ってメトリクスをフィルタしたり、グルーピングしたりできます。
我々の監視構成ではnodeのメトリクスはNode Exporter経由で収集していますが、Node Exporterが提供するメトリクスにNodeGroupラベルは付与されていません。
また、relabel_configs等のPrometheusが提供するラベル付与機能では決まった文字列のラベルを付与することはできても、「メトリクスの送信元ラベルからNodeGroupラベルをマッピングして付与する」といった動的なラベル付与はできません。

解決策

nodeにラベル(メトリクスのラベルではなく、Kubernetes nodeに付与されているラベル)として付与されているNodeGroupの名前をKubernetes API経由で取得し、メトリクスにNodeGroupラベルを付与するプロキシ(Proxy Container)をNode Exporter Podにアダプタとして追加しました。

Proxy ContainerはGoで実装していて、以下のように動作します。

NodeGroupラベルの取得の挙動

  1. 自分自身がデプロイされているkubernetes nodeのhostnameを取得。
  2. 前のステップで取得したhostnameに対応するnodeのラベル一覧をKubernetes API経由で取得。
    • 取得したnodeのラベル一覧にNodeGroupラベルが含まれる。

Proxyとしての挙動

  1. Prometheusからリクエストを受信する。
  2. Node Exporterコンテナにメトリクスのリクエストをする。
  3. Node Exporterコンテナからレスポンスとしてメトリクス情報を受信する。
  4. 取得したメトリクス情報にテキスト処理を行い、メトリクスにNodeGroupラベル付与する。
  5. Prometheusにレスポンスを返す。

まとめ

NodeGroup単位でメトリクスを収集する方法について紹介させていただきました。
本記事で紹介したProxy ContainerはPrometheus形式のメトリクスに対して、任意のラベルを挿入できるように実装しています。
動的にメトリクスのラベルを弄りたくなる状況が同じようにあれば、これを再利用していきたいと思います。

エニグモではエンジニアを含む各種ポジションで求人を募集しております。

株式会社エニグモ すべての求人一覧

hrmos.co