TidbMonitor 廃止 + Grafana 一本化 + ダッシュボード IaC 化
2026-06-25_construction_plan.md の Phase 4 (TidbMonitor) と Phase 4.5 (kube-prometheus-stack) を整理し、Grafana / Prometheus を kube-prometheus-stack 一本 に統合する移行メモ。検証が落ち着いたら本編 (2026-06-25_construction_plan.md) に統合して、最初から廃止構成で組めるようにする。
動機
Phase 4 + Phase 4.5 を素直に積むと、クラスタには Grafana が 2 つ、Prometheus も 2 つ 動くことになる(tidb-grafana と node-grafana)。
観点 |
現状の痛み |
|---|---|
動線 |
TiDB 系メトリクスとホスト系メトリクスで Grafana を切り替えないといけない |
ダッシュボード品質 |
TidbMonitor 配布の公式ダッシュボードは Angular plugin 依存パネルがあり、Grafana 11 系で一部描画されない |
カスタマイズ |
TidbMonitor は CR 経由のため Grafana 設定 / ダッシュボードを Git で素直に管理しにくい |
リソース |
Prometheus 2 重 scrape + 2 重 TSDB で MiniPC のメモリを無駄に喰う |
統合監視 |
ホスト + TiDB + 自作アプリ + ネットワーク機器をまとめて見たい時、kube-prom-stack 側に寄せた方が伸びる |
TiDB 各コンポーネントは /metrics を素直に公開しているので、TidbMonitor を経由しなくても kube-prom-stack の PodMonitor で直接 scrape すれば足りる。
廃止方針
B 案: Prometheus も Grafana も kube-prom-stack に一本化、TidbMonitor は完全廃止。
要素 |
移行後 |
|---|---|
TiDB メトリクス収集 |
kube-prom-stack の Prometheus が PodMonitor で直接 scrape |
Recording / Alert rule |
TidbMonitor 同梱のものから必要分を |
ダッシュボード |
自作 JSON を |
履歴メトリクス |
捨てる |
NgMonitoring (Top SQL / Continuous Profiling) |
単体 Deployment 化で復活 → |
Reloader |
kube-prom-stack Operator が同等の CR 監視 / 再読込を担う |
TiDB Dashboard (PD 組み込み) |
影響なし。引き続き |
移行手順
前提: Phase 4 まで完了 (TidbCluster 稼働中)、Phase 4.5 完了 (kube-prom-stack 稼働中)。 作業は 手元の Mac から実行する想定 (kubeconfig は
~/.kube/configに配置済み、Tailscale 経由でnode1:6443に到達できる状態)。
Step 1: マニフェスト群の確認
実体は本リポジトリの manifests/monitoring/ 配下に既に揃っている。ファイル一覧と役割は manifests/monitoring/README.md 参照。雛形に過不足があれば編集する:
PrometheusRule (
prometheus-rules/tidb-rules.yaml) — 最小の recording + alert rule のみ。自分が見たい指標 / アラート条件を AI と相談しながら肉付けする。引用元として pingcap/tidb-operator manifests/monitor の公式 rule を AI に渡すと精度が上がるダッシュボード (
dashboards/tidb-overview.json) — 4 パネル (QPS / SQL p99 / TiKV write p99 / Component up) の最小構成。以後は Grafana UI で編集 → Export → 上書きコミットの運用に切り替える
Step 2: PodMonitor + PrometheusRule + ダッシュボード一括投入
# リポジトリルートから
kubectl apply -k manifests/monitoring/
# Prometheus 側で TiDB target が UP になったか確認
kubectl -n monitoring port-forward svc/kube-prom-stack-kube-prome-prometheus 9090:9090 &
# ブラウザで http://localhost:9090/targets
# tidb-cluster/tidb-pd, tidb-cluster/tidb-tidb, tidb-cluster/tidb-tikv が UP
# Prometheus が rule をロードしたか確認
# http://localhost:9090/rules に tidb.recording / tidb.alerts が出てくる
release: kube-prom-stacklabel は kube-prom-stack のデフォルトpodMonitorSelector/ruleSelectorに合わせている。helm values で selector を変えている場合は実体ファイル側を合わせる。
Step 3: 動作確認
# 自作ダッシュボードが kube-prom-stack Grafana に表示されることを確認
kubectl -n monitoring port-forward svc/kube-prom-stack-grafana 13000:80
# http://localhost:13000 (admin / Phase 4.5 で設定した値)
# 左メニューから "TiDB Overview" を開いて全パネル描画されれば成功
Step 4: TidbMonitor 削除 + ストレージ掃除
TidbMonitor は CR 削除だけではゴミが残る (実機で確認済み):
削除した時点で残るもの |
理由 |
|---|---|
PVC |
tidb-operator は PVC を自動削除しない |
PV |
local-path provisioner の ReclaimPolicy が |
ノード上のディレクトリ |
PV を消しても実データは残留 |
完全に消すには 4 段階の掃除が必要。
# 1. TidbMonitor CR 削除 (Pod / Service / 関連 ConfigMap は Operator が片付ける)
kubectl -n tidb-cluster delete tidbmonitor basic
# 2. PVC 削除 (Operator が片付けないので明示削除)
# PV 名を先に控える: PVC を消すと claimRef が消えて PV の特定が面倒になる
PV=$(kubectl -n tidb-cluster get pvc tidbmonitor-basic-monitor-0 -o jsonpath='{.spec.volumeName}' 2>/dev/null)
kubectl -n tidb-cluster delete pvc tidbmonitor-basic-monitor-0 --ignore-not-found
# 3. PV 削除 (Retain policy で Released のまま残るため明示削除)
[[ -n "$PV" ]] && kubectl delete pv "$PV" --ignore-not-found
# 4. ノード上の実データディレクトリを削除
# どのノードに居たか分からないので 3 台全部に問い合わせる (空振りは無害)
for n in node1 node2 node3; do
ssh $n 'sudo rm -rf /opt/local-path-provisioner/*tidbmonitor*'
done
# 5. クリーンか確認
kubectl -n tidb-cluster get all,cm,pvc 2>/dev/null | grep -i monitor || echo "✅ kubectl: clean"
kubectl get pv -o jsonpath='{range .items[?(@.spec.claimRef.namespace=="tidb-cluster")]}{.metadata.name} {.spec.claimRef.name}{"\n"}{end}' | grep tidbmonitor || echo "✅ PV: clean"
for n in node1 node2 node3; do
ssh $n "ls -d /opt/local-path-provisioner/*tidbmonitor* 2>/dev/null && echo '❌ $n: leftover' || echo \"✅ $n: clean\""
done
Step 5: TiDB Dashboard の Prometheus アドレスを切り替え
TiDB Dashboard (PD 組み込み) は Overview や TiDB CPU Usage 等のパネルでメトリクスを描画する際、PD config の metric-storage を参照する。TidbMonitor 稼働中は Operator がここに http://basic-prometheus.tidb-cluster.svc:9090 を入れていたが、TidbMonitor 削除後はその Service が消えているため、Dashboard を開くと次のエラーが各パネルに出る:
failed to send requests to Prometheus, caused by: Get "http://basic-prometheus.tidb-cluster.svc:9090/api/v1/query_range?...":
dial tcp: lookup basic-prometheus.tidb-cluster.svc on 10.96.0.10:53: no such host
kube-prom-stack の Prometheus に向け直す:
# 1. kube-prom-stack の Prometheus Service 名・ポート確認
kubectl -n monitoring get svc kube-prom-stack-kube-prome-prometheus
# → ClusterIP / 9090/TCP
# 2. PD config の metric-storage を新 URL に設定
kubectl -n tidb-cluster exec basic-pd-0 -- /pd-ctl config set metric-storage \
"http://kube-prom-stack-kube-prome-prometheus.monitoring:9090"
# → "Success!" が返れば反映完了
# 3. 反映確認
kubectl -n tidb-cluster exec basic-pd-0 -- /pd-ctl config show all | grep metric-storage
# → "metric-storage": "http://kube-prom-stack-kube-prome-prometheus.monitoring:9090"
ブラウザで TiDB Dashboard をリロードすると Overview の各パネルが描画されるようになる。
Dashboard UI 上の
Change Prometheus Addressボタンからも同じ設定変更が可能だが、再構築のたびに手作業になるので CLI / Git 管理する方を採用。
metric-storageは PD config のトップレベルキー (dashboard.metric-storageではない)。pd-ctl config set dashboard metric-storage ...のように書くと「dashboard が config set のサブコマンドではない」エラーで弾かれる。
Step 6: Tailscale 公開設定の整理
Phase 6 で立てた tidb-grafana-public Service (Tailscale Operator 経由) を撤去し、node-grafana-public 一本に集約する。
# tidb-grafana-public Service を削除
kubectl -n tidb-cluster delete svc tidb-grafana-public
# Tailscale Admin Console (https://login.tailscale.com/admin/machines) で
# ts-tidb-grafana-public-* マシンが消えたことを確認
/etc/hosts や個人ブックマークの tidb-grafana.<tailnet>.ts.net も削除。以後はホスト / TiDB / k8s メトリクス全部 node-grafana.<tailnet>.ts.net に集約。
TiDB Dashboard (
tidb-dashboard.<tailnet>.ts.net:2379/dashboard) はそのまま残す。これは PD 組み込みで TidbMonitor とは独立。
Step 7: Grafana ダッシュボード整理 (全消し → 自作 2 枚体制)
Phase 4.5 をそのまま積むと Grafana には kube-prom-stack 同梱 20+ 枚 + 手動 import 分 + 自作分が並んで「どれを見ればいいか分からない」状態になる。役割で割り切る:
対象 |
どこで見るか |
|---|---|
TiDB クラスタ全体 / SQL / Key Visualizer / Profile |
TiDB Dashboard (PD 組み込み) |
ホスト OS / k8s リソース |
Grafana 自作 2 枚 ( |
詳細メトリクス調査 |
Grafana の Explore で PromQL 直叩き |
全消し 4 段階
defaultDashboardsEnabled: false を helm values に入れただけでは 既に作られた ConfigMap は削除されない (helm は手放したリソースを消さない)。手動削除が必要:
# 1. 旧自作 ConfigMap (もしあれば)
kubectl -n monitoring delete cm dashboards-tidb-overview --ignore-not-found
# 2. helm values を Git 管理化して適用 (defaultDashboardsEnabled: false + sidecar 設定)
helm upgrade kube-prom-stack prometheus-community/kube-prometheus-stack \
-n monitoring -f manifests/monitoring/kube-prom-stack-values.yaml
# 3. 同梱 ConfigMap の手動削除 (label `release=kube-prom-stack` で絞ると自作は残せる)
kubectl -n monitoring delete cm -l grafana_dashboard=1,release=kube-prom-stack
# 4. Grafana API で手動 import 分削除 (provisioned 由来は 412 で弾かれて自動スキップ)
PW=$(kubectl -n monitoring get secret kube-prom-stack-grafana -o jsonpath='{.data.admin-password}' | base64 -d)
kubectl -n monitoring port-forward svc/kube-prom-stack-grafana 13000:80 &
sleep 3
for uid in $(curl -s -u "admin:$PW" "http://localhost:13000/api/search?type=dash-db" | jq -r '.[].uid'); do
curl -s -X DELETE -u "admin:$PW" "http://localhost:13000/api/dashboards/uid/$uid" > /dev/null
done
pkill -f "port-forward.*grafana.*13000"
自作 2 枚の中身
ファイル |
内容 |
|---|---|
|
ホスト OS の CPU/Memory/Disk/Network/Load/Uptime を node 単位で可視化 (node template変数あり) |
|
Pod 別 CPU/Memory トップ10、Restart 累積、Not Ready Pod、namespace 別カウント (namespace template変数あり) |
最終確認
PW=$(kubectl -n monitoring get secret kube-prom-stack-grafana -o jsonpath='{.data.admin-password}' | base64 -d)
kubectl -n monitoring port-forward svc/kube-prom-stack-grafana 13000:80 &
sleep 3
curl -s -u "admin:$PW" "http://localhost:13000/api/search?type=dash-db" | jq -r '.[] | [.uid, .title] | @tsv'
# → cluster-nodes / cluster-pods の 2 行だけ表示されればクリーン
pkill -f "port-forward.*grafana.*13000"
ダッシュボード IaC の運用
リポジトリレイアウト
manifests/monitoring/ 配下に kustomize 構成で集約。ディレクトリ構造とファイル一覧は manifests/monitoring/README.md 参照。実体ファイルとドキュメントの 2 重管理を避けるため、本資料には YAML を再掲しない。
ダッシュボード追加 / 更新フロー
Grafana UI で編集: kube-prom-stack Grafana で対象ダッシュボードを開き、パネルを編集
Export: ダッシュボード右上 Share → Export → "Export for sharing externally" を オフ にして JSON を保存
コミット:
manifests/monitoring/dashboards/<name>.jsonとして配置新規追加なら
manifests/monitoring/dashboards/kustomization.yamlのconfigMapGenerator.filesにも追記
適用:
kubectl apply -k manifests/monitoring/sidecar (
grafana-sc-dashboard) が ConfigMap 変更を検知して Grafana に自動反映
Datasource UID の扱い
kube-prom-stack はデフォルトで Prometheus datasource の UID を prometheus 固定で provisioning するので、ダッシュボード JSON 中の "datasource": {"uid": "prometheus"} 直書きで実用上問題ない。複数 datasource に切り替えたくなったら Grafana 標準の __inputs / ${DS_PROMETHEUS} パターンに切り替える。
GitOps 化 (将来)
ArgoCD / Flux を入れる時は manifests/monitoring/ を Application としてそのまま向けるだけ。手動 kubectl apply -k から argocd app sync への切替が Application 1 つで完結する構成になっている。
失うものと補完方針
失うもの |
補完 |
|---|---|
過去のメトリクス履歴 (TidbMonitor Prometheus の 14 日分) |
捨てる |
NgMonitoring (Top SQL / Continuous Profiling) |
単体 Deployment 化で復活 ( |
TidbMonitor 同梱の公式ダッシュボード一式 |
全削除。TiDB は Dashboard (PD 組み込み)、ホスト/k8s は自作 |
kube-prom-stack 同梱の defaultDashboards 20+ 枚 |
全削除 (Step 7)。役割で割り切り「ダッシュボードがありすぎ問題」を根絶 |
Reloader (PingCAP 独自) |
kube-prom-stack Operator が同等 (PodMonitor / PrometheusRule の変更検知 + Prometheus reload) |
ImageInitializer によるダッシュボード自動投入 |
sidecar が ConfigMap を監視する仕組みで代替 |
失わないもの:
TiDB Dashboard (PD 組み込み) — Key Visualizer / SQL Statements / Slow Queries / Profiling
TiDB / TiKV / PD の生メトリクス (PodMonitor で直接 scrape)
アラート機能 (kube-prom-stack の Alertmanager に集約)
本編 (2026-06-25_construction_plan.md) 統合 TODO
本資料の手順が実機で安定したら、本編に取り込んで「最初から廃止構成で組む」状態にする。具体的な差分:
本編セクション |
統合作業 |
|---|---|
Phase 4 「node1 で実行: TidbMonitor 導入」(L1265-1330) |
章ごと削除し、PodMonitor + PrometheusRule + ダッシュボード ConfigMap の節に置換 |
Phase 4 「決めたこと」(L1391-1400) の「TidbMonitor 同梱の Grafana / Prometheus」記述 |
kube-prom-stack に一本化された旨に書き換え |
Phase 4.5 「動機」(L1410-1417) の TidbMonitor との比較記述 |
TidbMonitor は前提から消えたため、純粋なホスト監視の動機に整理 |
Phase 4.5 「node1 で実行: kube-prometheus-stack 導入」の |
|
Phase 4.5 「Grafana で見るダッシュボード」セクション (公式 ID 15172/11074/15760/15757/15758 等の手動 import 説明) |
章ごと削除。Grafana には自作 |
Phase 4.5 「決めたこと」(L1574-1577) の |
「Prometheus / Grafana 一本化」方針に書き換え |
Phase 6 「Grafana (TidbMonitor 同梱)」セクション (L1844-) |
章ごと削除。 |
Phase 6 公開エンドポイント表 (L1932-1933, L2185-2186) |
|
付録「再構築」手順 (L2195-) の TidbMonitor 削除 / 再作成ステップ |
TidbMonitor 関連行を削除 |
全体 Pod / リソース一覧 (L2132, L2171) |
|
関連資料
2026-06-27_ng_monitoring_standalone.md: NgMonitoring を単体 Deployment で復活させる手順 (Top SQL / Continuous Profiling の再開)。v8.1 系ではpd-ctl ng-monitoring-addressは存在せず、ng-monitoring が PD に自己登録するので Service と Deployment を立てるだけで Dashboard 側のヘルスチェックが通る
参考
pingcap/tidb-operator manifests/monitor — recording / alert rule の流用元
pingcap/tidb pkg/metrics/grafana — 公式ダッシュボード JSON
kube-prometheus-stack — Sidecar dashboards — ConfigMap label による自動ロード仕組み