介绍
越来越多的组织开始采用 Kubernetes 来管理他们的容器,因此需要一种解决方案来监视分布式系统的健康状况。因此,您可以使用 Prometheus – 一个功能强大的开源工具来监视 K8s 空间中的容器化应用。
在本教程中,您将学习如何安装和配置 Prometheus 堆栈,以监视您的 DOKS 集群中的所有 pod,以及 Kubernetes 集群状态指标。然后,您将连接 Prometheus 和 Grafana,可视化所有指标并使用 PromQL 语言执行查询。最后,您将为 Prometheus 实例配置持久存储,以持久保存所有 DOKS 集群和应用程序指标数据。
目录
- 先决条件
- 步骤 1 – 安装 Prometheus 堆栈
- 步骤 2 – 配置 Prometheus 和 Grafana
- 步骤 3 – PromQL(Prometheus 查询语言)
- 步骤 4 – 使用 Grafana 可视化指标
- 第5步 – 配置Prometheus的持久存储
- 第6步 – 配置Grafana的持久存储
- 结论
先决条件
要完成本教程,您需要:
- A Git client to clone the Starter Kit repository.
- Helm用于管理Prometheus堆栈的发布和升级。
- Kubectl用于与Kubernetes交互。
- Curl用于测试示例(后端应用程序)。
- 在集群中部署的Emojivoto示例应用。请按照其存储库README中的步骤操作。
请确保kubectl
上下文已配置为指向您的Kubernetes集群。请参阅DOKS设置教程中的第3步 – 创建DOKS集群。
步骤 1 – 安装 Prometheus Stack
在此步骤中,您将安装 kube-prometheus
堆栈,这是用于 Kubernetes 的一套具有主观意见的完整监控堆栈。它包括 Prometheus Operator、kube-state-metrics
、预构建清单、节点导出器、指标 API、Alerts Manager 和 Grafana。
您将使用 Helm 软件包管理器来完成此任务。可供学习的 Helm 图表位于 这里。
首先,克隆 Starter Kit 存储库并将目录更改为您的本地副本。
接下来,添加 Helm 存储库并列出可用的图表:
输出结果类似于以下内容:
NAME CHART VERSION APP VERSION DESCRIPTION
prometheus-community/alertmanager 0.18.1 v0.23.0 The Alertmanager handles alerts sent by client ...
prometheus-community/kube-prometheus-stack 35.5.1 0.56.3 kube-prometheus-stack collects Kubernetes manif...
...
感兴趣的图表是 prometheus-community/kube-prometheus-stack
,它将在集群上安装 Prometheus、Promtail、Alertmanager 和 Grafana。请访问 kube-prometheus-stack 页面以获取有关此图表的更多详细信息。
然后,使用您选择的编辑器(最好支持YAML lint)打开并检查Starter Kit存储库中提供的04-setup-observability/assets/manifests/prom-stack-values-v35.5.1.yaml
文件。默认情况下,kubeSched
和etcd
指标被禁用 – 这些组件由DOKS
管理,对Prometheus不可访问。请注意,存储设置为emptyDir
。这意味着如果Prometheus pod重新启动,存储将会丢失(您稍后将在为Prometheus配置持久存储部分修复此问题)。
[可选]如果您遵循了《在DigitalOcean托管的Kubernetes集群中设置观测环境》指南的第4步 – 为观测添加专用节点,您需要编辑Starter Kit存储库中提供的04-setup-observability/assets/manifests/prom-stack-values-v35.5.1.yaml
文件,并取消注释Grafana和Prometheus的affinity
部分。
上述配置的说明:
preferredDuringSchedulingIgnoredDuringExecution
– 调度程序尝试找到符合规则的节点。如果找不到匹配的节点,调度程序仍然会调度Pod。preference.matchExpressions
– 选择器用于根据标准匹配特定节点。上面的示例告诉调度器将工作负载(例如Pod)放置在使用键 –preferred
和值 –observability
进行标记的节点上。
最后,使用Helm
安装kube-prometheus-stack
:
A specific version of the Helm chart is used. In this case 35.5.1
was picked, which maps to the 0.56.3
version of the application (see output from Step 2.). It’s a good practice to lock on a specific version. This helps to have predictable results and allows versioning control via Git.
–create-namespace \
现在,检查Prometheus堆栈Helm发行版的状态:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kube-prom-stack monitoring 1 2022-06-07 09:52:53.795003 +0300 EEST deployed kube-prometheus-stack-35.5.1 0.56.3
输出类似于以下内容。注意STATUS
列的值 – 它应该显示deployed
。
查看可用于Prometheus的Kubernetes资源:
NAME READY STATUS RESTARTS AGE
pod/alertmanager-kube-prom-stack-kube-prome-alertmanager-0 2/2 Running 0 3m3s
pod/kube-prom-stack-grafana-8457cd64c4-ct5wn 2/2 Running 0 3m5s
pod/kube-prom-stack-kube-prome-operator-6f8b64b6f-7hkn7 1/1 Running 0 3m5s
pod/kube-prom-stack-kube-state-metrics-5f46fffbc8-mdgfs 1/1 Running 0 3m5s
pod/kube-prom-stack-prometheus-node-exporter-gcb8s 1/1 Running 0 3m5s
pod/kube-prom-stack-prometheus-node-exporter-kc5wz 1/1 Running 0 3m5s
pod/kube-prom-stack-prometheus-node-exporter-qn92d 1/1 Running 0 3m5s
pod/prometheus-kube-prom-stack-kube-prome-prometheus-0 2/2 Running 0 3m3s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 3m3s
service/kube-prom-stack-grafana ClusterIP 10.245.147.83 <none> 80/TCP 3m5s
service/kube-prom-stack-kube-prome-alertmanager ClusterIP 10.245.187.117 <none> 9093/TCP 3m5s
service/kube-prom-stack-kube-prome-operator ClusterIP 10.245.79.95 <none> 443/TCP 3m5s
service/kube-prom-stack-kube-prome-prometheus ClusterIP 10.245.86.189 <none> 9090/TCP 3m5s
service/kube-prom-stack-kube-state-metrics ClusterIP 10.245.119.83 <none> 8080/TCP 3m5s
service/kube-prom-stack-prometheus-node-exporter ClusterIP 10.245.47.175 <none> 9100/TCP 3m5s
service/prometheus-operated ClusterIP None <none> 9090/TCP 3m3s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/kube-prom-stack-prometheus-node-exporter 3 3 3 3 3 <none> 3m5s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kube-prom-stack-grafana 1/1 1 1 3m5s
deployment.apps/kube-prom-stack-kube-prome-operator 1/1 1 1 3m5s
deployment.apps/kube-prom-stack-kube-state-metrics 1/1 1 1 3m5s
NAME DESIRED CURRENT READY AGE
replicaset.apps/kube-prom-stack-grafana-8457cd64c4 1 1 1 3m5s
replicaset.apps/kube-prom-stack-kube-prome-operator-6f8b64b6f 1 1 1 3m5s
replicaset.apps/kube-prom-stack-kube-state-metrics-5f46fffbc8 1 1 1 3m5s
NAME READY AGE
statefulset.apps/alertmanager-kube-prom-stack-kube-prome-alertmanager 1/1 3m3s
statefulset.apps/prometheus-kube-prom-stack-kube-prome-prometheus 1/1 3m3s
您应该已部署以下资源:prometheus-node-exporter
、kube-prome-operator
、kube-prome-alertmanager
、kube-prom-stack-grafana
和kube-state-metrics
。输出类似于:
然后,您可以通过端口转发到本地机器连接到Grafana(使用默认凭据:admin/prom-operator
– 参见prom-stack-values-v35.5.1文件):
您应该不要将Grafana暴露给公共网络(例如,创建一个入口映射或LB服务)与default login/password
。
Grafana安装附带了几个仪表板。在localhost:3000上打开一个网络浏览器。登录后,您可以转到仪表板 -> 浏览,并选择不同的仪表板。
在接下来的部分,您将了解如何设置Prometheus来发现监控目标。作为示例,将使用Emojivoto
示例应用程序。您还将学习ServiceMonitor
是什么。
您已经将Prometheus和Grafana部署到了集群中。在此步骤中,您将学习如何使用ServiceMonitor
。ServiceMonitor是告诉Prometheus如何发现新的监控目标的首选方式之一。
在先决条件部分的步骤5中创建的Emojivoto部署默认在端口8801
上通过Kubernetes服务提供了/metrics
端点。
接下来,您将了解负责为Prometheus公开指标数据的Emojivoto服务。相关服务称为emoji-svc
和voting-svc
(请注意,它正在使用emojivoto
命名空间):
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
emoji-svc ClusterIP 10.245.135.93 <none> 8080/TCP,8801/TCP 22h
voting-svc ClusterIP 10.245.164.222 <none> 8080/TCP,8801/TCP 22h
web-svc ClusterIP 10.245.61.229 <none> 80/TCP 22h
输出类似于以下内容:
接下来,执行port-forward
以检查指标:
暴露的指标可以通过在浏览器中导航到localhost或通过curl进行可视化:
输出类似于以下内容:
go_gc_duration_seconds{quantile="0"} 5.317e-05
go_gc_duration_seconds{quantile="0.25"} 0.000105305
go_gc_duration_seconds{quantile="0.5"} 0.000138168
go_gc_duration_seconds{quantile="0.75"} 0.000225651
go_gc_duration_seconds{quantile="1"} 0.016986437
go_gc_duration_seconds_sum 0.607979843
go_gc_duration_seconds_count 2097
# TYPE go_gc_duration_seconds summary
要检查voting-svc
服务的指标,请停止emoji-svc
端口转发,并对第二个服务执行相同的步骤。
- 接下来,将Prometheus连接到Emojivoto指标服务。有几种方法可以做到这一点:
- <static_config> – 允许指定一系列目标和一个共同的标签集。
- <kubernetes_sd_config> – 允许从Kubernetes的REST API中检索抓取目标,并始终与集群状态同步。
Prometheus Operator – 通过CRD简化了Kubernetes集群内的Prometheus监视。
接下来,您将利用Prometheus Operator公开的ServiceMonitor
CRD来定义用于监视的新目标。
首先,更改目录(如果尚未)到Starter Kit Git存储库被克隆的位置:
接下来,使用您选择的文本编辑器(最好支持YAML lint)打开提供的Starter Kit存储库中的04-setup-observability/assets/manifests/prom-stack-values-v35.5.1.yaml
文件。请删除additionalServiceMonitors
部分周围的注释。输出类似于:
- 上述配置的说明:
selector -> matchExpressions
– 告诉ServiceMonitor
要监视哪个服务。它将目标定为具有标签键app和值emoji-svc
和voting-svc
的所有服务。可以通过运行以下命令获取这些标签:kubectl get svc --show-labels -n emojivoto
namespaceSelector
– 在这里,您希望匹配部署了Emojivoto
的命名空间。
endpoints -> port
– 引用要监视的服务的端口。
最后,使用Helm应用更改:
接下来,请检查是否已将Emojivoto
目标添加到Prometheus进行抓取。为Prometheus创建一个端口转发,端口为9090
:
在localhost:9090上打开一个Web浏览器。然后,导航至Status -> Targets页面,并检查结果(注意serviceMonitor/monitoring/emojivoto-monitor/0
路径):
在发现的目标下有2个条目,因为Emojivoto
部署由2个公开度量终点的服务组成。
在接下来的步骤中,您将了解PromQL以及一些简单示例,帮助您入门并了解该语言。
步骤 3 – PromQL(Prometheus 查询语言)
在这一步中,您将学习Prometheus 查询语言(PromQL)的基础知识。PromQL帮助您对来自您的DOKS集群中所有Pod和应用程序的各种指标执行查询。
PromQL是一种专门为Prometheus构建的DSL或特定领域语言,允许您查询指标。整体表达式定义了最终值,而嵌套表达式表示参数和操作数的值。要了解更详细的解释,请访问官方的PromQL页面。
接下来,您将检查Emojivoto
指标之一,即emojivoto_votes_total
,它表示总投票数。这是一个计数器值,每次对Emojivoto
投票端点发出请求时都会增加。
首先,在端口9090
上为Prometheus创建端口转发:
接下来,打开表达式浏览器。
emojivoto_votes_total{container="voting-svc", emoji=":100:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 20
emojivoto_votes_total{container="voting-svc", emoji=":bacon:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 17
emojivoto_votes_total{container="voting-svc", emoji=":balloon:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 21
emojivoto_votes_total{container="voting-svc", emoji=":basketball_man:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 10
emojivoto_votes_total{container="voting-svc", emoji=":beach_umbrella:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 10
emojivoto_votes_total{container="voting-svc", emoji=":beer:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 11
在查询输入字段中粘贴emojivoto_votes_total
,然后按Enter键。输出看起来类似于:
导航至Emojivoto
应用程序,并从首页点击100表情符号以投票支持它。
emojivoto_votes_total{container="voting-svc", emoji=":100:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 21
emojivoto_votes_total{container="voting-svc", emoji=":bacon:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 17
emojivoto_votes_total{container="voting-svc", emoji=":balloon:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 21
emojivoto_votes_total{container="voting-svc", emoji=":basketball_man:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 10
emojivoto_votes_total{container="voting-svc", emoji=":beach_umbrella:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 10
emojivoto_votes_total{container="voting-svc", emoji=":beer:", endpoint="prom", instance="10.244.25.31:8801", job="voting-svc", namespace="emojivoto", pod="voting-74ff7f8b55-jl6qs", service="voting-svc"} 11
从第三步导航至查询结果页面,然后点击执行按钮。您应该会看到100表情符号的计数器增加了一个。输出类似于:
PromQL将类似的数据分组到所谓的向量中。如上所示,每个向量都有一组属性,使其与其他向量不同。您可以根据感兴趣的属性对结果进行分组。例如,如果您只关心来自voting-svc
服务的请求,请在查询字段中键入以下内容:
emojivoto_votes_total{container="voting-svc", emoji=":100:", endpoint="prom", instance="10.244.6.91:8801", job="voting-svc", namespace="emojivoto", pod="voting-6548959dd7-hssh2", service="voting-svc"} 492
emojivoto_votes_total{container="voting-svc", emoji=":bacon:", endpoint="prom", instance="10.244.6.91:8801", job="voting-svc", namespace="emojivoto", pod="voting-6548959dd7-hssh2", service="voting-svc"} 532
emojivoto_votes_total{container="voting-svc", emoji=":balloon:", endpoint="prom", instance="10.244.6.91:8801", job="voting-svc", namespace="emojivoto", pod="voting-6548959dd7-hssh2", service="voting-svc"} 521
输出类似于(请注意,它仅选择与您的标准匹配的结果):
以上结果显示了来自发出指标的Emojivoto
部署的每个Pod的总请求数(由2个组成)。
这只是对PromQL是什么以及它能做什么的一个非常简单的介绍。但它可以做的远不止于此,例如计算指标数量、计算预定义时间间隔内的速率等等。请访问官方PromQL页面,了解语言的更多特性。
在下一步中,您将学习如何使用Grafana来可视化Emojivoto
示例应用程序的指标。
虽然 Prometheus 内置了一些支持数据可视化的功能,但更好的方法是通过 Grafana 实现,它是一个用于监控和可观察性的开源平台,让您可以可视化和探索集群的状态。
官方页面描述可以:
查询、可视化、对数据进行警报,并理解数据存储的位置。
安装 Grafana 不需要额外的步骤,因为第1步 – 安装 Prometheus Stack已经为您安装了 Grafana。您所需做的只是像下面这样进行端口转发,即可立即访问仪表板(默认凭据:admin/prom-monitor
):
要查看所有Emojivoto
指标,您将使用 Grafana 中默认安装的一个仪表板。
导航到Grafana 仪表板部分。
接下来,搜索General/Kubernetes/Compute Resources/Namespace(Pods)仪表板并访问它。
最后,选择Prometheus 数据源并添加emojivoto
命名空间。
您可以在Grafana中玩耍,并添加更多面板来可视化其他数据源,还可以根据范围对它们进行分组。此外,您可以从Grafana kube-mixin 项目中探索可用的Kubernetes仪表板。
在下一步中,您将使用DigitalOcean块存储为Prometheus配置持久性存储,以便在服务器重新启动或集群故障时保留您的DOKS和应用程序指标。
在这一步中,您将学习如何为Prometheus启用持久性存储,以便在服务器重新启动或集群故障时保留指标数据。
首先,您需要一个存储类来继续。运行以下命令来检查可用的存储类。
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
do-block-storage (default) dobs.csi.digitalocean.com Delete Immediate true 4d2h
输出应类似于以下内容。请注意,您可以使用DigitalOcean块存储。
接下来,更改目录(如果尚未更改)到已克隆Starter Kit Git存储库的位置:
然后,使用您选择的文本编辑器(最好支持YAML lint)打开Starter Kit存储库中提供的04-setup-observability/assets/manifests/prom-stack-values-v35.5.1.yaml
文件。搜索storageSpec
行,并取消对Prometheus所需部分的注释。 storageSpec
定义应如下所示:
- 上述配置的解释如下:
volumeClaimTemplate
– 定义一个新的PVC。storageClassName
– 定义存储类(应使用与kubectl get storageclass
命令输出相同的值)。
resources
– 设置存储请求值。在本例中,为新卷请求了总容量为5 Gi。
最后,使用Helm应用设置:
完成上述步骤后,检查PVC状态:
NAME STATUS VOLUME CAPACITY ACCESS MODES AGE
kube-prome-prometheus-0 Bound pvc-768d85ff-17e7-4043-9aea-4929df6a35f4 5Gi RWO do-block-storage 4d2h
A new Volume should appear in the Volumes web page from your DigitalOcean account panel:
输出类似于以下内容。 STATUS
列应显示Bound
。
在这一步,您将学习如何为Grafana启用持久存储,以便图形在服务器重新启动或集群故障时得以保留。您将定义一个使用DigitalOcean块存储的5 Gi持久卷索取(PVC)。接下来的步骤与第5步 – 配置Prometheus的持久存储相同。
首先,使用您选择的文本编辑器(最好支持YAML lint)打开提供在Starter Kit存储库中的04-setup-observability/assets/manifests/prom-stack-values-v35.5.1.yaml
文件。Grafana的持久存储部分应该如下所示:
接下来,使用Helm应用设置:
完成上述步骤后,请检查PVC状态:
NAME STATUS VOLUME CAPACITY ACCESS MODES AGE
kube-prom-stack-grafana Bound pvc-768d85ff-17e7-4043-9aea-4929df6a35f4 5Gi RWO do-block-storage 4d2h
A new Volume should appear in the Volumes web page from your DigitalOcean account panel:
输出应该类似于以下内容。STATUS
列应该显示Bound
。
- 根据您的需求计算卷的大小,请遵循官方文档建议和公式:
- Prometheus 每个样本平均仅存储 1-2 字节。因此,为了规划 Prometheus 服务器的容量,您可以使用以下大致公式:
needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample
要降低样本的摄取速率,您可以减少抓取的时间序列数量(减少目标或减少每个目标的系列数量),或者增加抓取间隔。然而,由于在系列内对样本的压缩,减少系列数量可能更有效。