8 维多利亚仓库下指定暴露 NS 监控通过联邦模式实现
由于工作业务需求,我们不想给用户提供全量的监控指标,需要单独的指定业务所需的 NS 监控数据从而实现暴露给业务部门,并且我们的监控数据是通过 vm(维多利亚采集),多以我们的联邦模式下的 Prometheus 需要从 vm 监控数据源进行采集
在下面的实例中我需要部署一个 vm 和一个 Prometheus-operate 以及单独的一个 Prometheus deployment,以实现公司现有的环境,Prometheus-operate 采集数据然后才再将数据转存至 vm 中,另外一个 Prometheus 则将联邦模式配置为 vm,实现数据的分类,并且对 test ns 进行数据采集
8.1 部署 vm 集群模式
8.1.1 安装 longhorn
由于 vmstorage 组件持久化 PV 中使用到了 Longhorn 所以这里我们还需要部署一个 Longhorn 来作为存储
$ kubectl apply -f https://raw.githubusercontent.com/rancher/longhorn/master/deploy/longhorn.yaml
$ kubectl get pod -n longhorn-system
创建StorageClass需要使用另一个命令,然而作为附加步骤,你可以将新的class设置为默认,这样你无需每次都指定它:
$ kubectl apply -f https://raw.githubusercontent.com/rancher/longhorn/master/examples/storageclass.yaml
# default sc longhorn 已经创建,并且改 sc 就是下面 thanos-sidecar 要使用的
$ kubectl get storageclasses.storage.k8s.io
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
longhorn (default) driver.longhorn.io Delete Immediate true 91m
longhorn-test driver.longhorn.io Delete Immediate true 3m6s
访问 Longhorn Dashboard
$ kubectl edit svc -n longhorn-system longhorn-frontend
type: NodePort # 修改字段
$ kubectl get svc -n longhorn-system longhorn-frontend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
longhorn-frontend NodePort 172.30.0.254 <none> 80:30168/TCP 34m
http://10.0.0.200:30168/#/dashboard
部署完了 longhorn 以后我们就需要部署下面的 vmstorage
8.1.2 部署 vmstorage
由于 vmstorage 组件是有状态的,这里我们先使用 StatefulSet 进行部署,由于该组件也是可以进行扩展的,这里我们首先部署两个副本,对应的资源清单如下所示:
# cluster-vmstorage.yaml
apiVersion: v1
kind: Service
metadata:
name: cluster-vmstorage
namespace: kube-vm
labels:
app: vmstorage
spec:
clusterIP: None
ports:
- port: 8482
targetPort: http
name: http
- port: 8401
targetPort: vmselect
name: vmselect
- port: 8400
targetPort: vminsert
name: vminsert
selector:
app: vmstorage
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vmstorage
namespace: kube-vm
labels:
app: vmstorage
spec:
serviceName: cluster-vmstorage
selector:
matchLabels:
app: vmstorage
replicas: 2
podManagementPolicy: OrderedReady
template:
metadata:
labels:
app: vmstorage
spec:
containers:
- name: vmstorage
image: "victoriametrics/vmstorage:v1.77.0-cluster"
imagePullPolicy: "IfNotPresent"
args:
- "--retentionPeriod=7d" # 存储时间为 7 天
- "--storageDataPath=/storage"
#- --dedup.minScrapeInterval=60s
- --envflag.enable=true
- --envflag.prefix=VM_
- --loggerFormat=json
ports:
- name: http
containerPort: 8482
- name: vminsert
containerPort: 8400
- name: vmselect
containerPort: 8401
livenessProbe:
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
tcpSocket:
port: http
timeoutSeconds: 5
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
httpGet:
path: /health
port: http
volumeMounts:
- name: storage
mountPath: /storage
volumeClaimTemplates:
- metadata:
name: storage
spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "2Gi"
首先需要创建一个 Headless 的 Service,因为后面的组件需要访问到每一个具体的 Pod,在 vmstorage 启动参数中通过 --retentionPeriod
参数指定指标数据保留时长,1 表示一个月,这也是默认的时长,然后通过 --storageDataPath
参数指定了数据存储路径,记得要将该目录进行持久化。
应用该资源即可:
$ kubectl apply -f cluster-vmstorage.yaml
$ kubectl get pods -n kube-vm -l app=vmstorage
NAME READY STATUS RESTARTS AGE
vmstorage-0 1/1 Running 0 5m22s
vmstorage-1 1/1 Running 0 2m58s
$ kubectl get svc -n kube-vm -l app=vmstorage
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-vmstorage ClusterIP None <none> 8482/TCP,8401/TCP,8400/TCP 9m21s
8.1.3 部署 vmselect
接着可以部署 vmselect 组件,由于该组件是无状态的,我们可以直接使用 Deployment 来进行管理,对应的资源清单文件如下所示:
# cluster-vmselect.yaml
apiVersion: v1
kind: Service
metadata:
name: vmselect
namespace: kube-vm
labels:
app: vmselect
spec:
ports:
- name: http
port: 8481
targetPort: http
selector:
app: vmselect
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vmselect
namespace: kube-vm
labels:
app: vmselect
spec:
selector:
matchLabels:
app: vmselect
template:
metadata:
labels:
app: vmselect
spec:
containers:
- name: vmselect
image: "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
#- --dedup.minScrapeInterval=30s
- --envflag.enable=true
- --envflag.prefix=VM_
- --loggerFormat=json
ports:
- name: http
containerPort: 8481
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
livenessProbe:
tcpSocket:
port: http
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
其中最重要的部分是通过 --storageNode
参数指定所有的 vmstorage 节点地址,上面我们使用的 StatefulSet 部署的,所以可以直接使用 FQDN 的形式进行访问,因为 vmselect 需要将数据写到我们的存储模块中直接应用上面的对象:
$ kubectl apply -f cluster-vmselect.yaml
$ kubectl get pod -n kube-vm -l app=vmselect
NAME READY STATUS RESTARTS AGE
vmselect-f4fd588b-wmpqd 1/1 Running 0 93s
$ kubectl get svc -n kube-vm -l app=vmselect
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vmselect ClusterIP 172.30.0.25 <none> 8481/TCP 106s
8.1.4 对接 Grafana
如果要进行查询,那么我们可以直接对外暴露 vmselect 这个 Service 服务即可,修改 Grafana 数据源地址为 http://<select-service>/select/0/prometheus/
。
如下图:
8.1.5 部署 vminsert
接着就需要部署用来接收指标数据插入的 vminsert 组件,同样该组件是无状态的,其中最重要的也是需要通过 --storageNode
参数指定所有的 vmstorage 节点:
因为该节点需要通过 vmstorage 采集数据
# cluster-vminsert.yaml
apiVersion: v1
kind: Service
metadata:
name: vminsert
namespace: kube-vm
labels:
app: vminsert
spec:
ports:
- name: http
port: 8480
targetPort: http
selector:
app: vminsert
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vminsert
namespace: kube-vm
labels:
app: vminsert
spec:
selector:
matchLabels:
app: vminsert
template:
metadata:
labels:
app: vminsert
spec:
containers:
- name: vminsert
image: "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=json
ports:
- name: http
containerPort: 8480
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
livenessProbe:
tcpSocket:
port: http
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
由于本身是无状态的,所以可以根据需要增加副本数量,也可以配置 HPA 进行自动扩缩容。直接应用上面的资源清单:
$ kubectl apply -f cluster-vminsert.yaml
$ kubectl get pods -n kube-vm -l app=vminsert
NAME READY STATUS RESTARTS AGE
vminsert-844689747d-wbbv4 0/1 Running 0 43s
$ kubectl get svc -n kube-vm -l app=vminser
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vminsert ClusterIP 172.30.0.31 <none> 8480/TCP 54s
8.2 部署 Prometheus-operate
这里我就不写操作步骤,至于步骤可以看该链接,里面有关于 Prometheus-operate 的部署
8.3 Prometheus-operate 对接 vm
这里部署完了 Prometheus-operate 就需要对接到 vm 上
对接步骤如下:
$ kubectl edit prometheus -n monitoring
# spec.externalLabels
spec:
replicas: 1
externalLabels:
tenant_id: test
将 替换为您的租户标识符。这将为每个采集到的指标添加一个名为 tenant_id
的标签。
- 启动 VictoriaMetrics:使用适当的选项(例如,
-storage.local.dataPath=/path/to/data
)启动 VictoriaMetrics。 - 在 Prometheus 中配置 VictoriaMetrics 作为远程存储:修改 Prometheus 的配置文件,添加以下内容:
# spec.remoteWrite
# vm 单机版 api
remote_write:
- url: "http://localhost:8428/api/v1/write" # 这里的 URL 是您 VictoriaMetrics 单机版的地址
# vm 集群版 api
remoteWrite:
- url: http://vminsert:8480/insert/0/prometheus/ # 这里的 URL 是您 VictoriaMetrics 集群版的地址
8.4 vm 对接 promxy 实现可视化数据查询
我们都知道 vmselect 是用来查询数据,所以我们可以通过 promxy 将其实现可视化从而实现 web 页面查询数据
# vm-promxy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: promxy-config
namespace: kube-vm
data:
config.yaml: |
promxy:
server_groups:
- static_configs:
- targets: [vmselect:8481] # 指定 vmselect svc地址,有多个则往后追加即可
path_prefix: /select/0/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
- "--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
查看端口
$ kubectl get svc -n kube-vm | grep prom
promxy NodePort 172.30.0.110 <none> 8082:31344/TCP 4m3s
浏览器访问
8.5 部署 Prometheus-deployment 并对接 VM 获取对应 NS 数据
接下来我们就需要部署对应的 Prometheus 实例,并且通过配置 configmap 文件实现联邦模式,然后对 promxy 的 API 进行监控数据调用
编写 configmap yaml
# vm-prom-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: kube-vm
data:
prometheus.yaml: |
global:
scrape_interval: 100s
scrape_timeout: 100s # 这里我将时间调长一点为了数据的抓取
scrape_configs:
- job_name: 'prometheus-federate-1'
scrape_interval: 100s # 抓取数据间隔
honor_labels: true # 保留联邦 Prometheus 上的原标签,不做替换
metrics_path: '/federate' # 联邦模式下的数据采集路径
params:
'match[]': # 匹配 job
- '{namespace="monitoring"}' # 后续修改为我们需要的采集的 ns 即可,这里我对 monitoring 做采集
static_configs:
- targets: ["10.0.0.100:31344"] # 这里是 promxy URL 和对外暴露的端口,当然也可以写 promxy svc + 端口
同样要给 Prometheus 数据做持久化,所以也需要创建一个对应的 PVC 资源对象:
# cat vm-prom-pvc.yaml
---
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:
- node-2 # 这里指定将 pv 绑定至 node-2 节点上
---
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 数据路径等,资源清单文件如下所示:
# vim 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
创建 yaml
$ kubectl apply -f vm-prom-config.yaml
$ kubectl apply -f vm-prom-pvc.yaml
$ kubectl apply -f vm-prom-deploy.yaml
$ kubectl get pod -n kube-vm
NAME READY STATUS RESTARTS AGE
prometheus-585bcc4446-fc6x2 1/1 Running 0 8m24s
$ kubectl get svc -n kube-vm
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus NodePort 172.30.0.247 <none> 9090:31626/TCP 47m
浏览器访问
可以看到这里对 up{namespace!="monitoring"}
取反,并没有拿到其他数据,
总结:
如果想采集数据,我们只需要配置联邦 Prometheus 即可,包括后期的动态服务发现也是在联邦节点上配置,而我们的 Prometheus-Server 只是一个用来采集联邦节点的数据并非采集各个 expoter 数据