前言

对于多个技术部门,多个项目系统的背景,不仅要满足权限管理的隔离,又要资源隔离,但同时还得追求资源共用,毕竟都是要钱的玩意。。。这种场景是不是有点矛盾?目前博主手上掌控着不到20个k8s集群,总资源达9600c/19T,由于国有化原因一直没有上prometheus上(很多其他云原生的东西都没有上),我也不知道他们是怎么过来的╮(╯▽╰)╭。最近听老大说终于终于终于审批过了测试环境安装prometheus的申请,整起(☆▽☆)

方案需求:

  • 管理上需要满足各个项目组的隔离,各项目组只能看自己负责的系统应用(我们这边是用ns隔离)
  • grafana需要开发项目权限编辑,减轻运维负担
  • 尽可能节省资源

思考了下可以先这样改造

  • 第一点:一个prometheus实例对应一个tsdb,不能怼多个,看来需要多个prometheus实例,每个集群一个总控prometheus监控当前集群组件+各ns一个prometheus实例监控项目组
  • 第二点:我既然给项目组权限编辑,就得给他们edit角色,这个角色可以随意查看已接入得数据源数据,对于grafana博主开始以为这玩意能有数据源权限隔离,没想到是商业版上的功能。看来也得建多个实例啊
  • 第三点:根据前两点,好像这一点没得节省。。。顶多prometheus-operator公用,其他声明多个资源呗

初步假想以小组的管理拓扑,此处无alertmanager,因为网络出不了外网的

后续上升到部门视图则由一个grafana提供,这个资源成本由运维管理部门组提供,对于这个grafana,除了运维部门组有edit权限,其他业务部门都是view权限。该grafana会为每个部门提供部门级资源视图,给部门领导看的~,所以不会有太细的指标。。。

prometheus多实例部署

创建专门抓取kube-system空间的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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 删除prometheus-operator安装时起来得prometheus
[root@k8s-master manifests]# kubectl delete -f prometheus-prometheus.yaml

# 修改prometheus-prometheus.yaml,调整其只监控kube-system空间下得资源
[root@k8s-master manifests]# cat >prometheus-prometheus.yaml<<-'EOF'
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s-system
name: k8s-system
namespace: monitoring
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
image: quay.mirrors.ustc.edu.cn/prometheus/prometheus:v2.15.2
nodeSelector:
kubernetes.io/os: linux
podMonitorNamespaceSelector:
matchLabels:
monitoring-role: system
podMonitorSelector: {}
replicas: 1
resources:
requests:
memory: 400Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector:
matchLabels:
monitoring-role: system
serviceMonitorSelector: {}
version: v2.15.2
storage: # 添加pvc模板,存储类指向nfs
volumeClaimTemplate:
apiVersion: v1
kind: PersistentVolumeClaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: nfs-storage
EOF

创建专门抓取groupX空间的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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
[root@k8s-master manifests]# cat >prometheus-prometheus-group1.yaml<<-'EOF'
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s-group1
name: k8s-group1
namespace: monitoring
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
image: quay.mirrors.ustc.edu.cn/prometheus/prometheus:v2.15.2
nodeSelector:
kubernetes.io/os: linux
podMonitorNamespaceSelector:
matchLabels:
monitoring-role: group1
podMonitorSelector: {}
replicas: 1
resources:
requests:
memory: 400Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector:
matchLabels:
monitoring-role: group1
serviceMonitorSelector: {}
version: v2.15.2
storage: # 添加pvc模板,存储类指向nfs
volumeClaimTemplate:
apiVersion: v1
kind: PersistentVolumeClaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: nfs-storage
EOF

# 其他空间组的prometheus实例类似
[root@k8s-master manifests]# cp prometheus-prometheus-group1.yaml prometheus-prometheus-group2.yaml
[root@k8s-master manifests]# cp prometheus-prometheus-group1.yaml prometheus-prometheus-group3.yaml
[root@k8s-master manifests]# sed -i 's/group1/group2/g' prometheus-prometheus-group2.yaml
[root@k8s-master manifests]# sed -i 's/group1/group3/g' prometheus-prometheus-group3.yaml

[root@k8s-master manifests]# kubectl apply -f prometheus-prometheus-group1.yaml
prometheus.monitoring.coreos.com/k8s-group1 created
[root@k8s-master manifests]# kubectl apply -f prometheus-prometheus-group2.yaml
prometheus.monitoring.coreos.com/k8s-group2 created
[root@k8s-master manifests]# kubectl apply -f prometheus-prometheus-group3.yaml
prometheus.monitoring.coreos.com/k8s-group3 created

创建prometheus的svc服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@k8s-master manifests]# cat >prometheus-service.yaml<<-'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
prometheus: k8s
name: prometheus-k8s-system
namespace: monitoring
spec:
type: NodePort
ports:
- name: web
port: 9090
targetPort: web
selector:
app: prometheus
prometheus: k8s-system
sessionAffinity: ClientIP
EOF

[root@k8s-master manifests]# sed 's/system/group1/g' prometheus-service.yaml > prometheus-service-group1.yaml
[root@k8s-master manifests]# sed 's/system/group2/g' prometheus-service.yaml > prometheus-service-group2.yaml
[root@k8s-master manifests]# sed 's/system/group3/g' prometheus-service.yaml > prometheus-service-group3.yaml

此时集群内拥有几个prometheus实例

1
2
3
4
5
6
[root@k8s-master manifests]# kubectl get prometheus -n monitoring --show-labels
NAME VERSION REPLICAS AGE LABELS
k8s-group1 v2.15.2 1 63s prometheus=k8s-group1
k8s-group2 v2.15.2 1 55s prometheus=k8s-group2
k8s-group3 v2.15.2 1 46s prometheus=k8s-group3
k8s-system v2.15.2 1 88m prometheus=k8s-system

创建测试空间

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
# 创建测试空间
[root@k8s-master manifests]# kubectl create ns group1
namespace/group1 created
[root@k8s-master manifests]# kubectl create ns group2
namespace/group2 created
[root@k8s-master manifests]# kubectl create ns group3
namespace/group3 created

# 为空间打标签
[root@k8s-master manifests]# kubectl label ns group1 monitoring-role=group1
namespace/group1 labeled
[root@k8s-master manifests]# kubectl label ns group2 monitoring-role=group2
namespace/group2 labeled
[root@k8s-master manifests]# kubectl label ns group3 monitoring-role=group3
namespace/group2 labeled
[root@k8s-master manifests]# kubectl label ns kube-system monitoring-role=system
namespace/kube-system labeled

# 查看当前空间标签情况
[root@k8s-master manifests]# kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 3h43m <none>
group1 Active 2m46s monitoring-role=group1
group2 Active 2m44s monitoring-role=group2
group3 Active 2m42s monitoring-role=group3
kube-node-lease Active 3h43m <none>
kube-public Active 3h43m <none>
kube-system Active 3h43m monitoring-role=system
monitoring Active 3h41m <none>

为各空间创建app样例应用

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
53
54
55
56
57
[root@k8s-master example-app]# cat >group1-example-app.yaml<<-'EOF'
kind: Service
apiVersion: v1
metadata:
name: example-app
labels:
tier: frontend
group: group1
namespace: group1
spec:
selector:
app: example-app
ports:
- name: web
protocol: TCP
port: 8080
targetPort: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
namespace: group1
spec:
selector:
matchLabels:
app: example-app
version: 1.1.3
group: group1
replicas: 4
template:
metadata:
labels:
app: example-app
version: 1.1.3
group: group1
spec:
containers:
- name: example-app
image: quay.io/fabxc/prometheus_demo_service
ports:
- name: web
containerPort: 8080
protocol: TCP
EOF

[root@k8s-master example-app]# sed 's/group1/group2/g' group1-example-app.yaml > group2-example-app.yaml
[root@k8s-master example-app]# sed 's/group1/group3/g' group1-example-app.yaml > group3-example-app.yaml
[root@k8s-master example-app]# kubectl apply -f group1-example-app.yaml
service/example-app created
deployment.apps/example-app created
[root@k8s-master example-app]# kubectl apply -f group2-example-app.yaml
service/example-app created
deployment.apps/example-app created
[root@k8s-master example-app]# kubectl apply -f group3-example-app.yaml
service/example-app created
deployment.apps/example-app created

在各空间下创建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
[root@k8s-master example-app]# cat >servicemonitor-frontend-group1.yaml<<-'EOF'
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: monitor-frontend
namespace: group1
labels:
tier: frontend
group: group1
spec:
selector:
matchLabels:
tier: frontend
group: group1
targetLabels:
- tier
- group
endpoints:
- port: web
interval: 10s
namespaceSelector:
matchNames:
- group1
EOF

[root@k8s-master example-app]# sed 's/group1/group2/g' servicemonitor-frontend-group1.yaml > servicemonitor-frontend-group2.yaml
[root@k8s-master example-app]# sed 's/group1/group3/g' servicemonitor-frontend-group1.yaml > servicemonitor-frontend-group3.yaml

# 查看当前所有servicemonitor,自行将monitoring空间下的servicemonitor迁移到kube-system。。。
[root@k8s-master example-app]# kubectl get servicemonitor -A
NAMESPACE NAME AGE
group1 monitor-frontend 9m
group2 monitor-frontend 8s
group3 monitor-frontend 3s
kube-system kube-apiserver 4h12m
monitoring alertmanager 4h12m
monitoring coredns 4h12m
monitoring grafana 4h12m
monitoring kube-controller-manager 4h12m
monitoring kube-scheduler 4h12m
monitoring kube-state-metrics 4h12m
monitoring kubelet 4h12m
monitoring node-exporter 4h12m
monitoring prometheus 4h12m
monitoring prometheus-operator 4h12m

查看每个prometheus此时的target

至此,我们实现了每个prometheus监控特定的空间资源,接下就是grafan的多个实例部署

grafana接入多个数据源

此处只建一个grafana接入多个数据源,自行参考grafana-deployment.yaml修改创建多个grafana实例,然后为多个grafana接入不同数据源来分配给各个部门

使用configmap配置grafana

grafan的dashboardDatasources

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
[root@k8s-master manifests]# cat  grafana-dashboardDatasources.yaml
apiVersion: v1
data:
datasources.yaml: ewogICAgImFwaVZlcnNpb24iOiAxLAogICAgImRhdGFzb3VyY2VzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgIm9yZ0lkIjogMSwKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1cmwiOiAiaHR0cDovL3Byb21ldGhldXMtazhzLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9CiAgICBdCn0=
kind: Secret
metadata:
name: grafana-datasources
namespace: monitoring
type: Opaque

[root@k8s-master manifests]# echo 'ewogICAgImFwaVZlcnNpb24iOiAxLAogICAgImRhdGFzb3VyY2VzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgIm9yZ0lkIjogMSwKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1cmwiOiAiaHR0cDovL3Byb21ldGhldXMtazhzLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9CiAgICBdCn0=' base64 -d
{
"apiVersion": 1,
"datasources": [
{
"access": "proxy",
"editable": false,
"name": "prometheus",
"orgId": 1,
"type": "prometheus",
"url": "http://prometheus-k8s.monitoring.svc:9090",
"version": 1
}
]
}

# 上面是源文件内容,根据内容添加相应的数据源
[root@k8s-master manifests]# cat >datasource.json<<-'EOF'
{
"apiVersion": 1,
"datasources": [
{
"access": "proxy",
"editable": false,
"name": "cluster-devops-group1",
"orgId": 1,
"type": "prometheus",
"url": "http://prometheus-k8s-group1.monitoring.svc:9090",
"version": 1
},
{
"access": "proxy",
"editable": false,
"name": "cluster-devops-group2",
"orgId": 1,
"type": "prometheus",
"url": "http://prometheus-k8s-group2.monitoring.svc:9090",
"version": 1
},
{
"access": "proxy",
"editable": false,
"name": "cluster-devops-group3",
"orgId": 1,
"type": "prometheus",
"url": "http://prometheus-k8s-group3.monitoring.svc:9090",
"version": 1
},
{
"access": "proxy",
"editable": false,
"name": "cluster-devops-system",
"orgId": 1,
"type": "prometheus",
"url": "http://prometheus-k8s-system.monitoring.svc:9090",
"version": 1
}
]
}
EOF

[root@k8s-master manifests]# cat datasource.json base64 tr -d '\n'
ewogICAgImFwaVZlcnNpb24iOiAxLAogICAgImRhdGFzb3VyY2VzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJjbHVzdGVyLWRldm9wcy1ncm91cDEiLAogICAgICAgICAgICAib3JnSWQiOiAxLAogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVybCI6ICJodHRwOi8vcHJvbWV0aGV1cy1rOHMtZ3JvdXAxLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJjbHVzdGVyLWRldm9wcy1ncm91cDIiLAogICAgICAgICAgICAib3JnSWQiOiAxLAogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVybCI6ICJodHRwOi8vcHJvbWV0aGV1cy1rOHMtZ3JvdXAyLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJjbHVzdGVyLWRldm9wcy1ncm91cDMiLAogICAgICAgICAgICAib3JnSWQiOiAxLAogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVybCI6ICJodHRwOi8vcHJvbWV0aGV1cy1rOHMtZ3JvdXAzLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgImFjY2VzcyI6ICJwcm94eSIsCiAgICAgICAgICAgICJlZGl0YWJsZSI6IGZhbHNlLAogICAgICAgICAgICAibmFtZSI6ICJjbHVzdGVyLWRldm9wcy1zeXN0ZW0iLAogICAgICAgICAgICAib3JnSWQiOiAxLAogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVybCI6ICJodHRwOi8vcHJvbWV0aGV1cy1rOHMtc3lzdGVtLm1vbml0b3Jpbmcuc3ZjOjkwOTAiLAogICAgICAgICAgICAidmVyc2lvbiI6IDEKICAgICAgICB9CiAgICBdCn0gCg==

# 将上面base64编码后的内容重新写入grafana-dashboardDatasources.yaml并重建grafana应用
[root@k8s-master manifests]# kubectl replace -f grafana-dashboardDatasources.yaml
[root@k8s-master manifests]# kubectl delete pods -n monitoring grafana-7fbbc6cb58-zssh5

上面配置的是本集群的数据源,外部数据则提供nodeport或ingress方式接入,此处使用nodeport方式

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
# prod集群中的prometheus-system
[root@k8s-master manifests]# kubectl get svc -n monitoring grep k8s
prometheus-k8s-system NodePort 10.96.98.221 <none> 9090:32551/TCP,10901:32712/TCP 6s

# 回到中控集群为prod集群创建svc/ep
[root@k8s-master thanos]# cat >cluster-prod-system.yaml<<-'EOF'
---
apiVersion: v1
kind: Endpoints
metadata:
name: cluster-prod-system
namespace: monitoring
subsets:
- addresses:
- ip: 192.168.44.169
ports:
- name: http
port: 32551
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: cluster-prod-system
name: cluster-prod-system
namespace: monitoring
spec:
ports:
- name: http
port: 9090
protocol: TCP
targetPort: http
type: ClusterIP
EOF

[root@k8s-master thanos]# kubectl apply -f cluster-prod-system.yaml
endpoints/cluster-prod-system created
service/cluster-prod-system created
[root@k8s-master thanos]# kubectl get -f cluster-prod-system.yaml
NAME ENDPOINTS AGE
endpoints/cluster-prod-system 192.168.44.169:32551 4s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cluster-prod-system ClusterIP 10.96.224.101 <none> 9090/TCP 4s

# 重新修改grafana-dashboardDatasources.yaml添加数据源:cluster-prod-system.monitoring.svc:9090即可,此处略

至此我们的grafana已经可以接入多个项目组数据源,只需要一个部门一个grafana即可,让部门内在grafan使用team来划分group,实现部门自治

grafan的dashboard面板json

当有了集群划分后,则对于system空间得面板就有得调整了,我们需将面板的datasource变量过滤下(不然会有很多无关数据源),以apiserver面板为例

上面修改完成后无法是无法保存的,需要将修改后的json文件拿下来重新创建dashboard.yaml即可,dashboard资源定义在grafana-dashboardDefinitions.yaml,自行参考并未该json创建对应的confimap文件

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
[root@k8s-master manifests]# kubectl get cm -n monitoring  grep das
grafana-dashboard-apiserver 1 4d3h
grafana-dashboard-cluster-total 1 4d3h
grafana-dashboard-controller-manager 1 4d3h
grafana-dashboard-k8s-resources-cluster 1 4d3h
grafana-dashboard-k8s-resources-namespace 1 4d3h
grafana-dashboard-k8s-resources-node 1 4d3h
grafana-dashboard-k8s-resources-pod 1 4d3h
grafana-dashboard-k8s-resources-workload 1 4d3h
grafana-dashboard-k8s-resources-workloads-namespace 1 4d3h
grafana-dashboard-kubelet 1 4d3h
grafana-dashboard-namespace-by-pod 1 4d3h
grafana-dashboard-namespace-by-workload 1 4d3h
grafana-dashboard-node-cluster-rsrc-use 1 4d3h
grafana-dashboard-node-rsrc-use 1 4d3h
grafana-dashboard-nodes 1 4d3h
grafana-dashboard-persistentvolumesusage 1 4d3h
grafana-dashboard-pod-total 1 4d3h
grafana-dashboard-prometheus 1 4d3h
grafana-dashboard-prometheus-remote-write 1 4d3h
grafana-dashboard-proxy 1 4d3h
grafana-dashboard-scheduler 1 4d3h
grafana-dashboard-statefulset 1 4d3h
grafana-dashboard-workload-total 1 4d3h
grafana-dashboards 1 4d3h

# 自行准备apiserver.json
[root@k8s-master manifests]# kubectl -n monitoring delete cm grafana-dashboard-apiserver
[root@k8s-master manifests]# kubectl -n monitoring create cm grafana-dashboard-apiserver --from-file=apiserver.json

# dashobard挂载文件在grafana-deployment.yaml,自行参考新增

使用thanos模式优化管理员视角

部署thanos sidecar

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
53
54
55
56
[root@k8s-master manifests]# cat prometheus-prometheus.yaml
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s-system
name: k8s-system
namespace: monitoring
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
image: quay.mirrors.ustc.edu.cn/prometheus/prometheus:v2.15.2
nodeSelector:
kubernetes.io/os: linux
podMonitorNamespaceSelector:
matchLabels:
monitoring-role: system
podMonitorSelector: {}
replicas: 1
resources:
requests:
memory: 400Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector:
matchLabels:
monitoring-role: system
serviceMonitorSelector: {}
version: v2.15.2
externalLabels:
env: devops # 部署到不同环境需要修改此处label
cluster: devops-idc-cluster # 部署到不同环境需要修改此处label
storage: # 添加pvc模板,存储类指向nfs
volumeClaimTemplate:
apiVersion: v1
kind: PersistentVolumeClaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: nfs-storage
thanos: # 添加thano-sidecar容器
baseImage: thanosio/thanos
version: main-2022-09-22-ff9ee9ac

部署query组件

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
53
54
55
56
57
58
[root@k8s-master thanos]# cat thanos-query.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-query
namespace: monitoring
labels:
app: thanos-query
spec:
selector:
matchLabels:
app: thanos-query
template:
metadata:
labels:
app: thanos-query
spec:
containers:
- name: thanos
image: thanosio/thanos:main-2022-09-22-ff9ee9ac
args:
- query
- --log.level=debug
- --query.replica-label=prometheus_replica # prometheus-operator 里面配置的副本标签为 prometheus_replica
# Discover local store APIs using DNS SRV.
- --store=192.168.44.151:30901
ports:
- name: http
containerPort: 10902
- name: grpc
containerPort: 10901
livenessProbe:
httpGet:
path: /-/healthy
port: http
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /-/healthy
port: http
initialDelaySeconds: 15
---
apiVersion: v1
kind: Service
metadata:
name: thanos-query
namespace: monitoring
labels:
app: thanos-query
spec:
ports:
- port: 9090
targetPort: http
name: http
nodePort: 30909
selector:
app: thanos-query
type: NodePort

打开thanos-query界面

grafana接入keycloak进行统一认证管理

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
bash-5.0$ egrep -v '^$^#' /etc/grafana/grafana.ini
;app_mode = production
;instance_name = ${HOSTNAME}
[paths]
;data = /var/lib/grafana
;temp_data_lifetime = 24h
;logs = /var/log/grafana
;plugins = /var/lib/grafana/plugins
;provisioning = conf/provisioning
[server]
;protocol = http
;http_addr =
;http_port = 3000
;domain = localhost
;enforce_domain = false
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
;serve_from_sub_path = false
;router_logging = false
;static_root_path = public
;enable_gzip = false
;cert_file =
;cert_key =
;socket =
[database]
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
;password =
;url =
;ssl_mode = disable
;ca_cert_path =
;client_key_path =
;client_cert_path =
;server_cert_name =
;path = grafana.db
;max_idle_conn = 2
;max_open_conn =
;conn_max_lifetime = 14400
;log_queries =
;cache_mode = private
[remote_cache]
;type = database
;connstr =
[dataproxy]
;logging = false
;timeout = 30
;send_user_header = false
[analytics]
;reporting_enabled = true
;check_for_updates = true
;google_analytics_ua_id =
;google_tag_manager_id =
[security]
;disable_initial_admin_creation = false
;admin_user = admin
;admin_password = admin
;secret_key = SW2YcwTIb9zpOOhoPsMm
;disable_gravatar = false
;data_source_proxy_whitelist =
;disable_brute_force_login_protection = false
;cookie_secure = false
;cookie_samesite = lax
;allow_embedding = false
;strict_transport_security = false
;strict_transport_security_max_age_seconds = 86400
;strict_transport_security_preload = false
;strict_transport_security_subdomains = false
;x_content_type_options = false
;x_xss_protection = false
[snapshots]
;external_enabled = true
;external_snapshot_url = https://snapshots-origin.raintank.io
;external_snapshot_name = Publish to snapshot.raintank.io
;public_mode = false
;snapshot_remove_expired = true
[dashboards]
;versions_to_keep = 20
[users]
;allow_sign_up = true
;allow_org_create = true
;auto_assign_org = true
;auto_assign_org_id = 1
;auto_assign_org_role = Viewer
;verify_email_enabled = false
;login_hint = email or username
;password_hint = password
;default_theme = dark
;external_manage_link_url =
;external_manage_link_name =
;external_manage_info =
;viewers_can_edit = false
;editors_can_admin = false
[auth]
;login_cookie_name = grafana_session
;login_maximum_inactive_lifetime_days = 7
;login_maximum_lifetime_days = 30
;token_rotation_interval_minutes = 10
;disable_login_form = false
;disable_signout_menu = false
;signout_redirect_url =
;oauth_auto_login = false
;api_key_max_seconds_to_live = -1
[auth.anonymous]
;enabled = false
;org_name = Main Org.
;org_role = Viewer
[auth.github]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://github.com/login/oauth/authorize
;token_url = https://github.com/login/oauth/access_token
;api_url = https://api.github.com/user
;allowed_domains =
;team_ids =
;allowed_organizations =
[auth.gitlab]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = api
;auth_url = https://gitlab.com/oauth/authorize
;token_url = https://gitlab.com/oauth/token
;api_url = https://gitlab.com/api/v4
;allowed_domains =
;allowed_groups =
[auth.google]
;enabled = false
;allow_sign_up = true
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
;auth_url = https://accounts.google.com/o/oauth2/auth
;token_url = https://accounts.google.com/o/oauth2/token
;api_url = https://www.googleapis.com/oauth2/v1/userinfo
;allowed_domains =
;hosted_domain =
[auth.grafana_com]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =
[auth.generic_oauth]
;enabled = false
;name = OAuth
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;email_attribute_name = email:primary
;email_attribute_path =
;auth_url = https://foo.bar/login/oauth/authorize
;token_url = https://foo.bar/login/oauth/access_token
;api_url = https://foo.bar/user
;allowed_domains =
;team_ids =
;allowed_organizations =
;role_attribute_path =
;tls_skip_verify_insecure = false
;tls_client_cert =
;tls_client_key =
;tls_client_ca =
[auth.saml] # Enterprise only
;enabled = false
;certificate =
;certificate_path =
;private_key =
;# Path to the private key. Used to decrypt assertions from the IdP
;private_key_path =
;idp_metadata =
;idp_metadata_path =
;idp_metadata_url =
;max_issue_delay = 90s
;metadata_valid_duration = 48h
;assertion_attribute_name = displayName
;assertion_attribute_login = mail
;assertion_attribute_email = mail
[auth.basic]
;enabled = true
[auth.proxy]
;enabled = false
;header_name = X-WEBAUTH-USER
;header_property = username
;auto_sign_up = true
;sync_ttl = 60
;whitelist = 192.168.1.1, 192.168.2.1
;headers = Email:X-User-Email, Name:X-User-Name
;enable_login_token = false
[auth.ldap]
;enabled = false
;config_file = /etc/grafana/ldap.toml
;allow_sign_up = true
;sync_cron = "0 0 1 * * *"
;active_sync_enabled = true
[smtp]
;enabled = false
;host = localhost:25
;user =
;password =
;cert_file =
;key_file =
;skip_verify = false
;from_address = admin@grafana.localhost
;from_name = Grafana
;ehlo_identity = dashboard.example.com
[emails]
;welcome_email_on_sign_up = false
;templates_pattern = emails/*.html
[log]
;mode = console file
;level = info
;filters =
[log.console]
;level =
;format = console
[log.file]
;level =
;format = text
;log_rotate = true
;max_lines = 1000000
;max_size_shift = 28
;daily_rotate = true
;max_days = 7
[log.syslog]
;level =
;format = text
;network =
;address =
;facility =
;tag =
[quota]
; enabled = false
; org_user = 10
; org_dashboard = 100
; org_data_source = 10
; org_api_key = 10
; user_org = 10
; global_user = -1
; global_org = -1
; global_dashboard = -1
; global_api_key = -1
; global_session = -1
[alerting]
;enabled = true
;execute_alerts = true
;error_or_timeout = alerting
;nodata_or_nullvalues = no_data
;concurrent_render_limit = 5
;evaluation_timeout_seconds = 30
;notification_timeout_seconds = 30
;max_attempts = 3
;min_interval_seconds = 1
[explore]
;enabled = true
[metrics]
;enabled = true
;interval_seconds = 10
;disable_total_stats = false
; basic_auth_username =
; basic_auth_password =
[metrics.graphite]
;address =
;prefix = prod.grafana.%(instance_name)s.
[grafana_com]
;url = https://grafana.com
[tracing.jaeger]
;address = localhost:6831
;always_included_tag = tag1:value1
;sampler_type = const
;sampler_param = 1
;zipkin_propagation = false
;disable_shared_zipkin_spans = false
[external_image_storage]
;provider =
[external_image_storage.s3]
;endpoint =
;path_style_access =
;bucket =
;region =
;path =
;access_key =
;secret_key =
[external_image_storage.webdav]
;url =
;public_url =
;username =
;password =
[external_image_storage.gcs]
;key_file =
;bucket =
;path =
[external_image_storage.azure_blob]
;account_name =
;account_key =
;container_name =
[external_image_storage.local]
[rendering]
;server_url =
;callback_url =
[panels]
;disable_sanitize_html = false
[plugins]
;enable_alpha = false
;app_tls_skip_verify_insecure = false
[enterprise]
;license_path =
[feature_toggles]
;enable =