数据采集流程
抓取目标识别
- 服务发现:每个抓取周期,Prometheus都会检查执行的抓取任务,这些抓取任务将会生成抓取目标列表,也即服务发现过程。服务发现返回一个抓取目标列表,其中包含一组称为元数据的标签,这些标签以
__meta__
为前缀,不同的服务发现机制会生成不同的元数据标签,例如,AWS EC2的服务发现机制会返回名为__meta_ec2_availability_zone
的标签,表明实例所在的可用区(availability zone)。 - 配置覆盖:服务发现还会根据目标的配置来设置其他标签,这些标签带有
__
的前缀和后缀,包括__scheme__
、__address__
和__metrics_path__
。这些标签包含目标的模式(http或https)
、目标的地址
以及指标的具体路径
。每个标签通常都有一个默认值,例如,__metrics_path__
默认为/metrics
,__scheme__
默认为http
。 此外,如果路径中存在任何URL参数
,则它们的前缀会设置为__param_*
。配置标签会在抓取的生命周期中重复利用以生成其他标签。例如,指标上instance
标签的默认内容是__address__
标签的内容。
注意:任何带
__
前缀和后缀的元数据标签在生命周期的后期被删除了,并且所有这些标签都被专门排除掉,不在Web UI上显示。
然后这些目标列表和标签会返回给Prometheus,其中一些标签可以在配置中被覆盖,例如,通过metrics_path
参数设置的指标路径以及通过scheme
参数指定的模式。
scrape_configs:
- job_name: 'node'
scheme: https
metrics_path: /moremetrics
static_configs:
- targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.168:9100']
这里,我们将schema覆盖为https,将metrics_path覆盖为/moremetrics。
- 抓取目标重新标记:Prometheus提供了可以重新标记目标的机会,并可能使用你的服务发现所添加的一些元数据。你还可以过滤目标,以删除或保留特定条目。
样本数据抓取
- 样本数据获取:然后就是真正的数据抓取,以及样本指标数据返回。
- 样本指标重新标记:当指标被抓取后,你将拥有最后一次机会针对样本指标数据,在将它们保存到服务器之前重新标记并过滤。
标签重写概览
在一个集中的复杂监控环境中,有时你无法控制监控的所有资源以及所有暴露的监控数据。通过重新标记
,你可以控制、管理并标准化环境中的抓取目标及样本指标数据。
抓取目标的一些最常见的用例是:
- 服务发现时通过标签重写重新设置
__address__
地址
样本指标的一些最常见的用例是:
- 删除不必要的指标
- 从指标中删除敏感或不需要的标签
- 添加、编辑或修改指标的标签值或标签格式
请记住,我们有两个阶段可以重新标记:
- 抓取目标重新标记:第一个阶段是对来自服务发现的目标进行重新标记,这对于将来自服务发现的元数据标签中的信息应用于指标上的标签来说非常有用。这是在作业内的
relabel_configs
块中完成的。 - 样本指标重新标记:第二个阶段是在抓取之后且指标被保存于存储系统之前。这样,我们就可以确定哪些指标需要保存、哪些需要丢以 及这些指标的样式。这是在我们作业内的
metric_relabel_configs
块中完成的。
记住这两个阶段的最简单方法是:在抓取之前使用
relabel_configs
,在抓取之后使用metric_relabel_configs
。
配置项说明
- source_labels: [, …] ## 需要进行
relabel
操作的meta labels
;多个标签的内容将会通过系统配置的分隔符进行连接,并用于匹配下面配置的regex
进行一系列的动作 - target_label: ##
relabel
操作的目标标签,当使用action
为replace
时会把替换的结果写入target_label
- regex: ## 正则表达式,用于在
source_labels
的标签值中提取匹配的内容。默认为"(.*)"
- modulus: ## 用于获取源标签值的哈希的模数
- replacement: ##
regex
可能匹配到多个内容,replacement
指定要使用哪一个匹配内容进行替换,默认为"$1"
,表示使用第一个匹配的内容 - action:
## 定义对 source_labels
进行何种操作,默认为replace
- replace: 通过
regex
匹配来源标签值通过分隔符连接后的值,通过匹配到的分组(${1}, ${2}, ...
)内容替换目标标签值;如果没有任何匹配,则不做替换操作 - keep:通过
regex
匹配来源标签值通过分隔符连接后的值,丢弃未匹配到regex
的抓取目标
- drop:通过
regex
匹配来源标签值通过分隔符连接后的值,丢弃匹配到regex
的抓取目标
- hashmod:将来源标签值通过分隔符连接后的值进行取模,然后设置为目标标签值
- labelmap:通过
regex
匹配所有标签名称,然后拷贝匹配到的标签值作为目标标签值,目标标签名称可使用replacement
中匹配到的分组(${1}, ${2}, ...
)进行定义 - labeldrop:通过
regex
匹配所有标签名称,丢弃匹配到regex
的标签
- labelkeep:通过
regex
匹配所有标签名称,丢弃没有匹配到regex
的标签
使用
labeldrop
和labelkeep
标签重写后需要注意保证metrics+labels
仍旧唯一。另外,keep/drop
在relabel_configs
中操作的是抓取目标
,而在metric_relabel_configs
中操作的是样本指标数据
。
- replace: 通过
案例分析
抓取目标重新标记
保留/删除抓取目标
当需要过滤target
时,可以将action
项定义为keep
或drop
。
scrape_configs:
- …
- job_name: "cephs"
relabel_configs:
- action: keep
source_labels:
- __address__
regex: ceph01.*
标签映射
将原始标签的一部分转换为target标签,这一功能replace无法实现。
relabel_configs:
- action: labelmap
regex: (.*)(address)(.*)
replacement: ${2}
修改标签值
配置K8S服务发现:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: "prometheus-config"
namespace: kube-system
data:
prometheus.yml: |-
global:
scrape_interval: 15s
external_labels:
monitor: 'codelab-monitor'
scrape_configs:
- job_name: kubernetes-nodes-kubelet
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- 将
__address__
修改为kubernetes.default.svc:443
,而最终抓取目标的Endpoint地址最终由__scheme__ + __address__ + __metrics_path__
组成。 - 将
/metrics
修改为/api/v1/nodes/[NODE_NAME]/proxy/metrics/cadvisor
,此处__meta_kubernetes_node_name
是K8S服务发现机制中提供的元数据标签,这个标签可以取到Node名称。 - 通过
labelmap
提供更丰富的标签,K8S服务发现机制中提供了很多更丰富的元数据标签,例如,__meta_kubernetes_node_label_beta_kubernetes_io_os
、__meta_kubernetes_node_label_beta_kubernetes_io_arch
、__meta_kubernetes_node_label_kubernetes_io_hostname
,可以看到,regex: __meta_kubernetes_node_label_(.+)
就是匹配__meta_kubernetes_node_label_
开头的标签,然后截取原始标签名的后半部分作为新的标签,最终结果会保留:beta_kubernetes_io_os
、beta_kubernetes_io_arch
以及kubernetes_io_hostname
,且值为原始标签值。
多标签合并
标签合并,可以将多个源标签合并为一个目标标签,可以取源标签的值,也可以进行hash。
例如,在文件服务发现中,将标签sd_type=”file”和filename=”mysql.yml”合并为sd=”file;mysql.yml”,标签值使用分号连接
scrape_configs:
- …
- job_name: "sd_file_mysql"
file_sd_configs:
- files:
- mysql.yml
refresh_interval: 1m
relabel_configs:
- source_labels:
- sd_type
- filename
separator: ;
target_label: sd
再例如,将多个标签的值进行hash,形成一个target标签,只要target标签一致,则表示源标签一致,可以用来实现prometheus的负载均衡。
scrape_configs:
- …
- job_name: "sd_file_mysql"
file_sd_configs:
- files:
- mysql.yml
refresh_interval: 1m
relabel_configs:
- action: hashmod
source_labels:
- __scheme__
- __metrics_path__
modulus: 64
target_label: hash_id
样本指标重新标记
让我们来看看cAdvisor指标的重新标记。cAdvisor收集了大量数据,但并非所有数据都是有用的。 因此,我们来看看如何在它们进入存储之前删除其中一些指标,以避免占用不必要的空间。
scrape_configs:
- job_name: 'docker'
static_configs:
- targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.168:9100']
metric_relabel_configs:
- source_labels: [__name__]
regex: '(container_tasks_state|container_memory_failures_total)'
action: 'drop'
保留/删除样本指标数据
我们使用sourcelabels参数选择要操作的指标,并且还需要一组标签名称。在示例中我们使用__name__
标签,`_name标签是一个系统内置预留标签,表示的是指标名称。因此,本例中
docker抓取任务的源标签(
source_labels`)是指所有从cAdvisor抓取的样本数据的指标名称。
多个标签通过分隔符连接在一起,默认分隔符为【;】,也可以使用
separator
参数覆盖分隔符配置。
接下来,我们指定一个正则表达式来搜索连接后的指标名称并进行匹配。正则表达式使用RE2表达式语法,这也是Go的正则表达式库RegExp使用的语法。
如上,我们的正则表达式为(container_tasks_state|container_memory_failures_total)
,它将匹配并捕获两个指标:
- container_tasks_state
- container_memory_failures_total
如果指定了多个源标签,那么我们将使用分隔符隔开每个正则表达式,例如:rgex1;regex2;regex3
。然后执行action
参数中指定的操作。在示例中,这两个指标都包含大量的时间序列,但是可能仅有部分数据有价值,所以我们使用了drop
操作,这将在数据存储之前删除指标。其他操作(如keep
)则会保留与正则表达式匹配的指标,并删除所有其他指标。
替换标签值/修改标签名
我们还可以替换标签的值。举个例子,许多cAdvisor指标都有一个id标签,其中包含正在运行的进程的名称。如果该进程是一个容器,那么我们会看到类似如下的信息:id="/docker/6faxx33jll3434xxxx"
。
上面的内容有点冗长,我们想要从中获取容器ID:6faxx33jll3434xxxx
。然后将其放入一个新标签cont ainer_id中,通过重新标记我们可以这样做:
metric_relabel_configs:
- source_labels: [id]
regex: '/docker/([a-z0-9]+)'
replacement: '$1'
target_label: container_id
重新标记是按顺序执行的,使用配置文件中自上而下的顺序。 我们的源标签是
id
。然后,指定匹配并捕获容器ID的正则表达式(regex)。replacement
字段包含新标签值,在示例中使用的是匹配的结果$1
。然后,在target_label
参数中指定捕获信息的目标,此处为container_id
。 你可能会注意到我们没有为此指定action
。这是因为默认操作是replace
,如果没有指定操作,那么 Prometheus将假定你要执行替换操作。
删除标签
这通常用于隐藏敏感信息或简化时间序列。在这个(为演示 而创建的)示例中,我们将删除kernelVersion
标签,隐藏Docker主机的内核版本。
metric_relabel_configs:
- regex: 'kernelVersion'
action: labeldrop
为了删除标签,我们指定一个正则表达式,然后指定删除标签的操作labeldrop
。这将删除与正则表达式匹配的所有标签。
此操作还有一个对应的反向操作labelkeep
,它将保留与正则表达式匹配的标签,并删除所有其他标签。
请记住,标签是时间序列的唯一性约束。如果你删除标签并导致时间序列重复,那么系统可能会出现问题!