IT 团队已经明确意识到对基础设施进行监控的必要性。目前市面上存在着大量适用于传统基础设施且历史悠久的解决方案:Nagios、Zabbix 等工具都是其中的代表。
但这些工具并不足以解决 Kubernetes 生态系统在多层级抽象与故障排查方面的实际需求。不少 DevOps 工程师一次又一次被以下问题所困扰:
调度失败,找不到与以下所有谓词相匹配的节点::CPU 不足
集群资源监控对于实时跟踪而言至关重要。与传统基础设施相比,集群资源一直在不断扩展和变化。我们永远无法知晓自己的 Pod 在集群中的启动位置。出于这些考虑,我们需要监控集群的底层资源以及内部集群的运行状态。
更重要的是,如果不配合警报机制,单纯进行监控还远远不够。因为很明显,运营工程师不可能整晚对着关键生产集群的仪表板等待。
1 为什么要选择 Prometheus 与 Grafana?即使拥有广泛的警报与监控工具可供选择,我们为什么要专门点名 Prometheus 与 Grafana?
PrometheusPrometheus 是一款开源监控工具。它最初在 Soundcloud 上开发完成,但如今已经转化为独立的开源项目,从 2016 年开始成为云原生计算基金会(CNCF)的一部分,并成为继 Kubernetes 本身之后的第二个项目。也正因为如此,这两款组件通常会紧密关联在一起。
除此之外,Prometheus 不同于其他众多监控工具的一大核心,在于其基本架构始终以 pull 为基础。它不断从受到监控的组件当中抓取指标。
最后,从架构本身来看,Prometheus 使用到多维数据模型,此模型与 Kubernetes 通过标签组织数据的方式非常相似。与点数据模型相反,点数据模型中的每项指标都是唯一的,而每个不同的参数都将对应不同的指标;而使用 Prometheus,所有数据都将按时间序列存储为键 - 值对:
<metric name>{<label name>=<label value>, …}
Prometheus 架构包含三大主要组件:
Prometheus 服务器本身,用于收集指标并通过 API 应答查询。
Pushgateway,公布关于临时及短期作业的指标。
Alertmanager:按照名称提示启用警报发布。
Prometheus 架构与生态系统组件
我们还将把 prometheusnode_exporter 与 kube_state_metrics 相结合,用以发布关于集群的各项指标。
GrafanaGrafana 是一款颇为流行的 Prometheus 开源(Apache 2.0 许可)可视化层,支持以开箱即用的方式按时间查询 Prometheus 数据。实际上,从 Grafana 2.5.0 (2015–10–28) 版本开始就已经把 Prometheus 纳入为 Grafana 数据源。
最重要的是,它非常易于使用,其中提供的模板功能可帮助您轻松创建可实时编辑的动态仪表板。
最后,Grafana 提供良好的说明文档以及广泛的社区共享体系,包括各类公共仪表板。在本文中,我们将使用两套专为 Kubernetes 设计的公共仪表板。
理论到此结束,下面开始动手环节!
2 安装的先决条件完成演练项目的唯一要求,就是拥有一套有效的 Kubernetes 集群。为了简单起见,本文将在 AWS EC2 上使用 minikube 完成安装。
Minikube 是一种便捷方法,能够快速高效地安装一套非生产、主要用于实验室及测试场景的单节点 Kubernetes 集群。由于对资源需求不高,而且支持多种现成 K8s 功能,大家可以借此在单一计算机上轻松获取 Kubernetes 集群。
只要使用虚拟机管理程序在机器上创建本地计算机,系统即可正常工作。但这里我们使用 AWS 虚拟机,并在演示中使用 Minikube 的 vm-driver=none 模式。
3 使用 Helm 安装 Prometheus 与 Grafana接下来就是安装这两款产品了。这里我们使用 Helm, 这款 Kubernetes 软件包管理器已经在 2019 年 11 月正式更新为 3.0 版本。
从历史来看,此次更新非常重要,因为开发社区对 Helm 进行深度重写,借此适应 RBAC 与自定义角色定义等 Kubernetes 发展成果。新版本较以往版本更适合生产要求。以往,由于固有安全模型以及高度依赖于存在争议的 Tiller 组件(现已从 3.0 版本中删除),不少 IT 专家都不愿意将 Helm 应用于生产级集群。
我们还将使用稳定版 Helmrepo 中的 charts(Helm 打包格式)对 Kubernetes 集群组件及系统指标进行监控。
安装 Helm将稳定版 repo 添加至您的 Helm 安装:
$ helm repo add stable[https://kubernetes-charts.storage.googleapis.com/](https://kubernetes-charts.storage.googleapis.com/)$ helm repo update
接下来,我们在 K8s 集群上创建一个自定义命名空间,用以管理所有监控栈:
$kubectlcreate ns monitoring
安装 Prometheus 现在,我们可以在新创建的监控命名空间中安装 Prometheuschart 了:
$ helm installprometheusstable/prometheus--namespace monitoringNAME:prometheusLAST DEPLOYED: Tue Apr 14 09:22:27 2020NAMESPACE: monitoringSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster:prometheus-server.monitoring.svc.cluster.local[...]
接下来,我们可以使用 K8s 的本地指令命令创建一个 NodePort,借此从集群外部直接与 Pod 通信。请注意,如果您不打算在未安装 Grafana 的前提下查询 Prometheus,也可以直接跳过此步骤。
我们可以看到,端口 30568 被自动分配并映射至指向该 Pod 的端口 9090.
现在,我们可以使用公共 DNS 及浏览器中的 30568 端口访问 Prometheus 端点。
接下来,我们可以使用以下命令直接查询 Prometheus 以获取各类指标,例如命名空间的 CPU 消耗量:
sum(rate(container_cpu_usage_seconds_total{container_name!=”POD”,namespace!=””}[5m])) by (namespace)
4 安装 Grafana 现在,Prometheus 已经安装完成。相较于单独查询各项指标,我们可以使用 Grafana 以聚合方式通过统一的仪表板快速查看多项指标。
我们再次使用 helm 将 grafana 安装在监控命名空间当中:
$ helm installgrafanastable/grafana--namespace monitoring
可以看到,grafanaPod 开始配合 Prometheus 组件运行:
这里,我们再创建一个 NodePort 服务,从集群外部访问 Grafana(此步骤为强制要求):
$kubectl-n monitoring expose pod grafana-5b74c499c6-kt4bw --typeNodePort--namegrafana-npservice/grafana-np exposed
而后将外部端口映射至 Grafana 的侦听端口 3000:(这里为 31399)
$kubectl-n monitoringgetsvcgrafana-npNAMETYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEgrafana-npNodePort10.111.59.2 80:30368/TCP,3000:31399/TCP 3h8m
在浏览器中输入:yourPublicDNS:yourPort 与 tada!
Grafana 提供用户管理功能,在默认情况下您需要使用 admin 用户方可接入。
要获取 admin 密码,请输入以下命令:
kubectlget secret — namespace monitoringgrafana-ojsonpath=”{.data.admin-password}” | base64 — decode ;echoADMINPASSWORD
现在即可开始正式连接。
第一步是使用 Kubernetes 的内部 DNS 结构将 Prometheus 配置为数据源:
http://prometheusServiceName.namespace.svc.cluster.local:port
在本示例中为:
http://prometheus-server.monitoring.svc.cluster.local(:80 可选)
现在数据已经添加完成,我们将导入两套社区仪表板,用于监控我们的工作负载与集群运行情况。这些仪表板应该可以开箱即用。
点击 import 按钮并输入 Grafana 仪表板 ID:
首先安装 1860,而后安装 8685:
现在,我们已经拥有了两套工作仪表板:
我们已经可以轻松监控系统指标与集群配置了!
5 通过 Slack 频道发布警报现在,我们已经拥有了一套高效的监控解决方案,第二步就是激活警报。很明显,如果没有警报机制的支持,运营团队不可能整天盯着生产环境中的众多仪表板。
我们可以通过两种方式在监控栈中实施警报。首先是使用 PrometheusAlertManager 组件(由 helm chart 安装),其次是使用 Garfana 的内置警报功能。这里我们选择后一种方式,因为其更易于现实。
Grafana 能够通过 Slack、电子邮件、webhook 或者其他通信渠道发布警报。由于我个人经常使用 Slack,而且不少企业也在使用 Slack 作为内部通信平台,因此本示例就以 Slack 为警报通道。
创建 Slack 通知频道第一步是将 Slack 添加为通知频道。在 Grafana 当中,单击左侧的铃铛图标,选择通知频道菜单,而后创建一个新频道。
您将在这里看到多种与 Grafana 相兼容的警报工具。
选择 Slack,而后输入您的 Slack webhook URL(其他字段为可选项)。
如果您还没有 webhook URL,请参阅此教程进行创建:
https://api.slack.com/messaging/webhooks
如此一来,您将拥有一个端点,用于将消息发送至 Slack 服务器上的特定频道。
创建并测试自定义警报现在,频道已经设置完毕,接下来使用“K8s Cluster Summary”仪表板,而后单击“Cluster Pod Capacity”标题以编辑面板。
我们将设置一项警报来监控 Pod 容量,在默认情况下,每个节点上的 Kubernetes 限制为 110 个。此上限总体属于可靠上限。如果集群中的节点数量受到限制,而且已经达到 110 个这一硬上限,则剩余的 Pod 将进入挂起状态。而这会在高业务活动强度期间给生产集群扩展造成巨大问题。
我们将警报设置为 90 个 Pod:
回到我们的集群,创建一个包含 100 个 nginx 副本的任意部署:
$kubectlcreate nsloadtestnamespaceloadtestcreated$kubectlcreate deploymentnginx--image=nginx-nloadtestdeployment.apps/nginxcreated$kubectl-nloadtestscale deploymentnginx--replicas=100deployment.apps/nginxscaled
可以看到,由于集群中已经包含 15 个初始 Pod,且 Pod 容量迅速增加到 115 个:
这比许可的 Pod 上限 110 个还多了 5 个。实际上,我们可以在仪表板中看到 5 个 Pod 处于待处理状态。
5 分钟之后,警报进入 ALERTING 状态,并在 Slack 频道上发送带有自定义消息及当前值的通知。
我们可以将部署缩减至 1 个 Pod:
$kubectl-nloadtestscale deploymentnginx— replicas=1deployment.apps/nginxscaled
Pod Capacity 已经冷却:
警报会向 Slack 发送返回正常状态的通知。
这项小小的演练非常有趣,因为它不仅实施起来相当简单,而且足以反映真实的运营场景。
关于 Grafana 警报功能,还有其他一些注意事项。我们的两套仪表板都使用被称为模板变量的函数。变量是您可以在主机、集群或者命名空间等仪表板之上进行更改的值。根据设计,Grafana 不可根据模板变量发出警报,原因很多。如果尝试在仪表板的某些面板上放置一些警报,则有可能因此而出错。解决方案是为各项警报指定一个特定的主机、集群或者节点,而非使用变量进行监控。
6 总结在与 Prometheus 与 Grafana 打过一番交道之后,希望大家喜欢这篇文章,并感受到监控对于 Kubernetes 生态系统的重要意义。
原文链接
https://gregoiredayet.medium.com/monitoring-and-alerting-on-your-kubernetes-cluster-with-prometheus-and-grafana-55e4b427b22d
今日推荐文章对话Ruby on Rails之父DHH:我们需要重新审视软件开发
点个在看少个 bug ?