NgMonitoring 単体 Deployment 化 (Top SQL / Continuous Profiling 復活)
2026-06-27_tidbmonitor_decommission.md で TidbMonitor を廃止した結果、同梱されていた NgMonitoring が消滅し、TiDB Dashboard のヘッダーに以下の警告が出るようになった。
System Health Check Failed
A required component `NgMonitoring` is not started in this cluster. Some features may not work.
同時に左メニューの Top SQL / Continuous Profiling が無効化される。本資料は NgMonitoring を 単体 Deployment で立て直し、両機能を復活させる手順。
なぜ単体 Deployment か
NgMonitoring は元々 TidbMonitor の Pod 内サイドカーとして動いていたが、TidbMonitor を廃止した時点で「TiDB Dashboard が利用したいヘルスチェック付き軽量コンポーネント」だけが残った。TidbMonitor を NgMonitoring 用に部分復活させると Operator が Grafana / Prometheus も巻き戻し気味に管理し始めるため、純粋な ng-monitoring サーバーだけを Deployment で立てるのが最小構成。
仕組み
ng-monitoring サーバー (
pingcap/ng-monitoring) は起動時に--pd.endpointsで渡された PD に対して 自己登録 する (PD 内部の etcd/topology/ng-monitoring/...に書き込み)TiDB Dashboard (PD 組み込み) は
/topology/ng-monitoringを見に行って ng-monitoring の住所を発見し、/topsql/v1/...//continuous-profiling/...を叩くv8.1 系では
pd-ctl config set ng-monitoring-addressは 存在しない (config item ng-monitoring-address not foundで弾かれる)。Service と Deployment を立てれば自動発見されるので明示登録は不要動作確認は
GET /dashboard/api/info/infoのngm_stateフィールド。"started"なら Dashboard 側のヘルスチェックも通る
マニフェスト構成
実体は manifests/monitoring/ng-monitoring/ に配置済み。
manifests/monitoring/ng-monitoring/
├── kustomization.yaml # namespace: tidb-cluster
├── configmap.yaml # ng-monitoring.toml (pd / log / storage / continuous_profiling / metric_storage)
├── pvc.yaml # local-path 5Gi (Continuous Profiling のサンプル保持用)
├── deployment.yaml # pingcap/ng-monitoring:v8.1.0, replicas=1, strategy=Recreate
└── service.yaml # ClusterIP :12020
manifests/monitoring/kustomization.yaml の resources にも - ng-monitoring を追加してあるので、kubectl apply -k manifests/monitoring/ 一発で kube-prom-stack 周辺と一緒に投入される。
設定ポイント (config map)
address = "0.0.0.0:12020"
storage_path = "/var/lib/ng-monitoring"
metric_storage = "http://kube-prom-stack-kube-prome-prometheus.monitoring:9090"
[log]
path = ""
level = "INFO" # ← 大文字必須。"info" は弾かれて起動失敗する
[pd]
endpoints = ["basic-pd:2379"]
[continuous_profiling]
enable = true
profile_seconds = 10
interval_seconds = 60
timeout_seconds = 120
data_retention_seconds = 259200 # 3日
log.levelは大文字 (DEBUG/INFO/WARN/ERROR)。小文字を指定するとFailed to initialize config, err: log level should be DEBUG, INFO, WARN or ERRORで CrashLoopBackOff になるmetric_storageは kube-prom-stack の Prometheus を向ける。Decommission 手順 Step 5 で PD のmetric-storageに入れたのと同じ宛先continuous_profiling.enable = trueは初回起動時 (docdb が空のとき) の初期値にしかならない。一度 UI / API で OFF にされると docdb に永続化された値が TOML より優先され、Pod を再起動しても無効のまま (復旧は後述「Continuous Profiling の有効化」)
deployment ポイント
args:
- --config=/etc/ng-monitoring/ng-monitoring.toml
- --advertise-address=$(POD_IP):12020
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
--advertise-address は PD への自己登録に使われる。Pod IP を渡しておくと Dashboard / 他コンポーネントから Pod IP に直接アクセスできる (Service 経由でも到達可能だが、PD 自己登録には個別 Pod IP の方が無難)。
適用手順
前提:
~/.kube/config-myclusterから TiDB クラスタへ到達可能 (Tailscale 経由node1:6443)
export KUBECONFIG=~/.kube/config-mycluster
# 1. 適用
kubectl apply -k manifests/monitoring/ng-monitoring/
# 2. Pod Ready 待ち
kubectl -n tidb-cluster rollout status deploy/ng-monitoring --timeout=90s
# 3. ログで config 読み込みと PD client 接続を確認
kubectl -n tidb-cluster logs deploy/ng-monitoring --tail=20
# "Welcome to ng-monitoring." と
# "create pd client success" [pd-address=basic-pd:2379] が出ていれば OK
Top SQL の計測を有効化 (TiDB 側)
ng-monitoring を立てても、TiDB は デフォルトでは Top SQL データを送らない。tidb_enable_top_sql システム変数を ON にする必要がある (TiDB v6.0+)。SET GLOBAL は mysql.global_variables に永続化されるので Pod 再起動では消えないが、TiDB Cluster ごと作り直したら再投入が必要。
export KUBECONFIG=~/.kube/config-mycluster
kubectl -n tidb-cluster port-forward svc/basic-tidb 14000:4000 >/dev/null 2>&1 &
sleep 2
# TiDB の Pod / Service には mysql クライアントが入っていないので手元から実行
mysql -h 127.0.0.1 -P 14000 -u root --protocol=TCP -e "
SET GLOBAL tidb_enable_top_sql = 1;
SELECT @@global.tidb_enable_top_sql AS top_sql_global;
"
# → top_sql_global = 1 になればOK
pkill -f "port-forward.*basic-tidb.*14000"
Continuous Profiling は ng-monitoring 側だけで完結するが、Top SQL は TiDB 側のフラグも要る、という非対称があるので注意。
Continuous Profiling の有効化 (ng-monitoring 実行時設定)
TOML の [continuous_profiling] enable = true は 初回起動時 (docdb が空のとき) の初期値 でしかない。一度でも Dashboard UI や API で OFF にされると docdb に false が永続化され、以後 Pod を再起動しても docdb の値が TOML より優先される。ON に戻すには ng-monitoring の /config API を叩く (Dashboard UI の「プロファイリングを有効化」ボタンが裏で呼んでいるのと同じ API)。
export KUBECONFIG=~/.kube/config-mycluster
kubectl -n tidb-cluster port-forward svc/ng-monitoring 12020:12020 >/dev/null 2>&1 &
sleep 2
# 実効設定の確認 (TOML ではなく docdb 反映後の値が返る)
curl -s http://localhost:12020/config | jq .continuous_profiling
# 有効化 (docdb に永続化。Pod 再起動でも維持、PVC を消したら再投入が必要)
curl -s -X POST http://localhost:12020/config \
-H 'Content-Type: application/json' \
-d '{"continuous_profiling": {"enable": true}}'
# → {"status":"ok"}
# 収集確認 (interval_seconds=60 なので 1〜2 分待ってから)
NOW=$(date +%s)
curl -s "http://localhost:12020/continuous_profiling/group_profiles?begin_time=$((NOW-300))&end_time=$NOW" \
| jq '[.[] | {ts, state}]'
# → state: "finished" のエントリが 1 分刻みで並べば OK
pkill -f "port-forward.*ng-monitoring.*12020"
Top SQL (
tidb_enable_top_sql) と同じ性質: コマンドで永続化され Pod 再起動では消えないが、ストレージ (PVC) ごと作り直したら再投入が必要。TOML だけ直しても docdb に古い値が残っていると反映されない。
動作確認
Dashboard 側のヘルスチェック
# TiDB Dashboard が動いている PD pod に port-forward (dashboard-address を見て選ぶ)
kubectl -n tidb-cluster exec basic-pd-0 -- /pd-ctl config show all | grep dashboard-address
# → "dashboard-address": "http://basic-pd-1.basic-pd-peer.tidb-cluster.svc:2379"
kubectl -n tidb-cluster port-forward basic-pd-1 12379:2379 &
sleep 2
curl -s http://localhost:12379/dashboard/api/info/info | jq .ngm_state
# → "started" ← これになれば Dashboard ヘッダーの赤バナーは消える
pkill -f "port-forward basic-pd-1 12379"
ブラウザ側
https://tidb-dashboard.<tailnet>.ts.net:2379/dashboard をリロード:
ヘッダーの
System Health Check Failed - NgMonitoring is not startedバナーが消える左メニューの Top SQL が活性化し、TiDB instance を選んでしばらくすると (収集間隔約 1 分) SQL 別の CPU 使用率時系列が描画される
描画されない場合は
tidb_enable_top_sql = 1が入っているか再確認 (上記「Top SQL の計測を有効化」)
左メニューの Continuous Profiling が活性化し、
Start Profilingボタンから On-CPU / Off-CPU / Mutex / Goroutine プロファイルを取れる
トラブルシュート
CrashLoopBackOff: log level エラー
Failed to initialize config, err: log level should be DEBUG, INFO, WARN or ERROR
→ configmap.yaml の [log] level を大文字に直して kubectl apply -k → kubectl -n tidb-cluster rollout restart deploy/ng-monitoring
CrashLoopBackOff: PD に繋がらない
"create pd client failed" ... connection refused
→ [pd] endpoints の Service 名/ポートが間違っているか、PD が起動していない。
kubectl -n tidb-cluster get svc basic-pd でポート (2379/TCP) を確認。
Top SQL タブが "No data" のまま
TiDB の
tidb_enable_top_sqlが 0 のまま。「Top SQL の計測を有効化」節の手順で 1 にするそれでも出ない時は ng-monitoring の
metric_storageが kube-prom-stack の Prometheus を向いているか確認 (configmap.yaml)。Top SQL UI は ng-monitoring 経由で Prometheus にも問い合わせる一定時間経過しても出ない場合は
kubectl -n tidb-cluster logs deploy/ng-monitoring | grep -i topsqlでエラーがないか確認
Continuous Profiling が TOML で enable = true なのに無効のまま
実行時設定は docdb に永続化された値が TOML より優先される。「Continuous Profiling の有効化」節の
/configAPI で ON に戻す有効化直後の収集で
finished_with_error(TiKV heap profile のUnable to create profile directory /root/jeprof: File exists) が単発で出ることがあるが、以降の収集がfinishedになっていれば問題ない
Dashboard で ngm_state が "unknown" のまま
ng-monitoring Pod が
Runningでも--advertise-addressが Service ClusterIP やlocalhostになっていると PD からの自己登録が見えない。--advertise-address=$(POD_IP):12020になっていることを確認:kubectl -n tidb-cluster get pod -l app.kubernetes.io/name=ng-monitoring -o jsonpath='{.items[0].spec.containers[0].args}'
それでも直らない時は ng-monitoring を再起動 (
rollout restart) して PD への登録を打ち直す
廃止する場合
export KUBECONFIG=~/.kube/config-mycluster
kubectl delete -k manifests/monitoring/ng-monitoring/
# ノード上の PVC 実体 (local-path)
PV=$(kubectl -n tidb-cluster get pvc ng-monitoring -o jsonpath='{.spec.volumeName}' 2>/dev/null)
[[ -n "$PV" ]] && kubectl delete pv "$PV" --ignore-not-found
for n in node1 node2 node3; do
ssh $n 'sudo rm -rf /opt/local-path-provisioner/*ng-monitoring*'
done
manifests/monitoring/kustomization.yaml から - ng-monitoring 行も削除。
TODO
2026-06-25_construction_plan.mdの本編に NgMonitoring 単体 Deployment 構成として統合する (Phase 4.5 の直後あたり)2026-06-27_tidbmonitor_decommission.mdの「別資料化 TODO」セクションから本資料へのリンクに更新
参考
pingcap/ng-monitoring — 上流リポジトリ。config フィールド名と起動フラグの一次ソース
TiDB Operator monitor manifest (参考用) — TidbMonitor 内で ng-monitoring に渡している args / config を参考にした
docs/source/tasks/2026-06-27-tidbmonitor-decommission.md— 本資料の前段 (なぜ単体 Deployment 化が必要か)