Prometheus的配置与服务发现
本文将分析Prometheus的常见配置与服务发现,分为概述、配置详解、服务发现、常见场景四个部分进行讲解。

一. 概述

Prometheus的配置可以用命令行参数、或者配置文件,如果是在k8s集群内,一般配置在configmap中(以下均为prometheus2.7版本)
查看可用的命令行参数,可以执行 ./prometheus -h
也可以指定对应的配置文件,参数:--config.file 一般为prometheus.yml
如果配置有修改,如增添采集job,Prometheus可以重新加载它的配置。只需要向其 进程发送SIGHUP或向/-/reload端点发送HTTP POST请求。如:
curl -X POST http://localhost:9090/-/reload

二. 配置详解

2.1 命令行参数

执行./prometheus -h 可以看到各个参数的含义,例如:
1
--web.listen-address="0.0.0.0:9090" 监听端口默认为9090,可以修改只允许本机访问,或者为了安全起见,可以改变其端口号(默认的web服务没有鉴权)
2
3
--web.max-connections=512 默认最大连接数:512
4
5
--storage.tsdb.path="data/" 默认的存储路径:data目录下
6
7
--storage.tsdb.retention.time=15d 默认的数据保留时间:15天。原有的storage.tsdb.retention配置已经被废弃
8
9
--alertmanager.timeout=10s 把报警发送给alertmanager的超时限制 10s
10
11
--query.timeout=2m 查询超时时间限制默认为2min,超过自动被kill掉。可以结合grafana的限时配置如60s
12
13
--query.max-concurrency=20 并发查询数 prometheus的默认采集指标中有一项prometheus_engine_queries_concurrent_max可以拿到最大查询并发数及查询情况
14
15
--log.level=info 日志打印等级一共四种:[debug, info, warn, error],如果调试属性可以先改为debug等级
16
17
.....
Copied!
在prometheus的页面上,status的Command-Line Flags中,可以看到当前配置,如promethues-operator的配置是:

2.2 prometheus.yml

从官方的download页下载的promethues二进制文件,会自带一份默认配置prometheus.yml
3
[email protected] console_libraries
5
6
[email protected] prometheus.yml
Copied!
prometheus.yml配置了很多属性,包括远程存储、报警配置等很多内容,下面将对主要属性进行解释:
1
# 默认的全局配置
2
global:
3
scrape_interval: 15s # 采集间隔15s,默认为1min一次
4
evaluation_interval: 15s # 计算规则的间隔15s默认为1min一次
5
scrape_timeout: 10s # 采集超时时间,默认为10s
6
external_labels: # 当和其他外部系统交互时的标签,如远程存储、联邦集群时
7
prometheus: monitoring/k8s # 如:prometheus-operator的配置
8
prometheus_replica: prometheus-k8s-1
9
10
# Alertmanager的配置
11
alerting:
12
alertmanagers:
13
- static_configs:
14
- targets:
15
- 127.0.0.1:9093 # alertmanager的服务地址,如127.0.0.1:9093
16
alert_relabel_configs: # 在抓取之前对任何目标及其标签进行修改。
17
- separator: ;
18
regex: prometheus_replica
19
replacement: $1
20
action: labeldrop
21
22
# 一旦加载了报警规则文件,将按照evaluation_interval即15s一次进行计算,rule文件可以有多个
23
rule_files:
24
# - "first_rules.yml"
25
# - "second_rules.yml"
26
27
# scrape_configs为采集配置,包含至少一个job
28
29
scrape_configs:
30
# Prometheus的自身监控 将在采集到的时间序列数据上打上标签job=xx
31
- job_name: 'prometheus'
32
# 采集指标的默认路径为:/metrics,如 localhost:9090/metric
33
# 协议默认为http
34
static_configs:
35
- targets: ['localhost:9090']
36
37
# 远程读,可选配置,如将监控数据远程读写到influxdb的地址,默认为本地读写
38
remote_write:
39
127.0.0.1:8090
40
41
# 远程写
42
remote_read:
43
127.0.0.1:8090
Copied!

2.3 scrape_configs配置

prometheus的配置中,最常用的就是scrape_configs配置,比如添加新的监控项,修改原有监控项的地址频率等。
最简单配置为:
1
scrape_configs:
2
- job_name: prometheus
3
metrics_path: /metrics
4
scheme: http
5
static_configs:
6
- targets:
7
- localhost:9090
Copied!
完整配置为(附prometheus-operator的推荐配置):
1
# job 将以标签形式出现在指标数据中,如node-exporter采集的数据,job=node-exporter
2
job_name: node-exporter
3
4
# 采集频率:30s
5
scrape_interval: 30s
6
7
# 采集超时:10s
8
scrape_timeout: 10s
9
10
# 采集对象的path路径
11
metrics_path: /metrics
12
13
# 采集协议:http或者https
14
scheme: https
15
16
# 可选的采集url的参数
17
params:
18
name: demo
19
20
# 当自定义label和采集到的自带label冲突时的处理方式,默认冲突时会重名为exported_xx
21
honor_labels: false
22
23
24
# 当采集对象需要鉴权才能获取时,配置账号密码等信息
25
basic_auth:
26
username: admin
27
password: admin
28
password_file: /etc/pwd
29
30
# bearer_token或者文件位置(OAuth 2.0鉴权)
31
bearer_token: kferkhjktdgjwkgkrwg
32
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
33
34
# https的配置,如跳过认证,或配置证书文件
35
tls_config:
36
# insecure_skip_verify: true
37
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
38
server_name: kubernetes
39
insecure_skip_verify: false
40
41
# 代理地址
42
proxy_url: 127.9.9.0:9999
43
44
# Azure的服务发现配置
45
azure_sd_configs:
46
47
# Consul的服务发现配置
48
consul_sd_configs:
49
50
# DNS的服务发现配置
51
dns_sd_configs:
52
53
# EC2的服务发现配置
54
ec2_sd_configs:
55
56
# OpenStack的服务发现配置
57
openstack_sd_configs:
58
59
# file的服务发现配置
60
file_sd_configs:
61
62
# GCE的服务发现配置
63
gce_sd_configs:
64
65
# Marathon的服务发现配置
66
marathon_sd_configs:
67
68
# AirBnB的服务发现配置
69
nerve_sd_configs:
70
71
# Zookeeper的服务发现配置
72
serverset_sd_configs:
73
74
# Triton的服务发现配置
75
triton_sd_configs:
76
77
# Kubernetes的服务发现配置
78
kubernetes_sd_configs:
79
- role: endpoints
80
namespaces:
81
names:
82
- monitoring
83
84
# 对采集对象进行一些静态配置,如打特定的标签
85
static_configs:
86
- targets: ['localhost:9090', 'localhost:9191']
87
labels:
88
my: label
89
your: label
90
91
# 在Prometheus采集数据之前,通过Target实例的Metadata信息,动态重新写入Label的值。
92
如将原始的__meta_kubernetes_namespace直接写成namespace,简洁明了
93
94
relabel_configs:
95
- source_labels: [__meta_kubernetes_namespace]
96
separator: ;
97
regex: (.*)
98
target_label: namespace
99
replacement: $1
100
action: replace
101
- source_labels: [__meta_kubernetes_service_name]
102
separator: ;
103
regex: (.*)
104
target_label: service
105
replacement: $1
106
action: replace
107
- source_labels: [__meta_kubernetes_pod_name]
108
separator: ;
109
regex: (.*)
110
target_label: pod
111
replacement: $1
112
action: replace
113
- source_labels: [__meta_kubernetes_service_name]
114
separator: ;
115
regex: (.*)
116
target_label: job
117
replacement: ${1}
118
action: replace
119
- separator: ;
120
regex: (.*)
121
target_label: endpoint
122
replacement: web
123
action: replace
124
125
# 指标relabel的配置,如丢掉某些无用的指标
126
metric_relabel_configs:
127
- source_labels: [__name__]
128
separator: ;
129
regex: etcd_(debugging|disk|request|server).*
130
replacement: $1
131
action: drop
132
133
# 限制最大采集样本数,超过了采集将会失败,默认为0不限制
134
sample_limit: 0
Copied!

三. 服务发现

上边的配置文件中,有很多*_sd_configs的配置,如kubernetes_sd_configs,就是用于服务发现的采集配置。
支持的服务发现类型:
1
// prometheus/discovery/config/config.go
2
type ServiceDiscoveryConfig struct {
3
StaticConfigs []*targetgroup.Group `yaml:"static_configs,omitempty"`
4
DNSSDConfigs []*dns.SDConfig `yaml:"dns_sd_configs,omitempty"`
5
FileSDConfigs []*file.SDConfig `yaml:"file_sd_configs,omitempty"`
6
ConsulSDConfigs []*consul.SDConfig `yaml:"consul_sd_configs,omitempty"`
7
ServersetSDConfigs []*zookeeper.ServersetSDConfig `yaml:"serverset_sd_configs,omitempty"`
8
NerveSDConfigs []*zookeeper.NerveSDConfig `yaml:"nerve_sd_configs,omitempty"`
9
MarathonSDConfigs []*marathon.SDConfig `yaml:"marathon_sd_configs,omitempty"`
10
KubernetesSDConfigs []*kubernetes.SDConfig `yaml:"kubernetes_sd_configs,omitempty"`
11
GCESDConfigs []*gce.SDConfig `yaml:"gce_sd_configs,omitempty"`
12
EC2SDConfigs []*ec2.SDConfig `yaml:"ec2_sd_configs,omitempty"`
13
OpenstackSDConfigs []*openstack.SDConfig `yaml:"openstack_sd_configs,omitempty"`
14
AzureSDConfigs []*azure.SDConfig `yaml:"azure_sd_configs,omitempty"`
15
TritonSDConfigs []*triton.SDConfig `yaml:"triton_sd_configs,omitempty"`
16
}
Copied!
因为prometheus采用的是pull方式来拉取监控数据,这种方式需要由server侧决定采集的目标有哪些,即配置在scrape_configs中的各种job,pull方式的主要缺点就是无法动态感知新服务的加入,因此大多数监控都默认支持服务发现机制,自动发现集群中的新端点,并加入到配置中。
Prometheus支持多种服务发现机制:文件,DNS,Consul,Kubernetes,OpenStack,EC2等等。基于服务发现的过程并不复杂,通过第三方提供的接口,Prometheus查询到需要监控的Target列表,然后轮询这些Target获取监控数据。
对于kubernetes而言,Promethues通过与Kubernetes API交互,然后轮询资源端点。目前主要支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。对应配置文件中的role: node/role:service
如:动态获取所有节点node的信息,可以添加如下配置:
1
- job_name: kubernetes-nodes
2
scrape_interval: 1m
3
scrape_timeout: 10s
4
metrics_path: /metrics
5
scheme: https
6
kubernetes_sd_configs:
7
- api_server: null
8
role: node
9
namespaces:
10
names: []
11
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
12
tls_config:
13
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
14
insecure_skip_verify: true
15
relabel_configs:
16
- separator: ;
17
regex: __meta_kubernetes_node_label_(.+)
18
replacement: $1
19
action: labelmap
20
- separator: ;
21
regex: (.*)
22
target_label: __address__
23
replacement: kubernetes.default.svc:443
24
action: replace
25
- source_labels: [__meta_kubernetes_node_name]
26
separator: ;
27
regex: (.+)
28
target_label: __metrics_path__
29
replacement: /api/v1/nodes/${1}/proxy/metrics
30
action: replace
Copied!
就可以在target中看到具体内容
对应的service、pod也是同样的方式。
需要注意的是,为了能够让Prometheus能够访问收到Kubernetes API,我们要对Prometheus进行访问授权,即serviceaccount。否则就算配置了,也没有权限获取。
prometheus的权限配置是一组ClusterRole+ClusterRoleBinding+ServiceAccount,然后在deployment或statefulset中指定serviceaccount。
ClusterRole.yaml
1
apiVersion: rbac.authorization.k8s.io/v1
2
kind: ClusterRole
3
metadata:
4
namespace: kube-system
5
name: prometheus
6
rules:
7
- apiGroups: [""]
8
resources:
9
- configmaps
10
- secrets
11
- nodes
12
- pods
13
- nodes/proxy
14
- services
15
- resourcequotas
16
- replicationcontrollers
17
- limitranges
18
- persistentvolumeclaims
19
- persistentvolumes
20
- namespaces
21
- endpoints
22
verbs: ["get", "list", "watch"]
23
- apiGroups: ["extensions"]
24
resources:
25
- daemonsets
26
- deployments
27
- replicasets
28
- ingresses
29
verbs: ["get", "list", "watch"]
30
- apiGroups: ["apps"]
31
resources:
32
- daemonsets
33
- deployments
34
- replicasets
35
- statefulsets
36
verbs: ["get", "list", "watch"]
37
- apiGroups: ["batch"]
38
resources:
39
- cronjobs
40
- jobs
41
verbs: ["get", "list", "watch"]
42
- apiGroups: ["autoscaling"]
43
resources:
44
- horizontalpodautoscalers
45
verbs: ["get", "list", "watch"]
46
- apiGroups: ["policy"]
47
resources:
48
- poddisruptionbudgets
49
verbs: ["get", list", "watch"]
50
- nonResourceURLs: ["/metrics"]
51
verbs: ["get"]
Copied!
ClusterRoleBinding.yaml
1
apiVersion: rbac.authorization.k8s.io/v1
2
kind: ClusterRoleBinding
3
metadata:
4
namespace: kube-system
5
name: prometheus
6
roleRef:
7
apiGroup: rbac.authorization.k8s.io
8
kind: ClusterRole
9
name: prometheus
10
subjects:
11
- kind: ServiceAccount
12
name: prometheus
13
namespace: kube-system
Copied!
ServiceAccount.yaml
1
apiVersion: v1
2
kind: ServiceAccount
3
metadata:
4
namespace: kube-system
5
name: prometheus
Copied!
prometheus.yaml
1
....
2
spec:
3
serviceAccountName: prometheus
4
5
....
Copied!
完整的kubernete的配置如下:
1
- job_name: kubernetes-apiservers
2
scrape_interval: 1m
3
scrape_timeout: 10s
4
metrics_path: /metrics
5
scheme: https
6
kubernetes_sd_configs:
7
- api_server: null
8
role: endpoints
9
namespaces:
10
names: []
11
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
12
tls_config:
13
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
14
insecure_skip_verify: true
15
relabel_configs:
16
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
17
separator: ;
18
regex: default;kubernetes;https
19
replacement: $1
20
action: keep
21
- job_name: kubernetes-nodes
22
scrape_interval: 1m
23
scrape_timeout: 10s
24
metrics_path: /metrics
25
scheme: https
26
kubernetes_sd_configs:
27
- api_server: null
28
role: node
29
namespaces:
30
names: []
31
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
32
tls_config:
33
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
34
insecure_skip_verify: true
35
relabel_configs:
36
- separator: ;
37
regex: __meta_kubernetes_node_label_(.+)
38
replacement: $1
39
action: labelmap
40
- separator: ;
41
regex: (.*)
42
target_label: __address__
43
replacement: kubernetes.default.svc:443
44
action: replace
45
- source_labels: [__meta_kubernetes_node_name]
46
separator: ;
47
regex: (.+)
48
target_label: __metrics_path__
49
replacement: /api/v1/nodes/${1}/proxy/metrics
50
action: replace
51
- job_name: kubernetes-cadvisor
52
scrape_interval: 1m
53
scrape_timeout: 10s
54
metrics_path: /metrics
55
scheme: https
56
kubernetes_sd_configs:
57
- api_server: null
58
role: node
59
namespaces:
60
names: []
61
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
62
tls_config:
63
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
64
insecure_skip_verify: false
65
relabel_configs:
66
- separator: ;
67
regex: __meta_kubernetes_node_label_(.+)
68
replacement: $1
69
action: labelmap
70
- separator: ;
71
regex: (.*)
72
target_label: __address__
73
replacement: kubernetes.default.svc:443
74
action: replace
75
- source_labels: [__meta_kubernetes_node_name]
76
separator: ;
77
regex: (.+)
78
target_label: __metrics_path__
79
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
80
action: replace
81
- job_name: kubernetes-service-endpoints
82
scrape_interval: 1m
83
scrape_timeout: 10s
84
metrics_path: /metrics
85
scheme: http
86
kubernetes_sd_configs:
87
- api_server: null
88
role: endpoints
89
namespaces:
90
names: []
91
relabel_configs:
92
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
93
separator: ;
94
regex: "true"
95
replacement: $1
96
action: keep
97
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
98
separator: ;
99
regex: (https?)
100
target_label: __scheme__
101
replacement: $1
102
action: replace
103
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
104
separator: ;
105
regex: (.+)
106
target_label: __metrics_path__
107
replacement: $1
108
action: replace
109
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
110
separator: ;
111
regex: ([^:]+)(?::\d+)?;(\d+)
112
target_label: __address__
113
replacement: $1:$2
114
action: replace
115
- separator: ;
116
regex: __meta_kubernetes_service_label_(.+)
117
replacement: $1
118
action: labelmap
119
- source_labels: [__meta_kubernetes_namespace]
120
separator: ;
121
regex: (.*)
122
target_label: kubernetes_namespace
123
replacement: $1
124
action: replace
125
- source_labels: [__meta_kubernetes_service_name]
126
separator: ;
127
regex: (.*)
128
target_label: kubernetes_name
129
replacement: $1
130
action: replace
Copied!
配置成功后,对应的target是:

四. 常见场景

  • 1.获取集群中各节点信息,并按可用区或地域分类
如使用k8s的role:node采集集群中node的数据,可以通过"meta_domain_beta_kubernetes_io_zone"标签来获取到该节点的地域,该label为集群创建时为node打上的标记,kubectl decribe node可以看到。
然后可以通过relabel_configs定义新的值
1
relabel_configs:
2
- source_labels: ["meta_domain_beta_kubernetes_io_zone"]
3
regex: "(.*)"
4
replacement: $1
5
action: replace
6
target_label: "zone"
Copied!
后面可以直接通过node{zone="XX"}来进行地域筛选
  • 2.过滤信息,或者按照职能(RD、运维)进行监控管理
对于不同职能(开发、测试、运维)的人员可能只关心其中一部分的监控数据,他们可能各自部署的自己的Prometheus Server用于监控自己关心的指标数据,不必要的数据需要过滤掉,以免浪费资源,可以最类似配置;
1
metric_relabel_configs:
2
- source_labels: [__name__]
3
separator: ;
4
regex: etcd_(debugging|disk|request|server).*
5
replacement: $1
6
action: drop
Copied!
action: drop代表丢弃掉符合条件的指标,不进行采集。
  • 3.搭建prometheus联邦集群,管理各IDC(地域)监控实例
    如果存在多个地域,每个地域又有很多节点或者集群,可以采用默认的联邦集群部署,每个地域部署自己的prometheus server实例,采集自己地域的数据。然后由统一的server采集所有地域数据,进行统一展示,并按照地域归类
配置:
1
scrape_configs:
2
- job_name: 'federate'
3
scrape_interval: 15s
4
honor_labels: true
5
metrics_path: '/federate'
6
params:
7
'match[]':
8
- '{job="prometheus"}'
9
- '{__name__=~"job:.*"}'
10
- '{__name__=~"node.*"}'
11
static_configs:
12
- targets:
13
- '192.168.77.11:9090'
14
- '192.168.77.12:9090'
Copied!
本文为容器监控实践系列文章,完整内容见:container-monitor-book