Prometheus + Grafana + Helm で Kubernetesクラスタのモニタリング環境を構築する
サービスが期待通りに動作することを保証するためにモニタリングは重要です。Kubernetes 上で動作するアプリケーションのモニタリングは、モニタリング用の OSS ( Prometheus など) 、SaaS ( Datadog など )、クラウドプラットフォームのコンソール ( GCP など) を使う方法があります。本記事ではモニタリング用の OSS である Prometheus と Grafana を使って Kubernetes クラスタとクラスタ上で動作するアプリケーションをモニタリングするダッシュボードを構築する方法を紹介します。
使用するツール
Prometheus
Prometheus はシステムやシステム上で動作するアプリケーションの監視ツールです。導入が簡単かつ、様々なツールと連携して監視用のメトリクスを収集可能な点が特徴です。CNCF の Graduated Project で、開発が盛んで広く使われています
Grafana
Grafana は時系列データの可視化ツールです。Prometheus,ElasticSearch, 各種DBなど様々なツールのデータの可視化や、データを元に通知を飛ばす事が可能です
Helm
Helm は Kubernetesのパッケージマネージャです。Kubernetes のリソースを一纏めにして1つのアプリケーションのように扱うことが可能です。helm/charts で公式で提供されているパッケージ(これをChart と呼びます)の一覧を見ることができます。
前準備
下記ツールをインストールしてください。
- minikube
- VirtualBox をインストール
- brew cask install minikube
- minikube start でローカルにクラスタを立ち上げる
- Helm
- brew install kubernetes-helm
Prometheus と Grafana をセットアップ
クラスタに Helm をインストール
helm init を実行しましょう。kubectlが参照しているクラスタにhelmの利用に必要なリソースがデプロイされます。
> kubectl get po,deploy,svc -n kube-system -l name=tiller
NAME READY STATUS RESTARTS AGE
pod/tiller-deploy-c48485567-jf82k 1/1 Running 0 25s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/tiller-deploy 1/1 1 1 25s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tiller-deploy ClusterIP 10.107.207.6 <none> 44134/TCP 25s
Prometheus をデプロイ
クラスタへ Helm で Prometheus をデプロイします。今回は stable/prometheusを使います。
Helm では values.yaml に chart のデフォルト設定パラメータを記述します。例えば、stable/prometheus の values.yaml はこのようになります。 helm inspect stable/prometheus で確認することもできます。デプロイ時に上書きしたいパラメータを yaml ファイルに記述して与えることができます。
クラスタやアプリケーションのメトリクスを正しく取得するため、下記のyamlファイルを deployments/helm/prometheus-customize-values.yaml に作成してください。
server:
ingress:
enabled: true
hosts:
- prometheus.minikube
persistentVolume:
size: 1Gi
storageClass: "standard"
retention: "12h"
nodeExporter: # Grafanaのダッシュボードにnode-exporterのバージョンをあわせる
image:
repository: prom/node-exporter
tag: v0.17.0
pullPolicy: IfNotPresent
pushgateway:
enabled: false
alertmanager:
ingress:
enabled: false
下記コマンドで stable/prometheus をデプロイします。 -f で先程作成した yaml ファイルを指定しています。
helm install --name prometheus -f deployments/helm/prometheus-customize-values.yaml stable/prometheus
Grafanaをデプロイ
次に Grafana をデプロイします。前節と同様に、下記の yaml ファイルを deployments/helm/granfana-customize-values.yaml に作成してください。
ingress:
enabled: true
hosts:
- grafana.minikube
persistence:
enabled: true
storageClassName: "standard"
accessModes:
- ReadWriteOnce
size: 1Gi
下記コマンドで stable/grafana をデプロイします。
helm install --name grafana -f deployments/helm/grafana-customize-values.yaml stable/grafana
これで Prometheus と Grafana がデプロイされました。
> kube get deploy,svc,ing
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/grafana 1/1 1 1 10m
deployment.extensions/prometheus-kube-state-metrics 1/1 1 1 10m
deployment.extensions/prometheus-server 1/1 1 1 10m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/grafana ClusterIP 10.103.119.133 <none> 80/TCP 10m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9h
service/prometheus-kube-state-metrics ClusterIP None <none> 80/TCP 10m
service/prometheus-node-exporter ClusterIP None <none> 9100/TCP 10m
service/prometheus-server ClusterIP 10.96.168.192 <none> 80/TCP 10m
NAME HOSTS ADDRESS PORTS AGE
ingress.extensions/grafana grafana.minikube 80 10m
ingress.extensions/prometheus-server prometheus.minikube 80 10m
ingressの有効化
minikubeではデフォルトでingressが無効になっているので、下記コマンドを実行し、ingressコントローラをデプロイします。これでingressからserviceへルーティングされるようになります。
minikube addons enable ingress
ドメインの割り当て
ingress で接続先サービスを見分けられるよう、Minikube の ip にドメインを割り当てます。
minikube ip で取得した ip を /etc/hosts ( MacOS の場合 ) に指定してください。
192.168.99.102 prometheus.minikube grafana.minikube app.minikube
これで http://prometheus.minikube で Prometheus へ、http://grafana.minikube で Grafana へアクセスできるようになりました。Grafana へのログインは、ID:admin, Passwordは下記コマンドで得られる文字列を与えることでログインできます( Grafana デプロイ時のログで説明されています )。
kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
ダッシュボードの作成
それではダッシュボードを作っていきましょう。まず Grafana にログインします。すると設定ページが開かれます。
まずデータソースを設定します。Add datasource をクリックし、下記のように入力し、Save & Test をクリックします。
Prometheus が正常にデプロイされており、ingressの設定がうまく行っていれば、 Data source is working が表示されます。
次にダッシュボードを作成します。左タブの + マークから Import を選びます。
ダッシュボードには、Grafana Labs のテンプレートを利用します。今回は Kubernetes Clusterダッシュボードを利用します。
ダッシュボードID の入力か JSON ファイルの入力を求められるので、Kubernetes Cluster ダッシュボードのID、7249を入力し、Loadをクリックします。すると下記のようにダッシュボードが表示されます。ダッシュボードではクラスタ全体のリソースの使用状況などが確認できます。
以上でクラスタのモニタリング環境が整いました。
サンプルアプリケーションのモニタリング環境の構築
次に Kubernetes 上で動作するアプリケーションのモニタリングの設定を行っていきます。
サンプルアプリケーションのデプロイ
サンプルアプリケーションをデプロイします。下記コマンドを実行してください。サンプルアプリケーションは soichisumi-sandbox/k8s-monitoring-sample を使用します。
> https://raw.githubusercontent.com/soichisumi-sandbox/k8s-monitoring-sample/master/deployments/deployment.yaml | kubectl apply -f -
> https://raw.githubusercontent.com/soichisumi-sandbox/k8s-monitoring-sample/master/deployments/service.yaml | kubectl apply -f -
> https://raw.githubusercontent.com/soichisumi-sandbox/k8s-monitoring-sample/master/deployments/ingress.yaml | kubectl apply -f -
curl app.minikube/app/ で動作確認ができます。
ダッシュボードの修正
minikube の addon でデプロイされる nginx-ingress コントローラはバージョンが新しいので、ダッシュボードのパネルのうちConnections と Request Time の値は表示されていないと思います。パネルの編集画面からクエリを下記のように編集してください。
Connections
nginx_ingress_controller_nginx_process_connections_total{state="active"}
Request Time
histogram_quantile(
0.99,
sum by (le)(
rate(
nginx_ingress_controller_request_duration_seconds_bucket{
service="k8s-monitoring-sample",
status="200"
}[1h]
)
)
)
以上で、下図のようにConnection と 99 パーセンタイルの Response Time が取得できるようになりました。
Response Time が NaN の場合は 1 時間以内にサンプルアプリケーションへのリクエストが 1 つもないので、curl app.minikube/app を数回実行して少し待ってみてください。
まとめ
本記事ではモニタリング用の OSS である Prometheus と Grafana を使って Kubernetes クラスタとクラスタ上で動作するアプリケーションをモニタリングするダッシュボードを構築する方法を紹介しました。Helm と Grafana Labs を使うことにより Prometheus と Grafana をデプロイし、基本的なリソースをモニタリングできるダッシュボードの構築を簡単に行うことができました。
クエリを編集したり、他のメトリクスを使ってダッシュボードを改良したい場合は、Prometheusクエリ道場 - Qiita が参考になります。もし興味があれば見てみてください。