在OpenFaas自带的Prometheus中接入k8s集群性能监控

需求概述

OpenFaas部署后,自带的Prometheus默认只能监控函数级别的指标,现在想要将k8s集群的监控也接入到OpenFaas自带的Prometheus中,因此需要进行相关的处理。

除了函数性能之外,我们主要进行三方面的性能监控:

  • pod性能:容器的相关性能,使用cadvisor来实现监控
  • node性能:物理机节点的相关性能,使用node-exporter来实现监控
  • k8s性能:k8s资源对象,包括pod、service、deployment等,使用kube-state-metrics来实现监控

准备工作

OpenFaas中的Prometheus,对应的配置文件等存放在fass-netes/yaml目录下,对应有四个文件,分别为prometheus-cfg.ymlprometheus-dep.ymlprometheus-rabc.ymlprometheus-svc.yml

默认情况下,OpenFaas中的Prometheus服务并没有向外暴露端口。我们需要修改prometheus-svc.yml,将其类型修改为NodePort,并指定暴露端口。这里向外暴露端口为31119,修改内容如下:

1
2
3
4
5
6
7
8
spec:
type: NodePort
ports:
- name: http
port: 9090
targetPort: 9090
protocol: TCP
nodePort: 31119

prometheus-rabc.yml文件中,我们需要修改其中的Role Kind,以及添加相关的规则。主要修改为kind从Role变为ClusterRole、在rules中添加更多的规则、rolebinding的类型从RoleBinding修改为ClusterRoleBinding,以及roleRef的类型修改为ClusterRole。修改后的整体文件内容如下:

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
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: openfaas-prometheus
namespace: "openfaas"
labels:
app: openfaas
component: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: openfaas-prometheus
namespace: "openfaas"
labels:
app: openfaas
component: prometheus
rules:
- apiGroups: [""]
resources:
- services
- endpoints
- pods
- nodes
- nodes/proxy
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources:
- configmaps
verbs: ["get"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: openfaas-prometheus-fn
namespace: "openfaas-fn"
labels:
app: openfaas
component: prometheus
rules:
- apiGroups: [""]
resources:
- services
- endpoints
- pods
- nodes
- nodes/proxy
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources:
- configmaps
verbs: ["get"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: openfaas-prometheus
namespace: "openfaas"
labels:
app: openfaas
component: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: openfaas-prometheus
subjects:
- kind: ServiceAccount
name: openfaas-prometheus
namespace: "openfaas"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: openfaas-prometheus-fn
namespace: "openfaas-fn"
labels:
app: openfaas
component: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: openfaas-prometheus-fn
subjects:
- kind: ServiceAccount
name: openfaas-prometheus
namespace: "openfaas"

prometheus-dep.yml文件不做修改。

prometheus-cfg.yml文件会在后续进行较多的修改,这里就首先简单介绍一下该配置文件中的格式。我们主要关注该文件中data下的prometheus.yml,有如下的结构:

  • global:全局的默认配置
  • rule_files:获取所有规则文件中的规则,包括报警规则和数据处理的规则
  • alerting:定义告警属性,用来管理Alertmanager
  • scrape_configs:用于配置拉取数据节点。我们后续的监控数据接入也是在这个部分完成的。每个拉取配置主要包含下面的参数
    • job_name:任务名称
    • honor_labels: 用于解决拉取数据标签有冲突,当设置为 true, 以拉取数据为准,否则以服务配置为准
    • params:数据拉取访问时带的请求参数
    • scrape_interval: 拉取时间间隔
    • scrape_timeout: 拉取超时时间
    • metrics_path: 拉取节点的 metric 路径
    • static_configs:配置访问路径前缀,如ip+port,或者域名地址,或者通过服务发现,
    • scheme: 拉取数据访问协议,如http
    • sample_limit: 存储的数据标签个数限制,如果超过限制,该数据将被忽略,不入存储;默认值为0,表示没有限制
    • relabel_configs: 拉取数据重置标签配置
    • metric_relabel_configs:metric 重置标签配置

cadvisor

cadvisor可以对物理机器Node上的资源以及容器进行实时监控和性能数据采集,包括CPU占用、内存使用情况、网络吞吐量以及文件系统使用情况等。在k8s集群上,每个Node机器上都会有一个cadvisor对该机器进行监控。在已有k8s集群的前提下,我们无需额外安装。

接下来我们需要将监控数据接入OpenFaas下的Prometheus。接入方式就是在prometheus-cfg.yml文件中的scrape_configs中添加相应的任务配置项。在添加过程中我们可以静态指定节点,也可以利用Prometheus对k8s的自动服务发现,包括对node、service、pod、endpoint等的自动服务发现,即自动识别所有在k8s集群中的角色。

添加的任务配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# k8s的node节点自动发现,自动发现k8s中所有node节点并进行监控
- job_name: 'kubernetes-cadvisor'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
target_label: __metrics_path__
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- source_labels: [__meta_kubernetes_node_name]
action: replace
target_label: node
- source_labels: [__meta_kubernetes_node_label_node]
action: replace
target_label: node_name

添加完配置之后,对服务进行更新。利用kubectl apply重新配置资源,然后重启对应的pod。这里重新启动我们直接删除对应的pod,因为对应的pod创建器没有被删除,因此执行删除操作后,k8s会再次启动一个pod。

1
2
3
4
5
6
7
kubectl apply -f prometheus-cfg.yml

# 查看对应的pod名称 prometheus-xxxxxxxxxx-xxxxx
kubectl get pods -n openfaas

# 删除对应的pod
kubectl delete pod prometheus-xxxxxxxxxx-xxxxx -n openfaas

之后就可以在Prometheus的前端页面进行查看,在Target页面中会出现kubernetes-cadvisor任务,在查询页面中能够出现容器相关信息即表示配置成功。

node-exporter

node-exporter可以监控物理机系统级别的信息,包括服务器CPU占用、内存、磁盘和IO等信息。使用node-exporter之前我们需要在集群中的每个节点上都进行安装,首先下载对应的可执行文件node-exporter,之后创建对应的配置文件,最后启动服务即可。这里我们可以使用脚本完成安装:

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
#!/bin/bash
#批量安装node_exporter
soft_dir=/root/soft
if [ ! -e $soft_dir ];then
mkdir $soft_dir
fi

netstat -lnpt | grep 9100
if [ $? -eq 0 ];then
use=`netstat -lnpt | grep 9100 | awk -F/ '{print $NF}'`
echo "9100端口已经被占用,占用者是 $use"
exit 1
fi

cd $soft_dir
wget https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-amd64.tar.gz
tar xf node_exporter-1.0.1.linux-amd64.tar.gz
mv node_exporter-1.0.1.linux-amd64 /usr/local/node_exporter

cat <<EOF >/usr/lib/systemd/system/node_exporter.service
[Unit]
Description=https://prometheus.io

[Service]
Restart=on-failure
ExecStart=/usr/local/node_exporter/node_exporter --collector.systemd --collector.systemd.unit-whitelist=(docker|kubelet|node_exporter).service

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable node_exporter
systemctl restart node_exporter

netstat -lnpt | grep 9100

if [ $? -eq 0 ];then
echo "node_eporter install finish..."
fi

执行完毕之后可以查看对应的9100端口情况netstat -nlpt | grep 9100

安装完成之后,需要在Prometheus配置文件中添加任务配置,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# node_exporter服务自动发现
- job_name: 'kubernetes-node-exporter'
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
action: replace
- source_labels: [__meta_kubernetes_node_name]
action: replace
target_label: node
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- source_labels: [__meta_kubernetes_node_address_InternalIP]
action: replace
target_label: ip

同样重启服务之后在前端进行查看,在Target页面下出现kubernetes-node-exporter,在查询页面中出现节点相关信息则表示配置成功。

kube-state-metrics

kube-state-metrics可以监控k8s内部对象的状态,如nodes、pods、deployments等。在使用之前需要进行部署,需要用到的yaml文件在官方文档中路径录下https://github.com/kubernetes/kube-state-metrics/tree/master/examples/standard。我们需要修改其中的service.yaml,在metadata中添加如下内容:

1
2
3
metadata:
annotations:
prometheus.io/scrape: 'true'

之后执行命令进行部署:

1
kubectl apply -f .

可以使用kubectl get pods --all-namespaces来查看部署情况,如果全部为running则表示部署成功。但是在kube-state-metrics的部署过程中,可能会出现镜像无法拉取的情况,需要的镜像为registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0,我们可以通过本地拉取镜像之后改名的操作来解决对应的问题。首先docker search进行镜像的搜索,docker pull拉取对应的镜像之后,使用docker tag进行名称修改。

当pod出现错误的时候,我们可以使用如下的错误信息查看指令,错误信息能够帮助我们快速定位和解决。

1
2
3
4
5
6
7
8
# 首先查看对应的pod名称
kubectl get pods -n namespace_name

# 查看详细信息
kubectl describe pod pod_name -n namespace_name

# 查看日志
kubectl logs -f --tail=200 pod_name -n namespace_name

在kube-state-metrics对应的pod运行起来后,向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
# kube-state-metrics
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
- source_labels: [__meta_kubernetes_pod_container_port_number]
action: replace
target_label: container_port

同样进行Prometheus服务的重新启动,在Target页面下出现kubernetes-service-endpoints,在查询页面下能够出现kubernetes相关信息即表示配置成功。

参考文章

  1. prometheus监控k8s集群_fengge55的博客-CSDN博客_prometheus监控k8s集群
  2. 总结:Promethus配置文件_小魏的博客的博客-CSDN博客_prometheus配置文件
  3. prometheus监控k8s集群系列之cadvisor篇_一粒菜鸟的博客-CSDN博客_cadvisor prometheus
  4. prometheus监控k8s集群系列之node-exporter篇_一粒菜鸟的博客-CSDN博客_k8s node-exporter
  5. prometheus监控k8s集群系列之kube-state-metrics_一粒菜鸟的博客-CSDN博客_prometheus-kube-state-metrics
  6. k8s拉取镜像失败处理 ImagePullBackOff ErrImageNeverPull_车码平川的博客-CSDN博客_k8s拉取镜像失败

在OpenFaas自带的Prometheus中接入k8s集群性能监控
http://example.com/2022/07/30/在OpenFaas自带的Prometheus中接入k8s集群性能监控/
作者
EverNorif
发布于
2022年7月30日
许可协议