Grafanaでサービスグラフを表示する
こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。
分散システムの運用の悩みどころは「どこで何が起きているのか把握しにくい」という方も多いと思います。
サービスグラフ(サービスマップ)は、分散システムの関係性を視覚化するための有効な手段です。
Grafana ファミリーを使ってサービスグラフを表示する方法を紹介します。
セットアップ
kubectl インストール
Kubernetes クラスターを操作するために kubectl をインストールします。
Install Tools に OS ごとのインストール方法が記載されています。それを参照してインストールしましょう。
minikube インストール
今回は minikube を使用します。
minikube はローカル環境で Kubernetes クラスターを起動できるツールです。
インストール手順は minikube start を参照ください。
$ brew install minikube
# help が表示されることを確認
$ minikube --help
minikube は、開発ワークフロー用に最適化されたローカル Kubernetes クラスターを構築・管理します。
〜〜省略〜〜
minikube を起動するのですが、デモの動作環境メモリが「6 GB of free RAM for the application」なので、minikube 起動時にメモリ容量を 6GB 以上に指定します。
$ minikube start --cpus='4' --memory='8G'
Helm インストール
Helm のインストール を参照してインストールしてください。
難しくないです。Mac なら brew でインストールできます。
$ brew install helm
OpenTelemetry Demo Helm Chart ダウンロード
今回は OpenTelemetry のデモを使用します。Helm Chart をダウンロードします。
$ helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
$ helm repo update
$ helm pull open-telemetry/opentelemetry-demo
$ tar -zxf opentelemetry-demo-0.30.2.tgz
TAR Ball を展開すると、opentelemetry-demo
というディレクトリが作成されます。
Tempo Helm Chart ダウンロード
サービスグラフを表示する方法はいくつかありますが、Grafana ファミリーの Tempo を使用します。
Tempo の Helm Chart をダウンロードします。
opentelemetry-demo/charts/
に展開します。ディレクトリに移動して helm pull、展開の順に実施します。
$ cd opentelemetry-demo/charts/
$ helm repo add grafana https://grafana.github.io/helm-charts
$ helm repo update
$ helm pull grafana/tempo-distributed
$ tar -xzf tempo-distributed-1.9.4.tgz
Chart.yamk に Tempo を追記
opentelemetry-demo/Chart.yaml
に以下を追記します。
apiVersion: v2
appVersion: 1.9.0
dependencies:
(省略)
# dependencies ブロックに以下の4行を追記
- condition: tempo.enabled
name: tempo-distributed
repository: https://grafana.github.io/helm-charts
version: 1.9.4
(省略)
values.schema.json に Tempo のスキーマを追記
opentelemetry-demo/values.schema.json
に以下を追記します。
(省略)
"opensearch": {
"type": "object"
}, # ← セミコロンを追加
# opensearch の下に以下3行を追記
"tempo-distributed": {
"type": "object"
}
(省略)
Tempo の設定
opentelemetry-demo/values.yaml
の末に Tempo を追記します。
ここで注目してほしいのは metricsGenerator です。
metricsGenerator は、トレースからメトリクスを生成します。
分散システムの関係性を示すためのサービスグラフを生成する service-graphs
、RED (Request, Error and Duration) を生成する span-metrics
、高度な計算のためスパンをローカルに保存する local-blocks
を有効にしています。
tempo-distributed:
enabled: true
traces:
otlp:
grpc:
enabled: true
compactor:
compaction:
block_retention: 8h # Optional. Duration to keep blocks. Default is 14 days (336h).
storage:
trace:
backend: local # ローカルで動かすのでストレージもローカルに設定
wal:
path: /var/tempo/wal
local:
path: /var/tempo/blocks
metricsGenerator:
enabled: true
persistence:
enabled: true
config:
storage:
remote_write: # スパンからメトリクスを生成して Prometheus に送信する設定
- url: http://my-otel-demo-prometheus-server:9090/api/v1/write
send_exemplars: true
global_overrides:
metrics_generator_processors: # metricsGenerator を有効にするための設定
- "service-graphs"
- "span-metrics"
- "local-blocks"
resources:
limits:
memory: 150Mi
OpenTelemetry Collector の設定
opentelemetry-demo/values.yaml
の opentelemetry-collector
ブロックに Tempo 向けの設定を追記します。
OpenTelemetry Demo では Jaeger にトレースを送信していますが、Tempo に送信するように変更します。
opentelemetry-collector:
(省略)
exporters:
(省略)
# exporter に以下のブロックを追記
otlp/tempo:
endpoint: '{{ include "otel-demo.name" . }}-tempo-distributor:4317'
tls:
insecure: true
(省略)
service:
pipelines:
traces:
processors: [memory_limiter, resource, batch]
exporters: [otlp/tempo, debug] # traces の exporters を otlp/tempo に向ける
(省略)
Prometheus の設定
opentelemetry-demo/values.yaml
の prometheus
ブロックに Remote Write Receiver 設定を追記します。
Tempo でトレースをメトリクスに変換します。そのメトリクスを Prometheus に送信するための設定です。
prometheus:
(省略)
server:
extraFlags:
- "enable-feature=exemplar-storage"
- "enable-feature=otlp-write-receiver"
- "web.enable-remote-write-receiver" # この行を追記、Tempo からのメトリクスを受け取るための設定
(省略)
Grafana の設定
opentelemetry-demo/values.yaml
の grafana
ブロックに Tempo の設定を追記します。
ここが本エントリの本題です。Grafana でサービスグラフを表示するための設定です。
grafana:
(省略)
- name: Tempo
type: tempo
uid: tempo
url: 'http://{{ include "otel-demo.name" . }}-tempo-query-frontend:3100'
access: proxy
editable: true
isDefault: false
jsonData:
httpMethod: GET
serviceMap:
datasourceUid: 'webstore-metrics'
(省略)
デモ起動
変更したらローカルに保存した chart を使ってデモを起動します。
$ helm install my-otel-demo ./opentelemetry-demo -n otel-demo --create-namespace
NAME: my-otel-demo
LAST DEPLOYED:
NAMESPACE: otel-demo
STATUS: deployed
REVISION: 1
NOTES:
=======================================================================================
██████╗ ████████╗███████╗██╗ ██████╗ ███████╗███╗ ███╗ ██████╗
██╔═══██╗╚══██╔══╝██╔════╝██║ ██╔══██╗██╔════╝████╗ ████║██╔═══██╗
██║ ██║ ██║ █████╗ ██║ ██║ ██║█████╗ ██╔████╔██║██║ ██║
██║ ██║ ██║ ██╔══╝ ██║ ██║ ██║██╔══╝ ██║╚██╔╝██║██║ ██║
╚██████╔╝ ██║ ███████╗███████╗ ██████╔╝███████╗██║ ╚═╝ ██║╚██████╔╝
╚═════╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝
- All services are available via the Frontend proxy: http://localhost:8080
by running these commands:
kubectl --namespace otel-demo port-forward svc/my-otel-demo-frontendproxy 8080:8080
The following services are available at these paths once the proxy is exposed:
Webstore http://localhost:8080/
Grafana http://localhost:8080/grafana/
Load Generator UI http://localhost:8080/loadgen/
Jaeger UI http://localhost:8080/jaeger/ui/
# 正常起動確認、数分かかります
$ kubectl get pod -n otel-demo
出力で示されている通り、別ターミナルを開いてコマンドを実行します。
http://localhost:8080/grafana/
で Grafana にアクセスできます。
$ kubectl --namespace otel-demo port-forward svc/my-otel-demo-frontendproxy 8080:8080
Grafana から Explore → Tempo → Service Graph を選択すると、RED (Request, Error and Duration) とサービスグラフが表示されます。
参考
Get started with Grafana Tempo using the Helm chart
Configure Tempo
Metrics-generator
Discussion