1、Prometheus介绍和架构
1.1 Prometheus介绍
Prometheus是一个开源的系统监视和警报工具包,自2012成立以来,许多公司和组织采用了Prometheus。它现在是一个独立的开源项目,并独立于任何公司维护。在2016年,Prometheus加入云计算基金会作为Kubernetes之后的第二托管项目。
Prometheus的关键特性如下:
- 由度量名和键值对标识的时间序列数据的多维数据模型
- 灵活的查询语言
- 不依赖于分布式存储;单服务器节点是自治的
- 通过HTTP上的拉模型实现时间序列收集
- 通过中间网关支持推送时间序列
- 通过服务发现或静态配置发现目标
- 图形和仪表板支持的多种模式
Prometheus的组件:
Prometheus生态由多个组件组成,并且这些组件大部分是可选的:
- Prometheus服务器,用于获取和存储时间序列数据;
- 仪表应用数据的客户端类库(Client Library)
- 支持临时性工作的推网关(Push Gateway)
- 特殊目的的输出者(Exporter),提供被监控组件信息的 HTTP 接口,例如HAProxy、StatsD、MySQL、Nginx和Graphite等服务都有现成的输出者接口
- 处理告警的告警管理器(Alert Manager)
- 其它支持工具
Prometheus的整体架构
Prometheus从jobs获取度量数据,也直接或通过推送网关获取临时jobs的度量数据。它在本地存储所有被获取的样本,并在这些数据运行规则,对现有数据进行聚合和记录新的时间序列,或生成警报。通过Grafana或其他API消费者,可以可视化的查看收集到的数据。下图显示了Pometheus的整体架构和生态组件:
Prometheus的整体工作流程:
1)Prometheus 服务器定期从配置好的 jobs 或者 exporters 中获取度量数据;或者接收来自推送网关发送过来的 度量数据。
2)Prometheus 服务器在本地存储收集到的度量数据,并对这些数据进行聚合;
3)运行已定义好的 alert.rules,记录新的时间序列或者向告警管理器推送警报。
4)告警管理器根据配置文件,对接收到的警报进行处理,并通过email等途径发出告警。
5)Grafana等图形工具获取到监控数据,并以图形化的方式进行展示。
1.2 Prometheus关键概念
1.2.1 数据模型
Prometheus从根本上将所有数据存储为时间序列:属于相同度量标准和同一组标注尺寸的时间戳值流。除了存储的时间序列之外,普罗米修斯可能会生成临时派生时间序列作为查询的结果。
- 度量名称和标签:每个时间序列都是由度量标准名称和一组键值对(也称为标签)组成唯一标识。度量名称指定被测量的系统的特征(例如:http_requests_total-接收到的HTTP请求的总数)。它可以包含ASCII字母和数字,以及下划线和冒号。它必须匹配正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*。标签启用Prometheus的维度数据模型:对于相同度量标准名称,任何给定的标签组合都标识该度量标准的特定维度实例。查询语言允许基于这些维度进行筛选和聚合。更改任何标签值(包括添加或删除标签)都会创建新的时间序列。标签名称可能包含ASCII字母,数字以及下划线。他们必须匹配正则表达式[a-zA-Z_][a-zA-Z0-9_]*。以__开始的标签名称保留给供内部使用。
- 样本:实际的时间序列,每个序列包括:一个 float64 的值和一个毫秒级的时间戳。
-
格式:给定度量标准名称和一组标签,时间序列通常使用以下格式来标识:
{=, ...}
例如,时间序列的度量名称为api_http_requests_total,标签method=”POST”和handler=”/messages”,则标记为:
api_http_requests_total{method="POST", handler="/messages"}
1.2.2 度量类型
Prometheus 客户端库主要提供Counter、Gauge、Histogram和Summery四种主要的 metric 类型:
- Counter(计算器):Counter是一种累加的度量,它的值只能增加或在重新启动时重置为零。例如,您可以使用计数器来表示提供的请求数,已完成的任务或错误的数量。不要使用计数器来表达可减少的值。例如,不要使用Counter来计算当前正在运行的进程的数量,而是使用Gauge。
- Gauge(测量):Gauge表示单个数值,表达可以任意地上升和下降的度量。Gauge通常用于测量值,例如温度或当前的内存使用情况,但也可以表达上升和下降的“计数”,如正在运行的goroutines的数量。
- Histogram(直方图):Histogram样本观测(例如:请求持续时间或响应大小),并将它们计入配置的桶中。它也提供所有观测值的总和。具有基本度量标准名称的histogram的在获取数据期间会显示多个时间序列:
- 观察桶的累计计数器,暴露为 _bucket{le=””}
- 所有观察值的总和,暴露为_sum
- 已观察到的事件的计数,暴露为_count(等同于_bucket{le=”+Inf”})
Summery:类似于Histogram,Summery样本观察(通常是请求持续时间和响应大小)。虽然它也提供观测总数和所有观测值的总和,但它计算滑动时间窗内的可配置分位数。在获取数据期间,具有基本度量标准名称的Summery会显示多个时间序列:
- 流动φ分位数(0≤φ≤1)的观察事件,暴露为{quantile=””}
- 所有观察值的总和,暴露为_sum
- 已经观察到的事件的计数,暴露为_count
1.2.3 工作和实例
按照Prometheus的说法,可以获取数据的端点被称为实例(instance),通常对应于一个单一的进程。具有相同目的的实例集合(例如为了可伸缩性或可靠性而复制的进程)称为作业(job)。
例如,具有四个复制实例的API服务器作业:
- 工作: api-server
- 实例1: 1.2.3.4:5670
- 实例2: 1.2.3.4:5671
- 实例3: 5.6.7.8:5670
- 实例4: 5.6.7.8:5671
自动生成标签和时间序列
当Prometheus获取目标时,它会自动附加一些标签到所获取的时间序列中,以识别获取目标:
- job:目标所属的配置作业名称。
- instance::被抓取的目标网址部分。
如果这些标签中的任何一个已经存在于抓取的数据中,则行为取决于honor_labels配置选项。
对于每个实例抓取,Prometheus会在以下时间序列中存储一个样本:
- up{job=””, instance=””}:1 如果实例健康,即可达;或者0抓取失败。
- scrape_duration_seconds{job=””, instance=””}:抓取的持续时间。
- scrape_samples_post_metric_relabeling{job=””, instance=””}:应用度量标准重新标记后剩余的样本数。
- scrape_samples_scraped{job=””, instance=””}:目标暴露的样本数量。
up时间序列是实例可用性的监控。
1.3 使用Helm在Kubernetes中部署Prometheus
1.3.1 环境要求
- 已有Kubernetes 1.6+环境;
- 已部署helm客户端和tiller服务端(请参考:https://docs.helm.sh/using_helm/#installing-helm):
- 在Kubernetes中创建了具备足够权限访问权限的service account;
- 并通过此service account在Kubernetes部署了tiller服务端(请参考:https://docs.helm.sh/using_helm/#role-based-access-control)。
- 在Kubernetes中提供2个容量大于10g的持久化存储卷。
1.3.2 Helm chart配置
下表列示了Prometheus chart的配置参数和默认值:
参数 | 描述 | 默认值 |
---|---|---|
alertmanager.enabled |
如果为true,创建告警管理器 | true |
alertmanager.name |
告警管理器容器名称 | alertmanager |
alertmanager.image.repository |
告警管理器容器镜像仓库 | prom/alertmanager |
alertmanager.image.tag |
告警管理器容器镜像标记 | v0.13.0 |
alertmanager.image.pullPolicy |
告警管理器容器镜像拉取策略 | IfNotPresent |
alertmanager.prefixURL |
The prefix slug at which the server can be accessed | “ |
alertmanager.baseURL |
The external url at which the server can be accessed | / |
alertmanager.extraArgs |
额外的告警管理器容器参数 | {} |
alertmanager.configMapOverrideName |
Prometheus alertmanager ConfigMap override where full-name is {{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}} and setting this value will prevent the default alertmanager ConfigMap from being generated |
"" |
alertmanager.ingress.enabled |
If true, alertmanager Ingress will be created | false |
alertmanager.ingress.annotations |
告警管理器Ingress注释 | {} |
alertmanager.ingress.extraLabels |
警告管理器Ingress额外标签 | {} |
alertmanager.ingress.hosts |
警告管理器Ingress主机名称 | [] |
alertmanager.ingress.tls |
警告管理器Ingress TLS配置(YAML) | [] |
alertmanager.nodeSelector |
用于警告管理器pod指派的node标签 | {} |
alertmanager.tolerations |
node玷污容忍 (requires Kubernetes >=1.6) | [] |
alertmanager.schedulerName |
警告管理器警告调度名称 | nil |
alertmanager.persistentVolume.enabled |
如果为true,告警管理器江创建一个持久化存储卷声明 | true |
alertmanager.persistentVolume.accessModes |
告警管理器数据持久化存储访问模式 | [ReadWriteOnce] |
alertmanager.persistentVolume.annotations |
持久化存储卷声明注释 | {} |
alertmanager.persistentVolume.existingClaim |
告警管理器数据持久化存储卷存在声明名称 | "" |
alertmanager.persistentVolume.mountPath |
告警管理器数据持久化存储卷挂接根路径 | /data |
alertmanager.persistentVolume.size |
告警数据持久化存储卷大小 | 2Gi |
alertmanager.persistentVolume.storageClass |
告警管理器数据持久化存储卷存储类 | unset |
alertmanager.persistentVolume.subPath |
Subdirectory of alertmanager data Persistent Volume to mount | "" |
alertmanager.podAnnotations |
添加到告警管理器Pod中的注释 | {} |
alertmanager.replicaCount |
告警管理器Pod的期望副本数量 | 1 |
alertmanager.resources |
告警管理器Pod资源请求和限制 | {} |
alertmanager.securityContext |
为告警管理器容器定制安全上下文 | {} |
alertmanager.service.annotations |
告警管理器服务的注释 | {} |
alertmanager.service.clusterIP |
内部的告警管理器集群服务IP | "" |
alertmanager.service.externalIPs |
告警管理器服务外部IP地址 | [] |
alertmanager.service.loadBalancerIP |
指派给负载均衡器的IP地址 | "" |
alertmanager.service.loadBalancerSourceRanges |
list of IP CIDRs allowed access to load balancer (if supported) | [] |
alertmanager.service.servicePort |
告警管理器服务端口 | 80 |
alertmanager.service.type |
告警管理器服务的类型 | ClusterIP |
alertmanagerFiles.alertmanager.yml |
Prometheus告警管理器配置 | example configuration |
configmapReload.name |
configmap-reload container name | configmap-reload |
configmapReload.image.repository |
configmap-reload container image repository | jimmidyson/configmap-reload |
configmapReload.image.tag |
configmap-reload container image tag | v0.1 |
configmapReload.image.pullPolicy |
configmap-reload container image pull policy | IfNotPresent |
configmapReload.extraArgs |
Additional configmap-reload container arguments | {} |
configmapReload.extraConfigmapMounts |
Additional configmap-reload configMap mounts | [] |
configmapReload.resources |
configmap-reload pod resource requests & limits | {} |
initChownData.enabled |
If false, don’t reset data ownership at startup | true |
initChownData.name |
init-chown-data container name | init-chown-data |
initChownData.image.repository |
init-chown-data container image repository | busybox |
initChownData.image.tag |
init-chown-data container image tag | latest |
initChownData.image.pullPolicy |
init-chown-data container image pull policy | IfNotPresent |
initChownData.resources |
init-chown-data pod resource requests & limits | {} |
kubeStateMetrics.enabled |
If true, create kube-state-metrics | true |
kubeStateMetrics.name |
kube-state-metrics容器名称 | kube-state-metrics |
kubeStateMetrics.image.repository |
kube-state-metrics容器镜像仓库 | quay.io/coreos/kube-state-metrics |
kubeStateMetrics.image.tag |
kube-state-metrics容器镜像版本 | v1.3.1 |
kubeStateMetrics.image.pullPolicy |
kube-state-metrics容器镜像拉取策略 | IfNotPresent |
kubeStateMetrics.args |
kube-state-metrics容器参数 | {} |
kubeStateMetrics.nodeSelector |
node labels for kube-state-metrics pod assignment | {} |
kubeStateMetrics.podAnnotations |
annotations to be added to kube-state-metrics pods | {} |
kubeStateMetrics.tolerations |
node taints to tolerate (requires Kubernetes >=1.6) | [] |
kubeStateMetrics.replicaCount |
kube-state-metrics Pod的期望副本数量 | 1 |
kubeStateMetrics.resources |
kube-state-metrics资源请求和限制(YAML) | {} |
kubeStateMetrics.securityContext |
为kube-state-metrics容器定制安全上下文 | {} |
kubeStateMetrics.service.annotations |
kube-state-metrics服务的注释 | {prometheus.io/scrape: "true"} |
kubeStateMetrics.service.clusterIP |
内部的kube-state-metrics集群服务IP | None |
kubeStateMetrics.service.externalIPs |
kube-state-metrics服务外部IP地址 | [] |
kubeStateMetrics.service.loadBalancerIP |
指派给负载均衡的IP地址(如果支持的话) | "" |
kubeStateMetrics.service.loadBalancerSourceRanges |
list of IP CIDRs allowed access to load balancer (if supported) | [] |
kubeStateMetrics.service.servicePort |
kube-state-metrics服务端口 | 80 |
kubeStateMetrics.service.type |
type of kube-state-metrics service to create | ClusterIP |
nodeExporter.enabled |
如果为true,则创建node-exporter | true |
nodeExporter.name |
node-exporter容器名称 | node-exporter |
nodeExporter.image.repository |
node-exporter容器镜像仓库 | prom/node-exporter |
nodeExporter.image.tag |
node-exporter容器镜像版本 | v0.15.2 |
nodeExporter.image.pullPolicy |
node-exporter容器镜像拉取策略 | IfNotPresent |
nodeExporter.extraArgs |
额外的node-exporter容器参数 | {} |
nodeExporter.extraHostPathMounts |
额外的node-exporter hostPath 挂接 | [] |
nodeExporter.extraConfigmapMounts |
Additional node-exporter configMap mounts | [] |
nodeExporter.nodeSelector |
node labels for node-exporter pod assignment | {} |
nodeExporter.podAnnotations |
annotations to be added to node-exporter pods | {} |
nodeExporter.pod.labels |
labels to be added to node-exporter pods | {} |
nodeExporter.tolerations |
node taints to tolerate (requires Kubernetes >=1.6) | [] |
nodeExporter.resources |
node-exporter resource requests and limits (YAML) | {} |
nodeExporter.securityContext |
securityContext for containers in pod | {} |
nodeExporter.service.annotations |
annotations for node-exporter service | {prometheus.io/scrape: "true"} |
nodeExporter.service.clusterIP |
internal node-exporter cluster service IP | None |
nodeExporter.service.externalIPs |
node-exporter service external IP addresses | [] |
nodeExporter.service.loadBalancerIP |
IP address to assign to load balancer (if supported) | "" |
nodeExporter.service.loadBalancerSourceRanges |
list of IP CIDRs allowed access to load balancer (if supported) |
.