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

[IBM Cloud PrivateでモニタリングデータをPVに保管する](https://qiita.com/sotoiwa/items/6e66494add8e65e10a08)

ICPでモニタリングデータを永続化する方法を書いたが、deploymentを直接編集するよりもhelm upgradeする方がよさそうだったのでその方法のメモ。

## helm upgrade

現在のリリースのチャートバージョンを確認。

```
helm ls --tls monitoring
```

現在のリリースのvaluesをファイルに保存する。

```
helm get values monitoring --tls > values.yaml
```

`helm get values`に`-a`オプションをつけると、明示的に設定されていないデフォルト値も確認できるので、そちらも参考にして`values.yaml`を修正する。

```yaml:values.yaml
alertmanager:
  image:
    repository: ibmcom/alertmanager
  service:
    type: ClusterIP
  persistentVolume:            # 追加
    enabled: true              # 追加
    size: 1Gi                  # 追加
    storageClass: alertmanager # 追加
certGen:
  image:
    repository: ibmcom/icp-cert-gen
collectdExporter:
  image:
    repository: ibmcom/collectd-exporter
configmapReload:
  image:
    repository: ibmcom/configmap-reload
curl:
  image:
    repository: ibmcom/curl
elasticsearchExporter:
  image:
    repository: ibmcom/elasticsearch-exporter
grafana:
  image:
    repository: ibmcom/grafana
  service:
    type: ClusterIP
  persistentVolume:       # 追加
    enabled: true         # 追加
    size: 1Gi             # 追加
    storageClass: grafana # 追加
kubeStateMetrics:
  image:
    repository: ibmcom/kube-state-metrics
mode: managed
nodeExporter:
  image:
    repository: ibmcom/node-exporter
prometheus:
  etcdTarget:
    enabled: true
    etcdAddress:
    - 172.30.1.224
    etcdPort: "4001"
  image:
    repository: ibmcom/prometheus
  service:
    type: ClusterIP
  persistentVolume:          # 追加
    enabled: true            # 追加
    size: 10Gi               # 追加
    storageClass: prometheus # 追加
router:
  image:
    repository: ibmcom/icp-router
  subjectAlt: 18.179.83.130

```

現在のリリースと同じバージョンチャートを用意する。インターネットにつながらない場合は以下からファイルをダウンロードしてきてチャートのファイルを配置する。

https://github.com/IBM/charts/tree/master/repo/stable

インターネットにつながる場合はibm-chartsのレポジトリを登録する。

```
$ helm repo list
NAME  	URL
stable	https://kubernetes-charts.storage.googleapis.com
local 	http://127.0.0.1:8879/charts
$ helm repo add ibm-charts https://raw.githubusercontent.com/IBM/charts/master/repo/stable/
"ibm-charts" has been added to your repositories
$ helm repo list
NAME      	URL
stable    	https://kubernetes-charts.storage.googleapis.com
local     	http://127.0.0.1:8879/charts
ibm-charts	https://raw.githubusercontent.com/IBM/charts/master/repo/stable/
$
```

現在のチャートと同じバージョンを指定して`helm upgrade`を実行する。

```
helm upgrade monitoring ibm-charts/ibm-icpmonitoring --version 1.1.1 -f values.yaml --tls
```

## PVの作成

PendingとなっているPersitentVolumeClaimを確認する。

```
# kubectl get pvc -l release=monitoring-n kube-system
NAME                                 STATUS    VOLUME                          CAPACITY   ACCESS MODES   STORAGECLASS               AGE
monitoring-grafana                   Pending                                                             grafana                    4m
monitoring-prometheus                Pending                                                             prometheus                 4m
monitoring-prometheus-alertmanager   Pending                                                             alertmanager               4m
#
```

今回はPVとしてhostPathを使うため、ディレクトリを作成する。

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

PVCに合うようにマニフェストファイルを作成する。チャートのバージョンによってアクセスモードが違うかもしれないので注意。

```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
```

```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
```

```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
```

PVを作成する。

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

PendingであったPVCがBoundとなったことを確認する。

```
# kubectl get pvc -n kube-system -l release=monitoring
NAME                                 STATUS    VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
monitoring-grafana                   Bound     grafana-pv        1Gi        RWO            grafana        2m
monitoring-prometheus                Bound     prometheus-pv     100Gi      RWO            prometheus     2m
monitoring-prometheus-alertmanager   Bound     alertmanager-pv   1Gi        RWO            alertmanager   2m
#
```

monitringのPodがRunningとなったことを確認する。

```
# kubectl get po -l release=monitoring -n kube-system
NAME                                                          READY     STATUS    RESTARTS   AGE
monitoring-exporter-6b88bcd65b-d54lh                          1/1       Running   10         14d
monitoring-grafana-688d67b6b-w4zg5                            2/2       Running   0          18m
monitoring-prometheus-alertmanager-7468b8ccb8-pd5jd           3/3       Running   0          18m
monitoring-prometheus-b5d998dd8-r5h2l                         3/3       Running   0          18m
monitoring-prometheus-elasticsearchexporter-bc66cf47d-zfzqg   1/1       Running   10         14d
monitoring-prometheus-kubestatemetrics-855bcd8dcb-5vwkz       1/1       Running   10         14d
monitoring-prometheus-nodeexporter-k2cj9                      1/1       Running   10         14d
#
```

## 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を実行する。

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