Skip to content

Victormetrics

Victormetrics

img

目录

[toc]

1、单节点

img

1.简介

img

VictoriaMetrics(VM)是一个支持高可用、经济高效且可扩展的监控解决方案和时间序列数据库,可用于 Prometheus 监控数据做长期远程存储。

img

前面章节我们介绍了 Thanos 方案也可以用来解决 Prometheus 的高可用和远程存储的问题,那么为什么我们还要使用 VictoriaMetrics 呢?

相对于 Thanos,VictoriaMetrics 主要是一个可水平扩容的本地全量持久化存储方案,VictoriaMetrics 不仅仅是时序数据库,它的优势主要体现在一下几点。(Thanos:它不是做本地全量的,其很多数据都是存储在oss上的。)

  • 对外支持 Prometheus 相关的 API,可 以直接用于 Grafana 作为 Prometheus 数据源使用
  • 指标数据摄取和查询具备高性能和良好的可扩展性,性能比 InfluxDB 和 TimescaleDB 高出 20 倍
  • 在处理高基数时间序列时,内存方面也做了优化,比 InfluxDB 少 10x 倍,比 Prometheus、Thanos 或 Cortex 少 7 倍
  • 高性能的数据压缩方式,与 TimescaleDB 相比,可以将多达 70 倍的数据点存入有限的存储空间,与 Prometheus、Thanos 或 Cortex 相比,所需的存储空间减少 7 倍
  • 它针对具有高延迟 IO 和低 IOPS 的存储进行了优化
  • 提供全局的查询视图,多个 Prometheus 实例或任何其他数据源可能会将数据摄取到 VictoriaMetrics
  • 操作简单
    • VictoriaMetrics 由一个没有外部依赖的小型可执行文件组成
    • 所有的配置都是通过明确的命令行标志和合理的默认值完成的
    • 所有数据都存储在 - storageDataPath 命令行参数指向的目录中
    • 可以使用 vmbackup/vmrestore工具轻松快速地从实时快照备份到 S3 或 GCS 对象存储中
  • 支持从第三方时序数据库获取数据源
  • 由于存储架构,它可以保护存储在非正常关机(即 OOM、硬件重置或 kill -9)时免受数据损坏
  • 同样支持指标的 relabel 操作

2.架构

VM 分为单节点和集群两个方案,根据业务需求选择即可。

单节点版直接运行一个二进制文件既,官方建议采集数据点(data points)低于 100w/s,推荐 VM 单节点版,简单好维护,但不支持告警

集群版支持数据水平拆分

下图是 VictoriaMetrics集群版官方的架构图。

img

注意

vmselect这里是有配置一个缓存的,当然你可以用StatefuleSet的pvc把缓存持久化下来。这里就使用无状态服务的Deployment的emptyDir了。

主要包含以下几个组件:

  • vmstorage:数据存储以及查询结果返回,默认端口为 8482
  • vminsert:数据录入,可实现类似分片、副本功能,默认端口 8480
  • vmselect:数据查询,汇总和数据去重,默认端口 8481
  • vmagent:数据指标抓取,支持多种后端存储,会占用本地磁盘缓存,默认端口 8429
  • vmalert:报警相关组件,如果不需要告警功能可以不使用该组件,默认端口为 8880

集群方案把功能拆分为 vmstorage、 vminsert、vmselect 组件,如果要替换 Prometheus,还需要使用 vmagent、vmalert。从上图也可以看出 vminsert 以及 vmselect 都是无状态的,所以扩展很简单,只有 vmstorage 是有状态的

vmagent的主要目的是用来收集指标数据然后存储到 VM 以及 Prometheus 兼容的存储系统中(支持 remote_write 协议即可)。

下图是 vmagent 的一个简单架构图,可以看出该组件也实现了 metrics 的 push 功能,此外还有很多其他特性:

  • 替换 prometheus 的 scraping target
  • 支持基于 prometheus relabeling 的模式添加、移除、修改 labels,可以方便在数据发送到远端存储之前进行数据的过滤
  • 支持多种数据协议,influx line 协议,graphite 文本协议,opentsdb 协议,prometheus remote write 协议,json lines 协议,csv 数据
  • 支持收集数据的同时,并复制到多种远端存储系统
  • 支持不可靠远端存储(通过本地存储 -remoteWrite.tmpDataPath),同时支持最大磁盘占用
  • 相比 prometheus 使用较少的内存、cpu、磁盘 io 以及网络带宽

img

接下来我们就分别来介绍了 VM 的单节点和集群两个方案的使用。

3.单节点

💘 实战:vm单节点安装及使用(测试成功)-2022.7.24

这里我们采集 node-exporter 为例进行说明,首先使用 Prometheus 采集数据,然后将 Prometheus 数据远程写入 VM 远程存储。

由于 VM 提供了 vmagent组件,最后我们使用 VM 来完全替换 Prometheus,可以使架构更简单、更低的资源占用。🤣

实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:namespace/kube-vmcreated
2.创建DaemonSet 类型的node-exporter
  • 首先我们这 kube-vm命名空间下面使用 DaemonSet 控制器运行 node-exporter,对应的资源清单文件如下所示:

[root@master1 ~]#mkdir vm

[root@master1 ~]#cd vm

[root@master1 vm]#vim vm-node-exporter.yaml

yaml
# vm-node-exporter.yamlapiVersion:apps/v1kind:DaemonSetmetadata:name:node-exporternamespace:kube-vmspec:selector:matchLabels:app:node-exportertemplate:metadata:labels:app:node-exporterspec:hostPID:truehostIPC:truehostNetwork:true#注意这里是hostNetwork方式nodeSelector:kubernetes.io/os:linuxcontainers:- name:node-exporterimage:prom/node-exporter:v1.3.1args:- --web.listen-address=$(HOSTIP):9111#这里修改监听端口为9111- --path.procfs=/host/proc- --path.sysfs=/host/sys- --path.rootfs=/host/root- --no-collector.hwmon# 禁用不需要的一些采集器- --no-collector.nfs- --no-collector.nfsd- --no-collector.nvme- --no-collector.dmi- --no-collector.arp- --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/containerd/.+|/var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)- --collector.filesystem.ignored-fs-types=^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$ports:- containerPort:9111env:- name:HOSTIPvalueFrom:fieldRef:fieldPath:status.hostIPresources:requests:cpu:150mmemory:180Milimits:cpu:150mmemory:180MisecurityContext:runAsNonRoot:truerunAsUser:65534volumeMounts:- name:procmountPath:/host/proc- name:sysmountPath:/host/sys- name:rootmountPath:/host/rootmountPropagation:HostToContainerreadOnly:truetolerations:# 添加容忍- operator:"Exists"volumes:- name:prochostPath:path:/proc- name:devhostPath:path:/dev- name:syshostPath:path:/sys- name:roothostPath:path:/

由于前面章节中我们也创建了 node-exporter,为了防止端口冲突,这里我们使用参数 --web.listen-address=$(HOSTIP):9111配置端口为 9111

img

img

img

  • 直接应用上面的资源清单即可。
bash
[root@master1 vm]#kubectl apply -f vm-node-exporter.yaml daemonset.apps/node-exportercreated[root@master1 vm]#kubectl get po -owide -nkube-vmNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESnode-exporter-56p881/1Running012s172.29.9.51master1<none><none>node-exporter-bjk821/1Running012s172.29.9.53node2<none><none>node-exporter-wnwgt1/1Running012s172.29.9.52node1<none><none>
3.重新部署一套独立的 Prometheus

然后重新部署一套独立的 Prometheus,为了简单我们直接使用 static_configs静态配置方式来抓取 node-exporter 的指标,配置清单如下所示:

  • 创建p8s的ConfigMap资源对象:

[root@master1 vm]#pwd

/root/vm

[root@master1 vm]#vim vm-prom-config.yaml

yaml
# vm-prom-config.yamlapiVersion:v1kind:ConfigMapmetadata:name:prometheus-confignamespace:kube-vmdata:prometheus.yaml:|global:scrape_interval:15sscrape_timeout:15sscrape_configs:- job_name:"nodes"static_configs:- targets:['172.29.9.51:9111','172.29.9.52:9111','172.29.9.53:9111']relabel_configs:# 通过 relabeling 从 __address__ 中提取 IP 信息,为了后面验证 VM 是否兼容 relabeling- source_labels:[__address__]regex:"(.*):(.*)"replacement:"${1}"target_label:'ip'action:replace

上面配置中通过 relabel操作从 __address__中将 IP 信息提取出来,后面可以用来验证 VM 是否兼容 relabel操作。

  • 对p8s做数据持久化:

同样要给 Prometheus 数据做持久化,所以也需要创建一个对应的 PVC 资源对象:

先到node2节点上创建下本地目录:

bash
[root@master1 ~]#cd vm[root@master1 vm]#ssh node2Lastlogin:SatJul2311:55:592022frommaster1[root@node2 ~]#mkdir -p /data/k8s/prometheus[root@node2 ~]#exitlogoutConnectiontonode2closed.

[root@master1 vm]#vim vm-prom-pvc.yaml

yaml
# apiVersion:storage.k8s.io/v1# kind:StorageClass# metadata:# name:local-storage# provisioner:kubernetes.io/no-provisioner# volumeBindingMode:WaitForFirstConsumer---apiVersion:v1kind:PersistentVolumemetadata:name:prometheus-dataspec:accessModes:- ReadWriteOncecapacity:storage:20GistorageClassName:local-storagelocal:path:/data/k8s/prometheuspersistentVolumeReclaimPolicy:RetainnodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key:kubernetes.io/hostnameoperator:Invalues:- node2---apiVersion:v1kind:PersistentVolumeClaimmetadata:name:prometheus-datanamespace:kube-vmspec:accessModes:- ReadWriteOnceresources:requests:storage:20GistorageClassName:local-storage
  • 然后直接创建 Prometheus 即可,将上面的 PVC 和 ConfigMap 挂载到容器中,通过 --config.file参数指定配置文件文件路径,指定 TSDB 数据路径等,资源清单文件如下所示:

[root@master1 vm]#vim vm-prom-deploy.yaml

yaml
# vm-prom-deploy.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:prometheusnamespace:kube-vmspec:selector:matchLabels:app:prometheustemplate:metadata:labels:app:prometheusspec:volumes:- name:datapersistentVolumeClaim:claimName:prometheus-data- name:config-volumeconfigMap:name:prometheus-configcontainers:- image:prom/prometheus:v2.35.0name:prometheusargs:- "--config.file=/etc/prometheus/prometheus.yaml"- "--storage.tsdb.path=/prometheus"# 指定tsdb数据路径- "--storage.tsdb.retention.time=2d"- "--web.enable-lifecycle"# 支持热更新,直接执行localhost:9090/-/reload立即生效ports:- containerPort:9090name:httpsecurityContext:runAsUser:0volumeMounts:- mountPath:"/etc/prometheus"name:config-volume- mountPath:"/prometheus"name:data---apiVersion:v1kind:Servicemetadata:name:prometheusnamespace:kube-vmspec:selector:app:prometheustype:NodePortports:- name:webport:9090targetPort:http
  • 直接应用上面的资源清单即可。
bash
[root@master1 vm]#kubectl apply -f vm-prom-config.yaml configmap/prometheus-configcreatedservice/prometheuscreated[root@master1 vm]#kubectl apply -f vm-prom-pvc.yamlpersistentvolume/prometheus-datacreatedpersistentvolumeclaim/prometheus-datacreated[root@master1 vm]#kubectl apply -f vm-prom-deploy.yaml deployment.apps/prometheuscreated[root@master1 vm]#kubectl get pvNAMECAPACITYACCESSMODESRECLAIMPOLICYSTATUSCLAIMSTORAGECLASSREASONAGEgrafana-local2GiRWORetainBoundmonitor/grafana-pvclocal-storage80dprometheus-data20GiRWORetainBoundkube-vm/prometheus-datalocal-storage8m34sprometheus-local20GiRWORetainBoundmonitor/prometheus-datalocal-storage84dpv0011GiRWORetainTerminatingdefault/www-web-0251dpv0021GiRWORetainTerminatingdefault/www-web-1251d[root@master1 vm]#kubectl get pvc -nkube-vmNAMESTATUSVOLUMECAPACITYACCESSMODESSTORAGECLASSAGEprometheus-dataBoundprometheus-data20GiRWOlocal-storage8m40s[root@master1 vm]#kubectl get po -owide -nkube-vmNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESnode-exporter-56p881/1Running04h40m172.29.9.51master1<none><none>node-exporter-bjk821/1Running04h40m172.29.9.53node2<none><none>node-exporter-wnwgt1/1Running04h40m172.29.9.52node1<none><none>prometheus-dfc9f6-l59mw1/1Running06m13s10.244.2.225node2<none><none>[root@master1 vm]#kubectl get svc -nkube-vmNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEprometheusNodePort10.103.243.22<none>9090:30832/TCP6m21s[root@master1 vm]#

img

  • 部署完成后可以通过 http:apiVersion:v1kind:ServiceAccount#创建一个ServiceAccountmetadata:name:prometheusnamespace:kube-vm---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:prometheusrules:- apiGroups:- ""resources:- nodes- services- endpoints- pods- nodes/proxyverbs:- get- list- watch- apiGroups:- "extensions"resources:- ingressesverbs:- get- list- watch- apiGroups:- ""resources:- configmaps- nodes/metricsverbs:- get- nonResourceURLs:- /metricsverbs:- get---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRoleBindingmetadata:name:prometheusroleRef:apiGroup:rbac.authorization.k8s.iokind:ClusterRolename:prometheussubjects:- kind:ServiceAccountname:prometheusnamespace:monitor- kind:ServiceAccountname:prometheusnamespace:kube-vm

这里直接在原来那个yaml里更新,或者重新创建一个就好吧。

这边可以先不创建,先当做遗留问题就好。

经测试,先不创建这个rbac资源,p8s是可以正常起来的。

哈哈,老师解惑了:

问题:我们这里是不是没配置rbac,p8s也是可以访问的呢?

答案:

因为目前只是p8s静态地去把数据抓取过来的,而不是自动发现的(不是用过apiserver去访问的)。所以现在,我们没有配置rbac是没有任何问题的。

疑问2:这里的local-storage只是一个标识而已的吧?(已解决)

img

按老师说的,这里要重新创建一个sc呀……

注意:

img

img

但是自己之前的实验这里都是没创建local-storage的sc呀……

img

img

个人预测结论:

这里的local-storage只是一个标识而已,不需要来创建。!!!

经测试:

我的k8s集群里未创建这个local-storage sc,也是可以正常使用pv/pvc的。因此,这里的storageClassName:local-storage只是一个标识而已。

img

  • 结论

storageClassName这里只是一个标识而已!!!

img

img

4.以同样的方式重新部署 Grafana
  • 先到node2节点上创建下本地目录:
bash
[root@master1 vm]#ssh node2Lastlogin:SatJul2316:14:212022frommaster1[root@node2 ~]#mkdir -p /data/k8s/grafana[root@node2 ~]#exitlogoutConnectiontonode2closed.
  • 同样的方式重新部署 Grafana,资源清单如下所示:

[root@master1 vm]#vim vm-grafana.yaml

yaml
# vm-grafana.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:grafananamespace:kube-vmspec:selector:matchLabels:app:grafanatemplate:metadata:labels:app:grafanaspec:volumes:- name:storagepersistentVolumeClaim:claimName:grafana-datacontainers:- name:grafanaimage:grafana/grafana:mainimagePullPolicy:IfNotPresentports:- containerPort:3000name:grafanasecurityContext:runAsUser:0env:- name:GF_SECURITY_ADMIN_USERvalue:admin- name:GF_SECURITY_ADMIN_PASSWORDvalue:admin321volumeMounts:- mountPath:/var/lib/grafananame:storage---apiVersion:v1kind:Servicemetadata:name:grafananamespace:kube-vmspec:type:NodePortports:- port:3000selector:app:grafana---apiVersion:v1kind:PersistentVolumemetadata:name:grafana-dataspec:accessModes:- ReadWriteOncecapacity:storage:1GistorageClassName:local-storagelocal:path:/data/k8s/grafanapersistentVolumeReclaimPolicy:RetainnodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key:kubernetes.io/hostnameoperator:Invalues:- node2---apiVersion:v1kind:PersistentVolumeClaimmetadata:name:grafana-datanamespace:kube-vmspec:accessModes:- ReadWriteOnceresources:requests:storage:1GistorageClassName:local-storage
  • 部署
bash
[root@master1 vm]#kubectl apply -f vm-grafana.yaml deployment.apps/grafanacreatedservice/grafanacreatedpersistentvolume/grafana-datacreatedpersistentvolumeclaim/grafana-datacreated
  • 查看

img

  • 同样通过 http:Lastlogin:WedMay419:51:382022frommaster1[root@node1 ~]#mkdir -p /data/k8s/vm

[root@master1 vm]#vim vm.yaml

yaml
# vm.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:victoria-metricsnamespace:kube-vmspec:selector:matchLabels:app:victoria-metricstemplate:metadata:labels:app:victoria-metricsspec:volumes:- name:storagepersistentVolumeClaim:claimName:victoria-metrics-datacontainers:- name:vmimage:victoriametrics/victoria-metrics:v1.76.1imagePullPolicy:IfNotPresentargs:- -storageDataPath=/var/lib/victoria-metrics-data- -retentionPeriod=1w#默认一个月ports:- containerPort:8428name:httpvolumeMounts:- mountPath:/var/lib/victoria-metrics-dataname:storage---apiVersion:v1kind:Service#vm还附带了一个web服务,类似于p8s的那个web界面,方便我们操作。metadata:name:victoria-metricsnamespace:kube-vmspec:type:NodePortports:- port:8428selector:app:victoria-metrics---apiVersion:v1kind:PersistentVolumemetadata:name:victoria-metrics-dataspec:accessModes:- ReadWriteOncecapacity:storage:20GistorageClassName:local-storagelocal:path:/data/k8s/vm#必须先创建这个路径persistentVolumeReclaimPolicy:RetainnodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key:kubernetes.io/hostnameoperator:Invalues:- node2---apiVersion:v1kind:PersistentVolumeClaimmetadata:name:victoria-metrics-datanamespace:kube-vmspec:accessModes:- ReadWriteOnceresources:requests:storage:20GistorageClassName:local-storage

这里我们使用 -storageDataPath参数指定了数据存储目录,然后同样将该目录进行了持久化,-retentionPeriod参数可以用来配置数据的保持周期。

  • 直接应用上面的资源清单即可。
bash
[root@master1 vm]#kubectl apply -f vm.yaml deployment.apps/victoria-metricscreatedservice/victoria-metricscreatedpersistentvolume/victoria-metrics-datacreatedpersistentvolumeclaim/victoria-metrics-datacreated[root@master1 vm]#kubectl get deploy,svc,pod -n kube-vmNAMEREADYUP-TO-DATEAVAILABLEAGEdeployment.apps/grafana1/11116hdeployment.apps/prometheus1/11117hdeployment.apps/victoria-metrics1/1115m1sNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEservice/grafanaNodePort10.102.169.155<none>3000:30868/TCP16hservice/prometheusNodePort10.103.243.22<none>9090:30832/TCP17hservice/victoria-metricsNodePort10.111.174.185<none>8428:31526/TCP5m1sNAMEREADYSTATUSRESTARTSAGEpod/grafana-bbd99dc7-gjwxk1/1Running016hpod/node-exporter-56p881/1Running021hpod/node-exporter-bjk821/1Running021hpod/node-exporter-wnwgt1/1Running021hpod/prometheus-dfc9f6-l59mw1/1Running017hpod/victoria-metrics-7b5b5d4b65-zthq91/1Running02m14s[root@master1 vm]#kubectl logs -f victoria-metrics-7b5b5d4b65-zthq9 -nkube-vm2022-07-24T01:37:50.461ZinfoVictoriaMetrics/lib/mergeset/table.go:257openingtable"/var/lib/victoria-metrics-data/indexdb/1704A027396769B6"...2022-07-24T01:37:50.462ZinfoVictoriaMetrics/lib/mergeset/table.go:292table"/var/lib/victoria-metrics-data/indexdb/1704A027396769B6"hasbeenopenedin0.001seconds;partsCount:0;blocksCount:0,itemsCount:0;sizeBytes:02022-07-24T01:37:50.463ZinfoVictoriaMetrics/app/vmstorage/main.go:113successfullyopenedstorage"/var/lib/victoria-metrics-data"in0.011seconds;partsCount:0;blocksCount:0;rowsCount:0;sizeBytes:02022-07-24T01:37:50.464ZinfoVictoriaMetrics/app/vmselect/promql/rollup_result_cache.go:111loadingrollupResultcachefrom"/var/lib/victoria-metrics-data/cache/rollupResult"...2022-07-24T01:37:50.466ZinfoVictoriaMetrics/app/vmselect/promql/rollup_result_cache.go:137loadedrollupResultcachefrom"/var/lib/victoria-metrics-data/cache/rollupResult"in0.002seconds;entriesCount:0,sizeBytes:02022-07-24T01:37:50.467ZinfoVictoriaMetrics/app/victoria-metrics/main.go:61startedVictoriaMetricsin0.015seconds2022-07-24T01:37:50.467ZinfoVictoriaMetrics/lib/httpserver/httpserver.go:91startinghttpserverathttp:2022-07-24T01:37:50.467ZinfoVictoriaMetrics/lib/httpserver/httpserver.go:92pprofhandlersareexposedathttp:apiVersion:v1kind:ConfigMapmetadata:name:prometheus-confignamespace:kube-vmdata:prometheus.yaml:|global:scrape_interval:15sscrape_timeout:15sremote_write:# 远程写入到远程 VM 存储- url:http:scrape_configs:- job_name:"nodes"static_configs:- targets:['192.168.0.109:9111','192.168.0.110:9111','192.168.0.111:9111']relabel_configs:# 通过 relabeling 从 __address__ 中提取 IP 信息,为了后面验证 VM 是否兼容 relabeling- source_labels:[__address__]regex:"(.*):(.*)"replacement:"${1}"target_label:'ip'action:replace
  • 重新更新 Prometheus 的配置资源对象:
bash
[root@master1 vm]#kubectl apply -f vm-prom-config.yaml configmap/prometheus-configconfigured# 更新后执行 reload 操作重新加载 prometheus 配置[root@master1 vm]# curl -X POST "http:Last login:Sun Jul 24 09:34:40 2022 from master1[root@node2 ~]#ll /data/k8s/vm/data/total 0drwxr-xr-x 3 root root 23 Jul 24 09:37 big-rw-r--r-- 1 root root 0 Jul 24 09:37 flock.lockdrwxr-xr-x 3 root root 23 Jul 24 09:37 small
  • 现在我们去直接将 Grafana 中的数据源地址修改成 VM 的地址:

img

修改完成后重新访问 node-exporter 的 dashboard,正常可以显示,证明 VM 是兼容的。

img

奇怪:自己这个为什没数据呢?

img

估计是这个问题……

img

img

替换了不行的,这里有问题……reload不了。

img

但是,后面又有数据了……

img

img

img

还是有一些信息的。

img

2.替换 Prometheus

上面我们将 Prometheus 数据远程写入到了 VM,但是 Prometheus 开启 remote write 功能后会增加其本身的资源占用。理论上其实我们也可以完全用 VM 来替换掉 Prometheus,这样就不需要远程写入了,而且本身 VM 就比 Prometheus 占用更少的资源。

  • 现在我们先停掉 Prometheus 的服务:
bash
[root@master1 vm]#kubectl scale deployment prometheus --replicas=0-nkube-vmdeployment.apps/prometheusscaled
  • 然后将 Prometheus 的配置文件挂载到 VM 容器中,使用参数 -promscrape.config来指定 Prometheus 的配置文件路径,如下所示:

[root@master1 vm]#pwd

/root/vm

[root@master1 vm]#ls

vm-grafana.yaml vm-node-exporter.yaml vm-prom-config.yaml vm-prom-deploy.yaml vm-prom-pvc.yaml vm.yaml

[root@master1 vm]#vim vm.yaml

yaml
# vm.yaml#本次新增内容如下:apiVersion:apps/v1kind:Deploymentmetadata:name:victoria-metricsnamespace:kube-vmspec:selector:matchLabels:app:victoria-metricstemplate:metadata:labels:app:victoria-metricsspec:volumes:- name:storagepersistentVolumeClaim:claimName:victoria-metrics-data- name:prometheus-configconfigMap:#这里使用ConfigMapname:prometheus-configcontainers:- name:vmimage:victoriametrics/victoria-metrics:v1.76.1imagePullPolicy:IfNotPresentargs:- -storageDataPath=/var/lib/victoria-metrics-data- -retentionPeriod=1w- -promscrape.config=/etc/prometheus/prometheus.yaml#这里将prometheus.yaml 挂载进来ports:- containerPort:8428name:httpvolumeMounts:- mountPath:/var/lib/victoria-metrics-dataname:storage- mountPath:/etc/prometheus#挂载路径name:prometheus-config

完整代码如下:

yaml
cat vm.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:victoria-metricsnamespace:kube-vmspec:selector:matchLabels:app:victoria-metricstemplate:metadata:labels:app:victoria-metricsspec:volumes:- name:storagepersistentVolumeClaim:claimName:victoria-metrics-data- name:prometheus-configconfigMap:#这里使用ConfigMapname:prometheus-configcontainers:- name:vmimage:victoriametrics/victoria-metrics:v1.76.1imagePullPolicy:IfNotPresentargs:- -storageDataPath=/var/lib/victoria-metrics-data- -retentionPeriod=1w- -promscrape.config=/etc/prometheus/prometheus.yaml#这里将prometheus.yaml 挂载进来ports:- containerPort:8428name:httpvolumeMounts:- mountPath:/var/lib/victoria-metrics-dataname:storage- mountPath:/etc/prometheus#挂载路径name:prometheus-config---apiVersion:v1kind:Service#vm还附带了一个web服务,类似于p8s的那个web界面,方便我们操作。metadata:name:victoria-metricsnamespace:kube-vmspec:type:NodePortports:- port:8428selector:app:victoria-metrics---apiVersion:v1kind:PersistentVolumemetadata:name:victoria-metrics-dataspec:accessModes:- ReadWriteOncecapacity:storage:20GistorageClassName:local-storagelocal:path:/data/k8s/vm#必须先创建这个路径persistentVolumeReclaimPolicy:RetainnodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key:kubernetes.io/hostnameoperator:Invalues:- node2---apiVersion:v1kind:PersistentVolumeClaimmetadata:name:victoria-metrics-datanamespace:kube-vmspec:accessModes:- ReadWriteOnceresources:requests:storage:20GistorageClassName:local-storage
  • 记得先将 Prometheus 配置文件中的 remote_write 模块去掉:

[root@master1 vm]#ls

vm-grafana.yaml vm-node-exporter.yaml vm-prom-config.yaml vm-prom-deploy.yaml vm-prom-pvc.yaml vm.yaml

[root@master1 vm]#vim vm-prom-config.yaml

img

bash
[root@master1 vm]#kubectl delete -f vm-prom-config.yaml configmap"prometheus-config"deleted[root@master1 vm]#kubectl apply -f vm-prom-config.yaml configmap/prometheus-configcreated
  • 更新vm部署文件:
bash
[root@master1 vm]#kubectl apply -f vm-prom-config.yaml configmap/prometheus-configconfigerd[root@master1 vm]#kubectl delete -f vm.yaml deployment.apps"victoria-metrics"deletedservice"victoria-metrics"deletedpersistentvolume"victoria-metrics-data"deletedpersistentvolumeclaim"victoria-metrics-data"deleted[root@master1 vm]#kubectl apply -f vm.yamldeployment.apps/victoria-metricscreatedservice/victoria-metricscreatedpersistentvolume/victoria-metrics-datacreatedpersistentvolumeclaim/victoria-metrics-datacreated[root@master1 vm]#kubectl get pods -n kube-vm -l app=victoria-metricsNAMEREADYSTATUSRESTARTSAGEvictoria-metrics-8466844968-s9slx1/1Running035s[root@master1 vm]#kubectl logs victoria-metrics-8466844968-s9slx -nkube-vm......2022-07-24T03:10:29.799ZinfoVictoriaMetrics/app/victoria-metrics/main.go:61startedVictoriaMetricsin0.021seconds2022-07-24T03:10:29.799ZinfoVictoriaMetrics/lib/httpserver/httpserver.go:91startinghttpserverathttp:2022-07-24T03:10:29.799ZinfoVictoriaMetrics/lib/httpserver/httpserver.go:92pprofhandlersareexposedathttp:2022-07-24T03:10:29.799ZinfoVictoriaMetrics/lib/promscrape/scraper.go:103readingPrometheusconfigsfrom"/etc/prometheus/prometheus.yaml"2022-07-24T03:10:29.800ZinfoVictoriaMetrics/lib/promscrape/config.go:96startingservicediscoveryroutines...2022-07-24T03:10:29.800ZinfoVictoriaMetrics/lib/promscrape/config.go:102startedservicediscoveryroutinesin0.000seconds2022-07-24T03:10:29.800ZinfoVictoriaMetrics/lib/promscrape/scraper.go:395static_configs:addedtargets:3,removedtargets:0;totaltargets:3

从 VM 日志中可以看出成功读取了 Prometheus 的配置,并抓取了 3 个指标(node-exporter)。

  • 现在我们再去 Grafana 查看 node-exporter 的 Dashboard 是否可以正常显示。先保证数据源是 VM 的地址。

img

img

这样我们就使用 VM 替换掉了 Prometheus,我们也可以这 Grafana 的 Explore 页面去探索采集到的指标。

img

3.UI 界面

VM 单节点版本本身自带了一个 Web UI 界面 - vmui,不过目前功能比较简单。

  • 可以直接通过 VM 的 NodePort 端口进行访问。
bash
[root@master1 ~]#kubectl get svc -nkube-vmNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEgrafanaNodePort10.102.169.155<none>3000:30868/TCP21hprometheusNodePort10.103.243.22<none>9090:30832/TCP22hvictoria-metricsNodePort10.103.196.207<none>8428:30458/TCP3h33m

我们这里可以通过 http:apiVersion:v1kind:ConfigMapmetadata:name:promxy-confignamespace:kube-vmdata:config.yaml:|promxy:server_groups:- static_configs:- targets:[victoria-metrics:8428] # 指定vm地址,有多个则往后追加即可path_prefix:/prometheus # 配置前缀---apiVersion:apps/v1kind:Deploymentmetadata:name:promxynamespace:kube-vmspec:selector:matchLabels:app:promxytemplate:metadata:labels:app:promxyspec:containers:- args:- "--config=/etc/promxy/config.yaml"- "--web.enable-lifecycle"- "--log-level=trace"env:- name:ROLEvalue:"1"command:- "/bin/promxy"image:quay.io/jacksontj/promxyimagePullPolicy:Alwaysname:promxyports:- containerPort:8082name:webvolumeMounts:- mountPath:"/etc/promxy/"name:promxy-configreadOnly:true- args:# container to reload configs on configmap change 这个需要特别注意下哦,是一个sidecar容器。- "--volume-dir=/etc/promxy"- "--webhook-url=http:image:jimmidyson/configmap-reload:v0.1name:promxy-server-configmap-reloadvolumeMounts:- mountPath:"/etc/promxy/"name:promxy-configreadOnly:truevolumes:- configMap:name:promxy-configname:promxy-config---apiVersion:v1kind:Servicemetadata:name:promxynamespace:kube-vmspec:type:NodePortports:- port:8082selector:app:promxy

  • 直接应用上面的资源对象即可:
bash
[root@master1 vm]#kubectl apply -f vm-promxy.yaml configmap/promxy-configcreateddeployment.apps/promxycreatedservice/promxycreated[root@master1 vm]#kubectl get pods -n kube-vm -l app=promxyNAMEREADYSTATUSRESTARTSAGEpromxy-5f7dfdbc64-82cr62/2Running034s[root@master1 vm]#kubectl get svc promxy -n kube-vmNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEpromxyNodePort10.97.84.86<none>8082:32380/TCP52s
  • 访问 Promxy 的页面效果和 Prometheus 自带的 Web UI 基本一致的。

img

这里面我们简单介绍了单机版的 victoriametrics的基本使用。

额额,我这里又报这个错误了……

img

估计是这里的问题:

img

  • 这里修改下,再次测试下

[root@master1 vm]#vim vm-promxy.yaml

img

bash
[root@master1 vm]#kubectl apply -f vm-promxy.yaml configmap/promxy-configconfigureddeployment.apps/promxyunchangedservice/promxyunchanged

img

(修改后果然好了。。。。)🤣

  • 这里是有点不一样,其他都差不多

img

测试结束。😘

2、集群版

img

对于低于每秒一百万个数据点的摄取率,建议使用单节点版本而不是集群版本。单节点版本可根据 CPU 内核、RAM 和可用存储空间的数量进行扩展。单节点版本比集群版本更容易配置和操作,所以在使用集群版本之前要三思而后行。上面我们介绍了 VM 的单节点版本的基本使用,接下来我们来介绍下如何使用集群版。

集群版主要特点

  • 支持单节点版本的所有功能。
  • 性能和容量水平扩展。
  • 支持时间序列数据的多个独立命名空间(多租户)。
  • 支持多副本。

组件服务

前面我们了解了 VM 的基本架构,对于集群模式下主要包含以下几个服务:

  • vmstorage:存储原始数据并返回指定标签过滤器在给定时间范围内的查询数据,当 -storageDataPath指向的目录包含的可用空间少于 -storage.minFreeDiskSpaceBytes时,vmstorage节点会自动切换到只读模式vminsert节点也会停止向此类节点发送数据并开始将数据重新路由到剩余的 vmstorage节点。
  • vminsert:接受摄取的数据并根据指标名称及其所有标签的一致性哈希将其分散存储到 vmstorage节点。
  • vmselect:通过从所有配置的 vmstorage节点获取所需数据来执行查询。

每个服务都可以进行独立扩展,vmstorage节点之间互不了解、互不通信,并且不共享任何数据。这样可以增加集群的可用性,并且简化了集群的维护和扩展。

最小集群必须包含以下节点:

  • 带有 -retentionPeriod(最小数据保留时间)-storageDataPath参数的单 vmstorage节点
  • 带有 -storageNode=<vmstorage_host>的单 vminsert节点
  • 带有 -storageNode=<vmstorage_host>的单 vmselect节点

但是我们建议为每个服务组件运行至少两个节点以实现高可用性,这样当单个节点暂时不可用时,集群会继续工作,而且其余节点还可以处理增加的工作负载。如果你的集群规模较大,那么可以运行多个小型的 vmstorage节点,因为这样可以在某些 vmstorage节点暂时不可用时减少剩余 vmstorage节点上的工作负载增加。

各个服务除了可以通过参数标志进行配置之外,也可以通过环境变量的方式进行配置:

  • -envflag.enable标志必须设置
  • 每个标志中的 .必须替换为 _,例如 -insert.maxQueueDuration <duration>可以转换为 insert_maxQueueDuration=<duration>
  • 对于重复的标志,可以使用另一种语法,通过使用 ,作为分隔符将不同的值连接成一个,例如 -storageNode <nodeA>-storageNode <nodeB>将转换为 -storageNode=<nodeA>,<nodeB>
  • 可以使用 -envflag.prefix为环境变量设置前缀,例如设置了 -envflag.prefix=VM*,则环境变量参数必须以 VM*开头

多租户

此外 VM 集群也支持多个独立的租户(也叫命名空间),租户由 accountIDaccountID:projectID来标识,它们被放在请求的 urls 中。

  • 每个 accountIDprojectID都由一个 [0 .. 2^32] 范围内的任意 32 位整数标识,如果缺少 projectID,则自动将其分配为 0。有关租户的其他信息,例如身份验证令牌、租户名称、限额、计费等,将存储在一个单独的关系型数据库中。此数据库必须由位于 VictoriaMetrics 集群前面的单独服务管理,例如 vmauthvmgateway
  • 当第一个数据点写入指定租户时,租户被自动创建。
  • 所有租户的数据均匀分布在可用的 vmstorage节点中,当不同租户有不同的数据量和不同的查询负载时,这保证了 vmstorage节点之间的均匀负载。
  • 数据库性能和资源使用不依赖于租户的数量,它主要取决于所有租户中活跃时间序列的总数。如果一个时间序列在过去一小时内至少收到一个样本,或者在过去一小时内被查询,则认为时间序列是活跃的。
  • VictoriaMetrics 不支持在单个请求中查询多个租户。

集群大小调整和可扩展性

VM 集群的性能和容量可以通过两种方式进行扩展:

  • 通过向集群中的现有节点添加更多资源(CPU、RAM、磁盘 IO、磁盘空间、网络带宽),也叫垂直可扩展性。
  • 通过向集群添加更多节点,又叫水平扩展性。

对于集群扩展有一些通用的建议:

  • 向现有 vmselect节点添加更多 CPU 和内存,可以提高复杂查询的性能,这些查询可以处理大量的时间序列和大量的原始样本。
  • 添加更多 vmstorage节点可以增加集群可以处理的活跃时间序列的数量,这也提高了对高流失率(churn rate)的时间序列的查询性能。集群稳定性也会随着 vmstorage节点数量的增加而提高,当一些 vmstorage节点不可用时,活跃的 vmstorage节点需要处理较低的额外工作负载。
  • 向现有 vmstorage节点添加更多 CPU 和内存,可以增加集群可以处理的活跃时间序列的数量。与向现有 vmstorage节点添加更多 CPU 和内存相比,最好添加更多 vmstorage节点,因为更多的 vmstorage节点可以提高集群稳定性,并提高对高流失率的时间序列的查询性能。
  • 添加更多的 vminsert节点会提高数据摄取的最大速度,因为摄取的数据可以在更多的 vminsert节点之间进行拆分。
  • 添加更多的 vmselect节点可以提高查询的最大速度,因为传入的并发请求可能会在更多的 vmselect节点之间进行拆分。

集群可用性

  • HTTP 负载均衡器需要停止将请求路由到不可用的 vminsertvmselect节点。
  • 如果至少存在一个 vmstorage节点,则集群仍然可用:
    • vminsert将传入数据从不可用的 vmstorage节点重新路由到健康的 vmstorage节点
    • 如果至少有一个 vmstorage节点可用,则 vmselect会继续提供部分响应。如果优先考虑可用性的一致性,则将 -search.denyPartialResponse标志传递给 vmselect或将请求中的 deny_partial_response=1查询参数传递给 vmselect

重复数据删除

如果 -dedup.minScrapeInterval命令行标志设置为大于 0 的时间,VictoriaMetrics 会去除重复数据点。例如,-dedup.minScrapeInterval=60s将对同一时间序列上的数据点进行重复数据删除,如果它们位于同一离散的 60 秒存储桶内,最早的数据点将被保留。在时间戳相等的情况下,将保留任意数据点。

-dedup.minScrapeInterval的推荐值是等于 Prometheus 配置中的 scrape_interval的值,建议在所有抓取目标中使用一个 scrape_interval配置。

如果 HA 中多个相同配置的 vmagent或 Prometheus 实例将数据写入同一个 VictoriaMetrics 实例,则重复数据删除会减少磁盘空间使用。这些 vmagent或 Prometheus 实例在其配置中必须具有相同的 external_labels部分,因此它们将数据写入相同的时间序列。

容量规划

根据我们的案例研究,与竞争解决方案(Prometheus、Thanos、Cortex、TimescaleDB、InfluxDB、QuestDB、M3DB)相比,VictoriaMetrics 在生产工作负载上使用的 CPU、内存和存储空间更少。

每种节点类型 - vminsertvmselectvmstorage都可以在最合适的硬件上运行。集群容量随着可用资源的增加而线性扩展。每个节点类型所需的 CPU 和内存数量很大程度上取决于工作负载 - 活跃时间序列的数量、序列流失率、查询类型、查询 qps 等。建议为你的生产工作负载部署一个测试的 VictoriaMetrics 集群,并反复调整每个节点的资源和每个节点类型的节点数量,直到集群变得稳定。同样也建议为集群设置监控,有助于确定集群设置中的瓶颈问题。

指定保留所需的存储空间(可以通过 vmstorage中的 -retentionPeriod命令行标志设置)可以从测试运行中的磁盘空间使用情况推断出来。例如,如果在生产工作负载上运行一天后的存储空间使用量为 10GB,那么对于 -retentionPeriod=100d(100 天保留期)来说,它至少需要 10GB*100=1TB的磁盘空间。可以使用 VictoriaMetrics 集群的官方 Grafana 仪表板监控存储空间使用情况。

img

img

img

建议留出以下数量的备用资源。

  • 所有节点类型中 50% 的空闲内存,以减少工作负载临时激增时因为 OOM 崩溃的可能性。
  • 所有节点类型中 50% 的空闲 CPU,以减少工作负载临时高峰期间的慢速概率。
  • vmstorage节点上 -storageDataPath命令行标志指向的目录中至少有 30%的可用存储空间。

VictoriaMetrics 集群的一些容量规划技巧:

  • 副本集将集群所需的资源量最多增加 N 倍,其中 N 是复制因子。
  • 可以通过添加更多 vmstorage节点和/或通过增加每个 vmstorage节点的内存和 CPU 资源来增加活跃时间序列的集群容量。
  • 可以通过增加 vmstorage节点的数量和/或通过增加每个 vmselect节点的内存和 CPU 资源来减少查询延迟。
  • 所有 vminsert节点所需的 CPU 内核总数可以通过摄取率计算:CPUs =ingestion_rate / 100K
  • vminsert节点上的 -rpc.disableCompression命令行标志可以增加摄取容量,但代价是 vminsertvmstorage之间的网络带宽使用率会更高。

复制和数据安全

默认情况下,VictoriaMetrics 的数据复制依赖 -storageDataPath指向的底层存储来完成。

但是我们也可以手动通过将 -replicationFactor=N命令参数传递给 vminsert来启用复制,这保证了如果多达 N-1vmstorage节点不可用,所有数据仍可用于查询。集群必须至少包含 2*N-1vmstorage节点,其中 N是复制因子,以便在 N-1个存储节点丢失时为新摄取的数据维持指定的复制因子。

例如,当 -replicationFactor=3传递给 vminsert时,它将所有摄取的数据复制到 3 个不同的 vmstorage节点,因此最多可以丢失 2 个 vmstorage节点而不会丢失数据。vmstorage节点的最小数量应该等于 2*3-1 =5,因此当 2 个 vmstorage节点丢失时,剩余的 3 个 vmstorage节点可以为新摄取的数据提供服务。

启用复制后,必须将 -dedup.minScrapeInterval=1ms命令行标志传递给 vmselect节点,当多达 N-1vmstorage节点响应缓慢和/或暂时不可用时,可以将可选的 -replicationFactor=N参数传递给 vmselect以提高查询性能,因为 vmselect不等待来自多达 N-1vmstorage节点的响应。有时,vmselect节点上的 -replicationFactor可能会导致部分响应。-dedup.minScrapeInterval=1ms在查询期间对复制的数据进行重复数据删除,如果重复数据从配置相同的 vmagent实例或 Prometheus 实例推送到 VictoriaMetrics,则必须根据重复数据删除文档将 -dedup.minScrapeInterval设置为更大的值。 请注意,复制不会从灾难中保存,因此建议执行定期备份。另外 复制会增加资源使用率 - CPU、内存、磁盘空间、网络带宽 - 最多 -replicationFactor倍。所以可以将复制转移 -storageDataPath指向的底层存储来做保证,例如 Google Compute Engine 永久磁盘,该磁盘可以防止数据丢失和数据损坏,它还提供始终如一的高性能,并且可以在不停机的情况下调整大小。对于大多数用例来说,基于 HDD 的永久性磁盘应该足够了。

备份

建议从即时快照执行定期备份,以防止意外数据删除等错误。必须为每个 vmstorage节点执行以下步骤来创建备份:

通过导航到/snapshot/create HTTP handler 来创建一个即时快照。它将创建快照并返回其名称。

  • 可以通过访问 /snapshot/create这个 HTTP handler 来创建即时快照,它将创建快照并返回其名称。
  • 使用 vmbackup组件从 <-storageDataPath>/snapshots/<snapshot_name>文件夹归档创建的快照。归档过程不会干扰 vmstorage工作,因此可以在任何合适的时间执行。
  • 通过 /snapshot/delete?snapshot=<snapshot_name>/snapshot/delete_all删除未使用的快照,以释放占用的存储空间。
  • 无需在所有 vmstorage节点之间同步备份。

从备份恢复:

  • 使用 kill -INT停止 vmstorage节点。
  • 使用 vmrestore组件将备份中的数据还原到 -storageDataPath目录。
  • 启动 vmstorage节点。

在了解了 VM 集群的一些配置细节后,接下来我们就来开始部署 VM 集群。

部署

💘 实战:VictoriaMetrics集群版部署(测试成功)-2022.8.13

如果你已经对 VM 组件非常了解了,那么推荐使用 Helm Chart 的方式进行一键安装。

bash
helmrepoaddvmhttps:helmrepoupdate# 导出默认的 values 值到 values.yaml 文件中helmshowvaluesvm/victoria-metrics-cluster>values.yaml# 根据自己的需求修改 values.yaml 文件配置# 执行下面的命令进行一键安装helminstallvictoria-metricsvm/victoria-metrics-cluster-fvalues.yaml-nNAMESPACE# 获取 vm 运行的 pods 列表kubectlgetpods-A|grep'victoria-metrics'

我们这里选择手动方式进行部署,之所以选择手动部署的方式是为了能够了解各个组件的更多细节。

实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:apiVersion:v1kind:Servicemetadata:name:cluster-vmstoragenamespace:kube-vmlabels:app:vmstoragespec:clusterIP:None#因为你是一个Statefulset,所以要用一个headless无头服务来着的ports:- port:8482targetPort:httpname:http- port:8401targetPort:vmselectname:vmselect- port:8400targetPort:vminsertname:vminsertselector:app:vmstorage---apiVersion:apps/v1kind:StatefulSetmetadata:name:vmstoragenamespace:kube-vmlabels:app:vmstoragespec:serviceName:cluster-vmstorageselector:matchLabels:app:vmstoragereplicas:2podManagementPolicy:OrderedReady#这个是什么??template:metadata:labels:app:vmstoragespec:containers:- name:vmstorageimage:"victoriametrics/vmstorage:v1.77.0-cluster"imagePullPolicy:"IfNotPresent"args:- "--retentionPeriod=1"#默认也是1个月- "--storageDataPath=/storage"- --envflag.enable=true- --envflag.prefix=VM_- --loggerFormat=jsonports:- name:http#storage暴露的api接口containerPort:8482- name:vminsertcontainerPort:8400- name:vmselectcontainerPort:8401livenessProbe:failureThreshold:10initialDelaySeconds:30periodSeconds:30tcpSocket:port:httptimeoutSeconds:5readinessProbe:failureThreshold:3initialDelaySeconds:5periodSeconds:15timeoutSeconds:5httpGet:path:/healthport:httpvolumeMounts:- name:storagemountPath:/storagevolumeClaimTemplates:#因为你是一个无状态,所以这里要使用volumeClaimTemplates- metadata:name:storagespec:storageClassName:longhorn#裂了,那我的k8s环境还要再部署一遍longhorn环境喽…… 后面自己已经部署好了longhorn环境了accessModes:- ReadWriteOnceresources:requests:storage:"2Gi"

首先需要创建一个 Headless 的 Service,因为后面的组件需要访问到每一个具体的 Pod,在 vmstorage 启动参数中通过 --retentionPeriod参数指定指标数据保留时长,1 表示一个月,这也是默认的时长,然后通过 --storageDataPath参数指定了数据存储路径,记得要将该目录进行持久化。

  • 这里使用nfs存储类也是可以的哈:

img

或者,当然你用OpenDBs去做一个LocalPV的自动创建也是可以的哈。😢

  • 同样直接应用该资源即可:
bash
#[root@master1 vm-cluster]#kubectl apply -f cluster-vmstorage.yaml service/cluster-vmstoragecreatedstatefulset.apps/vmstoragecreated[root@master1 vm-cluster]#kubectl get pods -n kube-vm -l app=vmstorage-owideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESvmstorage-01/1Running06m7s10.244.2.70node2<none><none>vmstorage-11/1Running02m22s10.244.2.71node2<none><none>[root@master1 vm-cluster]#kubectl get svc -n kube-vm -l app=vmstorageNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEcluster-vmstorageClusterIPNone<none>8482/TCP,8401/TCP,8400/TCP10m
2、部署vmselect 组件

接着可以部署 vmselect 组件,由于该组件是无状态的,我们可以直接使用 Deployment 来进行管理,对应的资源清单文件如下所示:

[root@master1 vm-cluster]#vim cluster-vmselect.yaml

yaml
# cluster-vmselect.yamlapiVersion:v1kind:Servicemetadata:name:vmselectnamespace:kube-vmlabels:app:vmselectspec:ports:- name:httpport:8481targetPort:httpselector:app:vmselect---apiVersion:apps/v1kind:Deploymentmetadata:name:vmselectnamespace:kube-vmlabels:app:vmselectspec:selector:matchLabels:app:vmselecttemplate:metadata:labels:app:vmselectspec:containers:- name:vmselectimage:"victoriametrics/vmselect:v1.77.0-cluster"imagePullPolicy:"IfNotPresent"args:- "--cacheDataPath=/cache"- --storageNode=vmstorage-0.cluster-vmstorage.kube-vm.svc.cluster.local:8401- --storageNode=vmstorage-1.cluster-vmstorage.kube-vm.svc.cluster.local:8401- --envflag.enable=true- --envflag.prefix=VM_- --loggerFormat=jsonports:- name:httpcontainerPort:8481readinessProbe:httpGet:path:/healthport:httpinitialDelaySeconds:5periodSeconds:15timeoutSeconds:5failureThreshold:3livenessProbe:tcpSocket:port:httpinitialDelaySeconds:5periodSeconds:15timeoutSeconds:5failureThreshold:3volumeMounts:- mountPath:/cachename:cache-volumevolumes:- name:cache-volumeemptyDir:{}

其中最重要的部分是通过 --storageNode参数指定所有的 vmstorage 节点地址,上面我们使用的 StatefulSet 部署的,所以可以直接使用 FQDN 的形式进行访问。直

  • 接着应用上面的对象:
bash
[root@master1 vm-cluster]#kubectl apply -f cluster-vmselect.yamlservice/vmselectcreateddeployment.apps/vmselectcreated[root@master1 vm-cluster]#kubectl get pods -n kube-vm -l app=vmselect-owideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESvmselect-bcb54965f-kq49c1/1Running02m51s10.244.1.181node1<none><none>[root@master1 vm-cluster]#kubectl get svc -n kube-vm -l app=vmselectNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEvmselectClusterIP10.100.142.147<none>8481/TCP3m8s
3、部署vminsert 组件

接着就需要部署用来接收指标数据插入的 vminsert 组件,同样该组件是无状态的,其中最重要的也是需要通过 --storageNode参数指定所有的 vmstorage 节点:

[root@master1 vm-cluster]#vim cluster-vminsert.yaml

yaml
# cluster-vminsert.yamlapiVersion:v1kind:Servicemetadata:name:vminsertnamespace:kube-vmlabels:app:vminsertspec:ports:- name:httpport:8480targetPort:httpselector:app:vminsert---apiVersion:apps/v1kind:Deploymentmetadata:name:vminsertnamespace:kube-vmlabels:app:vminsertspec:selector:matchLabels:app:vminserttemplate:metadata:labels:app:vminsertspec:containers:- name:vminsertimage:"victoriametrics/vminsert:v1.77.0-cluster"imagePullPolicy:"IfNotPresent"args:- --storageNode=vmstorage-0.cluster-vmstorage.kube-vm.svc.cluster.local:8400- --storageNode=vmstorage-1.cluster-vmstorage.kube-vm.svc.cluster.local:8400- --envflag.enable=true- --envflag.prefix=VM_- --loggerFormat=jsonports:- name:httpcontainerPort:8480readinessProbe:httpGet:path:/healthport:httpinitialDelaySeconds:5periodSeconds:15timeoutSeconds:5failureThreshold:3livenessProbe:tcpSocket:port:httpinitialDelaySeconds:5periodSeconds:15timeoutSeconds:5failureThreshold:3

由于本身是无状态的,所以可以根据需要增加副本数量,也可以配置 HPA 进行自动扩缩容。

  • 直接应用上面的资源清单:
bash
[root@master1 vm-cluster]#kubectl apply -f cluster-vminsert.yamlservice/vminsertcreateddeployment.apps/vminsertcreated[root@master1 vm-cluster]#kubectl get pods -n kube-vm -l app=vminsertNAMEREADYSTATUSRESTARTSAGEvminsert-66c88cd497-6wg2l1/1Running010m[root@master1 vm-cluster]#kubectl get svc -n kube-vm -l app=vminsertNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEvminsertClusterIP10.98.142.18<none>8480/TCP11m
4、配置Prometheus的remote_write

集群模式的相关组件部署完成后。

我们看下当前k8s环境,因为上次实验我们已经用vm单节点替代了prometheus了:

img

  • 先停掉vm单节点,将prometheus实例恢复过来
bash
[root@master1 vm]#kubectl scale deploy victoria-metrics --replicas=0-nkube-vmdeployment.apps/victoria-metricsscaled[root@master1 vm]#kubectl scale deploy prometheus --replicas=1-nkube-vmdeployment.apps/prometheusscaled
  • 同样我们可以先去配置前面的 Prometheus,将其数据远程写入到 VM 中来,修改 remote_write的地址为 http:apiVersion:v1kind:ConfigMapmetadata:name:prometheus-confignamespace:kube-vmdata:prometheus.yaml:|global:scrape_interval:15sscrape_timeout:15sremote_write:# 写入到远程 VM 存储,url 是远程写入接口地址- url:http:# queue_config:# 如果 Prometheus 抓取指标很大,可以加调整 queue,但是会提高内存占用# max_samples_per_send:10000 # 每次发送的最大样本数# capacity:20000# max_shards:30 # 最大分片数,即并发量。scrape_configs:- job_name:"nodes"static_configs:- targets:['172.29.9.51:9111','172.29.9.52:9111','172.29.9.53:9111']relabel_configs:# 通过 relabeling 从 __address__ 中提取 IP 信息,为了后面验证 VM 是否兼容 relabeling- source_labels:[__address__]regex:"(.*):(.*)"replacement:"${1}"target_label:'ip'action:replace
  • 更新 Prometheus 配置
bash
[root@master1 vm]#kubectl apply -f vm-prom-config3.yamlconfigmap/prometheus-configconfigured[root@master1 vm]#curl -X POST "http:......{"ts":"2022-05-06T08:35:15.786Z","level":"info","caller":"VictoriaMetrics/lib/storage/partition.go:206","msg":"creating a partition \"2022_05\"with smallPartsPath=\"/storage/data/small/2022_05\",bigPartsPath=\"/storage/data/big/2022_05\""}{"ts":"2022-05-06T08:35:15.802Z","level":"info","caller":"VictoriaMetrics/lib/storage/partition.go:222","msg":"partition \"2022_05\"has been created"}
  • 然后可以去 Grafana 重新查看 Dashboard 是否正常:

img

测试结束。😘

6、新增 vmstorage节点的方法

如果现在需要新增 vmstorage节点,那么需要按照下面的步骤进行操作:

  • 使用与集群中现有节点相同的 -retentionPeriod配置启动新的 vmstorage节点。
  • 逐步重新启动所有的 vmselect节点,添加新的 -storageNode参数包含 <new_vmstorage_host>
  • 逐步重新启动所有的 vminsert节点,添加新的 -storageNode参数包含 <new_vmstorage_host>
注意事项

🍀 又是老问题了:

grafna那里配置数据源,一直有问题……

img

img

因此:我把这个vmselect用NodePort类型的服务暴露出去,再使用nodeIP:nodePort来访问就可以了……

img

使用nodeIP:nodePort来访问:

img

img

此时,grafna上就可以正常访问了:

img

3、vmagent

img

1.vmagent

vmagent --就是帮我们去抓取指标的。

vmagent 可以帮助我们从各种来源收集指标并将它们存储到 VM 或者任何其他支持 remote write 协议的 Prometheus 兼容的存储系统中。vmagent 相比于 Prometheus 抓取指标来说具有更多的灵活性,比如除了拉取(pull)指标还可以推送(push)指标,此外还有很多其他特性:

  • 可以替换 prometheus 的 scraping target
  • 支持从 Kafka 读写数据
  • 支持基于 prometheus relabeling 的模式添加、移除、修改 labels,可以在数据发送到远端存储之前进行数据的过滤
  • 支持多种数据协议,influx line 协议,graphite 文本协议,opentsdb 协议,prometheus remote write 协议,json lines 协议,csv 数据等
  • 支持收集数据的同时,并复制到多种远端存储系统
  • 支持不可靠远端存储,如果远程存储不可用,收集的指标会在 -remoteWrite.tmpDataPath缓冲,一旦与远程存储的连接被修复,缓冲的指标就会被发送到远程存储,缓冲区的最大磁盘用量可以用 -remoteWrite.maxDiskUsagePerURL来限制。
  • 相比 prometheus 使用更少的内存、cpu、磁盘 io 以及网络带宽
  • 当需要抓取大量目标时,抓取目标可以分散到多个 vmagent 实例中
  • 可以通过在抓取时间和将其发送到远程存储系统之前限制唯一时间序列的数量来处理高基数和高流失率问题
  • 可以从多个文件中加载 scrape 配置

img

接下来我们以抓取 Kubernetes 集群指标为例说明如何使用 vmagent,我们这里使用自动发现的方式来进行配置。vmagent 是兼容 prometheus 中的 kubernetes_sd_configs配置的,所以我们同样可以使用。

2.部署

💘 实战:vmagent部署(测试成功)-2022.8.14

img

实验环境
bash
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:apiVersion:v1kind:ServiceAccountmetadata:name:vmagentnamespace:kube-vm---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:vmagentrules:- apiGroups:["","networking.k8s.io","extensions"]resources:- nodes- nodes/metrics- services- endpoints- endpointslices- pods- app- ingressesverbs:["get","list","watch"]- apiGroups:[""]resources:- namespaces- configmapsverbs:["get"]- nonResourceURLs:["/metrics","/metrics/resources"]verbs:["get"]---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRoleBindingmetadata:name:vmagentroleRef:apiGroup:rbac.authorization.k8s.iokind:ClusterRolename:vmagentsubjects:- kind:ServiceAccountname:vmagentnamespace:kube-vm

部署:

bash
[root@master1 vm-agent]#kubectl apply -f vmagent-rbac.yaml serviceaccount/vmagentcreatedclusterrole.rbac.authorization.k8s.io/vmagentcreatedclusterrolebinding.rbac.authorization.k8s.io/vmagentcreat
2、添加 vmagent 配置
  • 然后添加 vmagent 配置,我们先只配置自动发现 Kubernetes 节点的任务,创建如下所示的 ConfigMap 对象:

vim vmagent-config.yaml

yaml
# vmagent-config.yamlapiVersion:v1kind:ConfigMapmetadata:name:vmagent-confignamespace:kube-vmdata:scrape.yml:|global:scrape_interval:15sscrape_timeout:15sscrape_configs:- job_name:nodeskubernetes_sd_configs:- role:noderelabel_configs:- source_labels:[__address__]regex:"(.*):10250"replacement:"${1}:9111"target_label:__address__action:replace- action:labelmapregex:__meta_kubernetes_node_label_(.+)

这里我们通过自动发现 Kubernetes 节点获取节点监控指标,需要注意 node这种 role 的自动发现默认获取的是节点的 10250端口,这里我们需要通过 relabel将其 replace9111

部署:

bash
[root@master1 vm-agent]#kubectl apply -f vmagent-config.yaml configmap/vmagent-configcreated

注意:

如果是单个vmagent实例,用deployment也是可以的,本次使用后面的StatefuleSet来部署(多个vmagent实例)。

然后添加 vmagent 部署资源清单,如下所示:

yaml
# vmagent-deploy.yamlapiVersion:v1kind:PersistentVolumeClaimmetadata:name:vmagent-pvcnamespace:kube-vmspec:accessModes:- ReadWriteOnceresources:requests:storage:1GistorageClassName:nfs-client---apiVersion:apps/v1kind:Deploymentmetadata:name:vmagentnamespace:kube-vmlabels:app:vmagentspec:selector:matchLabels:app:vmagenttemplate:metadata:labels:app:vmagentspec:serviceAccountName:vmagentcontainers:- name:agentimage:"victoriametrics/vmagent:v1.77.0"imagePullPolicy:IfNotPresentargs:- -promscrape.config=/config/scrape.yml- -remoteWrite.tmpDataPath=/tmpData- -remoteWrite.url=http:- -envflag.enable=true- -envflag.prefix=VM_- -loggerFormat=jsonports:- name:httpcontainerPort:8429volumeMounts:- name:tmpdatamountPath:/tmpData- name:configmountPath:/configvolumes:- name:tmpdatapersistentVolumeClaim:claimName:vmagent-pvc- name:configconfigMap:name:vmagent-config

我们将 vmagent 配置通过 ConfigMap 挂载到容器 /config/scrape.yml,另外通过 -remoteWrite.url=http:vmagent-promscrape.cluster.membersCount=2-promscrape.cluster.memberNum=1-promscrape.config=/path/config.yml...

当 vmagent 在 Kubernetes 中运行时,可以将 -promscrape.cluster.memberNum设置为 StatefulSet pod 名称,pod 名称必须以 0 ... promscrape.cluster.memberNum-1范围内的数字结尾,例如,-promscrape.cluster.memberNum=vmagent-0

默认情况下,每个抓取目标仅由集群中的单个 vmagent 实例抓取。如果需要在多个 vmagent 实例之间复制抓取目标,则可以通过 -promscrape.cluster.replicationFactor参数设置为所需的副本数。例如,以下命令启动一个包含三个 vmagent 实例的集群,其中每个目标由两个 vmagent 实例抓取:

bash
vmagent-promscrape.cluster.membersCount=3-promscrape.cluster.replicationFactor=2-promscrape.cluster.memberNum=0-promscrape.config=/path/to/config.yml...vmagent-promscrape.cluster.membersCount=3-promscrape.cluster.replicationFactor=2-promscrape.cluster.memberNum=1-promscrape.config=/path/to/config.yml...vmagent-promscrape.cluster.membersCount=3-promscrape.cluster.replicationFactor=2-promscrape.cluster.memberNum=2-promscrape.config=/path/to/config.yml...

需要注意的是如果每个目标被多个 vmagent 实例抓取,则必须在 -remoteWrite.url指向的远程存储上启用重复数据删除。

所以如果你抓取的监控目标非常大,那么我们建议使用 vmagent 集群模式。

3、使用 StatefulSet 方式进行部署

那么可以使用 StatefulSet 方式进行部署vmagent 集群模式:

vim vmagent-sts.yaml

yaml
# vmagent-sts.yamlapiVersion:v1kind:Servicemetadata:name:vmagentnamespace:kube-vmannotations:prometheus.io/scrape:"true"#这个是为了采集vmagent本身prometheus.io/port:"8429"spec:selector:app:vmagentclusterIP:Noneports:- name:httpport:8429targetPort:http---apiVersion:apps/v1kind:StatefulSetmetadata:name:vmagentnamespace:kube-vmlabels:app:vmagentspec:replicas:2serviceName:vmagentselector:matchLabels:app:vmagenttemplate:metadata:labels:app:vmagentspec:serviceAccountName:vmagentcontainers:- name:agentimage:victoriametrics/vmagent:v1.77.0imagePullPolicy:IfNotPresentargs:- -promscrape.config=/config/scrape.yml- -remoteWrite.tmpDataPath=/tmpData- -promscrape.cluster.membersCount=2# - -promscrape.cluster.replicationFactor=2 # 可以配置副本数- -promscrape.cluster.memberNum=$(POD_NAME)- -remoteWrite.url=http:- -envflag.enable=true- -envflag.prefix=VM_- -loggerFormat=jsonports:- name:httpcontainerPort:8429env:- name:POD_NAME#downward apivalueFrom:fieldRef:fieldPath:metadata.namevolumeMounts:- name:tmpdatamountPath:/tmpData- name:configmountPath:/configvolumes:- name:configconfigMap:name:vmagent-configvolumeClaimTemplates:- metadata:name:tmpdataspec:accessModes:- ReadWriteOncestorageClassName:nfs-client#注意下:这里自己要部署下nfs的,当然用longhorn也是可以的,这里就使用nfs了。resources:requests:storage:1Gi

我们这里就使用 StatefulSet 的形式来管理 vmagent,直接应用上面的资源即可:

bash
# 先将前面示例中的 prometheus 停掉kubectlscaledeployprometheus--replicas=0-nkube-vm部署:kubectlapply-fvmagent-sts.yaml[root@master1 vm-agent]#kubectl get pods -n kube-vm -l app=vmagentNAMEREADYSTATUSRESTARTSAGEvmagent-01/1Running03mvmagent-11/1Running0117s
4、验证

这里我们部署了两个 vmagent 实例来抓取监控指标,我们这里一共 3 个节点。

bash
[root@master1 vm-agent]#kubectl get nodesNAMESTATUSROLESAGEVERSIONmaster1Readycontrol-plane,master287dv1.22.2node1Ready<none>287dv1.22.2node2Ready<none>287dv1.22.244dv1.22.8

所以两个 vmagent 实例会分别采集部分指标,我们可以通过查看日志来进行验证:

bash
kubectllogs-fvmagent-0-nkube-vm# ......{"ts":"2022-08-14T01:22:15.317Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/discovery/kubernetes/api_watcher.go:436","msg":"started node watcher for \"https:{"ts":"2022-08-14T01:22:15.327Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/discovery/kubernetes/api_watcher.go:589","msg":"reloaded 3 objects from \"https:{"ts":"2022-08-14T01:22:15.327Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/config.go:116","msg":"started service discovery routines in 0.010 seconds"}{"ts":"2022-08-14T01:22:15.332Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/scraper.go:393","msg":"kubernetes_sd_configs:added targets:1,removed targets:0;total targets:1"}kubectllogs-fvmagent-1-nkube-vm# ......{"ts":"2022-08-14T01:23:30.033Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/discovery/kubernetes/api_watcher.go:436","msg":"started node watcher for \"https:{"ts":"2022-08-14T01:23:30.044Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/discovery/kubernetes/api_watcher.go:589","msg":"reloaded 3 objects from \"https:{"ts":"2022-08-14T01:23:30.044Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/config.go:116","msg":"started service discovery routines in 0.011 seconds"}{"ts":"2022-08-14T01:23:30.045Z","level":"info","caller":"VictoriaMetrics/lib/promscrape/scraper.go:393","msg":"kubernetes_sd_configs:added targets:2,removed targets:0;total targets:2"}

从日志可以看出 vmagent-0实例发现了 1个 targets,vmagent-1实例发现了 2 个 targets,这也符合我们预期的。

5、访问Web UI

在集群版里,默认是带了之前的那个UI界面的

bash
[root@master1 vm-agent]#kubectl get svc -nkube-vmNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEcluster-vmstorageClusterIPNone<none>8482/TCP,8401/TCP,8400/TCP23hgrafanaNodePort10.102.169.155<none>3000:30868/TCP21dprometheusNodePort10.103.243.22<none>9090:30832/TCP21dpromxyNodePort10.97.84.86<none>8082:32380/TCP20dvictoria-metricsNodePort10.103.196.207<none>8428:30458/TCP20dvmagentClusterIPNone<none>8429/TCP16mvminsertClusterIP10.96.144.212<none>8480/TCP23hvmselectNodePort10.111.47.127<none>8481:30032/TCP23h

这里把vmselect用nodePort类型服务部署起来,然后再浏览器里访问:

http:apiVersion:v1kind:ConfigMapmetadata:name:vmagent-confignamespace:kube-vmdata:scrape.yml:|global:scrape_interval:15sscrape_timeout:15sscrape_configs:- job_name:nodeskubernetes_sd_configs:- role:noderelabel_configs:- source_labels:[__address__]regex:"(.*):10250"replacement:"${1}:9111"target_label:__address__action:replace- action:labelmapregex:__meta_kubernetes_node_label_(.+)- job_name:apiserverscheme:httpsbearer_token_file:/var/run/secrets/kubernetes.io/serviceaccount/tokentls_config:ca_file:/var/run/secrets/kubernetes.io/serviceaccount/ca.crtinsecure_skip_verify:truekubernetes_sd_configs:- role:endpointsrelabel_configs:- action:keepregex:default;kubernetes;httpssource_labels:- __meta_kubernetes_namespace- __meta_kubernetes_service_name- __meta_kubernetes_endpoint_port_name- job_name:cadvisorbearer_token_file:/var/run/secrets/kubernetes.io/serviceaccount/tokenscheme:httpstls_config:ca_file:/var/run/secrets/kubernetes.io/serviceaccount/ca.crtinsecure_skip_verify:truekubernetes_sd_configs:- role:noderelabel_configs:- action:labelmapregex:__meta_kubernetes_node_label_(.+)- replacement:/metrics/cadvisortarget_label:__metrics_path__- job_name:endpointskubernetes_sd_configs:- role:endpointsrelabel_configs:- action:dropregex:truesource_labels:- __meta_kubernetes_pod_container_init- action:keep_if_equalsource_labels:- __meta_kubernetes_service_annotation_prometheus_io_port- __meta_kubernetes_pod_container_port_number- action:keepregex:truesource_labels:- __meta_kubernetes_service_annotation_prometheus_io_scrape- action:replaceregex:(https?)source_labels:- __meta_kubernetes_service_annotation_prometheus_io_schemetarget_label:__scheme__- action:replaceregex:(.+)source_labels:- __meta_kubernetes_service_annotation_prometheus_io_pathtarget_label:__metrics_path__- action:replaceregex:([^:]+)(?::\d+)?;(\d+)replacement:$1:$2source_labels:- __address__- __meta_kubernetes_service_annotation_prometheus_io_porttarget_label:__address__- action:labelmapregex:__meta_kubernetes_service_label_(.+)- source_labels:- __meta_kubernetes_pod_nametarget_label:pod- source_labels:- __meta_kubernetes_namespacetarget_label:namespace- source_labels:- __meta_kubernetes_service_nametarget_label:service- replacement:${1}source_labels:- __meta_kubernetes_service_nametarget_label:job- action:replacesource_labels:- __meta_kubernetes_pod_node_nametarget_label:node

大部分的配置在前面 Prometheus 章节都介绍过了,核心就是通过 relabel_configs来控制抓取的任务。

vmagent 是兼容传统的 prometheus 重新标记规则的,但也有一些独特的 action,比如上面配置中我们使用了一个 keep_if_equal的操作,该操作的意思是如果指定的标签值相等则将该条数据保留下来。

有时,如果某个指标包含两个具有相同值的标签,则需要删除它。这可以通过 vmagent 支持的 drop_if_equal操作来完成。例如,如果以下 relabel 规则包含 real_portrequired_port的相同标签值,则它会删除指标:

该规则将删除以下指标:foo{real_port="123",needed_port="123"},但会保留以下指标:foo{real_port="123",needed_port="456"}

有时可能需要只对指标子集应用 relabel,在这种情况下,可以将 if选项添加到 relabel_configs规则中,例如以下规则仅将 {foo="bar"}标签添加到与 metric{label=~"x|y"}序列选择器匹配的指标:

if选项可以简化传统的 relabel_configs规则,例如,以下规则可以删除与 foo{bar="baz"}序列选择器匹配的指标:

这相当于以下传统的规则:

不过需要注意的是 Prometheus 还不支持 if选项,现在只支持 VictoriaMetrics。

配置刷新有两种方式:

img

img

Alertmanager 这里我们只配置了一个默认的路由规则,根据 severitysource两个标签进行分组,然后将触发的报警发送到 email 接收器中去。

部署:

bash
[root@master1 vmalert]#kubectl apply -f alertmanager.yaml configmap/alert-configcreatedservice/alertmanagercreateddeployment.apps/alertmanagercreated
2.添加用于报警的规则配置

接下来需要添加用于报警的规则配置,配置方式和 Prometheus 一样的:

vim vmalert-config.yaml

yaml
# vmalert-config.yamlapiVersion:v1kind:ConfigMapmetadata:name:vmalert-confignamespace:kube-vmdata:record.yaml:|groups:- name:recordrules:- record:job:node_memory_MemFree_bytes:percent # 记录规则名称expr:100 - (100 *node_memory_MemFree_bytes / node_memory_MemTotal_bytes)pod.yaml:|groups:- name:podrules:- alert:PodMemoryUsageexpr:sum(container_memory_working_set_bytes{pod!=""}) BY (instance,pod) / sum(container_spec_memory_limit_bytes{pod!=""} >0) BY (instance,pod) *100 >60for:2mlabels:severity:warningsource:podannotations:summary:"Pod {{$labels.pod }} High Memory usage detected"description:"{{$labels.instance}}:Pod {{$labels.pod }} Memory usage is above 60% (current value is:{{$value }})"node.yaml:|groups:- name:noderules:# 具体的报警规则- alert:NodeMemoryUsage # 报警规则的名称expr:(node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes *100 >30for:1mlabels:source:nodeseverity:criticalannotations:summary:"Node {{$labels.instance}} High Memory usage detected"description:"{{$labels.instance}}:Memory usage is above 30% (current value is:{{$value }})"

这里我们添加了一条记录规则,两条报警规则,更多报警规则配置可参考 https:configmap/vmalert-configcreated

3.部署 vmalert 组件

然后就可以部署 vmalert 组件服务了:

vim vmalert.yaml

yaml
# vmalert.yamlapiVersion:v1kind:Servicemetadata:name:vmalertnamespace:kube-vmlabels:app:vmalertspec:ports:- name:vmalertport:8080targetPort:8080type:NodePortselector:app:vmalert---apiVersion:apps/v1kind:Deploymentmetadata:name:vmalertnamespace:kube-vmlabels:app:vmalertspec:selector:matchLabels:app:vmalerttemplate:metadata:labels:app:vmalertspec:containers:- name:vmalertimage:victoriametrics/vmalert:v1.77.0imagePullPolicy:IfNotPresentargs:- -rule=/etc/ruler