指標抓取的生命周期
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> ] ]]