Solr Operator on GKE + Google Cloud Managed Service for Prometheus

GKEで[Solr Operator](https://solr.apache.org/operator/)を使用してSolrCloudを構築した際にSolr Prometheus Exporterによるメトリクスを可視化する際に自前のPrometheus+grafanaではなく、GCPのマネージドサービスである[Goole Cloud Managed Service for Prometheus(以下、GMP)](https://cloud.google.com/managed-prometheus?hl=ja)を使用してCloud Monitoring上で可視化してみましたのでその手順を記載します。



# Solr Operatorについて
Kubernetes上でSolrCloudを簡単に構築出来るコントールプレーンマネージャーです。
Solr Prometheus ExporterやSolr Backupなどにも対応しています。


従来の手順でSolrCloudを構築してサービス運用する場合は、構築や運用コストの高さに悩まされているところも多いのではないでしょうか。
Solr Operatorを利用すればSolrCloudを従来より簡単に構築することが可能です。

SolrOperatorに関する日本語情報は非常に少ないですが、GoogleのShimojo様が書かれた記事が非常に分かりやすく参考になります。
[Solr Operator を利用して SolrCloud クラスタを GKE Autopilot に構築する (前編)](https://zenn.dev/google_cloud_jp/articles/b9fb077a385906)
[Solr Operator を利用して SolrCloud クラスタを GKE Autopilot に構築する (後編)](https://zenn.dev/google_cloud_jp/articles/f6861e2671fff8)


2023年5月時点では[v0.7](https://github.com/apache/solr-operator/releases/tag/v0.7.0)がリリースされており、v0.8ではスケール周りの機能追加が予定されているようです。

# Google Cloud Managed Service for Prometheus
GCPで提供されているPrometheusのマネージドサービスです。
これを利用することでGKEなどで動いているアプリケーションなどのメトリクスを収集し、Cloud Monitoringで可視化することが出来ます。

SolrOperatorの公式ドキュメントでは自前でGKEクラスタ上にPrometheus+Grafanaのpodを稼働することでSolr Prometheus Exporterのメトリクスを可視化する方法を紹介しています。
もちろんこの方法でも問題ありませんが、GCPでサービス運用している場合は監視などにCloud Monitoringを利用することも多いと思います。それであればSolrのメトリクスのみ単独で管理するのではなく、寄せて一元管理してしまう方法も選択肢の一つになります。


# 構築手順
Solrのクラスタ構築手順は割愛します。
GKE Autopilot上でSolrCloudのpodが稼働している状態を前提とします。
ただし、前提条件としてGKEで以下のように「Managed Service for Prometheus」が「有効」になっている必要があります。
![gke-console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703844/e3f7a2f9-1cdd-cc78-5848-98a54e4b5775.png)
GKEバージョン1.25以降のAutopilotクラスタであればデフォルトで「有効」になっています。
有効になっていない場合は[マネージド コレクションを有効にする: GKE](https://cloud.google.com/stackdriver/docs/managed-prometheus/setup-managed?hl=ja#enable-mgdcoll-gke)を確認して設定変更を試してみてください。

構築後のpodの状態は以下となります。
```bash
$ kubectl -n solr get pods
NAME                                                READY   STATUS    RESTARTS   AGE
example-solrcloud-0                                 1/1     Running   0          23h
example-solrcloud-1                                 1/1     Running   0          23h
example-solrcloud-2                                 1/1     Running   0          23h
example-solrcloud-zookeeper-0                       1/1     Running   0          23h
example-solrcloud-zookeeper-1                       1/1     Running   0          23h
example-solrcloud-zookeeper-2                       1/1     Running   0          23h
solr-operator-dd5bdfbcc-pcchx                       1/1     Running   0          23h
solr-operator-zookeeper-operator-685cc96dff-cfpk4   1/1     Running   0          23h
```


## Solr Prometheus Exporterの設定
[Deploy Prometheus Exporter for Solr Metrics](https://apache.github.io/solr-operator/docs/solr-prometheus-exporter/#deploy-prometheus-exporter-for-solr-metrics)を参考に以下のyamlを用意します。
```yaml
apiVersion: solr.apache.org/v1beta1
kind: SolrPrometheusExporter
metadata:
  name: dev-prom-exporter
spec:
  customKubeOptions:
    podOptions:
      resources:
        requests:
          cpu: 300m
          memory: 900Mi
  solrReference:
    cloud:
      name: "example"
  numThreads: 6
```
`name`に設定する値はSolr Operatorで構築した際の名前になりますが、以下で確認出来ます。
```bash
$ kubectl -n solr get solrcloud
NAME      VERSION   TARGETVERSION   DESIREDNODES   NODES   READYNODES   UPTODATENODES   AGE
example   9.1                       3              3       3            3               23h
```

yamlを適用します。
```bash
$ kubectl -n solr apply -f SolrPrometheusExporter.yaml
solrprometheusexporter.solr.apache.org/dev-prom-exporter created
```

以下のようにpod,svcなどが構築されます。
```bash
$ kubectl -n solr get all -l solr-prometheus-exporter=dev-prom-exporter
NAME                                                  READY   STATUS    RESTARTS   AGE
pod/dev-prom-exporter-solr-metrics-5ffcbc54b8-px2k5   1/1     Running   0          2m45s

NAME                                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/dev-prom-exporter-solr-metrics   ClusterIP   10.8.128.212   <none>        80/TCP    2m45s

NAME                                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/dev-prom-exporter-solr-metrics   1/1     1            1           2m46s

NAME                                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/dev-prom-exporter-solr-metrics-5ffcbc54b8   1         1         1       2m46s
```

ログの確認
```bash
$ kubectl -n solr logs -l solr-prometheus-exporter=dev-prom-exporter
INFO  - 2023-05-22 15:01:40.323; org.apache.solr.prometheus.exporter.SolrExporter; Solr Prometheus Exporter is running. Collecting metrics for cluster d3b1c6d0a3: Solr Cloud ZK: example-solrcloud-zookeeper-0.example-solrcloud-zookeeper-headless.solr.svc.cluster.local:2181,example-solrcloud-zookeeper-1.example-solrcloud-zookeeper-headless.solr.svc.cluster.local:2181,example-solrcloud-zookeeper-2.example-solrcloud-zookeeper-headless.solr.svc.cluster.local:2181/
INFO  - 2023-05-22 15:01:41.764; org.apache.solr.prometheus.collector.SchedulerMetricsCollector; Completed metrics collection
INFO  - 2023-05-22 15:02:41.806; org.apache.solr.prometheus.collector.SchedulerMetricsCollector; Beginning metrics collection
INFO  - 2023-05-22 15:02:41.923; org.apache.solr.prometheus.collector.SchedulerMetricsCollector; Completed metrics collection
```

ローカル環境から`kubectl port-foward`コマンドを使用することで実際にメトリクスの結果を確認することが出来ます。
```bash
$ kubectl -n solr port-forward $(kubectl get pod -l solr-prometheus-exporter=dev-prom-exporter --no-headers -o custom-columns=":metadata.name") 8080

$ curl http://localhost:8080/metrics
```


## PodMonitoringの設定
[PodMonitoring リソースを構成する](https://cloud.google.com/stackdriver/docs/managed-prometheus/setup-managed?hl=ja#gmp-pod-monitoring)を参考に以下のyamlを用意します。
```yaml
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  name: prom-example
spec:
  selector:
    matchLabels:
      solr-prometheus-exporter: dev-prom-exporter
  endpoints:
  - port: solr-metrics
    interval: 30s
```

`port`に設定する名称ですが、以下のコマンドで確認出来ます。
```bash
kubectl -n solr get svc dev-prom-exporter-solr-metrics --output jsonpath="{@.spec.ports}"
[{"appProtocol":"http","name":"solr-metrics","port":80,"protocol":"TCP","targetPort":8080}]
```

適用します。
```bash
kubectl -n solr apply -f PodMonitoring.yaml
podmonitoring.monitoring.googleapis.com/prom-example created
```

GKE側の設定はこれで完了です。


## Cloud Monitoring
Metrics Explorerで指標に「solr」を入力して`Prometheus Target`->`Solr`が出てくればOKです。
SolrCloudにコレクションを作成していない状態だと有効な指標は5つほどしか表示されませんが
コレクションを作成すれば更に有効な指標は増えます。

![Monitoring.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703844/f6819152-2fea-d28e-f97c-2124169ba150.png)

`solr_collections_live_nodes/gauge`を選択してみるとグラフが表示されます。
SolrOperatorで作成したPod数と同じ値になっています。
![Monitoring2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703844/ef55ca41-e7e6-a065-021b-f072a8ddb792.png)

Solrに関連するメトリクスを専用のダッシュボードを作成してまとめる、アラートを作成するなどをしていけば良いかと思います。




# 参考
[Solr Operator Documentation](https://apache.github.io/solr-operator/)
[Prometheus 向けのマネージド サービス](https://cloud.google.com/managed-prometheus?hl=ja)