Metrics
VictoriaMetrics k8s stack
observability/base/victoria-metrics-k8s-stack/ deploys the
victoria-metrics-k8s-stack chart (0.91.0) — the kube-prometheus-stack
equivalent: VictoriaMetrics itself, vmagent, Alertmanager, a bundled Grafana
subchart, and the default recording/alerting rule set. Only vmsingle is
active; vmcluster sits in the same directory, fully valued, commented out
of kustomization.yaml.
| vmsingle (active) | vmcluster (standby) | |
|---|---|---|
| Retention | 1d — explicitly commented “Minimal retention, for tests only” | 10d |
| Replication | replicaCount: 1 | replicationFactor: 2, separate vmstorage/vmselect/vminsert with zone-aware anti-affinity |
| Storage | 10Gi RWO | 10Gi (vmstorage) + 2Gi (vminsert/vmselect) gp3 |
| Alertmanager | replicaCount unset (chart default) | replicaCount: 2 |
mycluster-0’s overlay (observability/mycluster-0/victoria-metrics-k8s-stack/kustomization.yaml)
adds no patches — it’s a pure passthrough to the base. Common values shared
by both modes (vm-common-helm-values-configmap.yaml, applied via
valuesFrom) disable the control-plane rule groups (kubernetes-system-apiserver,
-controller-manager, -scheduler) — EKS runs these as a managed service
this cluster can’t scrape, so the chart’s default absent()-based *Down
alerts would otherwise fire permanently — and disable kubeProxy scraping
for the same reason Cilium replaces it.
vmsingle is a real operational constraint, not a
typo to “fix”: anything you want to compare against last week is gone.
Cluster mode’s 10d retention is one kustomization.yaml edit away if that
becomes a problem, not a re-architecture.metrics-server
observability/base/metrics-server/ runs the standard metrics-server
chart (3.14.0) — but into kube-system, not observability, since it backs
kubectl top and HPA Resource metrics cluster-wide. Non-default
configuration worth knowing:
replicas: 2with aPodDisruptionBudget(maxUnavailable: 1) and hostname anti-affinity — HA by default, not a single point of failure for every HPA in the cluster.args: [--kubelet-insecure-tls]— required on EKS; the kubelet serving certificate isn’t signed by a CA metrics-server trusts otherwise.serviceMonitor.enabled: truewithadditionalLabels.prometheus: victoria-metrics-k8s-stackso vmagent picks it up.
Scrape mechanisms
Three CRDs from the VictoriaMetrics Operator cover how targets get discovered, each used somewhere in this repo:
VMServiceScrape — the ServiceMonitor equivalent, scrapes a Service’s
endpoints. Most charts in this repo render their own via a
vmServiceScrape.enabled: true value (runlore, victoria-traces,
victoria-logs, victoria-metrics-k8s-stack itself); a few are authored
directly, e.g. observability/base/victoria-metrics-k8s-stack/vmservicecrapes/karpenter.yaml
scrapes the karpenter namespace’s http-metrics port (Karpenter isn’t part
of this stack, but its metrics land in the same VictoriaMetrics — the
directory name carries an upstream typo, vmservicecrapes, not
vmservicescrapes).
VMScrapeConfig — for targets that aren’t a Kubernetes Service at all.
Two examples in vmscrapeconfigs/:
# observability/base/victoria-metrics-k8s-stack/vmscrapeconfigs/openbao.yaml
staticConfigs:
- targets:
- "bao.${private_domain_name}:8200"
labels:
job: openbao
scheme: HTTPS
tlsConfig:
ca:
secret:
name: openbao-ca
key: ca.crt
serverName: "bao.${private_domain_name}"
path: /v1/sys/metricsOpenBao is scraped by DNS name over HTTPS with a real CA, not EC2 service
discovery — the instance security group only admits the internal NLB on
8200, and the server certificate carries a single DNS SAN, so scraping
individual instance IPs could never verify TLS. ec2.yaml in the same
directory is the EC2-SD counterpart, used for node-exporter (tag
observability:node-exporter=true, port 9100) where per-instance scraping is
fine.
VMPodMonitor — scrapes Pods directly rather than through a Service.
Not currently used by any component in this repo; if you add one, it renders
the same way VMServiceScrape does.
Example queries
Written against metrics this cluster actually exposes, not generic placeholders:
# RunLore agent missing entirely (real alert: RunloreAgentDown)
absent(runlore_build_info)
# CloudNativePG: call volume by database, from the query-performance dashboard
sum by (database) (rate(cnpg_pg_stat_statements_calls[5m]))
# RunLore model-request p95 latency (real alert: RunloreModelLatencyHigh)
histogram_quantile(0.95, sum(rate(runlore_model_request_duration_seconds_bucket[15m])) by (le))The first two are drawn directly from
observability/base/victoria-metrics-k8s-stack/vmrules/runlore.yaml and
infrastructure/base/cloudnative-pg/grafana-dashboard-query-performance.yaml.
Standard cAdvisor/kube-state-metrics queries (container_cpu_usage_seconds_total,
kube_pod_status_phase, and similar) also work unchanged — they come from
the bundled kube-state-metrics/node-exporter subcharts, not from
anything specific to this repo.
CiliumNetworkPolicy exists in victoria-metrics-k8s-stack/ or
metrics-server/ for either component. Of the nine observability component
directories, only runlore ships one — see
Dashboards & Alerts
for the CiliumNetworkPolicy it does define, and for the CiliumClusterwideNetworkPolicy
that isn’t a default-deny (it only allows the Gateway API L7 proxy).