Kubernetes-基于Prometheus和Grafana进行性能监控

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 architecture

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 的值和一个毫秒级的时间戳。
  • 格式:给定度量标准名称和一组标签,时间序列通常使用以下格式来标识:

    <metric name>{<label name>=<label value>, ...}
    

    例如,时间序列的度量名称为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样本观测(例如:请求持续时间或响应大小),并将它们计入配置的桶中。它也提供所有观测值的总和。具有<basename>基本度量标准名称的histogram的在获取数据期间会显示多个时间序列:
    • 观察桶的累计计数器,暴露为 <basename>_bucket{le=”<upper inclusive bound>”}
    • 所有观察值的总和,暴露为<basename>_sum
    • 已观察到的事件的计数,暴露为<basename>_count(等同于<basename>_bucket{le=”+Inf”})

    Summery类似于HistogramSummery样本观察(通常是请求持续时间和响应大小)。虽然它也提供观测总数和所有观测值的总和,但它计算滑动时间窗内的可配置分位数。在获取数据期间,具有<basename>基本度量标准名称的Summery会显示多个时间序列:

    • 流动φ分位数(0≤φ≤1)的观察事件,暴露为<basename>{quantile=”<φ>”}
    • 所有观察值的总和,暴露为<basename>_sum
    • 已经观察到的事件的计数,暴露为<basename>_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:<host>:<port>被抓取的目标网址部分。

如果这些标签中的任何一个已经存在于抓取的数据中,则行为取决于honor_labels配置选项。

对于每个实例抓取,Prometheus会在以下时间序列中存储一个样本:

  • up{job=”<job-name>”, instance=”<instance-id>”}:1 如果实例健康,即可达;或者0抓取失败。
  • scrape_duration_seconds{job=”<job-name>”, instance=”<instance-id>”}:抓取的持续时间。
  • scrape_samples_post_metric_relabeling{job=”<job-name>”, instance=”<instance-id>”}:应用度量标准重新标记后剩余的样本数。
  • scrape_samples_scraped{job=”<job-name>”, instance=”<instance-id>”}:目标暴露的样本数量。

up时间序列是实例可用性的监控。

1.3 使用Helm在Kubernetes中部署Prometheus

1.3.1 环境要求

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)
.
K8S中文社区微信公众号