Kubernetesを利用することのメリットの一つに、監視エージェントなどの導入が不要で、一度、ワーカーノードにモニタリングの機能をデプロイしておけば、名前空間を追加して、アプリケーションを載せても、アプリケーション毎に設定は不要という点がある。もちろん、必要なビューは設定する必要があるが、これまでの労力から比べれば簡単である。
ROOK Ceph のブロックストレージを検証したメモの記事で、ダイナミック・プロビジョニング可能な永続ストレージが利用できるようになったので、この基盤を利用して、メトリックス監視の時系列データベースのプロメテウス(Promethus)とブラウザ画面であるグラファナ(Grafana)、そして、ログ分析 エラスティックサーチ(Elastiecsearch) とブラウザ画面 キバナ (Kibana)を導入してみたい。そこで、今回はプロメテウスとグラファナについてとりあげる。
この記事は、ROOK Ceph のブロックストレージを検証したメモ でインストールすたROOK Cephの環境を利用して、プロメテウスとグラファナを導入するものである。
kube-state-metrics とは
kube-state-metricsは、Kubernetes APIサーバーから情報を取得して、APIオブジェクトの状態に関するメトリックを生成するサービスである。このサービスはKubernetesの デプロイメント、ノード、ポッドなど内部のさまざまなオブジェクトの健全性に焦点を当てたものである。
kube-state-metricsは、修正なしにKubernetes APIオブジェクトからメトリックを生成する。これにより、kube-state-metricsによって提供される機能の安定性がKubernetes APIオブジェクト自体と同じグレードになる。しかし、注意点として kubectlは 特定のヒューリスティックを適用して包括的なメッセージを表示する事から、kube-state-metrics と kubectlの表示は一致しないことがある。kube-state-metricsは、Kubernetes APIから加工されない生データを取得して公開する。これにより、ユーザーは必要なすべてのデータを取得し、必要に応じてヒューリスティックと呼ばれる手法によりデータを加工して表示する。
ヒューリスティクス(heuristic)または「発見的手法」とは、必ず正しい答えを導けるわけではないが、ある程度のレベルで正解に近い解を得ることができる。この手法は、答えの精度が保証されない代わりに、回答に至るまでの時間が少ないという特徴がある。
メトリックは、HTTPエンドポイント /metrics
で、デフォルト8080のリスニングポートで公開される。。それらは平文として提供される。 これらは、Prometheus本体 または Prometheusクライアントのスクレイパーによって、データ収集されるように設計されている。 /metrics
を ブラウザで開いて、未加工のメトリックを表示することもできる。
kube-state-metrics のインストール
インストールは、GitHubからコードを取得して、デプロイすることができる。
git clone https://github.com/kubernetes/kube-state-metrics
cd kube-state-metrics
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=USER-MAIL-ADDRESS
kubectl apply -f examples/standard/
マスターノードに入って、エントリーポイントをリストして、得られたIPアドレスとポート番号そして/metrics
でアクセスして、生データを取得することができる。
vagrant ssh master
kubectl get ep -n kube-system kube-state-metrics
NAME ENDPOINTS AGE
kube-state-metrics 10.244.2.12:8080,10.244.2.12:8081 4m21s
curl http://10.244.2.12:8080/metrics
# HELP kube_certificatesigningrequest_labels Kubernetes labels converted to Prometheus labels.
# TYPE kube_certificatesigningrequest_labels gauge
# HELP kube_certificatesigningrequest_created Unix creation timestamp
# TYPE kube_certificatesigningrequest_created gauge
# HELP kube_certificatesigningrequest_condition The number of each certificatesigningrequest condition
# TYPE kube_certificatesigningrequest_condition gauge
# HELP kube_certificatesigningrequest_cert_length Length of the issued cert
# TYPE kube_certificatesigningrequest_cert_length gauge
# HELP kube_configmap_info Information about configmap.
# TYPE kube_configmap_info gauge
kube_configmap_info{namespace="rook-ceph",configmap="rook-ceph-osd-node3-config"} 1
kube_configmap_info{namespace="kube-system",configmap="kube-proxy"} 1
kube_configmap_info{namespace="kube-public",configmap="cluster-info"} 1
kube_configmap_info{namespace="rook-ceph",configmap="local-device-node1"} 1
kube_configmap_info{namespace="rook-ceph",configmap="rook-config-override"} 1
kube-state-metrics と metrics-server の違い
メトリック・サーバーは、Heapsterに触発され、コアメトリクスパイプラインの目標を果たすためのKubernetes監視アーキテクチャを実装するものです。これは、すべてのKubernetesノードのkubeletが提供するメトリックを定期的にスクレイピングして公開するクラスタ・レベルのコンポーネントです。これにより集約されたメトリックは、メモリに保存され、メトリックAPI形式で公開される。そして、最新の値のみを保存し、サードパーティの宛先へのメトリックの転送は行わない。
一方、kube-state-metricsは、例えば、デプロイメント、レプリカセットなどに基づくメトリックなど、KubernetesのAPIオブジェクトの状態から、完全に新しいメトリックを生成することに焦点を当てている。Kubernetes状態のスナップショット全体をメモリに保持し、それに基づいて新しいメトリックを継続的に生成する。そして、メトリックサーバーと同様に自発的にメトリックスを転送する責任はない。メトリック情報を必要する者が取りに来るのを待っているサービスである。
Prometheusなどの監視システムから、kube-state-metrics や metrics-server が提供するメトリック情報にアクセスすることもできる。
参考URL: https://github.com/kubernetes/kube-state-metrics
Promethuse のインストール
ここでは Promethuseをインストールするために、HELM バージョン3 を使用した。kubectl で K8sクラスタへアクセスできる状態にしておき、helm3のクライアントを使って、インストールを実施する。
最初に、Helmチャートのリポジトリを追加する。
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
確認として prometheusのチャートをサーチしてみる。
helm search repo prometheus
NAME CHART VERSION APP VERSION DESCRIPTION
stable/prometheus 10.3.1 2.15.2 Prometheus is a monitoring system and time seri...
stable/prometheus-adapter 2.0.1 v0.5.0 A Helm chart for k8s prometheus adapter
stable/prometheus-blackbox-exporter 3.0.0 0.15.1 Prometheus Blackbox Exporter
stable/prometheus-cloudwatch-exporter 0.6.0 0.6.0 A Helm chart for prometheus cloudwatch-exporter
stable/prometheus-consul-exporter 0.1.4 0.4.0 A Helm chart for the Prometheus Consul Exporter
stable/prometheus-couchdb-exporter 0.1.1 1.0 A Helm chart to export the metrics from couchdb...
stable/prometheus-mongodb-exporter 2.4.0 v0.10.0 A Prometheus exporter for MongoDB metrics
stable/prometheus-mysql-exporter 0.5.2 v0.11.0 A Helm chart for prometheus mysql exporter with...
stable/prometheus-nats-exporter 2.3.0 0.6.0 A Helm chart for prometheus-nats-exporter
stable/prometheus-node-exporter 1.8.1 0.18.1 A Helm chart for prometheus node-exporter
stable/prometheus-operator 8.5.14 0.34.0 Provides easy monitoring definitions for Kubern...
stable/prometheus-postgres-exporter 1.2.0 0.8.0 A Helm chart for prometheus postgres-exporter
stable/prometheus-pushgateway 1.2.13 1.0.1 A Helm chart for prometheus pushgateway
stable/prometheus-rabbitmq-exporter 0.5.5 v0.29.0 Rabbitmq metrics exporter for prometheus
stable/prometheus-redis-exporter 3.2.1 1.0.4 Prometheus exporter for Redis metrics
stable/prometheus-snmp-exporter 0.0.4 0.14.0 Prometheus SNMP Exporter
stable/prometheus-to-sd 0.3.0 0.5.2 Scrape metrics stored in prometheus format and ...
stable/elasticsearch-exporter 2.2.0 1.1.0 Elasticsearch stats exporter for Prometheus
stable/helm-exporter 0.3.2 0.4.0 Exports helm release stats to prometheus
stable/karma 1.4.0 v0.50 A Helm chart for Karma - an UI for Prometheus A...
stable/stackdriver-exporter 1.2.2 0.6.0 Stackdriver exporter for Prometheus
stable/weave-cloud 0.3.7 1.4.0 Weave Cloud is a add-on to Kubernetes which pro...
stable/kube-state-metrics 2.6.3 1.9.3 Install kube-state-metrics to generate and expo...
stable/kuberhealthy 1.2.6 v1.0.2 The official Helm chart for Kuberhealthy.
stable/mariadb 7.3.6 10.3.21 Fast, reliable, scalable, and easy to use open-...
次に prometheus用の名前空間(namespae)を作成する
kubectl create namespace prometheus
Helmチャートからパラメータを取得して編集するために、ディレクトリを作成して移動する。
mkdir prometheus
cd prometheus/
パラメータをファイルに取り出し編集する。
helm inspect values stable/prometheus > prometheus-values.yaml
編集内容は、ストレージクラスに、ROOK Cephを設定 storageClass: "rook-ceph-block"
と pushgateway
を無効にする。
パラメーターのYAMLの編集が終わったら、プロメテウスをデプロイする。
helm install prometheus --namespace prometheus -f prometheus-values.yaml stable/prometheus
以下は実行例で、プロメテウスのUIにアクセスする為の情報が表示される。
tkr@luigi:~/sandbox-rook/prometheus$ helm install prometheus --namespace prometheus -f prometheus-values.yaml stable/prometheus
NAME: prometheus
LAST DEPLOYED: Sat Jan 25 13:23:37 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) #####
#################################################################################
For more information on running Prometheus, visit:
https://prometheus.io/
起動完了の確認
ポッドの起動状態を確認する。以下のポッドが Running の状態になっていれば成功とみなして良い。
kubectl get po -n prometheus
NAME READY STATUS RESTARTS AGE
prometheus-alertmanager-84bbc87464-vpcs7 2/2 Running 0 3m27s
prometheus-kube-state-metrics-59bb448977-h5tz4 1/1 Running 0 3m27s
prometheus-node-exporter-7s8qk 1/1 Running 0 3m27s
prometheus-node-exporter-npnjr 1/1 Running 0 3m27s
prometheus-node-exporter-qwmpr 1/1 Running 0 3m27s
prometheus-server-c9977fd86-z7dk7 2/2 Running 0 3m27s
次にサービスをリストしておく。
kubectl get svc -n prometheus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-alertmanager ClusterIP 10.32.0.181 <none> 80/TCP 3m33s
prometheus-kube-state-metrics ClusterIP None <none> 80/TCP,81/TCP 3m33s
prometheus-node-exporter ClusterIP None <none> 9100/TCP 3m33s
prometheus-server ClusterIP 10.32.0.163 <none> 80/TCP 3m33s
公開先の追加
上記のClusterIPでは、外部のブラウザでアクセスできないので、サービスのタイプをNodePortに変更して、マスターノード経由でアクセスできるようにする。
変更するのは、prometheus-alertmanager と prometheus-server である。
kubectl edit svc -n prometheus prometheus-alertmanager
変更箇所は、32行目で type: NodePort
へ変更する。
20 spec:
21 clusterIP: 10.32.0.11
22 ports:
23 - name: http
24 port: 80
25 protocol: TCP
26 targetPort: 9093
27 selector:
28 app: prometheus
29 component: alertmanager
30 release: prometheus
31 sessionAffinity: None
32 type: NodePort
変更が有効になったこと、および、アサインされたポート番号を確認する。
kubectl get svc -n prometheus prometheus-alertmanager
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-alertmanager NodePort 10.32.0.181 <none> 80:30218/TCP 6m12s
もう一つ、下記も同様に変更する。
kubectl edit svc -n prometheus prometheus-server
変更が有効になったこと、および、アサインされたポート番号を確認する。
kubectl get svc -n prometheus prometheus-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-server NodePort 10.32.0.163 <none> 80:31255/TCP 6m58s
これで、プロメテウスの設定は完了である。
グラファナ(Grafana)のインストール
次に表示のアプリケーション グラファナも、Helmからインストールする。
helm search repo grafana
NAME CHART VERSION APP VERSION DESCRIPTION
stable/grafana 4.4.0 6.5.2 The leading tool for querying and visualizing t...
helm inspect values stable/grafana > grafana-values.yaml
修正箇所はストレージクラスで次のように storageClassName: rook-ceph-block
修正する。
デプロイ後に表示されるパスワードの取得方法をロスすると、グラファナにログインできなくなるので、注意が必要だ。
helm install grafana --namespace prometheus -f grafana-values.yaml stable/grafana
NAME: grafana
LAST DEPLOYED: Sat Jan 25 13:37:11 2020
NAMESPACE: prometheus
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:
kubectl get secret --namespace prometheus 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.prometheus.svc.cluster.local
Get the Grafana URL to visit by running these commands in the same shell:
export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=grafana,release=grafana" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace prometheus port-forward $POD_NAME 3000
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. #####
#################################################################################
これで二つの Helm インスタンスが実行されていることになる。
helm list --namespace prometheus
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
grafana prometheus 1 2020-01-25 13:37:11.709451488 +0900 JST deployed grafana-4.4.0 6.5.2
prometheus prometheus 1 2020-01-25 13:23:37.957212894 +0900 JST deployed prometheus-10.3.1 2.15.2
グラファナも前述同様に、サービスタイプを編集する。
kubectl get svc -n prometheus grafana
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana ClusterIP 10.32.0.110 <none> 80:31300/TCP 2m52s
変更箇所は、26行と31行である。
19 spec:
20 clusterIP: 10.32.0.110
21 ports:
22 - name: service
23 port: 80
24 protocol: TCP
25 targetPort: 3000
26 nodePort: 31300 <--- 追加
27 selector:
28 app: grafana
29 release: grafana
30 sessionAffinity: None
31 type: NodePort <--- 変更
これで、ノードのポート番号 31300 でアクセスできるようになった。
kubectl get svc -n prometheus grafana
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana NodePort 10.32.0.110 <none> 80:31300/TCP 2m52s
ログインする為のパスワードは、次のコマンドで取得できる。
kubectl get secret --namespace prometheus grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
マスターノードのVMホストのIPアドレス 192.168.1.91 に NodePortを開いているので、http://192.168.1.91:31300/ でグラファナのログイン画面が表示される。
ユーザー admin と上記で得られたパスワードでログインすることができる。
次の初期画面で、Add data sourcesをクリックして、プロメテウスを選択する。
HTTP URLに、プロメテウスのサービスのDNS名をセットする。これは Helmでインストールした時の応答メッセージに表示されたURLである。
テスト結果でグリーンの表示があれば成功なので次へすすむ。画面上左端のグラファナアイコンの右隣のHOMEのアイコンをクリックすると次の画面が表示される。
画面の右下のFind dashboard on Grafana.com をクリックするとダッシュボードのカタログが表示される。そして、Import dashboard でカタログのID番号をインプットして、データソースを選択すると、設定なしで既成のダッシュボードを利用できる。
筆者がお勧めのダッシュボードのIDと名前を以下に挙げておく。ImportからIDを入れるだけでダッシュボード画面が表示されるので大変便利である。
- 11074 1 Node Exporter for Prometheus Dashboard English Version UPDATE 1102
- 10000 Cluster Monitoring for Kubernetes
- 8685 K8s Cluster Summary
- 1860 Node Exporter Full
- 7249 Kubernetes Cluster
次の画面が、ID番号 11074 のダッシュボードである。
ダッシュボードを作成したり、閾値を設定して、通知するなど多彩な機能があるので、再度、とりあげたい。
まとめ
オンプレミスの環境でも、K8sクラスタ+ROOKがあれば、大抵の永続ストレージの問題は解決され、快適な実行環境になるということだ。これによって、手軽にプロメテウスやグラファナなど監視ツールもデプロイできるようになる。アプリケーションが監視システムと同じクラスタ上に乗ることは、抵抗感もあるが、名前空間を分けてリソースの割り当てを厳格にする。または、付帯機能とアプリケーションの配置するノードを分けるなど、適切な措置を取れば、問題もないと推定される。