跳到主要内容

运行监控

在微服务系统中,我们需要时刻了解系统和服务的各种运行指标,更需要在出现问题的时候警报通知我们。因此,监控系统对于微服务来说是必不可少的。

爱星物联IoT云平台,后端采用微服务的技术架构,因此配备监控系统实时监测云平台的运行状态也是必不可少的。IoT云平台集成了市面上最为流行的监控工具是Prometheus。下面简要介绍下Prometheus特点、组件、部署及用法。

Prometheus

Prometheus 最初是 SoundCloud 构建的开源系统监视和警报工具包 。自 2012 年成立以来,许多公司和组织都采用了 Prometheus,该项目拥有非常活跃的开发人员和用户社区。现在,它是一个独立的开源项目,并且独立于任何公司进行维护。为了强调这一点并阐明项目的治理结构,Prometheus 在 2016 年加入了 Cloud Native Computing Foundation,这是继 Kubernetes 之后的第二个托管项目。

特点

Prometheus 相较于其他监控工具具有如下特点:

· 多维数据:Prometheus 是个时间序列数据库,支持由指标名称和键值对标识的时间序列数据的多维数据模型。

· 强大的查询:PromQL 允许对收集的时间序列数据进行切片和切块,以生成临时图形,表格和警报

· 出色的可视化:Prometheus 具有多种用于可视化数据的模式:内置表达式浏览器,Grafana 集成和控制台模板语言。

· 高效存储:Prometheus 以有效的自定义格式将时间序列存储在内存中和本地磁盘上。通过功能性分片和联合来实现缩放。

· 部署简单:每个服务器在可靠性方面都是独立的,仅依赖于本地存储。用 Go 语言编写的所有二进制文件都是静态链接的,易于部署

· 精确警报:警报是基于 Prometheus 灵活的 PromQL 定义的,并维护尺寸信息。警报管理器处理通知和沉默。

· 提供了许多客户端库:客户端库可轻松检测服务。已经支持十多种语言,并且也很容易实现自定义库。

· 提供许多集成:现有的 Exporters 允许将第三方数据桥接到 Prometheus 中。比如:系统统计信息、Docker、HAProxy、StatsD 和 JMX 指标。

· 支持通过服务发现或静态配置发现目标

· 通过 HTTP 的服务拉取时间序列数据

· 支持推送的方式来添加时间序列数据:这点在一些生命周期很短的服务中非常有用,比如:定时任务中,每个任务都很短,可能等不及拉取的时间,任务的 Pod 就已经 Completed 了,这个时候就可以使用推送的方式。

组件

Prometheus 生态系统包含多个组件,其中许多是可选的:

· Prometheus Server:用于抓取指标、存储时间序列数据

· Client Librarys:客户端库

· Pushgateway:支持短期工作的推送网关,以推送的方式将指标数据推送到该网关

· exporters:暴露指标让任务来抓

· alertmanager:处理报警的报警组件

· 各种支持工具

大多数 Prometheus 组件都是用 Go 编写的,因此易于构建和部署为静态二进制文件。

架构

img

Prometheus 根据配置文件中设置的时间,直接或者通过中间的 Pushgateway 网关获取指标数据,在本地存储所有的获取的指标数据,并对这些数据进行一些规则整理,用来生成一些聚合数据或者报警信息,Grafana 或者其他工具用来可视化这些数据。

部署

为了熟悉 Prometheus 的详细工作流程,我们先在开发环境上搭建 Prometheus 和 Grafana,然后使用它们采集和展示一些指标。

ConfigMap

Prometheus 通过配置文件 prometheus.yml 启动。

#  prometheus.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: observability
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_timeout: 15s
rule_files:
# - "first.rules"
# - "second.rules"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

基本的配置文件包括以下三个模块:

· global:全局配置

· scrape_interval:抓取指标的频率,默认是 15s

· scrape_timeout:评估规则的频率,这里也设置为 15s。prometheus 使用规则产生新的时间序列数据或者产生警报。

· rule_files:规则的位置,prometheus 根据这个配置加载规则,用于生成新的时间序列数据或者报警信息,当前我们没有配置任何规则。

· scrape_configs:配置监控的资源。

· job:prometheus 通过 HTTP 的方式采集 target 的指标。target 需要为 prometheus 暴露 /metrics 接口。特殊地,prometheus 也暴露了对它本身的监控接口。所以,在默认的配置里有一个单独的 job,叫做 prometheus,它通过 URL:http://localhost:9090/metrics 采集 prometheus 本身的时间序列数据 (包含状态和性能)。如果还有其他的资源需要监控的话,直接配置在该模块下面就可以了。

Deployment

接下来,我们准备 Prometheus 的 Deployment 文件。

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: observability
labels:
app: prometheus
spec:
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
serviceAccountName: prometheus
containers:
- image: prom/prometheus:v2.19.0
name: prometheus
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention=24h"
- "--web.enable-admin-api" # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
- "--web.enable-lifecycle" # 支持热更新,直接执行localhost:9090/-/reload立即生效
ports:
- containerPort: 9090
protocol: TCP
name: http
volumeMounts:
- mountPath: "/prometheus"
subPath: prometheus
name: data
- mountPath: "/etc/prometheus"
name: config-volume
resources:
requests:
memory: "1Gi"
cpu: "100m"
limits:
memory: "2Gi"
cpu: "200m"
securityContext:
runAsUser: 0
volumes:
- name: data
emptyDir: {}
- configMap:
name: prometheus-config
name: config-volume

rbac

因为 prometheus 需要访问 Kubernetes 的相关信息,所以还需要配置 rbac 认证。

# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: observability
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: observability

Service

为了访问到 prometheus 服务,我们还需要创建一个 Service。

注:为了方便测试,这里指定 type 为 NodePort

# service.yaml
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: observability
labels:
app: prometheus
spec:
selector:
app: prometheus
type: NodePort
ports:
- name: web
port: 9090
targetPort: http

部署

# 创建 observability 命名空间,用于存放 Prometheus 的部署
$ kubectl create namespace observability
namespace/observability created

# 部署所有文件

$ kubectl apply -f prometheus.yaml
configmap/prometheus-config created

$ kubectl apply -f rbac.yaml
serviceaccount/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created

$ kubectl apply -f deployment.yaml
deployment.apps/prometheus created

$ kubectl apply -f service.yaml
service/prometheus created

webui

访问

获取访问服务端口(31033)

$ kubectl get service -n observability
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus NodePort 10.98.133.13 <none> 9090:31033/TCP 44s

然后通过 http://localhost:31033 即可访问 Prometheus webui 服务。

img

查看指标

输入并选择 prometheus_http_requests_total。选择 Graph,然后点击 Execute 即可以图形的形式查看指标 prometheus_http_requests_total 的具体数据。

img

prometheus_http_requests_total 这个指标是怎么加入到 Prometheus 的呢?

原因是在配置文件中配置了 Prometheus 自身的监控。而 Prometheus 自身在 9090 端口暴露了 /metrics 接口。所以,我们可以访问 http://localhost:9090/metrics 查看具体的 metrics。因为,我们使用 NodePort 暴露服务。所以,访问的地址变成 http://localhost:31033/metrics。

img

这里可以看到 Prometheus /metrics 接口中含有 prometheus_http_requests_total 指标,所以我们可以获取得到该指标的值。