PromQL でフィルタするのではなく、そもそもメトリクスを除いておきたい場合の話。
ServiceMonitor spec.attachMetadata.node
フィールドを true
に設定することで、Kubernetes Node の meta labels がターゲットに追加される。
__meta_kubernetes_node_label_<labelname>
__meta_kubernetes_node_labelpresent_<labelname>: true
あとはこれを使って Node ラベルで絞り込めばよい。
dedicated=db
ラベルを持つ Node 上で実行される node_exporter のみをスクレイプしたい場合は次のようになる。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
jobLabel: node-exporter
release: kube-prometheus-stack
name: kube-prometheus-stack-prometheus-node-exporter
spec:
jobLabel: jobLabel
selector:
matchLabels:
app.kubernetes.io/instance: kube-prometheus-stack
app.kubernetes.io/name: prometheus-node-exporter
attachMetadata:
node: true
endpoints:
- port: http-metrics
relabelings:
- sourceLabels:
- __meta_kubernetes_node_label_dedicated
regex: db
action: keep
scheme: http
ただ、この方法ではすべての node_exporter pods をサービスディスカバリで発見したうえで、Node ラベルでスクレイプ対象をフィルタしているため、Prometheus UI の "Service Discovery" ページにすべての Node のラベルが晒されてしまう。
晒されるとまずい場合には、そもそもサービスディスカバリが発見する node_exporter 自体を絞り込んでやる必要がある。これは ScrapeConfig CR で kubernetes_sd node
role を使うことで実現できる。
apiVersion: monitoring.coreos.com/v1alpha1
kind: ScrapeConfig
metadata:
name: node-exporter
labels:
release: kube-prometheus-stack
spec:
jobName: node-exporter
kubernetesSDConfigs:
- role: node
selectors:
- role: node
label: dedicated=db
relabelings:
- sourceLabels: [__address__]
targetLabel: __address__
regex: "(.*):.*"
replacement: "$1:9100"
ScrapeConfig CR は生の Prometheus 設定をそのまま書けるのでなんでもできる。困ったらこれを頼ればよい。
ただし、アルファ API なので、将来スペックに破壊的変更が入る可能性がある。気になる場合は Prometheus 設定を生で書いて Prometheus サーバに直接渡せばよい。
そのほか、スクレイプしたいグループ毎に node_exporter DaemonSet を分けて作成してやれば ServiceMonitor でも晒さないようにできるが、これは面倒だとおもう。