Konnect環境でPrometheusでメトリクスを取得する

初歩的なところなのに時間を食ってしまったのでメモ化。
KonnectだとAnalyticsというメトリクスの分析ツールが提供されるが、自前で既にPrometheus/Grafana環境を持っている人はKonnectの分析ツールを使わずに自前の環境にメトリクスを集約したいということも多いと思う。
今回はKonnect利用時にアプリへのトラフィックのメトリクスをPrometheus/Grafanaで可視化する方法をメモ化する。


## 前提

以下の環境で検証する。
- Kubernetes環境
- Prometheus/Grafanaは同一クラスタ内に展開済み
- スクレイプの設定はPrometheus OperatorのCRDの`ServiceMonitor`を利用

Prometheus/Grafanaは「[cert-managerとPrometheus OperatorでTLS化したPrometheus/Grafanaを立てる](https://qiita.com/ipppppei/items/c15acc5c7f7af3e7c289)」の手順で構築したものを使う。

## Data Planeの構築
Data Planeに設定を施す必要があるのでData Planeの構築から行う。
KonnectのUIから`Data Plane Nodes`->`Configure data plane`を選択する。
![Pasted image 20250513182718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/d0c9cc46-7443-4f84-b6ae-2dd73f1d52a6.png)

選択後の画面でPlatformにKubernetesを選択するとKubernetes向けのセットアップ手順が表示されるので、これに従って`values.yaml`を作るところまで進める。

`values.yaml`作成時、以下を追記する。
```yaml
serviceMonitor:
  enabled: true
  labels:
    release: prometheus-stack

status:
  enabled: true
  http:
    enabled: true
    containerPort: 8100
```
メトリクスの取得には[Status API](https://docs.konghq.com/gateway/api/status/latest/)を利用する。
Kong Gatewayのメトリクス取得はAdmin APIの`/metrics`かStatus APIの`/metrics`を使って取得するが、**Admin API経由は以下のようなデメリットがある**。
- **RBAC利用時に使えない（Prometheusにスクレイプさせるのが難しい）**
- **Control Planeにアクセス出来る必要あり（＝Konnect環境では利用不可）**

Status APIだと上記のデメリットを回避でき、Konnectの場合だと選択肢はこれのみとなる。
Status APIを使うために`status:`を記載してDeploymentにStatus API用の設定が埋め込む。
なお、[コードを見る感じ](https://github.com/search?q=repo%3AKong%2Fcharts%20%22Values.status.%22&type=code)、StatusAPIのためのServiceリソースは作られない模様。
あと、Prometheusが自動で`/metrics`を見つけてスクレイプするための`ServiceMonitor`リソースを作成するために`serviceMonitor:`の設定を入れている。
ラベルを指定しているのはPrometheus OperatorのServiceMonitor検知ルールに従うため。
詳細は以前書いた[こちら](https://qiita.com/ipppppei/items/d6034c6bed3364f89461)の記事を参照して欲しいが、環境によって違う場合があるので各自のものを確認の上設定して貰った方がよい。

上記設定でデプロイする。
```sh
helm upgrade -i -n kong my-kong kong/kong -f ./values.yaml --debug --wait
```
デプロイ後、StatusAPI用のServiceを作成する。
```sh
kubectl expose deploy my-kong-kong --port 8100 --name my-kong-kong-status --type ClusterIP -n kong -l enable-metrics="true"

```
なおラベルは`ServiceMonitor`が検知するためのもので、`ServiceMonitor`の`spec.selector.matchLabels`でスクレイプ対象が定義されている。
上手く行けばPrometheusのTargetsに以下のようにDPのエンドポイントが追加される。
![Pasted image 20250513185728.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/10af987d-4ec8-4734-9ac8-1b756cdbc83f.png)

PromQLでKong関連のメトリクスが見れることも確認する。
![Pasted image 20250513185811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/12ffd54c-c844-40d2-9149-9bdb61644cb6.png)

## 動作確認
適当にService、Routeを作成し、Prometheus Pluginを適用する。
今回は以下のものを作成した。（作成手順は割愛）
- Service
	- Service名はhttpbin-service
	- https://httpbin.org
- Route
	- /httpbin
- Plugin
	- **Prometheus PluginをRouteに設定**
	- Prometheus Pluginのメトリクスのチェックは全てON

Prometheus Pluginを設定しないと本体のメトリクスしか取得できず、リクエストのメトリクスは確認できないため注意。
作成後、DP経由でアクセスする。
```sh
watch curl dp.my.domain/httpbin/anything
```
アクセス後、Prometheusを見ると以下の様な感じで`exported_service`のタグに作成したサービス名が設定されたメトリクスが確認できる。
```json
kong_http_requests_total{code="200", container="proxy", endpoint="status", exported_service="httpbin-service", instance="192.168.28.183:8100", job="my-kong-kong-proxy", namespace="kong", pod="my-kong-kong-69474c4b-mhr6t", route="d3f0119f-bfe4-480d-a681-4a7d4592e214", service="my-kong-kong-proxy", source="service", workspace="default"}
```
ここでは割愛するが、Grafanaのダッシュボードからもメトリクスが確認できる。