はじめに
PrometheusとGrafanaを理解したいのと、稼働している複数のマシンのメトリクス(CPU/メモリ/ストレージ利用率など)を収集したくて、KubernetesのHelmチャートを作って構築してみました。
初めてPrometheusとGrafanaを触った時はDockerやDocker Composeを使って中途半端な状態で終わっていました。今回KubernetesのHelm,Helmfile(本記事では出てきませんが)で改めて構築して一歩前進したので、やったことをまとめます。
環境情報
- Kubernetes
- v1.27.1 (サーバ&クライアント)
- Helm
- v3.9.2+g1addefb
ノードは以下のように5台で構築
$ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion,OS-IMAGE:.status.nodeInfo.osImage
NAME VERSION OS-IMAGE
control-plane v1.27.1 Debian GNU/Linux 10 (buster)
node01 v1.27.1 Ubuntu 20.04.6 LTS
node02 v1.27.1 Ubuntu 22.04.1 LTS
node03 v1.27.1 Ubuntu 20.04.6 LTS
node04 v1.27.1 Ubuntu 20.04.6 LTS
やりたいことと実現方針
PrometheusとGrafanaをKubernetesのリソースとしてデプロイし、各ノードのメトリクスを収集して可視化するのが目標です。
以下のようにPrometheusとGrafanaのHelmチャートが用意されているので、パラメータを適切に設定しhelm install
コマンドでインストールして実現します。
Prometheus
https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus
このHelmチャートのメインの機能はPrometheus Serverですが、次の4つの機能のHelmチャートも一緒に(依存関係的に)インストールされます。
- alertmanager
- kube-state-metrics
- prometheus-node-exporter
- prometheus-pushgateway
筆者の知識不足もあって4つ全てを説明できませんが、少なくともprometheus-node-exporterが各ノードのメトリクスを収集し、本記事の目標達成に貢献してくれます。
※詳細未確認ですが、kube-state-metricsでKubernetesのメトリクスも収集できそうです!
Grafana
Prometheus Serverと連携して、Node exporter等が提供したメトリクスをいい感じで可視化してくれます。可視化部分は自分でクエリやダッシュボードを作って実現もできますが、既に公開されているNode exporterのダッシュボードを使うのが速いので今回はそれを使う方針にします。
全体像の中での位置づけ
公式サイトに出ているアーキテクチャーの図で対応づけて考えると、今回は以下の機能を使うことになります。
- Job/exporters(左下)
- Node exporterを使って各ノードのメトリクスを収集
- Prometheus Server(真ん中)
- Node exporterにメトリクス等の情報の収集命令を出す
- 収集した情報をHTTPサービスとして提供する
- Grafana(右下)
- Prometheus Serverが提供した情報を取得して可視化する
PrometheusのHelmチャートのデプロイ
Helmリポジトリの追加
READMEに書かれた通りに、prometheus-communityのHelmリポジトリを追加します。
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
PersistentVolume関連のパラメータ設定
prometheus-serverとprometheus-node-exporterに関しては、PersistentVolumeを使う設定がデフォルトになっています。そこで例えば変数定義ファイルを以下のように作り、StorageClassをで指定する必要があります。
server:
persistentVolume:
storageClass: <prometheus-server用のSC名>
alertmanager:
persistence:
storageClass: <prometheus-node-exporter用のSC名>
StorageClassがない環境であれば、以下のようにPersistentVolumeを使わない設定にすればOKです。
ただし、この設定だとPodを消したら各サービスが収集したメトリクス等の情報も(おそらく)消えてしまうのでご注意ください!
server:
persistentVolume:
enabled: false
alertmanager:
persistence:
enabled: false
デプロイ
以下のコマンドを実行します。
helm install --create-namespace --namespace prometheus \
prometheus prometheus-community/prometheus \
-f values-prometheus-local.yaml \
--version 24.1.0
数分ほど待ち、Podがデプロイされていることを確認します。以下のようにNode exporterがDaemonSetリソースとして各ノードにデプロイされていることがわかります。
(筆者環境だとNode exporterがcontrol-planeにもデプロイされていますが、デフォルトだとWorkerノードにしか作られないはずです)
$ kubectl get pod -n prometheus -o custom-columns=NAME:.metadata.name,READY:.status.containerStatuses[0].ready,STATUS:.status.phase,NODE:.spec.nodeName
NAME READY STATUS NODE
prometheus-alertmanager-0 true Running node01
prometheus-kube-state-metrics-b4557d966-9f2r9 true Running node01
prometheus-prometheus-node-exporter-6tn6r true Running node04
prometheus-prometheus-node-exporter-dpp5w true Running control-plane
prometheus-prometheus-node-exporter-gwqg6 true Running node03
prometheus-prometheus-node-exporter-vfhlt true Running node01
prometheus-prometheus-node-exporter-xcvs9 true Running node02
prometheus-prometheus-pushgateway-79ff799669-mgzjc true Running node01
prometheus-server-7f8bb747c4-wwk5t true Running node02
また、Serviceリソースが以下のように作られています。次の手順でprometheus-server
のServiceをGrafanaと連携します。
$ kubectl get svc -n prometheus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-alertmanager ClusterIP 10.107.241.238 <none> 9093/TCP 6d14h
prometheus-alertmanager-headless ClusterIP None <none> 9093/TCP 6d14h
prometheus-kube-state-metrics ClusterIP 10.104.23.189 <none> 8080/TCP 6d14h
prometheus-prometheus-node-exporter ClusterIP 10.107.210.162 <none> 9100/TCP 6d14h
prometheus-prometheus-pushgateway ClusterIP 10.103.56.16 <none> 9091/TCP 6d14h
prometheus-server ClusterIP 10.101.118.171 <none> 80/TCP 6d14h
GrafanaのHelmチャートのデプロイ
Helmリポジトリの追加
READMEに書かれた通りに、grafanaのHelmリポジトリを追加します。
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
Datasource,Dashboardのパラメータ設定
Grafanaをデプロイした際に、既にデプロイしたPrometheus Serverが連携され、かつNode exporterで収集したメトリクスがダッシュボードで見えるようにしたいです。これらの設定はGrafanaをデプロイした後にWebUI上でも行うことができますが、この方法だとGrafanaを更新した際などに設定が消えてしまうのであまり賢明ではありません。
そこで、以下のような変数定義ファイルを用意して設定が常に保持されるようにします。
# クラスター外からアクセスできるようにする一つの手段
service:
type: NodePort
# (1) Prometheus Serverとの連携
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: "Prometheus"
type: prometheus
access: proxy
url: http://prometheus-server.prometheus.svc.cluster.local
# (2) Dashboardの基本設定
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/default
# (3) Node exporterのDashboardを追加する設定
dashboards:
default:
node-exporter:
datasource: Prometheus
url: https://grafana.com/api/dashboards/1860/revisions/32/download
以下簡単に解説します。
(1) Prometheus Serverとの連携
Prometheus ServerのServiceリソースprometheus-server
と連携するための設定です。Namespaceがprometheus
なので、http://prometheus-server.prometheus.svc.cluster.local
と指定すればクラスター内でアクセス可能です。
(2) Dashboardの基本設定
筆者があまり理解できていない部分ですが、こちらの内容をそのまま使わせてもらいました。
(3) Node exporterのDashboardを追加する設定
"Node Exporter Full" というダッシュボートが下記から提供されています。
このサイトの右下の「Download JSON」のURLをurl:
に記載して、デプロイ時にインポートするようにします。
デプロイ
以下のコマンドを実行します。
helm install --create-namespace --namespace grafana \
grafana grafana/grafana \
-f values-grafana-local.yaml \
--version 6.59.0
Grafanaが稼働しているのを確認します。
$ kubectl get pod -n grafana
NAME READY STATUS RESTARTS AGE
grafana-5c4798c889-fnwr8 1/1 Running 0 2m13s
grafana
のServiceリソースはNodePortとして動いているので、3xxxx系の任意のポート番号が割り振られます。
$ kubectl get svc -n grafana
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana NodePort 10.110.8.136 <none> 80:3xxxx/TCP 2m44s
WebブラウザでGrafanaに接続して確認
ログイン
Webブラウザで以下のURLにアクセスします。(3xxxxはgrafana
のServiceリソースに任意に割り当てられるポート番号です)
http://[ノードのIPアドレス]:3xxxx
ユーザ名とパスワードはgrafana
というSecretリソースに格納されており、以下のコマンドで確認できます。
$ kubectl get secret -n grafana grafana -o jsonpath="{.data.admin-user}" | base64 -d
(出力結果)
admin
$ kubectl get secret -n grafana grafana -o jsonpath="{.data.admin-password}" | base64 -d
(出力結果)
xxxx....
Data sourceの連携確認
左メニューの"Connections"を選択後、"Data sources"をクリックし、以下のようにPrometheusのdata sourceが表示されることを確認します。
ちゃんと接続できるかまで確認したいのであれば、Prometheusをクリック後、Settings画面で一番下まで遷移し、"Save & test"のボタンをクリックして以下のように"Successfully queried the Prometheus API."とメッセージが出ればOKです。
Dashboardのインポート確認
左メニューの"Dashboards"をクリックして、以下のようにGeneralフォルダに"Node Exporter Full"がインポートされていることを確認します。
"Node Exporter Full"をクリックして、以下のようなDashboardが表示されたら成功です!