kubernetes之VictoriaMetrics单节点
转载自:https://blog.csdn.net/weixin_39246554/article/details/125982890
1、简介
VictoriaMetrics(VM) 是一个支持高可用、经济高效且可扩展的监控解决方案和时间序列数据库,可用于 Prometheus 监控数据做长期远程存储。
相对于 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 集群版官方的架构图。
主要包含以下几个组件:
- 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 以及网络带宽
接下来我们就分别来介绍了 VM 的单节点和集群两个方案的使用。
3、单节点
这里我们采集 node-exporter 为例进行说明,首先使用 Prometheus 采集数据,然后将 Prometheus 数据远程写入 VM 远程存储。
由于 VM 提供了 vmagent 组件,最后我们使用 VM 来完全替换 Prometheus,可以使架构更简单、更低的资源占用。
环境准备
1.创建kube-vm 命名空间
- 这里我们将所有资源运行在 kube-vm 命名空间之下:
[root@master1 ~]#kubectl create ns kube-vm
namespace/kube-vm created
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
# vm-node-exporter.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: kube-vm
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostPID: true
hostIPC: true
hostNetwork: true #注意这里是hostNetwork方式
nodeSelector:
kubernetes.io/os: linux
containers:
- name: node-exporter
image: prom/node-exporter:v1.3.1
args:
- --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: 9111
env:
- name: HOSTIP
valueFrom:
fieldRef:
fieldPath: status.hostIP
resources:
requests:
cpu: 150m
memory: 180Mi
limits:
cpu: 150m
memory: 180Mi
securityContext:
runAsNonRoot: true
runAsUser: 65534
volumeMounts:
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
- name: root
mountPath: /host/root
mountPropagation: HostToContainer
readOnly: true
tolerations: # 添加容忍
- operator: "Exists"
volumes:
- name: proc
hostPath:
path: /proc
- name: dev
hostPath:
path: /dev
- name: sys
hostPath:
path: /sys
- name: root
hostPath:
path: /
- 直接应用上面的资源清单即可。
[root@master1 vm]#kubectl apply -f vm-node-exporter.yaml
daemonset.apps/node-exporter created
[root@master1 vm]#kubectl get po -owide -nkube-vm
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node-exporter-56p88 1/1 Running 0 12s 172.29.9.51 master1 <none> <none>
node-exporter-bjk82 1/1 Running 0 12s 172.29.9.53 node2 <none> <none>
node-exporter-wnwgt 1/1 Running 0 12s 172.29.9.52 node1 <none> <none>
3.重新部署一套独立的 Prometheus
然后重新部署一套独立的 Prometheus,为了简单我们直接使用 static_configs 静态配置方式来抓取 node-exporter 的指标,配置清单如下所示:
- 创建k8s的ConfigMap资源对象:
[root@master1 vm]#pwd
/root/vm
[root@master1 vm]#vim vm-prom-config.yaml
# vm-prom-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: kube-vm
data:
prometheus.yaml: |
global:
scrape_interval: 15s
scrape_timeout: 15s
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
上面配置中通过 relabel 操作从 __address__
中将 IP 信息提取出来,后面可以用来验证 VM 是否兼容 relabel 操作。
- 对k8s做数据持久化:
同样要给 Prometheus 数据做持久化,所以也需要创建一个对应的 PVC 资源对象:
先到node2节点上创建下本地目录:
[root@master1 ~]#cd vm
[root@master1 vm]#ssh node2
Last login: Sat Jul 23 11:55:59 2022 from master1
[root@node2 ~]#mkdir -p /data/k8s/prometheus
[root@node2 ~]#exit
logout
Connection to node2 closed.
[root@master1 vm]#vim vm-prom-pvc.yaml
# apiVersion: storage.k8s.io/v1
# kind: StorageClass
# metadata:
# name: local-storage
# provisioner: kubernetes.io/no-provisioner
# volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: prometheus-data
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 20Gi
storageClassName: local-storage
local:
path: /data/k8s/prometheus
persistentVolumeReclaimPolicy: Retain
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prometheus-data
namespace: kube-vm
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: local-storage
- 然后直接创建 Prometheus 即可,将上面的 PVC 和 ConfigMap 挂载到容器中,通过
--config.file
参数指定配置文件文件路径,指定 TSDB 数据路径等,资源清单文件如下所示:
[root@master1 vm]#vim vm-prom-deploy.yaml
# vm-prom-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: kube-vm
spec:
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: prometheus-data
- name: config-volume
configMap:
name: prometheus-config
containers:
- image: prom/prometheus:v2.35.0
name: prometheus
args:
- "--config.file=/etc/prometheus/prometheus.yaml"
- "--storage.tsdb.path=/prometheus" # 指定tsdb数据路径
- "--storage.tsdb.retention.time=2d"
- "--web.enable-lifecycle" # 支持热更新,直接执行localhost:9090/-/reload立即生效
ports:
- containerPort: 9090
name: http
securityContext:
runAsUser: 0
volumeMounts:
- mountPath: "/etc/prometheus"
name: config-volume
- mountPath: "/prometheus"
name: data
---
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: kube-vm
spec:
selector:
app: prometheus
type: NodePort
ports:
- name: web
port: 9090
targetPort: http
- 直接应用上面的资源清单即可。
[root@master1 vm]#kubectl apply -f vm-prom-config.yaml
configmap/prometheus-config created
service/prometheus created
[root@master1 vm]#kubectl apply -f vm-prom-pvc.yaml
persistentvolume/prometheus-data created
persistentvolumeclaim/prometheus-data created
[root@master1 vm]#kubectl apply -f vm-prom-deploy.yaml
deployment.apps/prometheus created
[root@master1 vm]#kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
grafana-local 2Gi RWO Retain Bound monitor/grafana-pvc local-storage 80d
prometheus-data 20Gi RWO Retain Bound kube-vm/prometheus-data local-storage 8m34s
prometheus-local 20Gi RWO Retain Bound monitor/prometheus-data local-storage 84d
pv001 1Gi RWO Retain Terminating default/www-web-0 251d
pv002 1Gi RWO Retain Terminating default/www-web-1 251d
[root@master1 vm]#kubectl get pvc -nkube-vm
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
prometheus-data Bound prometheus-data 20Gi RWO local-storage 8m40s
[root@master1 vm]#kubectl get po -owide -nkube-vm
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node-exporter-56p88 1/1 Running 0 4h40m 172.29.9.51 master1 <none> <none>
node-exporter-bjk82 1/1 Running 0 4h40m 172.29.9.53 node2 <none> <none>
node-exporter-wnwgt 1/1 Running 0 4h40m 172.29.9.52 node1 <none> <none>
prometheus-dfc9f6-l59mw 1/1 Running 0 6m13s 10.244.2.225 node2 <none> <none>
[root@master1 vm]#kubectl get svc -nkube-vm
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus NodePort 10.103.243.22 <none> 9090:30832/TCP 6m21s
[root@master1 vm]#
- 部署完成后可以通过 http://
:30832 访问 Prometheus,正常可以看到采集的 3 个 node 节点的指标任务。
这边有2个疑问:
⚠️ 疑问1:说不是还要部署prometheus的rbac资源呢?(已解决)
之前p8s部署在k8s里的课程,是有配置这个步骤的,但是本次实验,为啥没有这一个操作的。
按理说不是还需要再创建一个这个SA吧?
# prometheus-rbac.yaml
apiVersion: v1
kind: ServiceAccount #创建一个ServiceAccount
metadata:
name: prometheus
namespace: kube-vm
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitor
- kind: ServiceAccount
name: prometheus
namespace: kube-vm
这里直接在原来那个yaml里更新,或者重新创建一个就好吧。
这边可以先不创建,先当做遗留问题就好。
经测试,先不创建这个rbac资源,p8s是可以正常起来的。
哈哈,老师解惑了:
问题:我们这里是不是没配置rbac,p8s也是可以访问的呢?
答案:因为目前只是p8s静态地去把数据抓取过来的,而不是自动发现的(不是用过apiserver去访问的)。所以现在,我们没有配置rbac是没有任何问题的。
⚠️ 疑问2:这里的local-storage只是一个标识而已的吧?(待解决……)
按老师说的,这里要重新创建一个sc呀……
但是自己之前的实验这里都是没创建local-storage的sc呀……
个人预测结论:
这里的local-storage只是一个标识而已,不需要来创建。!!!
经测试:
我的k8s集群里未创建这个local-storage sc,也是可以正常使用pv/pvc的。因此,这里的storageClassName: local-storage只是一个标识而已。
4.以同样的方式重新部署 Grafana
先到node2节点上创建下本地目录:
[root@master1 vm]#ssh node2
Last login: Sat Jul 23 16:14:21 2022 from master1
[root@node2 ~]#mkdir -p /data/k8s/grafana
[root@node2 ~]#exit
logout
Connection to node2 closed.
同样的方式重新部署 Grafana,资源清单如下所示:
[root@master1 vm]#vim vm-grafana.yaml
# vm-grafana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: kube-vm
spec:
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
volumes:
- name: storage
persistentVolumeClaim:
claimName: grafana-data
containers:
- name: grafana
image: grafana/grafana:main
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: grafana
securityContext:
runAsUser: 0
env:
- name: GF_SECURITY_ADMIN_USER
value: admin
- name: GF_SECURITY_ADMIN_PASSWORD
value: admin321
volumeMounts:
- mountPath: /var/lib/grafana
name: storage
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: kube-vm
spec:
type: NodePort
ports:
- port: 3000
selector:
app: grafana
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: grafana-data
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 1Gi
storageClassName: local-storage
local:
path: /data/k8s/grafana
persistentVolumeReclaimPolicy: Retain
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-data
namespace: kube-vm
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-storage
部署
[root@master1 vm]#kubectl apply -f vm-grafana.yaml
deployment.apps/grafana created
service/grafana created
persistentvolume/grafana-data created
persistentvolumeclaim/grafana-data created
同样通过 http://
然后导入 16098 这个 Dashboard,导入后效果如下图所示。(此json文件已下载到本地)
到这里就完成了使用 Prometheus 收集节点监控指标,接下来我们来使用 VM 来改造现有方案。
1.远程存储 VictoriaMetrics
首先需要一个单节点模式的 VM,运行 VM 很简单,可以直接下载对应的二进制文件启动,也可以使用 docker 镜像一键启动,我们这里同样部署到 Kubernetes 集群中。
k8s里部署单节点vm
资源清单文件如下所示。
先在node2上创建持久化路径:
[root@master1 vm]#ssh node1
Last login: Wed May 4 19:51:38 2022 from master1
[root@node1 ~]#mkdir -p /data/k8s/vm
[root@master1 vm]#vim vm.yaml
# vm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: victoria-metrics
namespace: kube-vm
spec:
selector:
matchLabels:
app: victoria-metrics
template:
metadata:
labels:
app: victoria-metrics
spec:
volumes:
- name: storage
persistentVolumeClaim:
claimName: victoria-metrics-data
containers:
- name: vm
image: victoriametrics/victoria-metrics:v1.76.1
imagePullPolicy: IfNotPresent
args:
- -storageDataPath=/var/lib/victoria-metrics-data
- -retentionPeriod=1w #默认一个月
ports:
- containerPort: 8428
name: http
volumeMounts:
- mountPath: /var/lib/victoria-metrics-data
name: storage
---
apiVersion: v1
kind: Service #vm还附带了一个web服务,类似于p8s的那个web界面,方便我们操作。
metadata:
name: victoria-metrics
namespace: kube-vm
spec:
type: NodePort
ports:
- port: 8428
selector:
app: victoria-metrics
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: victoria-metrics-data
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 20Gi
storageClassName: local-storage
local:
path: /data/k8s/vm #必须先创建这个路径
persistentVolumeReclaimPolicy: Retain
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: victoria-metrics-data
namespace: kube-vm
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: local-storage
这里我们使用 -storageDataPath
参数指定了数据存储目录,然后同样将该目录进行了持久化,-retentionPeriod
参数可以用来配置数据的保持周期。
直接应用上面的资源清单即可。
[root@master1 vm]#kubectl apply -f vm.yaml
deployment.apps/victoria-metrics created
service/victoria-metrics created
persistentvolume/victoria-metrics-data created
persistentvolumeclaim/victoria-metrics-data created
[root@master1 vm]#kubectl get deploy,svc,pod -n kube-vm
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/grafana 1/1 1 1 16h
deployment.apps/prometheus 1/1 1 1 17h
deployment.apps/victoria-metrics 1/1 1 1 5m1s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/grafana NodePort 10.102.169.155 <none> 3000:30868/TCP 16h
service/prometheus NodePort 10.103.243.22 <none> 9090:30832/TCP 17h
service/victoria-metrics NodePort 10.111.174.185 <none> 8428:31526/TCP 5m1s
NAME READY STATUS RESTARTS AGE
pod/grafana-bbd99dc7-gjwxk 1/1 Running 0 16h
pod/node-exporter-56p88 1/1 Running 0 21h
pod/node-exporter-bjk82 1/1 Running 0 21h
pod/node-exporter-wnwgt 1/1 Running 0 21h
pod/prometheus-dfc9f6-l59mw 1/1 Running 0 17h
pod/victoria-metrics-7b5b5d4b65-zthq9 1/1 Running 0 2m14s
[root@master1 vm]#kubectl logs -f victoria-metrics-7b5b5d4b65-zthq9 -nkube-vm
2022-07-24T01:37:50.461Z info VictoriaMetrics/lib/mergeset/table.go:257 opening table "/var/lib/victoria-metrics-data/indexdb/1704A027396769B6"...
2022-07-24T01:37:50.462Z info VictoriaMetrics/lib/mergeset/table.go:292 table "/var/lib/victoria-metrics-data/indexdb/1704A027396769B6" has been opened in 0.001 seconds; partsCount: 0; blocksCount: 0, itemsCount: 0; sizeBytes: 0
2022-07-24T01:37:50.463Z info VictoriaMetrics/app/vmstorage/main.go:113 successfully opened storage "/var/lib/victoria-metrics-data" in 0.011 seconds; partsCount: 0; blocksCount: 0; rowsCount: 0; sizeBytes: 0
2022-07-24T01:37:50.464Z info VictoriaMetrics/app/vmselect/promql/rollup_result_cache.go:111 loading rollupResult cache from "/var/lib/victoria-metrics-data/cache/rollupResult"...
2022-07-24T01:37:50.466Z info VictoriaMetrics/app/vmselect/promql/rollup_result_cache.go:137 loaded rollupResult cache from "/var/lib/victoria-metrics-data/cache/rollupResult" in 0.002 seconds; entriesCount: 0, sizeBytes: 0
2022-07-24T01:37:50.467Z info VictoriaMetrics/app/victoria-metrics/main.go:61 started VictoriaMetrics in 0.015 seconds
2022-07-24T01:37:50.467Z info VictoriaMetrics/lib/httpserver/httpserver.go:91 starting http server at http://127.0.0.1:8428/
2022-07-24T01:37:50.467Z info VictoriaMetrics/lib/httpserver/httpserver.go:92 pprof handlers are exposed at http://127.0.0.1:8428/debug/pprof/
到这里我们单节点的 VictoriaMetrics 就部署成功了。
远程存储 VictoriaMetrics
接下来我们只需要在 Prometheus 中配置远程写入我们的 VM 即可,更改 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-prom-config.yaml
# vm-prom-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: kube-vm
data:
prometheus.yaml: |
global:
scrape_interval: 15s
scrape_timeout: 15s
remote_write: # 远程写入到远程 VM 存储
- url: http://victoria-metrics:8428/api/v1/write
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 的配置资源对象:
[root@master1 vm]#kubectl apply -f vm-prom-config.yaml
configmap/prometheus-config configured
# 更新后执行 reload 操作重新加载 prometheus 配置
[root@master1 vm]# curl -X POST "http://172.29.9.51:30832/-/reload"
⚠️ 注意
这里其实可以部署一个sidecar容器,它去检查这个配置文件的变化,如果检测到了其有变化,他就会主动触发一个reload操作,这样就不用我们每次去执行reload操作了!!!(之前那个thanos就是这个原理)
配置生效后 Prometheus 就会开始将数据远程写入 VM 中,我们可以查看 VM 的持久化数据目录是否有数据产生来验证:
[root@master1 vm]#ssh node2
Last login: Sun Jul 24 09:34:40 2022 from master1
[root@node2 ~]#ll /data/k8s/vm/data/
total 0
drwxr-xr-x 3 root root 23 Jul 24 09:37 big
-rw-r--r-- 1 root root 0 Jul 24 09:37 flock.lock
drwxr-xr-x 3 root root 23 Jul 24 09:37 small
现在我们去直接将 Grafana 中的数据源地址修改成 VM 的地址:
修改完成后重新访问 node-exporter 的 dashboard,正常可以显示,证明 VM 是兼容的。
2.替换 Prometheus
上面我们将 Prometheus 数据远程写入到了 VM,但是 Prometheus 开启 remote write 功能后会增加其本身的资源占用。理论上其实我们也可以完全用 VM 来替换掉 Prometheus,这样就不需要远程写入了,而且本身 VM 就比 Prometheus 占用更少的资源。
现在我们先停掉 Prometheus 的服务:
[root@master1 vm]#kubectl scale deployment prometheus --replicas=0 -nkube-vm
deployment.apps/prometheus scaled
然后将 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
# vm.yaml
#本次新增内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: victoria-metrics
namespace: kube-vm
spec:
selector:
matchLabels:
app: victoria-metrics
template:
metadata:
labels:
app: victoria-metrics
spec:
volumes:
- name: storage
persistentVolumeClaim:
claimName: victoria-metrics-data
- name: prometheus-config
configMap: #这里使用ConfigMap
name: prometheus-config
containers:
- name: vm
image: victoriametrics/victoria-metrics:v1.76.1
imagePullPolicy: IfNotPresent
args:
- -storageDataPath=/var/lib/victoria-metrics-data
- -retentionPeriod=1w
- -promscrape.config=/etc/prometheus/prometheus.yaml #这里将prometheus.yaml 挂载进来
ports:
- containerPort: 8428
name: http
volumeMounts:
- mountPath: /var/lib/victoria-metrics-data
name: storage
- mountPath: /etc/prometheus #挂载路径
name: prometheus-config
完整代码如下:
cat vm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: victoria-metrics
namespace: kube-vm
spec:
selector:
matchLabels:
app: victoria-metrics
template:
metadata:
labels:
app: victoria-metrics
spec:
volumes:
- name: storage
persistentVolumeClaim:
claimName: victoria-metrics-data
- name: prometheus-config
configMap: #这里使用ConfigMap
name: prometheus-config
containers:
- name: vm
image: victoriametrics/victoria-metrics:v1.76.1
imagePullPolicy: IfNotPresent
args:
- -storageDataPath=/var/lib/victoria-metrics-data
- -retentionPeriod=1w
- -promscrape.config=/etc/prometheus/prometheus.yaml #这里将prometheus.yaml 挂载进来
ports:
- containerPort: 8428
name: http
volumeMounts:
- mountPath: /var/lib/victoria-metrics-data
name: storage
- mountPath: /etc/prometheus #挂载路径
name: prometheus-config
---
apiVersion: v1
kind: Service #vm还附带了一个web服务,类似于p8s的那个web界面,方便我们操作。
metadata:
name: victoria-metrics
namespace: kube-vm
spec:
type: NodePort
ports:
- port: 8428
selector:
app: victoria-metrics
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: victoria-metrics-data
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 20Gi
storageClassName: local-storage
local:
path: /data/k8s/vm #必须先创建这个路径
persistentVolumeReclaimPolicy: Retain
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: victoria-metrics-data
namespace: kube-vm
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: 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
[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-config created
更新vm部署文件:
[root@master1 vm]#kubectl apply -f vm-prom-config.yaml
configmap/prometheus-config configerd
[root@master1 vm]#kubectl delete -f vm.yaml
deployment.apps "victoria-metrics" deleted
service "victoria-metrics" deleted
persistentvolume "victoria-metrics-data" deleted
persistentvolumeclaim "victoria-metrics-data" deleted
[root@master1 vm]#kubectl apply -f vm.yaml
deployment.apps/victoria-metrics created
service/victoria-metrics created
persistentvolume/victoria-metrics-data created
persistentvolumeclaim/victoria-metrics-data created
[root@master1 vm]#kubectl get pods -n kube-vm -l app=victoria-metrics
NAME READY STATUS RESTARTS AGE
victoria-metrics-8466844968-s9slx 1/1 Running 0 35s
[root@master1 vm]#kubectl logs victoria-metrics-8466844968-s9slx -nkube-vm
......
2022-07-24T03:10:29.799Z info VictoriaMetrics/app/victoria-metrics/main.go:61 started VictoriaMetrics in 0.021 seconds
2022-07-24T03:10:29.799Z info VictoriaMetrics/lib/httpserver/httpserver.go:91 starting http server at http://127.0.0.1:8428/
2022-07-24T03:10:29.799Z info VictoriaMetrics/lib/httpserver/httpserver.go:92 pprof handlers are exposed at http://127.0.0.1:8428/debug/pprof/
2022-07-24T03:10:29.799Z info VictoriaMetrics/lib/promscrape/scraper.go:103 reading Prometheus configs from "/etc/prometheus/prometheus.yaml"
2022-07-24T03:10:29.800Z info VictoriaMetrics/lib/promscrape/config.go:96 starting service discovery routines...
2022-07-24T03:10:29.800Z info VictoriaMetrics/lib/promscrape/config.go:102 started service discovery routines in 0.000 seconds
2022-07-24T03:10:29.800Z info VictoriaMetrics/lib/promscrape/scraper.go:395 static_configs: added targets: 3, removed targets: 0; total targets: 3
从 VM 日志中可以看出成功读取了 Prometheus 的配置,并抓取了 3 个指标(node-exporter)。
现在我们再去 Grafana 查看 node-exporter 的 Dashboard 是否可以正常显示。先保证数据源是 VM 的地址。
这样我们就使用 VM 替换掉了 Prometheus,我们也可以这 Grafana 的 Explore 页面去探索采集到的指标。
3.UI 界面
VM 单节点版本本身自带了一个 Web UI 界面 - vmui,不过目前功能比较简单。
可以直接通过 VM 的 NodePort 端口进行访问。
[root@master1 ~]#kubectl get svc -nkube-vm
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana NodePort 10.102.169.155 <none> 3000:30868/TCP 21h
prometheus NodePort 10.103.243.22 <none> 9090:30832/TCP 22h
victoria-metrics NodePort 10.103.196.207 <none> 8428:30458/TCP 3h33m
我们这里可以通过 http://
可以通过 /vmui 这个 endpoint 访问 UI 界面:
如果你想查看采集到的指标 targets,那么可以通过 /targets 这个 endpoint 来获取:
这些功能基本上可以满足我们的一些需求,但是还是太过简单。
如果你习惯了 Prometheus 的 UI 界面,那么我们可以使用 promxy 来代替 vmui,而且 promxy 还可以进行多个 VM 单节点(不只是vm,对p8s也是可以的)的数据聚合,以及 targets 查看等,对应的资源清单文件如下所示:
[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-promxy.yaml
# vm-promxy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: promxy-config
namespace: kube-vm
data:
config.yaml: |
promxy:
server_groups:
- static_configs:
- targets: [victoria-metrics:8428] # 指定vm地址,有多个则往后追加即可
path_prefix: /prometheus # 配置前缀
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: promxy
namespace: kube-vm
spec:
selector:
matchLabels:
app: promxy
template:
metadata:
labels:
app: promxy
spec:
containers:
- args:
- "--config=/etc/promxy/config.yaml"
- "--web.enable-lifecycle"
- "--log-level=trace"
env:
- name: ROLE
value: "1"
command:
- "/bin/promxy"
image: quay.io/jacksontj/promxy
imagePullPolicy: Always
name: promxy
ports:
- containerPort: 8082
name: web
volumeMounts:
- mountPath: "/etc/promxy/"
name: promxy-config
readOnly: true
- args: # container to reload configs on configmap change 这个需要特别注意下哦,是一个sidecar容器。
- "--volume-dir=/etc/promxy"
- "--webhook-url=http://localhost:8082/-/reload"
image: jimmidyson/configmap-reload:v0.1
name: promxy-server-configmap-reload
volumeMounts:
- mountPath: "/etc/promxy/"
name: promxy-config
readOnly: true
volumes:
- configMap:
name: promxy-config
name: promxy-config
---
apiVersion: v1
kind: Service
metadata:
name: promxy
namespace: kube-vm
spec:
type: NodePort
ports:
- port: 8082
selector:
app: promxy
直接应用上面的资源对象即可:
[root@master1 vm]#kubectl apply -f vm-promxy.yaml
configmap/promxy-config created
deployment.apps/promxy created
service/promxy created
[root@master1 vm]#kubectl get pods -n kube-vm -l app=promxy
NAME READY STATUS RESTARTS AGE
promxy-5f7dfdbc64-82cr6 2/2 Running 0 34s
[root@master1 vm]#kubectl get svc promxy -n kube-vm
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
promxy NodePort 10.97.84.86 <none> 8082:32380/TCP 52s
访问 Promxy 的页面效果和 Prometheus 自带的 Web UI 基本一致的。