家里的各种服务,监控需求总是少不了的。目前最常用的监控莫过去prometheus
和grafana
组合了。但是网网上的多种都过期了,因为官方把helm charts分拆了,这里手把手教你如何从零开始安装它。
本文提供两种方案,一个是基于kube-prometheus-stack安装直接监控全家桶,新手是推荐的,免除不少折腾,开箱即用。另一种是基于prometheus-operator再一步步修改配置,并且安装插件以提供监控能力。
说明:本文假定你有一定基础,如果你要问啥是prometheus,那请关闭本文章去自行Google学习。
前置准备
为了让数据可以更加持久化,我们让Prometheus使用外部PV来保存数据,这样集群挂掉都不会丢失我们监控数据(其实这数据也没那么重要啦:D)。所以我基于longhorn部署了一套自用的分布式存储系统,这里不谈其具体部署(你或许也有其它选择),仅看一下PV的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| apiVersion: v1
kind: PersistentVolume
metadata:
name: prometheus-vol-pv
labels:
app: prometheus-vol-pv
spec:
capacity:
storage: 10Gi # 这个大小家用或许够了吧
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: longhorn
csi:
driver: driver.longhorn.io
fsType: ext4
volumeAttributes:
numberOfReplicas: '3'
staleReplicaTimeout: '2880'
# 这个需要先在Longhorn UI中先CreateVolume
volumeHandle: prometheus-pv
|
基于kube-prometheus-stack安装
这是全家桶,除了prometheus,operator等,还带了grafana。我们直基于Helm chart安装,可以简要看一下说明:
1
2
3
4
5
6
| {
"name": "prometheus-community/kube-prometheus-stack",
"version": "40.1.2",
"app_version": "0.59.1",
"description": "kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator."
}
|
基于自己的需求,定制了一些values选项:
- 关闭了一些用不到的选项
- 指定了我自己分配的PV(为了长期持久化保存监控数据,你可能需要静态PV)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # ----- 以下是 values-kube-stack.yaml 的内容 -------------
alertmanager:
enabled: false
pushgateway:
enabled: false
prometheus:
enabled: true
prometheusSpec:
## Prometheus StorageSpec for persistent data
## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/storage.md
storageSpec:
## Using PersistentVolumeClaim
volumeClaimTemplate:
spec:
storageClassName: longhorn # 这里我指定了另一个sc,可换成你正在用的或""
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
|
使用helm安装
我们可以直接用helm安装(这是最简便的):
1
| helm install prometheus prometheus-community/kube-prometheus-stack -f values-kube-stack.yaml -n prometheus
|
稍等一会,你可看到各个服务在上面指定的命名空间prometheus中启动了,有这些:
- prometheus-kube-prometheus-operator: [核心]控制器
- prometheus-kube-state-metrics: 插件:k8s指标收集
- prometheus-grafana: grafana,用于可视化
- prometheus-node-exporter: 插件:node指标收集
- prometheus-prometheus-kube-prometheus-prometheus-0: [核心]prometheus存储及服务
基本上你不用再配置啥了,直接去使用吧~
使用helmfile安装
另外如果你使用helmfile安装的话,注意其不会安装crds,需要我们手工安装,我们可以写个如下的kustomization文件:
1
2
3
4
5
6
7
8
9
10
11
12
| resources:
- pv.yaml # 前文所说的静态PV
# 首次执行需要安装crd,请反注释下面这一段
- crds/crd-alertmanagerconfigs.yaml
- crds/crd-alertmanagers.yaml
- crds/crd-podmonitors.yaml
- crds/crd-probes.yaml
- crds/crd-prometheuses.yaml
- crds/crd-prometheusrules.yaml
- crds/crd-servicemonitors.yaml
- crds/crd-thanosrulers.yaml
namespace: prometheus
|
然后kubectl apply -k .
即可将这些CRDs安装,再使用helmfile安装以上的helm chart。
1
2
3
4
5
6
7
8
9
10
| # ------- 如果你是 helmfile 安装,类似这样配置 -----------
repositories:
- name: prometheus-community
url: https://prometheus-community.github.io/helm-charts
releases:
- name: prometheus
namespace: prometheus
chart: prometheus-community/kube-prometheus-stack
values:
- values-kube-stack.yaml
|
执行helmfile apply
即可。结果和使用helm安装一样,同样你已经可以使用了。
另外如果想配置grafana,可以参考这里。
小结
优点明显,部署简单,开箱即用。
缺点,勉强说的话,你没机会搞清楚为啥它能工作的。接下来我们从零开始趟坑来学习一下:)
基于prometheus-operator安装
直接安装prometheus-operator后,还需要手工安装众多东西和配置(如Prometheus
资源等)要做,比较烦琐,但配置它让你对prometheus的流程能够更清晰。我们还是一步步走起。
安装operator
1
| kubectl create -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/bundle.yaml
|
做完这步之后只会有一个operator服务和crd就绪。
配置Prometheus
通过prometheus-operator可以创建我们需要的prometheus-server等。你可参考官方这里文档,我感觉这文档写得顺序有些小问题。
我们从上面链接中抄过来一些配置,这里指定了Prometheus资源和相关RBAC。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
labels:
prometheus: prometheus
spec:
replicas: 1
serviceAccountName: prometheus
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/metrics
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources:
- configmaps
verbs: ["get"]
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs: ["get", "list", "watch"]
- 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: prometheus
|
当你执行apply后,趟坑之旅开始。
问题1:PV权限问题
你可能会遇上一个问题:
1
2
| prometheus ts=2022-09-23T16:58:00.286Z caller=query_logger.go:91 level=error component=activeQueryTracker msg="Error opening query log file" file=/prometheus/queri │
│ prometheus panic: Unable to create mmap-ed active query log
|
容器文件权限问题,参考这个issue,我们要修改Prometheus
资源:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
labels:
prometheus: prometheus
spec:
replicas: 1
serviceAccountName: prometheus
# 添加下面的securityContext解决上述问题
securityContext:
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
fsGroup: 0
|
我们添加上面的securityContext,服务一切起来正常了。
问题2:ServiceMonitor/PodMonitor无效
上面服务就绪,我们先自己安装node-exporter
插件:
1
2
3
4
5
6
7
8
| # 这里使用helmfile安装了node-exporter插件,你可以直接用Helm等其它方式
repositories:
- name: prometheus-community
url: https://prometheus-community.github.io/helm-charts
releases:
- name: prometheus-node-exporter
namespace: prometheus
chart: prometheus-community/prometheus-node-exporter
|
然后再定义一个ServiceMonitor
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 使用ServiceMonitor让prometheus可以生成抓取node-exporter的配置
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: node-exporter
labels:
# 1. 这里要指向Prometheus设置的label,这样ServiceMonitor才会被选择
prometheus: kevin-prometheus
spec:
jobLabel: jobLabel
selector:
# 2. 这里要匹配要监控的目标标签
matchLabels:
app.kubernetes.io/instance: prometheus-node-exporter
app.kubernetes.io/name: prometheus-node-exporter
endpoints:
- port: metrics
namespaceSelector:
matchNames:
- prometheus
|
虽然惊奇的发现Apply后ServiceMonitor
(或PodMonitor
)没有作用。原因是ServiceMonitor是通过它的labels来和我们的Prometheus关联的。我们需要继续向Prometheus
添加一些参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
labels:
prometheus: prometheus
spec:
replicas: 1
serviceAccountName: prometheus
securityContext:
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
fsGroup: 0
# podMonitorSelector
podMonitorSelector:
matchLabels:
prometheus: kevin-prometheus
# serviceMonitorSelector
serviceMonitorSelector:
matchLabels:
prometheus: kevin-prometheus
|
没有上述的matchLabels等指定一些匹配的label,并不会默认为匹配所有,它是必须的。
问题3:跨namespace后ServiceMonitor等无效
如果你继续在其它名字空间定义ServiceMonitor资源,比如我就定义了一个资源监控我笔记本使用情况:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| apiVersion: v1
kind: Endpoints
metadata:
name: macbookpro15
labels:
system: macbookpro15
subsets:
- addresses:
- ip: 192.168.50.xx # 你的笔记本IP(或许要静态)
ports:
- name: metrics
port: 9100
protocol: TCP
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: macbookpro15
labels:
app: macbookpro15
prometheus: kevin-prometheus
spec:
selector:
matchLabels:
system: macbookpro15
namespaceSelector:
# any: true
matchNames:
- monitor
endpoints:
- port: metrics
interval: 10s
honorLabels: true
---
apiVersion: v1
kind: Service
metadata:
name: macbookpro15
labels:
system: macbookpro15
spec:
ports:
- name: metrics
port: 9100
protocol: TCP
targetPort: 9100
---
|
整个资源在另一个名字空间monitor
中,此时发现死活不能在Prometheus UI中发现这个服务。如果你通过UI查看Configuration,可能它不是下面这样的,而是指定的namespace,那就是问题所在:
1
2
3
4
5
| kubernetes_sd_configs:
- role: pod
kubeconfig_file: ""
follow_redirects: true
enable_http2: true
|
我们要加一下可以访问任何namespace的ServiceMonitor等资源,再一次修改Prometheus
资源:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
labels:
prometheus: prometheus
spec:
replicas: 1
serviceAccountName: prometheus
securityContext:
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
fsGroup: 0
podMonitorNamespaceSelector: {} # 这一行让可以选择任意namespace的PodMonitor
podMonitorSelector:
matchLabels:
prometheus: kevin-prometheus
serviceMonitorNamespaceSelector: {} # 这一行让可以选择任意namespace的ServiceMonitor
serviceMonitorSelector:
matchLabels:
prometheus: kevin-prometheus
storage:
volumeClaimTemplate:
spec:
storageClassName: longhorn
resources:
requests:
storage: 10Gi
enableAdminAPI: true
|
添加注释的两行后,现在各个Namespace下的相关资源都会被发现了。
小结
通过第二种纯手工方式,我们对其运作多了一分了解。也可以做到仅部署我们想部署的服务,不受全家桶影响:)
总结
有时候一种方法搞定了,但是另一种方法有问题时,这最让人纠结。而我却总是不想绕过,于是花费了不少时间趟这种坑。从事后来看,只有踏实的理解了原理,才能够清楚配置为什么是这样的,背后是如何运转的,也算是另一种收获吧~~
如果能帮到你,欢迎留言交流探讨。