ICPでモニタリングデータをPVに保管する

IBM Cloud Privateのデフォルトのインストールでは、モニタリングデータは永続化されない。インストール後にPVに保管するように設定変更する方法のメモ。

|コンポーネント|バージョン|
|---|---|
|IBM Cloud Private|v2.1.0.3|

## インストール時のパラメータ

インストール時の`config.yaml`のパラメータでstorageClassを指定できる。ただし、NFSなど動的プロビジョニングできない場合は指定できないし、インストール後に設定変更したい場合もあるのでインストール後に変更する方法を調べる。

```yaml
monitoring:
 prometheus:
   scrapeInterval: 1m
   evaluationInterval: 1m
   retention: 24h
   persistentVolume:
     enabled: false
     storageClass: "-"
 alertmanager:
   persistentVolume:
     enabled: false
     storageClass: "-"
 grafana:
   user: "admin"
   password: "admin"
   persistentVolume:
     enabled: false
     storageClass: "-"
```

方法としては以下ができる。

- Prometheus/Alertmanager/Grafanaのdeploymentを直接編集する
- ibm-icploggingのhelmリリースのvaluesを変えてhelm upgradeする

ここでは前者の方法を書いているが、後者の方法がよいと思う。後者の方法は以下。

[ICPでモニタリングデータをPVに保管する（helm upgrade）](https://qiita.com/sotoiwa/items/684b6b85e0e4265eeebb)

## PV/PVCの作成

Prometheus/Alertmanager/Grafanaがデータを保管するためのPV/PVCを作成する。今回はhostPathを使用。

ディレクトリを作成する。Prometheus/Alertmanagerプロセスはrootだが、Grafanaプロセスは104:107というUID:GIDで動作するので合わせておく。

```shell
mkdir -p /export/prometheus
mkdir -p /export/alertmanager
mkdir -p /export/grafana
chown 104:107 /export/grafana
```

マニフェストファイルを作成する。

```yaml:prometheus-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: prometheus-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  hostPath:
    path: /export/prometheus
    type: ""
  storageClassName: prometheus
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prometheus-pvc
  namespace: kube-system
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: prometheus
```

```yaml:alertmanager-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: alertmanager-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  hostPath:
    path: /export/alertmanager
    type: ""
  storageClassName: alertmanager
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: alertmanager-pvc
  namespace: kube-system
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: alertmanager
```

```yaml:grafana-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: grafana-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  hostPath:
    path: /export/grafana
    type: ""
  storageClassName: grafana
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-pvc
  namespace: kube-system
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: grafana
```

PV/PVCを作成する。

```
kubectl apply -f prometheus-pv.yaml
kubectl apply -f alertmanager-pv.yaml
kubectl apply -f grafana-pv.yaml
```

作成されたPV/PVCを確認。

```shell-session
# kubectl get pvc -n kube-system
NAME                            STATUS    VOLUME                          CAPACITY   ACCESS MODES   STORAGECLASS               AGE
alertmanager-pvc                Bound     alertmanager-pv                 1Gi        RWO                                       24s
data-logging-elk-data-0         Bound     logging-datanode-172.30.1.224   20Gi       RWO            logging-storage-datanode   53m
grafana-pvc                     Bound     grafana-pv                      1Gi        RWO                                       56s
helm-repo-pvc                   Bound     helm-repo-pv                    5Gi        RWO            helm-repo-storage          54m
image-manager-image-manager-0   Bound     image-manager-172.30.1.224      20Gi       RWO            image-manager-storage      1h
mongodbdir-icp-mongodb-0        Bound     mongodb-172.30.1.224            20Gi       RWO            mongodb-storage            59m
prometheus-pvc                  Bound     prometheus-pv                   10Gi       RWO                                       1m
# kubectl get pv
NAME                            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                                       STORAGECLASS               REASON    AGE
alertmanager-pv                 1Gi        RWO            Retain           Bound     kube-system/alertmanager-pvc                                                     36s
grafana-pv                      1Gi        RWO            Retain           Bound     kube-system/grafana-pvc                                                          1m
helm-repo-pv                    5Gi        RWO            Delete           Bound     kube-system/helm-repo-pvc                   helm-repo-storage                    54m
image-manager-172.30.1.224      20Gi       RWO            Retain           Bound     kube-system/image-manager-image-manager-0   image-manager-storage                1h
logging-datanode-172.30.1.224   20Gi       RWO            Retain           Bound     kube-system/data-logging-elk-data-0         logging-storage-datanode             1h
mongodb-172.30.1.224            20Gi       RWO            Retain           Bound     kube-system/mongodbdir-icp-mongodb-0        mongodb-storage                      1h
prometheus-pv                   10Gi       RWO            Retain           Bound     kube-system/prometheus-pvc                                                       1m
#
```

## Prometheusの設定変更

Prometheusのストレージを`emptyDir`から作成したPVCに変更する。

```shell
kubectl edit deploy -n kube-system monitoring-prometheus
```

以下の部分を

```yaml
      - emptyDir: {}
        name: storage-volume
```

以下に変更する。

```yaml
      - persistentVolumeClaim:
          claimName: prometheus-pvc
        name: storage-volume
```

## Alertmanagerの設定変更

Alertmanagerのストレージを`emptyDir`から作成したPVCに変更する。

```
kubectl edit deploy -n kube-system monitoring-prometheus-alertmanager
```

以下の部分を

```yaml
      - emptyDir: {}
        name: storage-volume
```

以下に変更する。

```yaml
      - persistentVolumeClaim:
          claimName: alertmanager-pvc
        name: storage-volume
```

## Grafanaの設定変更

Grafanaのストレージを`emptyDir`から作成したPVCに変更する。名前に注意。

```shell
kubectl edit deploy -n kube-system monitoring-grafana
```

以下の部分を

```yaml
      - emptyDir: {}
        name: grafana-storage
```

以下に変更する。

```yaml
      - persistentVolumeClaim:
          claimName: grafana-pvc
        name: grafana-storage
```

## Grafanaのデータソース登録

Podが再作成されたことでGrafanaのデータソース設定が消えているので、登録し直す。

以下のJobを作成する。

```yaml:job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  labels:
    app: monitoring-grafana
    component: setds
  name: monitoring-grafana-ds
  namespace: kube-system
spec:
  activeDeadlineSeconds: 300
  template:
    metadata:
      labels:
        app: monitoring-grafana
        component: setds
    spec:
      tolerations:
      - key: "dedicated"
        operator: "Exists"
        effect: "NoSchedule"
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: beta.kubernetes.io/arch
                operator: In
                values:
                - amd64
                - ppc64le
              - key: management
                operator: In
                values:
                - "true"
      containers:
      - name: grafana-ds
        image: "ibmcom/curl:3.6"
        command: ["/opt/entry/entrypoint.sh"]
        volumeMounts:
          - mountPath: "/opt/ibm/monitoring/certs"
            name: monitoring-client-certs
          - mountPath: "/opt/ibm/monitoring/ca-certs"
            name: monitoring-ca-cert
          - mountPath: "/opt/entry"
            name: grafana-ds-entry
      volumes:
        - name: monitoring-client-certs
          secret:
            secretName: monitoring-monitoring-client-certs
        - name: monitoring-ca-cert
          secret:
            secretName: monitoring-monitoring-ca-cert
        - name: grafana-ds-entry
          configMap:
            name: monitoring-grafana-ds-entry-config
            defaultMode: 0744
      restartPolicy: OnFailure
```

完了済みのJobを削除し、作成したJobを実行する。

```shell
kubectl delete jobs -n kube-system monitoring-grafana-ds
kubectl apply -f job.yaml -n kube-system
```

## 参考リンク

- [モニタリング・サービスの構成](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_2.1.0.3/installing/monitoring.html)
- [IBM® Cloud Private モニター・サービス](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_2.1.0.3/featured_applications/deploy_monitoring.html)