2026-09-11 10:46:15 +09:00
|
|
|
apiVersion: monitoring.coreos.com/v1
|
|
|
|
|
kind: ServiceMonitor
|
|
|
|
|
metadata:
|
|
|
|
|
name: vllm
|
|
|
|
|
namespace: monitoring
|
|
|
|
|
labels:
|
|
|
|
|
app.kubernetes.io/name: vllm
|
|
|
|
|
app.kubernetes.io/part-of: llm-serving
|
|
|
|
|
spec:
|
|
|
|
|
namespaceSelector:
|
|
|
|
|
matchNames:
|
|
|
|
|
- llm-serving
|
|
|
|
|
selector:
|
2026-09-29 22:05:00 +08:00
|
|
|
# Only the three engines that actually serve /metrics.
|
|
|
|
|
# ornith-predictor and qwen-cpu are Ollama, which has no Prometheus
|
|
|
|
|
# endpoint (/metrics returns 404) — selecting them would add permanently
|
|
|
|
|
# DOWN targets. Ollama-model visibility comes from the api-gateway
|
|
|
|
|
# ServiceMonitor instead (llm_ttft_seconds / llm_itl_seconds are
|
|
|
|
|
# measured at the proxy, so they cover every model including Ollama).
|
|
|
|
|
matchExpressions:
|
|
|
|
|
- key: app.kubernetes.io/name
|
|
|
|
|
operator: In
|
|
|
|
|
values:
|
|
|
|
|
- llm-reasoning # vLLM 0.11.0 — full engine metrics
|
|
|
|
|
- llm-embeddings # TEI 1.8.2 — CPU
|
|
|
|
|
- llm-reranker # TEI 1.8.2 — CPU
|
2026-09-11 10:46:15 +09:00
|
|
|
endpoints:
|
2026-09-29 22:05:00 +08:00
|
|
|
# targetPort, not port: the KServe-generated Services on llm-serving have
|
|
|
|
|
# UNNAMED ports, so `port: <name>` can never match. Naming them would mean
|
|
|
|
|
# editing the InferenceServices (predictor restart = full weights reload,
|
|
|
|
|
# tens of seconds on the vLLM slot), so scrape the pod port directly.
|
|
|
|
|
# prometheus-operator v0.94.1 supports targetPort on ServiceMonitor.
|
|
|
|
|
- targetPort: 8080
|
2026-09-11 10:46:15 +09:00
|
|
|
interval: 30s
|
|
|
|
|
scrapeTimeout: 10s
|
|
|
|
|
path: /metrics
|
|
|
|
|
scheme: http
|
|
|
|
|
relabelings:
|
2026-09-29 22:14:49 +08:00
|
|
|
# Prometheus's Kubernetes service discovery already supplies the
|
|
|
|
|
# namespace, pod and service labels; the only one that needs deriving
|
|
|
|
|
# is `app`, since the TEI panels aggregate by it (by (app)) and SD does
|
|
|
|
|
# not promote arbitrary pod labels.
|
|
|
|
|
#
|
|
|
|
|
# `action: replace` is written explicitly. It is the API server's
|
|
|
|
|
# default for relabeling rules, so omitting it leaves the live object
|
|
|
|
|
# diverged from this manifest and ArgoCD reports permanent OutOfSync.
|
|
|
|
|
- action: replace
|
|
|
|
|
sourceLabels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
|
2026-09-11 10:46:15 +09:00
|
|
|
targetLabel: app
|