指标抓取的生命周期
Prometheus 在每个 scrape_interval
期间都会检测执行的 job,这些 job 会根据指定的服务发现配置生成 target 列表;
- 服务发现会返回一个 target 列表,其中包含一组以
__meta_
为开头的元数据的标签; - 服务发现还会根据目标配置来设置其他标签,这些标签带有
__
前缀和后缀,包括__scheme__
、__address__
、和__metrics_path__
,分别保存有 target 支持使用的协议、target 的地址及指标的 uri 路径(默认为 metric),这些 target 列表和标签会返回给 Prometheus,其中一些标签也可以在配置中被覆盖。
配置标签会在抓取的生命周期中被重复利用以生成其他标签,比如指标上的 instance
标签的默认值就来自于 __address__
标签的值。
Prometheus 对发现的各个目标提供了重新打标的机会,可以在 job 配置段的 relabel_configs
中进行配置。通常用于实现过滤 target 和将元数据标签中的信息附加到指标的标签上。
在重新打标之后便会对指标数据进行抓取及指标数据返回的过程。收到的指标数据在保存之前,还允许用户在 metric_relabel_configs
配置段中对指标数据重新打标并对其进行过滤。通常用于删除不需要的指标、在指标中删除敏感或不需要的标签以及添加、编辑或者修改指标的标签值或标签格式。
服务发现
Prometheus Server 的数据抓取工作基于 Pull 模型,因而,它必须要事先知道各 target
的位置,然后才能从相应的 Exporter
或 Instrumentation
中抓取数据。
对于小型的系统环境,使用 static_configs
指定各 target
即可解决问题,但是在中大型的系统环境或具有较强动态性的云计算环境来说,静态配置难以适应。Prometheus 为此专门设计了一组服务发现机制,以便于能够基于服务注册中心自动发现、检测、分类可被监控的各 target
,以及更新发生了变动的 target
。
可集成的服务发现机制
Prometheus 可以集成到多种不同的开源服务发现工具上,以便动态发现需要监控的目标。Prometheus 可以很好的集成到 Kubernetes 平台上,通过其 API Server 动态发现各类被监控的 Pod、Service、Endpoint、Ingress 及 Node 对象,还支持基于文件实现的动态发现。
【提示】 Prometheus 还支持基于 docker swarm 和 marathon 两款编排工具进行服务发现。官方文档
基于文件的服务发现
基于文件的服务发现不依赖任何平台或第三方服务,是最为简单和通用的实现方式。配置文件格式如下
# 官方文档
# Patterns for files from which target groups are extracted.
files:
[ - <filename_pattern> ... ]
# Refresh interval to re-read the files.
[ refresh_interval: <duration> | default = 5m ]
# prometheus.yml
- job_name: "nodes"
file_sd_configs:
- files:
- "./targets/*.yaml"
refresh_interval: 1m
# targets/nodes.yaml
- labels:
server: "Prometheus"
targets:
- "localhost:9090"
- labels:
server: "haproxy"
role: "api-server endpoint"
targets:
- "node07.example.com:9100"
- "node08.example.com:9100"
动态发现文件中的内容通常由另一系统生成。如 Ansible、Saltstack 或 Puppet 等配置管理系统,亦可由脚本基于 CMDB 系统定期查询生成。
基于 Kubernetes API 的服务发现
基于 Kubernetes API 的服务发现机制支持将 API Server 中的 Pod、Service、Endpoint、Ingress 和 Node 等资源类型下的各资源对象作为 target 对其进行监控。这些资源对象分别由各自的发现机制进行定义,负责发现每种类型资源对象的组件,在 Prometheus 中被称为一个 role (并非 Kubernetes 中的 role)。并且支持在集群上基于 DaemonSet 控制器部署 node_exporter 后发现各节点。
Node 资源发现
Prometheus 的 node
role 将集群中的每个节点视作一个 target,这些节点都监听着 Kubelet
使用的端口。node role 会依次检索节点规范上的 NodeInternalIP
,NodeExternalIP
, NodeLegacyHostIP
和 NodeHostName
,并将发现的第一个地址作为目标地址 __address__
。
节点上 instance
标签的值取自 API Server 中发现的节点名称。
Service 资源发现
Prometheus 的 service
role 负责发现集群上的每个 service
资源。会把 service
上声明的每个端口视作一个 target,地址为 service
的 DNS 名称及相应的端口。
Pod 资源发现
Prometheus 的 pod
role 负责发现集群上的每个 pod
资源并暴露其容器为 target。会把 pod
上的每个端口视作一个 target,会为未指定端口的容器创建 “无端口” 类型的 target,方便用户通过 relabel 功能手动添加端口。
Endpoint 资源发现
Prometheus 的 endpoint
role 会从各 endpoint
资源中发现目标。会把 endpoint
上的每个端口都视作一个 target,如果 endpoint
的后端工作负载是 pod
则会把该 pod
上其他未绑定到 endpoint 的端口同样视作一个 target。
Ingress 资源发现
Prometheus 的 ingress
role 会从 API Server 中发现 ingress
资源。会把 Ingress
资源上的每一个 path 视作一个 target。相关的地址会被设定为 ingress 资源上相关 host 字段的值。
# The information to access the Kubernetes API.
# The API server addresses. If left empty, Prometheus is assumed to run inside
# of the cluster and will discover API servers automatically and use the pod's
# CA certificate and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/.
[ api_server: <host> ]
# The Kubernetes role of entities that should be discovered.
# One of endpoints, service, pod, node, or ingress.
role: <string>
# Optional path to a kubeconfig file.
# Note that api_server and kube_config are mutually exclusive.
[ kubeconfig_file: <filename> ]
# Optional authentication information used to authenticate to the API server.
# Note that `basic_auth` and `authorization` options are mutually exclusive.
# password and password_file are mutually exclusive.
# Optional HTTP basic authentication information.
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]
# Optional `Authorization` header configuration.
authorization:
# Sets the authentication type.
[ type: <string> | default: Bearer ]
# Sets the credentials. It is mutually exclusive with
# `credentials_file`.
[ credentials: <secret> ]
# Sets the credentials to the credentials read from the configured file.
# It is mutually exclusive with `credentials`.
[ credentials_file: <filename> ]
# Optional OAuth 2.0 configuration.
# Cannot be used at the same time as basic_auth or authorization.
oauth2:
[ <oauth2> ]
# Optional proxy URL.
[ proxy_url: <string> ]
# Configure whether HTTP requests follow HTTP 3xx redirects.
[ follow_redirects: <bool> | default = true ]
# TLS configuration.
tls_config:
[ <tls_config> ]
# Optional namespace discovery. If omitted, all namespaces are used.
namespaces:
names:
[ - <string> ]
# Optional label and field selectors to limit the discovery process to a subset of available resources.
# See https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/
# and https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ to learn more about the possible
# filters that can be used. Endpoints role supports pod, service and endpoints selectors, other roles
# only support selectors matching the role itself (e.g. node role can only contain node selectors).
# Note: When making decision about using field/label selector make sure that this
# is the best approach - it will prevent Prometheus from reusing single list/watch
# for all scrape configs. This might result in a bigger load on the Kubernetes API,
# because per each selector combination there will be additional LIST/WATCH. On the other hand,
# if you just want to monitor small subset of pods in large cluster it's recommended to use selectors.
# Decision, if selectors should be used or not depends on the particular situation.
[ selectors:
[ - role: <string>
[ label: <string> ]
[ field: <string> ] ]]