在 Kubernetes 上基于 VictoriaMetrics Cluster 构建高可用监控:复制与去重实战指南
2026/9/15 12:45:46 网站建设 项目流程

在 Kubernetes 上基于 VictoriaMetrics Cluster 构建高可用监控:复制与去重实战指南

【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics

本篇指南以 VictoriaMetrics 集群版(Cluster version)为对象,讲解如何在 Kubernetes 中通过 Helm 部署一套高可用(HA)监控体系:利用vminsertreplicationFactor: 2复制写入,配合vmselectdedup.minScrapeInterval去重读取,并借助vmagent的服务发现能力采集 Kubernetes 组件指标。读完本文,你将掌握 VictoriaMetrics 复制与去重机制的工作原理、完整部署命令与配置参数、查询验证方法,以及如何通过故障演练证明数据在单节点宕机时依然可用。

高可用原理:复制写入 + 去重读取

在本方案中,高可用通过配置vminsertreplicationFactor: 2实现。这意味着每条进入的数据点都会被写入两次,分别落到两个不同的vmstoragePod 上,只要某个时间序列的至少一个副本可达,数据就始终可用。

该方案需要两倍的存储空间,因为vminsert会把每次写入扇出(fan out)到两个vmstoragePod。

复制带来的直接副作用是:vmselect查询时会读到每个样本的两份拷贝,导致聚合结果被放大——例如sumcount这类聚合会把结果翻倍。因此必须在vmselectPod 上启用去重(deduplication),将每个抓取间隔内的副本折叠为单个样本。

关于复制与数据安全机制的官方说明,可进一步阅读 Cluster-VictoriaMetrics.md 中的 Replication and data safety 章节,其中明确指出:

  • 复制通过在vminsert上传递-replicationFactor=N命令行标志启用,指示vminsert将每条摄入样本存储 N 份到 N 个不同的vmstorage节点上,从而保证最多有N-1vmstorage节点不可用时数据依然可查询;
  • 集群至少需要2*N-1vmstorage节点(N 为复制因子),才能在N-1个存储节点不可用时,依然为新摄入数据维持给定的复制因子;
  • 复制会使 CPU、内存、磁盘空间、网络带宽等资源占用提升最多N倍,因此如果底层存储本身是带复制能力的高可用持久化卷,将复制下推到底层存储往往更经济;
  • 复制不能替代备份——文档明确建议仍需定期执行备份。

前置条件

本指南在 GCP 的 GKE 集群(v1.35)上验证,但同样适用于任何 Kubernetes 集群,例如 Amazon EKS 或自建集群。

开始前请准备好以下工具:

  • 一个可用的 Kubernetes 集群(如 GKE);
  • Helm 包管理器;
  • kubectl命令行工具;
  • jq工具,用于格式化 JSON 查询输出。

1. 添加 VictoriaMetrics Helm 仓库

执行以下命令添加 VictoriaMetrics 的 Helm 仓库并更新索引:

helm repo add vm https://victoriametrics.github.io/helm-charts/ helm repo update

随后验证图表是否可用:

helm search repo vm/

输出应类似如下(图表版本随发布迭代而变化,此处为参考示例):

NAME CHART VERSION APP VERSION DESCRIPTION vm/victoria-metrics-cluster 0.35.0 v1.136.0 VictoriaMetrics Cluster version - high-performa... vm/victoria-metrics-agent 0.32.0 v1.136.0 VictoriaMetrics Agent - collects metrics from v... vm/victoria-metrics-common 0.0.46 VictoriaMetrics Common - contains shared templa... ...(list continues)...

本指南将用到两个图表:

  • vm/victoria-metrics-cluster:部署集群版核心组件(vminsertvmstoragevmselect);
  • vm/victoria-metrics-agent:部署vmagent,负责抓取 Kubernetes 组件指标并写入集群。

2. 通过 Helm Chart 安装 VictoriaMetrics 集群版

VictoriaMetrics 集群版由三个服务组成:

  • vminsert:接收进入的指标,通过基于指标名和标签的一致性哈希(consistent hashing)将数据分布到各个vmstorage节点,并负责按复制因子扇出写入;
  • vmstorage:存储原始数据,并按时间范围与标签过滤来服务查询;
  • vmselect:跨所有配置的vmstorage节点拉取数据执行查询。

创建高可用配置文件victoria-metrics-cluster-values.yml

cat <<EOF > victoria-metrics-cluster-values.yml vmselect: extraArgs: dedup.minScrapeInterval: 1ms replicationFactor: 2 podAnnotations: prometheus.io/scrape: "true" prometheus.io/port: "8481" replicaCount: 3 vminsert: extraArgs: replicationFactor: 2 podAnnotations: prometheus.io/scrape: "true" prometheus.io/port: "8480" replicaCount: 3 vmstorage: podAnnotations: prometheus.io/scrape: "true" prometheus.io/port: "8482" replicaCount: 3 EOF

下面逐项拆解这份配置是如何实现高可用的:

  • replicaCount: 3:为vmselectvminsertvmstorage各创建 3 个副本(Pod)。vmstorage的 3 个副本满足复制因子为 2 时对节点数2*N-1 = 3的最低要求;
  • replicationFactor: 2:为vminsertvmselect启用复制:
    • vminsert利用replicationFactor扇出写入——每个样本写入两份,并分发到不同vmstoragePod;
    • vmselect也需要replicationFactor,这样它才知道期望读到多少个副本,以及何时将响应视为部分(partial)结果(后文详述);
  • dedup.minScrapeInterval: 1ms:为vmselect配置去重,避免从多个vmstoragePod 读取数据时对样本重复计数。VictoriaMetrics 的时间戳精度为毫秒,因此复制启用时-dedup.minScrapeInterval=1ms是必须传给vmselect的配置;如果你同时运行了多份配置完全相同的vmagent或 Prometheus 实例抓取同一批数据,则应把该值设为抓取配置中的scrape_interval,以便跨实例去重。官方文档同时建议在vmselectvmstorage上设置相同-dedup.minScrapeInterval值,以保证查询结果一致性(即使存储层尚未完成去重);
  • podAnnotations: prometheus.io/scrape: "true":开启指标抓取注解,让集群自身可以被监控;
  • podAnnotations: prometheus.io/port: "some_port":指定抓取端口——vminsert为 8480、vmselect为 8481、vmstorage为 8482。

执行安装(以下命令在 default 命名空间部署集群):

helm install vmcluster vm/victoria-metrics-cluster -f victoria-metrics-cluster-values.yml

安装成功的输出会包含各服务的访问方式,大致如下:

NAME: vmcluster LAST DEPLOYED: Mon Mar 2 12:50:25 2026 NAMESPACE: default STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None NOTES: Write API: The VictoriaMetrics write api can be accessed via port 8480 with the following DNS name from within your cluster: vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local. Get the Victoria Metrics insert service URL by running these commands in the same shell: export POD_NAME=$(kubectl get pods --namespace default -l "app=vminsert" -o jsonpath="{.items[0].metadata.name}") kubectl --namespace default port-forward $POD_NAME 8480 You need to update your Prometheus configuration file and add the following lines to it: prometheus.yml remote_write: - url: "http://<insert-service>/insert/0/prometheus/" for example - inside the Kubernetes cluster: remote_write: - url: http://vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local:8480/insert/0/prometheus/ Read API: The VictoriaMetrics read api can be accessed via port 8481 with the following DNS name from within your cluster: vmcluster-victoria-metrics-cluster-vmselect.default.svc.cluster.local. Get the VictoriaMetrics select service URL by running these commands in the same shell: export POD_NAME=$(kubectl get pods --namespace default -l "app=vmselect" -o jsonpath="{.items[0].metadata.name}") kubectl --namespace default port-forward $POD_NAME 8481 You need to specify the service URL in your Grafana: NOTE: you need to use the Prometheus Data Source Input this URL field into Grafana http://<select-service>/select/0/prometheus/ for example - inside the Kubernetes cluster: http://vmcluster-victoria-metrics-cluster-vmselect.default.svc.cluster.local.:8481/select/0/prometheus/

注意这里的 URL 格式:写路径是/insert/0/prometheus/,读路径是/select/0/prometheus/,其中0是默认租户 ID(集群版支持多租户)。

验证集群各 Pod 均已就绪:

kubectl get pods -l app.kubernetes.io/instance=vmcluster

预期输出(vmstorage以 StatefulSet 形式按序创建,因此 AGE 略有差异):

NAME READY STATUS RESTARTS AGE vmcluster-victoria-metrics-cluster-vminsert-788c76b69b-lphnn 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vminsert-788c76b69b-lxg2w 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vminsert-788c76b69b-qmtkp 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vmselect-65796bc88d-29cwm 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vmselect-65796bc88d-lz58p 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vmselect-65796bc88d-t42pr 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vmstorage-0 1/1 Running 0 106s vmcluster-victoria-metrics-cluster-vmstorage-1 1/1 Running 0 91s vmcluster-victoria-metrics-cluster-vmstorage-2 1/1 Running 0 76s

3. 通过 Helm Chart 安装 vmagent

为了从 Kubernetes 抓取指标并写入集群,需要安装 vmagent 并为其配置附加设置。

执行安装(使用官方示例 values 文件):

helm install vmagent vm/victoria-metrics-agent -f https://docs.victoriametrics.com/guides/examples/guide-vmcluster-vmagent-values.yaml

该示例 values 文件的完整内容已保存在本仓库中,可直接查看:docs/guides/examples/guide-vmcluster-vmagent-values.yaml。

下面解析该 values 文件中的关键配置项。

remoteWrite:指向 vminsert 的写入端点

remoteWrite定义了vmagent将遥测数据发送到的vminsert端点,其值必须与第 2 步安装输出中remote_write的 URL 完全一致:

remoteWrite: - url: http://vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local:8480/insert/0/prometheus/

metric_relabel_configs:指标标签重写规则

metric_relabel_configs定义对抓取到的指标执行标签重写的规则。示例文件在kubernetes-nodes-cadvisor任务中使用了如下规则:

metric_relabel_configs: - action: replace source_labels: [pod] regex: '(.+)' target_label: pod_name replacement: '${1}' - action: replace source_labels: [container] regex: '(.+)' target_label: container_name replacement: '${1}' - action: replace target_label: name replacement: k8s_stub - action: replace source_labels: [id] regex: '^/system\.slice/(.+)\.service$' target_label: systemd_service_name replacement: '${1}'

规则含义依次为:把pod标签复制为pod_name、把container标签复制为container_name、为指标补充固定标签name="k8s_stub"、从 cAdvisor 的id标签中提取 systemd 服务名到systemd_service_name

服务发现:抓取 Kubernetes 组件指标

示例 values 文件通过kubernetes_sd_configs配置了多种抓取角色,覆盖 Kubernetes 常见指标源:

  • kubernetes-apiserversrole: endpoints):抓取 API Server 指标,使用 service account 的 CA 与 token 进行 HTTPS 认证;
  • kubernetes-nodesrole: node):抓取 kubelet 暴露的节点级指标,并利用labelmap将节点标签映射到指标标签;
  • kubernetes-nodes-cadvisorrole: nodemetrics_path: /metrics/cadvisor):抓取节点上的容器运行时指标;
  • kubernetes-service-endpointsrole: endpoints):抓取带有prometheus.io/scrape: "true"注解的 Service 端点;
  • kubernetes-servicesrole: service):对带有prometheus.io/probe: "true"注解的服务执行黑盒探测(metrics_path: /probe,模块http_2xx);
  • kubernetes-podsrole: pod):抓取带有prometheus.io/scrape: "true"注解的 Pod,并通过relabel_configs将 Pod 名转换为kubernetes_pod_name标签——这正是后文验证查询中使用的标签。

其中kubernetes-pods任务的典型 relabel 逻辑包括:跳过 init 容器、通过keep_if_equal校验注解端口与容器端口一致、根据prometheus.io/scrape注解决定是否保留目标、将prometheus.io/path注解映射到__metrics_path__、修正抓取地址,并最终把命名空间、Pod 名、节点名等元数据转换为kubernetes_namespacekubernetes_pod_namekubernetes_node标签。

验证vmagentPod 已正常运行:

kubectl get pod -l app.kubernetes.io/instance=vmagent

预期输出:

NAME READY STATUS RESTARTS AGE vmagent-victoria-metrics-agent-6848c6b58d-87rf6 1/1 Running 0 32s

4. 验证集群高可用状态

先确认各 Service 已就绪:

kubectl get svc -l app.kubernetes.io/instance=vmcluster

预期输出:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE vmcluster-victoria-metrics-cluster-vminsert ClusterIP 10.43.157.170 <none> 8480/TCP 4m41s vmcluster-victoria-metrics-cluster-vmselect ClusterIP 10.43.222.181 <none> 8481/TCP 4m41s vmcluster-victoria-metrics-cluster-vmstorage ClusterIP None <none> 8482/TCP,8401/TCP,8400/TCP 4m41s

其中vmstorage的 Cluster-IP 为None,属于无头服务(Headless Service),每个存储节点拥有独立的 DNS 名称。

接着把vmselect的端口转发到本地,以便通过 curl 查询:

kubectl port-forward svc/vmcluster-victoria-metrics-cluster-vmselect 8481:8481

在另一个终端执行查询,统计集群中vmselectPod 的数量:

curl -sg 'http://127.0.0.1:8481/select/0/prometheus/api/v1/query?query=count(up{kubernetes_pod_name=~".*vmselect.*"})' | jq

命令拆解:

  • http://127.0.0.1:8481/select/0/prometheus/api/v1/query?query=使用 VictoriaMetrics 查询 API(兼容 Prometheus HTTP API)获取指标数据;
  • query=count(up{kubernetes_pod_name=~".*vmselect.*"})指定查询表达式:统计kubernetes_pod_name匹配vmselectup指标数量,即当前存活的vmselectPod 数;
  • 管道到jq让输出更易读。

预期结果中value应为3(即我们配置的副本数):

{ "status": "success", "isPartial": false, "data": { "resultType": "vector", "result": [ { "metric": {}, "value": [ 1773419630, "3" ] } ] }, "stats": { "seriesFetched": "3", "executionTimeMsec": 3 } }

也可以直接在浏览器中打开http://localhost:8481/select/0/vmui/使用 VMUI 界面执行同样查询(0为默认租户 ID)。输入count(up{kubernetes_pod_name=~".*vmselect.*"})并点击Execute query

还可以通过Explore>Prometheus metrics浏览从 Kubernetes 集群采集到的指标,例如 CPU 利用率:

5. 高可用故障演练

现在通过模拟故障来验证高可用是否真正生效——直接关停一个vmstoragePod。

vmstorage副本数从 3 缩到 2:

kubectl scale sts vmcluster-victoria-metrics-cluster-vmstorage --replicas=2

确认集群中现在只有两个存活的vmstoragePod:

kubectl get pods -l app=vmstorage

预期输出:

NAME READY STATUS RESTARTS AGE vmcluster-victoria-metrics-cluster-vmstorage-0 1/1 Running 0 3h20m vmcluster-victoria-metrics-cluster-vmstorage-1 1/1 Running 0 3h20m

用查询确认vmstorage节点数为 2:

curl -sg 'http://127.0.0.1:8481/select/0/prometheus/api/v1/query?query=count(up{kubernetes_pod_name=~".*vmstorage.*"})' | jq

输出应显示 2 个节点:

{ "status": "success", "isPartial": false, "data": { "resultType": "vector", "result": [ { "metric": {}, "value": [ 1773437033, "2" ] } ] }, "stats": { "seriesFetched": "2", "executionTimeMsec": 5 } }

由于每个数据点都存储在两个存储 Pod 上,丢失单个 Pod 不会影响查询结果——只要每个时间序列至少有一个副本可达,数据就始终可用。

读懂响应中的isPartial

判断查询结果是否完整,可以检查响应中的isPartial字段:

  • isPartial: false时,表示响应在请求的时间范围和序列上是完整的,即已经有足够数量的存储副本做出了响应(依据所配置的replicationFactor);
  • isPartial: true时,表示vmselect未能从vmstorage取回它预期的全部数据,返回的序列与数值可能不完整或不正确。

这与 Cluster-VictoriaMetrics.md 中关于集群可用性的说明一致:vmselect通过-replicationFactor=N标志被告知,只要不可用的vmstorage节点少于N个,就返回完整响应,因为剩余的存储节点被假定包含全部数据。同时,-search.denyPartialResponse标志可用于在追求一致性优先于可用性的场景中,让vmselect在任一存储节点不可用时直接返回错误。

其余副本不受影响

继续执行其他查询,例如count(up{kubernetes_pod_name=~".*vmselect.*"}),结果仍应为 3:

curl -sg 'http://127.0.0.1:8481/select/0/prometheus/api/v1/query?query=count(up{kubernetes_pod_name=~".*vmselect.*"})' | jq
{ "status": "success", "isPartial": false, "data": { "resultType": "vector", "result": [ { "metric": {}, "value": [ 1773437137, "3" ] } ] }, "stats": { "seriesFetched": "3", "executionTimeMsec": 5 } }

这说明查询与指标写入都不受单个存储 Pod "故障"的影响。

演练结束后,将vmstorage扩回 3 个副本恢复正常运行:

kubectl scale sts vmcluster-victoria-metrics-cluster-vmstorage --replicas=3

6. 总结与后续方向

至此,你已完成:

  • 在 Kubernetes 上部署了一套高可用的 VictoriaMetrics 集群;
  • 通过vmagent从运行中的服务采集指标并写入集群数据库;
  • 为集群配置了dedup.minScrapeIntervalreplicationFactor: 2以实现高可用;
  • 通过关停一个vmstorage节点的故障演练,验证了指标依然可用。

需要牢记的要点:

  • 复制因子为N时集群至少需要2*N-1vmstorage节点,本示例为N=2、节点数 3;
  • 复制会带来最多N倍的 CPU、内存、磁盘与网络开销;如果底层已使用带复制能力的持久化存储,可优先将复制下推到底层以降低成本;
  • 复制不等于备份,仍需配合 vmbackup 等工具定期备份数据;
  • vmselectvmstorage应设置相同的-dedup.minScrapeInterval,保证查询结果一致性。

后续可以进一步探索:

  • 深入阅读集群版完整文档,了解多级集群、vmstorage分组与-globalReplicationFactor等高级用法;
  • 使用 vmctl 将已有的指标数据迁移进 VictoriaMetrics;
  • 参照 k8s-monitoring-via-vm-cluster 指南 部署 Grafana 并通过 Prometheus 数据源连接vmselect,搭建完整的可视化监控大盘。

【免费下载链接】VictoriaMetricsVictoriaMetrics: fast, cost-effective monitoring solution and time series database项目地址: https://gitcode.com/GitHub_Trending/vi/VictoriaMetrics

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询