EKSで機械学習 #11 Prometheus/Grafanaの導入

# はじめに
このシリーズでは Amazon EKSで機械学習を行っていきたいと思います

# シリーズ目次
EKSで機械学習 #1 準備編
EKSで機械学習 #2 クラスター作成編
EKSで機械学習 #3 Managed Worker Node作成編
EKSで機械学習 #4 GPU Managed Worker Node作成編
EKSで機械学習 #5 Cluster AutoScaler設定編
EKSで機械学習 #6 HPAの設定
EKSで機械学習 #7 EFSの設定
EKSで機械学習 #8 Argo CDを利用したCD環境の構築
EKSで機械学習 #9 SageMaker Operaterの導入
EKSで機械学習 #10 Container Insightsの導入
EKSで機械学習 #11 Prometheus/Grafanaの導入（この記事）



# この記事の目的
前回はContainer Insightsを導入しましたが、今回はPrometheus/Grafanaを導入してみたいと思います。
本番環境では、どちらも導入することはあまりないと思うので、あくまで検証で両方入れてみたという位置づけです。


# 参考にしたドキュメント
https://eksworkshop.com/intermediate/240_monitoring/
こちらを参考にしました。リンク切れの場合は、
「eksworkshop prometheus」 で検索するとでてくるかと思います。

# helm のインストール
参考ドキュメントは helm を使って導入しているようなので、helmを入れます
https://eksworkshop.com/beginner/060_helm/helm_intro/install/


```sh
curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm version --short
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
helm search repo stable
helm repo update
```

# prometheusのインストール
## namespaceの作成

```namespace.yml
kind: Namespace
apiVersion: v1
metadata:
  name: prometheus
```

```sh
k apply -f namespace.yml 
namespace/prometheus created
```

## helm コマンドを使ってのprometheusのインストール

```sh
helm install prometheus stable/prometheus \
    --namespace prometheus \
    --set alertmanager.persistentVolume.storageClass="gp2" \
    --set server.persistentVolume.storageClass="gp2"

(output)
NAME: prometheus
LAST DEPLOYED: Sat Mar  7 14:49:44 2020
NAMESPACE: prometheus
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster:
prometheus-server.prometheus.svc.cluster.local


Get the Prometheus server URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace prometheus port-forward $POD_NAME 9090


The Prometheus alertmanager can be accessed via port 80 on the following DNS name from within your cluster:
prometheus-alertmanager.prometheus.svc.cluster.local


Get the Alertmanager URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus,component=alertmanager" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace prometheus port-forward $POD_NAME 9093
#################################################################################
######   WARNING: Pod Security Policy has been moved to a global property.  #####
######            use .Values.podSecurityPolicy.enabled with pod-based      #####
######            annotations                                               #####
######            (e.g. .Values.nodeExporter.podSecurityPolicy.annotations) #####
#################################################################################


The Prometheus PushGateway can be accessed via port 9091 on the following DNS name from within your cluster:
prometheus-pushgateway.prometheus.svc.cluster.local


Get the PushGateway URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus,component=pushgateway" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace prometheus port-forward $POD_NAME 9091

For more information on running Prometheus, visit:
https://prometheus.io/
```

## 確認

```sh
kubectl get all -n prometheus
NAME                                                 READY   STATUS    RESTARTS   AGE
pod/prometheus-alertmanager-86bfcc75db-bbmvl         2/2     Running   0          107s
pod/prometheus-kube-state-metrics-5ccb885bdc-gzcqn   1/1     Running   0          107s
pod/prometheus-node-exporter-dwv7c                   1/1     Running   0          107s
pod/prometheus-node-exporter-q9w4m                   1/1     Running   0          107s
pod/prometheus-pushgateway-7867ddb5cf-vjq5x          1/1     Running   0          107s
pod/prometheus-server-68677bcbd9-tn7nq               2/2     Running   0          107s

NAME                                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/prometheus-alertmanager         ClusterIP   10.100.46.107    <none>        80/TCP     107s
service/prometheus-kube-state-metrics   ClusterIP   10.100.193.251   <none>        8080/TCP   107s
service/prometheus-node-exporter        ClusterIP   None             <none>        9100/TCP   107s
service/prometheus-pushgateway          ClusterIP   10.100.111.192   <none>        9091/TCP   107s
service/prometheus-server               ClusterIP   10.100.61.62     <none>        80/TCP     107s

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/prometheus-node-exporter   2         2         2       2            2           <none>          107s

NAME                                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/prometheus-alertmanager         1/1     1            1           107s
deployment.apps/prometheus-kube-state-metrics   1/1     1            1           107s
deployment.apps/prometheus-pushgateway          1/1     1            1           107s
deployment.apps/prometheus-server               1/1     1            1           107s

NAME                                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/prometheus-alertmanager-86bfcc75db         1         1         1       107s
replicaset.apps/prometheus-kube-state-metrics-5ccb885bdc   1         1         1       107s
replicaset.apps/prometheus-pushgateway-7867ddb5cf          1         1         1       107s
replicaset.apps/prometheus-server-68677bcbd9               1         1         1       107s
```

Obbjectが正しく作成されていることが分かる

## UIを見てみる

```sh

kubectl port-forward -n prometheus deploy/prometheus-server 8080:9090
```

cloud9を想定しているので、参考ドキュメントの通り、previewを表示(/targets)すると
きちんと表示されていることが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/014b89ea-60ea-84b4-5290-b218db1a421d.png)

# Grafana のインストール
## grarana namespaceの作成

```namespace.yml
kind: Namespace
apiVersion: v1
metadata:
  name: grafana
```


```sh
k apply -f namespace.yml 
namespace/grafana created
```

## helm コマンドでインストールする

adminPassword は ```EKS!sAWSome``` だとみんな同じになってしまうので、任意なものにかえておきましょう

```sh
helm install grafana stable/grafana \
    --namespace grafana \
    --set persistence.storageClassName="gp2" \
    --set adminPassword='xxxxxx' \
    --set datasources."datasources\.yaml".apiVersion=1 \
    --set datasources."datasources\.yaml".datasources[0].name=Prometheus \
    --set datasources."datasources\.yaml".datasources[0].type=prometheus \
    --set datasources."datasources\.yaml".datasources[0].url=http://prometheus-server.prometheus.svc.cluster.local \
    --set datasources."datasources\.yaml".datasources[0].access=proxy \
    --set datasources."datasources\.yaml".datasources[0].isDefault=true \
    --set service.type=LoadBalancer

NAME: grafana
LAST DEPLOYED: Sat Mar  7 15:03:25 2020
NAMESPACE: grafana
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:

   kubectl get secret --namespace grafana grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

2. The Grafana server can be accessed via port 80 on the following DNS name from within your cluster:

   grafana.grafana.svc.cluster.local

   Get the Grafana URL to visit by running these commands in the same shell:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        You can watch the status of by running 'kubectl get svc --namespace grafana -w grafana'
     export SERVICE_IP=$(kubectl get svc --namespace grafana grafana -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
     http://$SERVICE_IP:80

3. Login with the password from step 1 and the username: admin
#################################################################################
######   WARNING: Persistence is disabled!!! You will lose your data when   #####
######            the Grafana pod is terminated.                            #####
#################################################################################
```

## 確認

```sh
kubectl get all -n grafana
NAME                           READY   STATUS    RESTARTS   AGE
pod/grafana-794598bb56-mslrg   1/1     Running   0          48s

NAME              TYPE           CLUSTER-IP      EXTERNAL-IP                                                              PORT(S)        AGE
service/grafana   LoadBalancer   10.100.79.227   xxxxxxxxxxxxx-365458450.us-west-2.elb.amazonaws.com   80:31243/TCP   48s

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/grafana   1/1     1            1           48s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/grafana-794598bb56   1         1         1       48s
```


## UIにアクセス

ELBの確認

```
k get svc -n grafana
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP                                                              PORT(S)        AGE
grafana   LoadBalancer   10.100.79.227   xxxxxx-365458450.us-west-2.elb.amazonaws.com   80:31243/TCP   16m
```

こちらででてきた、ELBのDNS名にブラウザからアクセスします。
userはadminで、passwordは自分で設定したものです。
こんな感じでアクセスできていることが分かります。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/5bc9dcb1-2cb8-1b46-2a2e-322a81062b04.png)



## テンプレ ダッシュボードの作成
https://eksworkshop.com/intermediate/240_monitoring/dashboards/
こちらを参考にすると簡単にできました。
同じイメージなので、スクショは省略しました。

# まとめ
ここでは　EKSWorkshopの手順にそって、EKS環境にPrometheus/Grafanaを導入しました。
あくまでも検証環境なので、Podが再作成されるとデータは消えます。
本番運用を見越した構成は近々考えたいと思います。