Prometheus+Grafanaでk8s上のGoアプリケーションのメトリクスを回収して可視化
February 28, 2020
Prometheus+Grafana で、k8s 上で動かしている Go アプリケーションの Memory やゴルーチン起動数などのメトリクスを回収し可視化する
最終的なグラフ
構成図
この記事では、Prometheus, Grafana も k8s 内で動作させます。 メトリクスの回収としては、Go のアプリケーションに Prometheus Exporter を入れてメトリクスを公開し、Promehteus はサービスディスカバリを使って、そのメトリクスを回収という挙動になります。
構築
kubernetes クラスタを立ち上げる
今回は EKS を利用します。eksctl を使うと簡単に EKS クラスタを立ち上げれます。
eksctl create cluster --name sample-cluster \
--version 1.14 \
--nodegroup-name sample-cluster-worker \
--node-type t3.small \
--nodes 3 \
--nodes-min 1 \
--nodes-max 5 \
--managed
Go アプリケーションにメトリクス回収用の設定を入れる
ここでの説明で使うコードはこちらのリポジトリにおいてます
github.com/prometheus/client_golang
を利用してメトリクスを公開します
go get github.com/prometheus/client_golang
あとはコードに下記のようにメトリクス公開用のポートをあげれば、アプリ側の設定は ok です。
import (
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":2112", nil)
}
ちゃんと運用する場合は下記のように別スレッドで動かしてあげると良いでしょう
func main() {
// 設定とかで、メトリクス公開設定とか入れとく
if conf.COLLECT_METRICS {
http.Handle("/metrics", promhttp.Handler())
go http.ListenAndServe(":2112", nil)
}
// メインの処理
// ...
}
一度ローカルで動作確認しておきましょう, ちゃんと 2112 ポートでメトリクスを回収できるか確認します
$ go run main.go
$ curl localhost:2112/metrics
## HELP go_gc_duration_seconds A summary of the GC invocation durations.
## TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
...
取れていますね。あとはこれを kubernetes に deploy します。 マニフェストで 2112 ポートを開けておいてください
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-go-app
spec:
selector:
matchLabels:
app: prometheus-export-sample
replicas: 4
template:
metadata:
labels:
app: prometheus-export-sample
spec:
containers:
- name: prometheus-export-sample
image: esaka/prometheus-export-sample
ports:
- containerPort: 2112
Prometheus+Grafana をデプロイ
こちらのマニフェストをベースにして、いくつか設定を変えたものが以下になります。
https://github.com/esakat/prometheus-exporter-sample/blob/master/prometheus-grafana.yml
変更点
- Dashboard の import 設定削除
- Grafana や Prometheus の image を新しいものに変更
- Grafana のサービスを LoadBalnacer に変更
- prometheus.yml に Go のメトリクス回収設定を追加(後述)
Go のメトリクス回収用設定を追加する
prometheus.yml に以下のような, Go アプリケーション回収用の設定を追加します。
- job_name: 'go-metrics'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels:
- __meta_kubernetes_namespace
- __meta_kubernetes_pod_container_port_number
regex: default;2112
action: keep
- source_labels:
- __meta_kubernetes_pod_name
target_label: job
- source_labels:
- __meta_kubernetes_pod_name
target_label: pod
Grafana にログイン
以下のコマンドで作成された ELB のアドレスを確認してください 立ち上がるまでは少し時間かかります。
$ kubectl get svc -n monitoring grafana
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana LoadBalancer 10.100.191.149 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.ap-northeast-1.elb.amazonaws.com 3000:32017/TCP 7m46s
立ち上がったら、3000 ポート指定で Grafana へ繋がります。 http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.ap-northeast-1.elb.amazonaws.com:3000
ログインユーザーとパスワードはadmin:admin
です
Prometheus をデータソースとして設定
データソース設定追加で Prometheus を選択し
URL にhttp://prometheus:9090
を設定しSave & Test
でお k です。
Dashboard を作成
Grafana のサイトに行くと、色々ダッシュボードが転がっています。 特にこだわりなければ、この中から Go アプリケーション可視化用のダッシュボードを使うと楽でしょう
https://grafana.com/grafana/dashboards/6671
こちらのダッシュボードがおすすめです。 Download Json で json ファイルを落としておきます。
そしたらhttp://<host>:3000/dashboard/import
にアクセスしUpload .json file
ボタンを押して、先ほど落としたgo-processes_rev2.json
をアップロードします。
そしたら、prometheus-apl
でPrometheus
を選択してImport
をすれば、以下のようなダッシュボードが見れるようになります
先ほどデプロイした sample-go-app のメトリクスが取れています。
まとめ
Go アプリに Prometheus Exporter を仕込んで、Prometheus にメトリクスを回収させ Grafana で可視化させました