Prometheus+Grafanaでk8s上のGoアプリケーションのメトリクスを回収して可視化

Prometheus+Grafanaでk8s上のGoアプリケーションのメトリクスを回収して可視化

February 28, 2020
Kubernetes, Middleware, Programming
kubernetes, golang, grafana, prometheus

Prometheus+Grafana で、k8s 上で動かしている Go アプリケーションの Memory やゴルーチン起動数などのメトリクスを回収し可視化する

最終的なグラフ

構成図

image.png

この記事では、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 です。

image.png

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-aplPrometheusを選択してImportをすれば、以下のようなダッシュボードが見れるようになります

image.png

先ほどデプロイした sample-go-app のメトリクスが取れています。

まとめ

Go アプリに Prometheus Exporter を仕込んで、Prometheus にメトリクスを回収させ Grafana で可視化させました