Prometheus 监控入门

Prometheus 是一个流行的且强大的 Kubernetes 监控工具包。本教程介绍如何开始使用。
197 位读者喜欢这篇文章。
Kubernetes

Jason Baker。CC BY-SA 4.0。

指标是表示系统整体健康状况以及您认为对于监控、警报或可观测性重要的任何其他特定信息的主要方式Prometheus 是一个领先的开源指标检测、收集和存储工具包 于 2012 年在 SoundCloud 构建。此后,它从云原生计算基金会毕业,并成为 Kubernetes 监控的事实标准。以下文章对其进行了详细介绍:

然而,这些文章都没有关注如何在 Kubernetes 上使用 Prometheus。本文

  • 描述 Prometheus 的架构和数据模型,以帮助您了解其工作原理和功能
  • 提供有关在 Kubernetes 集群中设置 Prometheus 并使用它来监控集群和应用程序的教程

架构

虽然了解 Prometheus 的工作原理对于有效使用它可能不是必需的,但它可能会有所帮助,尤其是在您考虑将其用于生产环境时。《Prometheus 文档》提供了此图表以及有关 Prometheus 基本要素以及各个部分如何连接在一起的详细信息。

Prometheus architecture

对于大多数用例,您应该了解 Prometheus 的三个主要组件

  1. Prometheus 服务器抓取并存储指标。请注意,它使用持久层,这是服务器的一部分,但文档中未明确提及。服务器的每个节点都是自治的,不依赖于分布式存储。稍后,在考虑使用专用时序数据库来存储 Prometheus 数据而不是依赖服务器本身时,我将重新讨论这一点。
  2. Web UI 允许您访问、可视化和绘制存储的数据。Prometheus 提供自己的 UI,但您也可以配置其他可视化工具(如 Grafana)以使用 PromQL(Prometheus 查询语言)访问 Prometheus 服务器。
  3. Alertmanager 从客户端应用程序(尤其是 Prometheus 服务器)发送警报。它具有用于重复数据删除、分组和路由警报的高级功能,并且可以通过 PagerDuty 和 OpsGenie 等其他服务进行路由。

理解 Prometheus 的关键在于它基本上依赖于从定义的端点抓取或拉取指标。这意味着您的应用程序需要公开一个指标可用的端点,并指示 Prometheus 服务器如何抓取它(这将在下面的教程中介绍)。对于许多不容易添加 Web 端点的应用程序(例如 KafkaCassandra(使用 JMX exporter)),都有导出器

数据模型

现在您已经了解了 Prometheus 如何工作以抓取和存储指标,接下来要学习的是 Prometheus 支持的指标类型。以下部分信息(用引号标记)来自 Prometheus 文档的“指标类型”部分。

计数器和仪表盘

两种最简单的指标类型是 计数器仪表盘。在开始使用 Prometheus(或更广泛地使用时序监控)时,这些是最容易理解的类型,因为很容易将它们与您可以想象监控的值联系起来,例如您的应用程序正在使用的系统资源量或它已处理的事件数。

计数器是一种累积指标,它表示一个单调递增的计数器,其值只能增加或在重新启动时重置为零。例如,您可以使用计数器来表示已处理的请求数、已完成的任务数或错误数。”

由于您无法减少计数器,因此它只能且应该仅用于表示累积指标。

仪表盘是一种指标,它表示一个可以任意上下波动的单个数值。仪表盘通常用于测量值,如 [CPU] 或当前内存使用率,但也用于可以上下波动的“计数”,如并发请求数。”

直方图和摘要

Prometheus 支持两种更复杂的指标类型:直方图 摘要。考虑到它们都跟踪观测值的数量和观测值的总和,这里有很多混淆的机会。您可能选择使用它们的原因之一是您需要计算观测值的平均值。请注意,它们在数据库中创建多个时间序列;例如,它们都创建一个带有 _sum 后缀的观测值总和。

直方图对观测值(通常是请求持续时间或响应大小之类的内容)进行采样,并在可配置的桶中对其进行计数。它还提供所有观测值的总和。”

这使其成为跟踪延迟等事物的绝佳选择,延迟可能具有针对其定义的服务级别目标 (SLO)。来自 文档

您可能有一个 SLO,要求在 300 毫秒内处理 95% 的请求。在这种情况下,配置一个直方图,使其桶的上限为 0.3 秒。然后,您可以直接表示在 300 毫秒内处理的请求的相对数量,并在值降至 0.95 以下时轻松发出警报。以下表达式按作业计算过去 5 分钟内处理的请求。请求持续时间是使用名为 http_request_duration_seconds 的直方图收集的。

sum(rate(http_request_duration_seconds_bucket{le="0.3"}[5m])) by (job)
/
sum(rate(http_request_duration_seconds_count[5m])) by (job)

 

回到定义

“与直方图类似,摘要对观测值(通常是请求持续时间和响应大小之类的内容)进行采样。虽然它也提供观测值的总计数和所有观测值的总和,但它会在滑动时间窗口内计算可配置的分位数。”

摘要和直方图之间的本质区别在于,摘要在客户端计算流式 φ 分位数并直接公开它们,而直方图公开分桶的观测计数,并且从直方图的桶中计算分位数发生在服务器端,使用 histogram_quantile() 函数。

如果您仍然感到困惑,我建议采取以下方法

  • 大多数情况下,对于简单的时序指标,请使用仪表盘。
  • 对于您知道会单调递增的事物,请使用计数器,例如,如果您要计算某事发生的次数。
  • 对于具有简单桶的延迟测量,请使用直方图,例如,一个桶用于“低于 SLO”,另一个桶用于“高于 SLO”。

这对于绝大多数用例来说应该足够了,对于更高级的场景,您应该依靠统计分析专家来帮助您。

现在您已经基本了解了 Prometheus 是什么、它的工作原理以及它可以收集和存储的数据类型,您就可以开始本教程了。

Prometheus 和 Kubernetes 动手教程

本教程涵盖以下内容

  • 在您的集群中安装 Prometheus
  • 下载示例应用程序并查看代码
  • 构建和部署应用程序并对其生成负载
  • 访问 Prometheus UI 并查看基本指标

本教程假设

  • 您已经部署了 Kubernetes 集群。
  • 您已配置 kubectl 命令行实用程序以进行访问。
  • 您具有 cluster-admin 角色(或至少具有创建命名空间和部署应用程序的足够权限)。
  • 您正在运行基于 Bash 的命令行界面。如果您运行其他操作系统或 shell 环境,请调整本教程。

如果您尚未运行 Kubernetes,则此 Minikube 教程 是在您的笔记本电脑上设置它的简便方法。

如果您现在准备好了,让我们开始吧。

安装 Prometheus

在本节中,您将克隆示例存储库并使用 Kubernetes 的配置文件将 Prometheus 部署到专用命名空间。

  1. 在本地克隆示例存储库并将其用作您的工作目录
    $ git clone https://github.com/yuriatgoogle/prometheus-demo.git
    $ cd  prometheus-demo
    $ WORKDIR=$(pwd)
  2. 为 Prometheus 部署创建一个专用命名空间
    $ kubectl create namespace prometheus
  3. 为您的命名空间授予集群读取器角色
    $ kubectl apply -f $WORKDIR/kubernetes/clusterRole.yaml 
    clusterrole.rbac.authorization.k8s.io/prometheus created
    clusterrolebinding.rbac.authorization.k8s.io/prometheus created
  4. 创建一个包含抓取和警报规则的 Kubernetes configmap
    $ kubectl apply -f $WORKDIR/kubernetes/configMap.yaml -n prometheus
    configmap/prometheus-server-conf created
  5. 部署 Prometheus
    $ kubectl create -f prometheus-deployment.yaml -n prometheus
    deployment.extensions/prometheus-deployment created
  6. 验证 Prometheus 正在运行
    $ kubectl get pods -n prometheus
    NAME                                     READY   STATUS    RESTARTS   AGE
    prometheus-deployment-78fb5694b4-lmz4r   1/1     Running   0          15s

查看基本指标

在本节中,您将访问 Prometheus UI 并查看正在收集的指标。

  1. 使用端口转发在本地启用对 Prometheus UI 的 Web 访问

    注意: 您的 prometheus-deployment 将具有与此示例不同的名称。查看并替换上一个命令输出中的 pod 名称。
    $ kubectl port-forward prometheus-deployment-7ddb99dcb-fkz4d 8080:9090 -n prometheus
    Forwarding from 127.0.0.1:8080 -> 9090
    Forwarding from [::1]:8080 -> 9090
  2. 在浏览器中转到 http://localhost:8080

    Prometheus console



    您现在可以查询 Prometheus 指标了!

  1. 一些基本的机器指标(如 CPU 核心数和内存)立即可用。例如,在表达式字段中输入 machine_memory_bytes,切换到“Graph”视图,然后单击“Execute”以查看指标图表

Prometheus metric channel
  1. 集群中运行的容器也会被自动监控。例如,输入 rate(container_cpu_usage_seconds_total{container_name="prometheus"}[1m]) 作为表达式,然后单击“Execute”以查看 Prometheus 的 CPU 使用率

CPU usage metric

现在您已经知道如何安装 Prometheus 并使用它来衡量一些开箱即用的指标,现在是进行一些实际监控的时候了。

黄金信号

正如 Google SRE 书籍的“监控分布式系统”章节中所述

“监控的四个黄金信号是延迟、流量、错误和饱和度。如果您只能衡量面向用户的系统的四个指标,请关注这四个。”

该书对所有四个信号都进行了详尽的描述,但本教程侧重于最容易作为用户幸福度代理的三个信号

  • 流量: 您正在接收多少请求
  • 错误率: 您可以成功处理多少请求
  • 延迟: 您可以多快地处理成功请求

您可能已经意识到,Prometheus 不会为您测量这些指标;您必须检测您部署的任何应用程序以发出这些指标。以下是一个示例实现。

打开 $WORKDIR/node/golden_signals/app.js 文件,这是一个用 Node.js 编写的示例应用程序(回想一下,我们之前克隆了 yuriatgoogle/prometheus-demo 并导出了 $WORKDIR)。首先查看第一部分,其中定义了要记录的指标

// total requests - counter
const nodeRequestsCounter = new prometheus.Counter({
    name: 'node_requests',
    help: 'total requests'
});

第一个指标是一个计数器,它将为每个请求递增;这就是计算请求总数的方式

// failed requests - counter
const nodeFailedRequestsCounter = new prometheus.Counter({
    name: 'node_failed_requests',
    help: 'failed requests'
});

第二个指标是另一个计数器,它为每个错误递增,以跟踪失败请求的数量

// latency - histogram
const nodeLatenciesHistogram = new prometheus.Histogram({
    name: 'node_request_latency',
    help: 'request latency by path',
    labelNames: ['route'],
    buckets: [100, 400]
});

第三个指标是一个直方图,用于跟踪请求延迟。基于延迟 SLO 为 100 毫秒的非常基本的假设,您将创建两个桶:一个用于 100 毫秒,另一个用于 400 毫秒延迟。

下一节处理传入的请求,为每个请求递增总请求指标,当出现(人为诱发的)错误时递增失败请求,并为每个成功请求记录延迟直方图值。我选择不记录错误的延迟;该实现细节由您决定。

app.get('/', (req, res) => {
    // start latency timer
    const requestReceived = new Date().getTime();
    console.log('request made');
    // increment total requests counter
    nodeRequestsCounter.inc();
    // return an error 1% of the time
    if ((Math.floor(Math.random() * 100)) == 100) {
        // increment error counter
        nodeFailedRequestsCounter.inc();
        // return error code
        res.send("error!", 500);
    } 
    else {
        // delay for a bit
        sleep.msleep((Math.floor(Math.random() * 1000)));
        // record response latency
        const responseLatency = new Date().getTime() - requestReceived;
        nodeLatenciesHistogram
            .labels(req.route.path)
            .observe(responseLatency);
        res.send("success in " + responseLatency + " ms");
    }
})

本地测试

现在您已经了解了如何实现 Prometheus 指标,请查看运行应用程序时会发生什么。

  1. 安装所需的软件包
    $ cd $WORKDIR/node/golden_signals
    $ npm install --save
  2. 启动应用程序
    $ node app.js
  3. 打开两个浏览器标签页:一个访问 http://localhost:8080,另一个访问 http://localhost:8080/metrics
  4. 当您转到 /metrics 页面时,您可以看到 Prometheus 指标正在被收集和更新,每次您重新加载主页时都会更新

Prometheus metrics being collected

您现在可以部署示例应用程序到您的 Kubernetes 集群并测试您的监控。

在 Kubernetes 上部署监控到 Prometheus

现在是时候看看指标是如何在部署在您的集群中的 Prometheus 实例中记录和表示的,通过

  • 构建应用程序镜像
  • 将其部署到您的集群
  • 对应用程序生成负载
  • 观察记录的指标

构建应用程序镜像

示例应用程序提供了一个 Dockerfile,您将使用它来构建镜像。本节假设您具有

  • 本地安装并配置了 Docker
  • 一个 Docker Hub 帐户
  • 创建了一个存储库

如果您使用 Google Kubernetes Engine 运行您的集群,则可以使用 Cloud Build 和 Google Container Registry 代替。

  1. 切换到应用程序目录
    $ cd $WORKDIR/node/golden_signals
  2. 使用此命令构建镜像
    $ docker build . --tag=<Docker username>/prometheus-demo-node:latest
  3. 确保您已登录到 Docker Hub
    $ docker login
  4. 使用此命令将镜像推送到 Docker Hub
    $ docker push <username>/prometheus-demo-node:latest 
  5. 验证镜像是否可用
    $ docker images

部署应用程序

现在应用程序镜像已在 Docker Hub 中,您可以将其部署到您的集群并运行应用程序。

  1. 修改 $WORKDIR/node/golden_signals/prometheus-demo-node.yaml 文件以从 Docker Hub 拉取镜像
    spec:
          containers:
          - image: docker.io/<Docker username>/prometheus-demo-node:latest
  2. 部署镜像
    $ kubectl apply -f $WORKDIR/node/golden_signals/prometheus-demo-node.yaml 
    deployment.extensions/prometheus-demo-node created
  3. 验证应用程序正在运行
    $ kubectl get pods
    NAME                                    READY   STATUS    RESTARTS   AGE
    prometheus-demo-node-69688456d4-krqqr   1/1     Running   0          65s
  4. 使用负载均衡器公开应用程序
    $ kubectl expose deployment prometheus-node-demo --type=LoadBalancer --name=prometheus-node-demo --port=8080
    service/prometheus-demo-node exposed
  5. 确认您的服务具有外部 IP 地址
    $ kubectl get services
    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
    kubernetes             ClusterIP      10.39.240.1     <none>           443/TCP          23h
    prometheus-demo-node   LoadBalancer   10.39.248.129   35.199.186.110   8080:31743/TCP   78m

生成负载以测试监控

现在您的服务已启动并正在运行,请使用 Apache Bench 对其生成一些负载。

  1. 将您的服务的 IP 地址作为变量获取
    $ export SERVICE_IP=$(kubectl get svc prometheus-demo-node -ojson | jq -r '.status.loadBalancer.ingress[].ip')
  2. 使用 ab 生成一些负载。您可能希望在单独的终端窗口中运行此操作。
    $ ab -c 3 -n 1000 http://${SERVICE_IP}:8080/

查看指标

在负载运行时,再次访问集群中的 Prometheus UI 并确认正在收集“黄金信号”指标。

  1. 建立与 Prometheus 的连接
    $ kubectl get pods -n prometheus
    NAME                                     READY   STATUS    RESTARTS   AGE
    prometheus-deployment-78fb5694b4-lmz4r   1/1     Running   0          15s
    
    $ kubectl port-forward prometheus-deployment-78fb5694b4-lmz4r 8080:9090 -n prometheus
    Forwarding from 127.0.0.1:8080 -> 9090
    Forwarding from [::1]:8080 -> 9090

    注意: 确保将第二个命令中的 pod 名称替换为第一个命令的输出。

  2. 在浏览器中打开 http://localhost:8080

Prometheus console
  1. 使用此表达式测量请求速率
    rate(node_requests[1m])

Measuring the request rate
  1. 使用此表达式测量您的错误率
    rate(node_failed_requests[1m])

Measuring the error rate
  1. 最后,使用此表达式验证您的延迟 SLO。请记住,您设置了两个桶,100 毫秒和 400 毫秒。此表达式返回满足 SLO 的请求百分比
    sum(rate(node_request_latency_bucket{le="100"}[1h])) / sum(rate(node_request_latency_count[1h]))

SLO query graph

opensource.com

大约 10% 的请求在 SLO 范围内。这是您应该预期的,因为代码会在 0 到 1,000 毫秒之间的随机毫秒数内休眠。因此,大约 10% 的时间,它会在超过 100 毫秒内返回,并且此图表显示您无法满足延迟 SLO。

总结

恭喜!您已完成本教程,希望您对 Prometheus 的工作原理、如何使用自定义指标检测您的应用程序以及如何使用它来衡量您的 SLO 合规性有了更好的理解。本系列的下一篇文章将介绍另一种使用 OpenCensus 的指标检测方法。

接下来阅读
标签
Yuri Grinshteyn - picture
Yuri Grinshteyn 在旧金山的 Google Cloud 工作,在那里他帮助客户构建可靠性和可观测性的架构。每当有人提到 SLO 时,他都会大声欢呼。

评论已关闭。

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.