优化云原生监控体验:VictoriaMetrics 入门指南

前言

本文首先对VictoriaMetrics的功能和架构进行介绍。接着,使用一个场景例子演示单集群VictoriaMetrics的安装,并验证其对Prometheus的兼容性和可替换性。

VictoriaMetrics简介

我们知道,若要保证一个系统的稳定运行,那么对于这个系统的监控是不可或缺的环节。当今在云原生领域中,Prometheus作为已经毕业的CNCF项目,已经成为了非常主流的监控和报警工具。但它也存在一些缺点,例如:默认情况下,其数据存储于本地文件的TSDB中,不利于容灾和做数据管理,若用于生产一般需要搭配第三方的如InfulxDB进行使用。大数据量的场景下,指标的收集和管理性能存在一定的瓶颈。

而我们今天介绍的VictoriaMetrics可以认为是Prometheus在上述问题上的一个增强版。它不仅能作为时序数据库结合Prometheus使用进行指标的长期远程存储,也能单独作为一个监控解决方案对Prometheus进行平替。

对比其他一些主流的监控方案、时序数据库,VictoriaMetrics具有如下优势:

  • 指标数据的收集和查询具有极高的性能和良好的垂直和水平伸缩性,比InfluxDB和TimesscaleDB的性能高出20倍
  • 在处理高技术时间序列时,内存方面做出了优化,比InfluxDB少10x倍,比Prometheus、Thanos或Cortex少7倍
  • 数据存储的压缩方式更加高效。比TimescaleDB少70倍,与Prometheus、Thanos、Cortex相比,所需存储空间也少7倍。
  • 针对高延迟IO和低IOPS存储进行了优化
  • 单节点的VictoriaMetrics即可替代Thanos、M3DB、Cortex、InfluxDB或TimescaleDB等竞品中等规模的集群
  • 对于Prometheus具有良好的兼容性,能够支持Prometheus的配置文件、PromQL、各类API、数据格式,并有一些自己的增强API。
  • VictoriaMetrics的架构

    VictoriaMetrics分为单节点和集群两个方案。两种方案都提供了二进制文件、docker、helm以及operator等部署方式。对于数据采集点对于100w/s的场景,官方推荐使用单节点版,单节点版相当于一个all-in-one的包,包含了大部分的功能,但不支持告警,简单好维护。多集群的架构图如图1所示:

    图1 VictoriaMetrics集群版架构图 图1 VictoriaMetrics集群版架构图

    VictorMetrics集群部分主要包含了以下几个组件:

    • vmstorage:它是一个有状态的组件,主要负责存储原始数据并返回指定标签过滤器在给定时间范围内的查询数据,集群部署的必选组件,默认端口为8482。
    • vminsert:无状态的服务组件,主要负责接收摄取的数据并根据指标名称和标签的哈希值分散从存储到部署了vmstorage的节点中去,集群部署的必选组件,默认端口为8480。
    • vmselect:无状态的额服务组件,面向外部终端的查询组件,根据收到的请求去各个vmstorage节点中获取数据,集群部署的必选组件,默认端口为8481。
    • vmagent:主要负责数据指标的抓取,并将它们存储在VictoriaMetrics或其他支持remote write协议的Prometheus兼容的存储系统中,会占用本地磁盘缓存。它是一个可选组件,位于图1的Writers那层Load balancer与各个采集源之间,类似于Prometheus中pushgateway的地位。是一个可选组件,默认占用端口8429。其组件作用如图2所示:

    图2 vmagent的作用 图2 vmagent的作用

    • vmalert:类似于Prometheus中的alertmanager,是一个告警的相关组件,如果不需要告警功能可以不使用该组件,是一个可选组件,默认占用端口为8880。

    集群部署模式下,各个服务可以进行独立的扩展,但部署vmstorage节点之间建议互不通信和进行数据共享,单节点模式的二进制文件或镜像已经集成了三个必选组件的功能。

    下面我们将使用单集群的方式在K8S中对VictoriaMetrics进行部署,并验证其对于Prometheus的兼容性。

    VictoriaMetrics单节点的安装和兼容性验证

    首先,我们使用Prometheus-Operator进行Prometheus以及相关诸如node-exporter、grafana的快速安装。接着,在K8S内部署单节点的VictoriaMetrics。最后,开启远程写入将Prometheus的数据写入VictoriaMetrics中,并在grafana中浏览Prometheus和VictoriaMetrics的指标,若结果相同,说明在不使用告警功能的情况下,VictoriaMetrics可兼容替换Prometheus进行使用(单节点版不包含告警功能)。整体的组件图如图3所示:

    图3 场景组件图 图3 场景组件图

    使用kube-prometheus安装prometheus相关组件

    首先,我们克隆和使用 kube-prometheus (https://github.com/prometheus-operator/kube-prometheus) 这个项目来进行图3中蓝色、黄色以及粉色部分组件的快速安装,该项目和 prometheus-operator 的区别就类似于 Linux 内核和 CentOS/Ubuntu

    这些发行版的关系,真正起作用的是 Operator 去实现的,kube-prometheus 项目编写了一系列常用的监控资源清单,更加容易上手安装。不过需要注意 Kubernetes 版本和 kube-prometheus 的兼容,各个版本的兼容关系如图4所示:

    图4 kube-prometheus项目版本兼容情况 图4 kube-prometheus项目版本兼容情况

    由于作者本地的K8s环境为1.21版本,所以我们这里下载使用release-0.9的版本到本地,接着进行进行解压并重命名(起始目录为压缩包所在目录),并进入工作目录,命令如下:

    • tar -xvf kube-prometheus-0.9.0.tar.gz
    • mv kube-prometheus-0.9.0 kube-prometheus
    • cd kube-prometheus

    下一步,我们执行命令:

    • kubectl create -f manifests/setup

    这会帮我们安装创建prometheus-operator的命名空间(默认是monitoring)和所需的CRD资源。

    接着,执行命令:

    • kubectl wait –for condition=Established –all CustomResourceDefinition –namespace=monitoring

    这个命令会校验和等待我们所需CRD和命名空间的完成。

    最后,执行命令:

    • kubectl create -f manifests/

    它会帮我们安装项目已经定义好的Prometheus、node-exporter、kube-state-metrics、alertmanager组件。为了后续方便使用Prometheus和grafana,我们将两个服务对应的service设置成NodePort(默认为ClusterIP)。命令为:

    • kubectl edit svc prometheus-k8s -n monitoring
    • kubectl edit svc grafana -n monitoring

    完成之后,总体的服务清单如图5所示:

    图 5 kube-prometheus安装后的总览图 图 5 kube-prometheus安装后的总览图

    我们通过http://:30246就可以访问grafana了,我们可以看到kube-prometheus这个项目的grafana已经为我们关联了图5中的prometheus,具体见图6:

    图 6 grafana内的prometheus数据源配置 图 6 grafana内的prometheus数据源配置

    点击面板左侧的Explore,我们可以进行指标查询,此处我们查询节点的CPU使用率指标“instance:node_cpu:ratio”,查询结果如图7和图8所示(由于作者的Prometheus做了联邦配置所以结果样本会偏多,只看cnp_cluster为“local-cluster”的样本即可):

    图 7 prometheus数据源指标浏览页面1 图 7 prometheus数据源指标浏览页面1 图 8 prometheus数据源指标浏览页面2 图 8 prometheus数据源指标浏览页面2

    在K8S中部署VictoriaMetrics

    接下来我们进行VictoriaMetrics的部署,由于我们要使用VictoriaMetrics作为远程存储,所以在部署时需要为VictoriaMetrics服务挂载一个存储,此处我们使用Local PV作为其存储(生产环境一般使用NFS或者ceph)。一般来说,Local PV对应的存储介质应该是一块外挂在宿主机的磁盘或者块设备,我们这里暂时将本机节点的/Users/chris/data/k8s/vm这个目录看成是一个挂载的独立磁盘,然后我们依次准备StorageClass、PV和PVC的资源清单,其内容如下代码块所示:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: local-storage
    provisioner: kubernetes.io/no-provisioner
    volumeBindingMode: WaitForFirstConsumer