可观测性与应用监控:实时性能分析和故障排查
大家好,
在现代软件开发中,应用程序的可观测性和实时性能分析变得越来越重要。随着应用程序规模和复杂性的增加,我们需要能够及时发现和解决潜在的性能问题和故障,并保持应用程序的高可用性。在本文中,我们将讨论可观测性的概念以及应用监控中的实时性能分析和故障排查方法。
首先,让我们明确可观测性的定义。可观测性是指我们能够全面地了解应用程序在运行时的状态和行为。这包括监控应用程序的性能指标、收集日志和跟踪请求的路径。通过实时监控和分析这些数据,我们可以更好地了解应用程序的健康状况,并及时发现和解决潜在的问题。
实时性能分析是实现可观测性的关键组成部分之一。它允许我们实时监测应用程序的性能指标,如响应时间、吞吐量和资源利用率。实时性能分析工具可以帮助我们追踪应用程序中的性能瓶颈,并提供关键的指标来评估应用程序的健康状况。一些流行的实时性能分析工具包括Prometheus、Grafana和DataDog。
故障排查是另一个关键的方面,它帮助我们快速发现和解决应用程序中的故障。当应用程序出现故障时,我们需要能够迅速定位问题所在,并采取相应的措施来修复。故障排查工具提供了可视化的界面和工具,帮助开发人员定位故障,并提供相关的上下文信息。一些常用的故障排查工具包括Jaeger、Zipkin和Sentry。
实现可观测性和应用监控的关键是在应用程序中集成监控和日志记录。这可以通过使用适当的监控代理和库来实现。例如,在Java应用程序中,我们可以使用Prometheus客户端库来公开自定义的监控指标,同时使用Logback或Log4j来记录关键的日志消息。
除了集成监控和日志记录,我们还应该关注监控数据的可视化和警报。可视化监控数据可以帮助我们更好地
理解应用程序的性能和行为,而警报系统可以及时通知我们应用程序中的异常情况。一些流行的监控数据可视化和警报工具包括Grafana、Kibana和Alertmanager。
在实施可观测性和应用监控时,我们还应该考虑安全性和隐私性。敏感数据的监控和记录可能会引发安全风险和隐私问题。因此,在实施可观测性方案时,我们应该遵循最佳实践,如数据脱敏、权限控制和加密。
总结一下,可观测性和应用监控是现代软件开发中至关重要的方面。通过实时性能分析和故障排查,我们可以及时发现和解决潜在的问题,确保应用程序的高可用性和稳定性。集成监控和日志记录、可视化监控数据以及设置警报系统都是实现可观测性的关键步骤。
希望本文对您在可观测性和应用监控方面的工作有所帮助。如果您对这个主题有任何疑问或想法,请在下方留言,我们很乐意与您讨论。
谢谢!
希望这篇文章能满足您的需求!如果您有任何其他问题,我会很乐意为您提供帮助。
带你读《Elastic Stack 实战手册》之76:——4.2.2.Elasticsearch智能巡检开发设计实践(1)
4.2.2.Elasticsearch智能巡检开发设计实践创作人:张妙成审稿人:田雪松 项目背景 PaaS 下管理了大量集群,监控和告警能快速的让开发维护人员,知道系统已经发生故障,并且辅助高效排障。 但是无法提前预知集群的健康状况,开发人员和维护人员均无法在故障前及时作出调整。为了帮助用户及时的知道集群的健康状态,更好使用 Elasticsearch 集群,可以定期对集群进行指标检查并给出相应报告。巡检作业及时发现集群的健康问题,集群的配置是否合理,提前主动发现问题,能有效保证集群的稳定性、健状性,从而减少业务中断时间保证服务质量。 为了解决集群健康状态提前预知困难的问题,可以通过抽取一些指标,进行定时检查达到健康诊断的目的。 巡检主要是对集群的各个指标检查,给出一份全方位的报告,并提供一定的推荐解决、优化方案。如阿里的 EYOU 平台(阿里云 Elasticsearch 智能诊断系统)会系统的在 Elasticsearch 公有云进行各个指标的检查,并给出相应报告,极大的减小了风险,降低了维护成本。 智能管理系统不是一个独立的检查系统,而是一个与其他系统相结合的闭环系统,独立的巡检模块对各项指标进行检查分析,将结果通过 PaaS 系统展示给用户,并在 PaaS 中给予入口,用以帮助用户手动再次触发检查,增强实时性,提高用户体验。 本文将介绍智能巡检系统在整个 Elasticsearch 相关系统中的位置与意义,并从指标分析选取、异常标准的角度,主要阐述智能巡检系统的设计与实现。整个应用的框架如上: l Elasticsearch 集群在 K8S 环境中(实际生产大多是 K8S 环境与物理机、虚拟机环境共存,这里简化成最终要达到的统一环境),由 PaaS 平台进行统一管理。l PaaS 的信息数据主要是与 DB 交互(PaaS 是与 DB 的唯一交互入口),用户主要与l PaaS平台进行交互。智能巡检系统信息收集模块(一组 Python Job)主要是 K8S 环境中的 Elasticsearchl cluster、宿主机进行交互,数据报告信息通过 PaaS 平台存入 DB。l 监控使用 VictoriaMetrics( Prometheus 的高可用方案)作为存储,grafana 作为前端展示页面。监控可以配置 Elasticsearch 各项指标,其中与智能巡检相关是巡检异常数量的监控面板,用来给 OPS 观察巡检亚健康集群异常点的修复(优化)情况。l PaaS 提供入口手动触发再次检查。指标选取简介 巡检的指标、异常阈值与告警配置的主要区别是,检的指标项会更加关心可能引发故障的某些现象和配置,参考阈值相对告警配置会更加宽松。巡检主要是通过指标的采集分析,得出一份相对全面的报告和推荐解决方案。为了报告的全面性与分析的准确性,巡检的指标项会与告警配置有一定相似或重复。 告警与巡检需要解决的问题不同,告警的目的是将异常指标恢复到正常状态,响应的实时性要求较高,而巡检的目的是预防故障、消除隐患、优化集群性能,以报告的形式推到平台和用户,不需要用户主动响应,只需解决问题后重新触发巡检。为推进优化,可将巡检报告中非健康指标配置成监控面板、告警。 集群健康程度可以从几个方面表现:cluster 层面、node 层面、shard 层面、index 层面、jvm 层面、threadpool 层面。如下为参考指标:Elasticsearch 功能强大、使用方便,也就意味着对用户来说有很多的默认设置,用户使用的自由度很高,也就意味着开放的能力丰富,用户的使用对集群健康程度有着很大的影响。 所以指标选取需要从两个角度,一是现有的现象指标,二是常用不合理的配置指标。接下来对选取的指标进行简要逐一分析。 《Elastic Stack 实战手册》——四、应用实践——4.2 可观测性应用场景 ——4.2.2.Elasticsearch智能巡检开发设计实践(2) https://developer.aliyun.com/article/1226094
带你读《Elastic Stack 实战手册》之75:——4.2.1.基于Elasticsearch实现预测系统(2)
《Elastic Stack 实战手册》——四、应用实践——4.2 可观测性应用场景 ——4.2.1.基于Elasticsearch实现预测系统(1) https://developer.aliyun.com/article/1226137Prometheus 与 Elasticsearch 的数据同步 Prometheus 支持一种称为远程读写(Remote Read/Write)的功能,可以在 Prometheus 拉取监控数据时将数据写入到远程的数据源中,或者从远程数据源中读取监控数据做处理。 Prometheus 目前支持的远程数据源多达几十种,所有数据源都支持远程写入,但并不是所有数据源都同时支持远程读取,比如我们这里要使用的 Elasticsearch 就只支持远程写入。注:7.10版本是支持的,可以通过 Metricbeat 对 Prometheus 进行远程拉取,参见:https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-metricset-prometheus-query.html Prometheus 为远程读取和写入,分别定义了独立的通信与编码协议,第三方存储组件需要向Prometheus 提供兼容该协议的 HTTP 接口地址。但由于众多第三方存储组件接收数据的方式并不相同,支持 Prometheus 读写协议的接口地址并不一定存在。为此,Prometheus 采用了适配器的方式屏蔽不同存储组件之间的差异, 如图1-2所示: 图1-2 Prometheus 远程读写只要提供了适配器,Prometheus 读写数据就可以转换成第三方存储组件支持的协议和编码。Elasticsearch 也需要使用适配器,这个适配器就是由 Elastic Stack 家族中的 Beat 组件担任。早期 Prometheus 官方推荐的适配器是 Infonova 开发的 Prometheusbeat,而在最新版本中已经转而推荐 Elastic Stack 官方的 Metricbeat。 无论是 Prometheusbeat 还是 Metricbeat,它们都可以向 Prometheus 开放 HTTP 监听地址,并且在接收到 Prometheus 监控数据后将它们存储到 Elasticsearch 中。Metricbeat 采用Module 的形式开启面向 Prometheus 的 HTTP 接口,具体配置如示例 1.1 所示:- module: prometheus
metricsets: ["remote_write"]
host: "localhost"
port: "9201"示例1.1 Metricbeat 配置添加示例所示配置内容后重启 Metricbeat,它就会在本机 9201端口开始监听 Prometheus 的写入数据。与此同时还要将这个监听地址告诉 Prometheus,这样它才知道在拉取到数据后向哪里写入。具体来说就是在 prometheus.yml中 添加如下内容: remote_write:
- url: "https://localhost:9201/write"示例1.2 Prometheus 配置使用 MetricBeat 组件保存监控数据,监控指标的标签(Label)会转换为 Elasticsearch 的文档字段。Metricbeat 还会附加一些 Metricbeat 自身相关的数据,所以文档中的字段会比实际监控指标的标签要多一些。 除了指标名称和标签以外,还包括主机地址、操作系统等信息,这可能会导致样本数据量急剧膨胀。但 Prometheus 并不支持在写入远程存储前过滤样本,所以只能通过 Beat 组件处理。 注:最高效的做法是在 metricbeat 上设置 drop_fields 的 processor,直接过滤,避免无效的网络传输。 比较理想的方法是将 Beat 组件的输出设置为 Logstash,然后再在 Logstash 中做数据过滤,最后再由 Logstash 转存到 Elasticsearch 中。在我们的系统中,除了要过滤以上 Metricbeat 附加的字段以外,还需要组合、修正一些业务相关的字段。所以为了更好的处理数据,我们在整个数据系统中加入了 Logstash 组件。 最终整个数据系统的大致结构如图 1-3 所示: Prometheus 在拉取到监控指标时,将数据同时发送给 Metricbeat 或 Prometheusbeat,它们在这里职责就是一个监控数据接收的端点。 Metricbeat 或 Prometheusbeat 再将数据发送给 Logstash,而 Logstash 则负责清洗和整理监控数据,并将它们存储到 Elasticsearch 中。我们将整个监控系统和数据系统部署在Kubernetes 集群中,而最终用于机器学习的数据源 Elasticsearch 则被部署为独立的集群。 这样就将监控系统与数据分析系统隔离开来,从而保证了监控系统,不会受到大量数据分析运算的影响而出现故障。实际上图 1-3 就是对图 1-1中 所展示的监控系统、数据系统以及Elasticsearch 集群的细化,但在实际应用中还有许多细节没有展现出来,需要读者根据项目实际情况做适当调整。 集成 Elasticsearch 与 Spark 事实上,新版 Kibana 组件中已经具备了非常强大的机器学习能力,但这项功能还未开放在基础授权中。此外我们的业务系统还有一些自身的特殊性,所以最终我们决定采用 Spark 编写代码实现这套智能预测系统。 一种显而易见的办法是利用 Elasticsearch 客户端接口,先将数据从 Elasticsearch 中读取出来再传给 Spark 进行分析处理。但 Spark 数据处理是先将任务分解成子任务,再将它们分发到不同计算节点上并行处理,以此提升海量数据分析处理的速度。而任务分解的同时是数据要分解,否则最终数据读取,就会成为所有子任务的瓶颈,这种分解后的数据在 Spark 中称为分区(Partition)。每个任务在各自的数据分区上运算处理,最终再将各自的处理结果按 Map/Reduce 的思想合并起来。Elasticsearch 中的分片(Shard)刚好与 Spark 分区相契合,如果能让任务运算于分片之上,这无疑可以更充分地利用 Elasticsearch 存储特征。但如果是先从 Elasticsearch 读取数据再发送给Spark做处理,数据就是经由分片合并后的数据,Spark 在运算时就需要对数据再次进行分区。 Elasticsearch 包含一个开源的 elasticsearch-hadoop 项目,可以很好地解决数据分区问题。elasticsearch-hadoop 可以与包括 Spark 在内的 Hadoop 生态良好集成,Spark 分区数据也可以与 Elasticsearch 分片数据直接对应起来。我们所要做只是将 elasticsearch-hadoop 的Spark 依赖添加到项目中,并使用其提供的接口将数据从 Elasticsearch 中读取进来即可。智能预测系统采用 Java 语言开发,所以使用 Maven 引入如下依赖: <dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-spark-${spark.major.version}_${scala.version}</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-mllib_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>如示例 1.3 所示,elasticsearch-hadoop 的 Spark 依赖为 elasticsearch-spark。由于需要用到Spark ML 相关库,示例也将 spark-sql 和 spark-mllib 依赖也一并引入了进来。elasticsearch-spark 在 org.elasticsearch.spark.rdd.api.java 包中定义了类 JavaEsSpark,它提供了大量用于读取和写入 Elasticsearch 的静态方法。其中,静态方法 esRDD 用于从 Elasticsearch中读取索引,而 saveToEs 则用于向 Elasticsearch 中存储数据。 示例展示了从 Elasticsearch 中读取索引数据的代码片段: List<Row> jobs = esRDD(sparkContext, metricIndex, queryString).values().map(
map -> {
Object[] values = new Object[featureFields.length+1];
for (int i = 0; i < featureFields.length; i++) {
values[i] = map.get(featureFields[i]);
}
values[featureFields.length] = map.get(labelField);
return RowFactory.create(values);
}
).collect();
StructField[] structFields = new StructField[featureFields.length + 1];
for (int i = 0; i < featureFields.length; i++) {
structFields[i] = new StructField(featureFields[i], DataTypes.StringType, true, Metadata.empty());
}
structFields[featureFields.length] = new StructField(labelField, DataTypes.StringType, true, Metadata.empty());
StructType schema = new StructType(structFields);
Dataset<Row> dataset = sparkSession.createDataFrame(jobs, schema);示例1.4 使用 Spark 读入数据示例中,sparkContext 是 SparkContext 实例,代表了与 Spark 运算环境相关的一些基本信息。MetricIndex 则是 esRDD 方法要读取文档数据的索引名称,而 queryString 则是检索文档的查询条件。esRDD 返回的类型为 JavaPairRDD,这是类似于一个 Pair 的集合。 每一个 Pair 代表索引中的一个文档,Pair 的 key 是字符串类型,代表了当前文档的标识符;而 value 则是一个 Map 类型,代表了整个文档数据。通过 JavaPairRDD 的 keys 方法将只返回所有文档的标识符,而通过 values 方法则会只返回所有文档的 Map 对象。 Map 的键为文档字段名称,而值则为文档字段对应的具体数值。示例中的代码就是通过调用values 方法只获取文档的 Map 对象,然后再通过 Map 和 collect 方法将它们转换成 Row 的集合。 《Elastic Stack 实战手册》——四、应用实践——4.2 可观测性应用场景 ——4.2.1.基于Elasticsearch实现预测系统(3) https://developer.aliyun.com/article/1226131
带你读《Elastic Stack 实战手册》之75:——4.2.1.基于Elasticsearch实现预测系统(1)
4.2.可观测性应用场景4.2.1.基于Elasticsearch实现预测系统创作人:田雪松审稿人:李捷 业务背景介绍 当代商业组织面临的最基本挑战,是互联网已经不再是一个替代或可选渠道,它已经成为许多企业最主要的、甚至是惟一的销售平台。网上店面在现实中往往比实体店面还要重要,所以人们就必须要像监视实体店面一样,监控网上应用。 监控系统通常会以推送(Push)或拉取(Pull)的方式,从服务或应用中获取监控指标(Metrics),并在监控指标出现异常时,发送警报或恢复服务,以实现网上店面实时可用的目标。 监控系统在提升了应用可用性同时,还在日积月累中形成海量监控数据,而从这些监控数据中可以挖掘出巨大的商业价值。监控指标会包含一些特定业务场景下的业务数据,借助大数据分析工具对它们进行处理和建模后,就可以辅助人们作出正确的市场决策。 本章要介绍的案例就是基于 Elasticsearch 对监控数据进行商业挖掘的一次尝试,我们内部称这套系统为 Prophet(大预言家)。Prophet 通过机器学习对历史监控数据进行处理,并创建预测模型,最终可以实现对单次用户请求处理的全面预测,包括处理结果是否成功、处理执行时长等等。 Prophet预测系统架构 Prophet 虽然只是监控数据最终的分析处理服务,但支撑 Prophet 实现智能预测的整个系统 却涵盖了四个主要部分: l 第一部分是产生海量监控数据的监控系统,它从被监控的业务系统中拉取监控数据,并提供实时告警服务。l 第二部分则是将监控数据,从监控系统中导入到 Elasticsearch 集群的数据系统,它还负责对监控数据进行清洗、转换。l 第三部分是用于存储历史监控数据的 Elasticsearch 集群,我们借助 Elasticsearch 冷热模型,延长了监控数据的保存时间。l 而最后一个才是最终处理这些数据的 Prophet 服务,它通过 Spark 运算集群,实现智能预测功能,未来还会添加更多数据分析功能。 四个系统之间的数据流动关系如图 1-1 所示:图1-1 Prophet周边生态除了 Elasticsearch 以外,HDFS 也是存储历史监控数据的一种不错选项,并且 HDFS 更容易与 Hadoop 的大数据生态系统集成。 我们之所以采用 Elasticsearch 主要还是被 Elasticsearch 强大的检索能力所吸引。同时,Elastic Stack 家族中的 Kibana 还提供了强大的数据可视化能力,至于数据分析则可以利用 elasticsearch-hadoop 插件整合 Hadoop 生态。使用 Elasticsearch 存储监控数据在 Prophet 诞生之前,我们的业务系统已经使用 Prometheus 做到了实时监控,同时还通过 Grafana 对监控数据做了可视化处理。 但 Prometheus 监控数据存储,在其内置 TSDB(Time Serie Database)中,PrometheusTSDB 中并没有分片和副本等概念,而只是简单地将数据保存在本地硬盘上。这意味着 Prometheus 无法支持数据高可用,同时也意味着 Prometheus TSDB 中的数据不能保存太久,否则本地硬盘迟早会被积累的数据撑爆。所以 Prometheus 默认只保存监控数据 15 天,超过这个时间后监控数据就会被直接删除。 对于一个监控系统来说这并不算什么大的问题,因为监控系统通常对实时数据更感兴趣,它只要能够实时快速地反映,被监控系统的异常就足够了。而历史数据分析和处理,并不能算是监控系统的职责范畴,应该交由 Elasticsearch 这样更专业的数据检索与分析工具来实现。 从另一个角度来说,由于预测系统,必须要基于历史数据创建预测模型,而如果直接在 Prometheus TSDB 上进行高频度的模型运算,则有可能会对监控系统本身造成性能上的影响。从系统监控与数据分析的职责角度来看,监控系统的稳定性无疑比数据分析更为重要。所以预测系统使用的历史数据,应该与 Prometheus 隔离开来,这就要求监控数据得从 Prometheus 中同步到 Elasticsearch 。一旦数据从 Prometheus 进入到 Elasticsearch ,我们就可以利用Elasticsearch 冷热架构对数据进行优化以保存更长时间。 《Elastic Stack 实战手册》——四、应用实践——4.2 可观测性应用场景 ——4.2.1.基于Elasticsearch实现预测系统(2) https://developer.aliyun.com/article/1226133
带你读《Elastic Stack 实战手册》之41:——3.4.3.Kibana基础应用(13)
《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.3.Kibana基础应用(12) https://developer.aliyun.com/article/1228972条件运算符查询 查询 http_code 的值是大于等于 400 的数据http_code >= 400逻辑运算符查询 查询 http_code 的值为大于 200 并且 method 的值是 POST 的数据http_code > 200 and method : POST查询 http_code 的值为大于 200 或者 method 的值是 GET 的数据http_code > 200 or method : GET通配符 查询某个字段的值存在的数据,存在则返回数据,不存在则返回为空 size: *name: *创作人简介:郭海亮,落魄的运维搬砖人,工作近四年,爱折腾,对 k8s、Jenkins、Prometheus等云原生技术有浓厚的兴趣,日拱一卒。 博客:https://github.com/ghl1024
带你读《Elastic Stack 实战手册》之15:——3.4.1.8. ECK 安装(20)
《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.1.Elastic Stack 安装部署——3.4.1.8. ECK 安装(19) https://developer.aliyun.com/article/1231261部署 Elasticsearch 集群 默认情况下,Istio 会为具有 Istio Sidecar 代理的工作负载之间的所有流量启用双向 TLS,需要对 Elasticsearch 资源文件进行以下修改才能确保 Elasticsearch 集群正常工作: l 1.禁用 elastic operator 使用自签名证书加密 Elasticsearch 集群的 HTTPS 流量,之后会在 Istio Gateway 加密 HTTPS 流量。 l 2.将 Elasticsearch 集群节点之前的传输端口 9300 排除在代理之外,目前 ECK 不支持关闭 Elasticsearch 传输端口的 X-Pack Security 和 TLS。如果允许 Istio 代理传输端口,则流量会被加密两次,会导致 Elasticsearch 节点之间的通信会中断。l 3.可选,仅当 Kubernetes 集群不支持发布第三方安全令牌时才需要设置 automountServiceAccountToken 为 true。apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: istio-elasticsearch
namespace: istio-demo
spec:
#禁用 elaticsearch 本身的 https,通过 istio 管理 tls
http:
tls:
selfSignedCertificate:
disabled: true
version: 7.14.0
nodeSets:
#master节点
- name: master
count: 3
config:
node.roles: ["master"]
podTemplate:
metadata:
annotations:
#将传输端口 9300 排除在代理之外
traffic.sidecar.istio.io/includeInboundPorts: "*"
traffic.sidecar.istio.io/excludeOutboundPorts: "9300"
traffic.sidecar.istio.io/excludeInboundPorts: "9300"
spec:
#仅当 Kubernetes 集群不支持发布第三方安全令牌时才需要设置
#automountServiceAccountToken: true
containers:
- name: elasticsearch
resources:
#限制资源使用
limits:
memory: 1Gi
cpu: 1
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: alicloud-disk-efficiency
#data 节点
- name: data
count: 3
config:
node.roles: ["data"]
podTemplate:
metadata:
annotations:
traffic.sidecar.istio.io/includeInboundPorts: "*"
traffic.sidecar.istio.io/excludeOutboundPorts: "9300"
traffic.sidecar.istio.io/excludeInboundPorts: "9300"
spec:
containers:
- name: elasticsearch
resources:
limits:
memory: 2Gi
cpu: 2
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: alicloud-disk-efficiency
#ingest 节点
- name: ingest
count: 3
config:
node.roles: ["ingest"]
podTemplate:
metadata:
annotations:
traffic.sidecar.istio.io/includeInboundPorts: "*"
traffic.sidecar.istio.io/excludeOutboundPorts: "9300"
traffic.sidecar.istio.io/excludeInboundPorts: "9300"
spec:
containers:
- name: elasticsearch
resources:
limits:
memory: 2Gi
cpu: 1
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: alicloud-disk-efficiency
#coordinating 节点
- name: coordinating
count: 3
config:
node.roles: []
podTemplate:
metadata:
annotations:
traffic.sidecar.istio.io/includeInboundPorts: "*"
traffic.sidecar.istio.io/excludeOutboundPorts: "9300"
traffic.sidecar.istio.io/excludeInboundPorts: "9300"
spec:
containers:
- name: elasticsearch
resources:
limits:
memory: 2Gi
cpu: 1
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: alicloud-disk-efficiency使用以下命令应用资源文件部署 Elasticsearh 集群。kubectl create ns istio-demo
kubectl label namespace istio-demo istio-injection=enabled
kubectl apply -f elasticsearch.yaml
获取 Elasticsearch 集群密码:PASSWORD=$(kubectl get secret -n istio-demo \
istio-elasticsearch-es-elastic-user \
-o go-template='{{.data.elastic | base64decode}}')
echo $PASSWORD
#elastic 用户密码
L733hU98Y467IZMft4DzLq5mIstio 可视化组件部署 Istio 和几个遥测应用做了集成,遥测能帮你了解服务网格的结构、展示网络的拓扑结构、分析网格的健康状态。使用下面命令部署 Kiali 仪表板,以及 Prometheus、Grafana、Jaeger。kubectl apply -f istio/istio-1.11.1/samples/addons通过 kubectl port-forward 的方式将 Kiali Service 服务转发到本地 20001 端口,便于我们本地访问测试。kubectl port-forward -n istio-system service/kiali 20001浏览器输入 http://localhost:20001 访问 Kiali 页面。《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.1.Elastic Stack 安装部署——3.4.1.8. ECK 安装(21) https://developer.aliyun.com/article/1231259
带你读《Elastic Stack 实战手册》之15:——3.4.1.8. ECK 安装(1)
3.4.1.8. ECK 安装创作人:程治玮审稿人:杨丛聿 ECK 简介 Kubernetes 是目前最受欢迎的容器编排技术,越来越多的应用开始往 Kubernetes 中迁移。Kubernetes 现有的 ReplicaSet、Deployment、Service 等资源对象已经可以满足无状态应用对于自动扩缩容、负载均衡等基本需求。但是对于有状态的、分布式的应用,通常拥有各自的一套模型定义规范,例如 Prometheus,Etcd,Zookeeper,Elasticsearch 等等。部署这些分布式应用往往需要熟悉特定领域的知识,并且在扩缩容和升级时需要考虑如何保证应用服务的可用性等问题。为了简化有状态、分布式应用的部署,Kubernetes Operator 应运而生。 Kubernetes Operator 是一种特定的应用控制器,通过 CRD(Custom Resource Definitions,自定义资源定义)扩展 Kubernetes API 的功能,可以用它来创建、配置和管理特定的有状态应用,而不需要直接去使用 Kubernetes 中最原始的一些资源对象,比如 Pod,Deployment,Service 等等。 Elastic Cloud on Kubernetes(ECK)是其中的一种 Kubernetes Operator,方便我们管理Elastic Stack 家族中的各种组件,例如 Elasticsearch,Kibana,APM,Beats 等等。比如只需要定义一个 Elasticsearch 类型的 CRD 对象,ECK 就可以帮助我们快速搭建出一套Elasticsearch 集群。通过 ECK 我们还可以轻松实现: l 管理和监控多个集群。l 集群版本升级。l 自动扩缩容。l 冷热架构。l 备份和快照。l 自定义配置和插件。l 默认提供安全保护。 版本支持 ECK 支持在以下平台和版本中运行: l Kubernetes 1.17-1.21l OpenShift 3.11, 4.3-4.7l Google Kubernetes Engine (GKE), Azure Kubernetes Service (AKS), and Amazonl Elastic Kubernetes Service (EKS) 以下版本的 Elack Stack 组件支持通过 ECK 部署: l Elasticsearch, Kibana, APM Server: 6.8+, 7.1+l Enterprise Search: 7.7+l Beats: 7.0+l Elastic Agent: 7.10+ (standalone), 7.14+ (Fleet)l Elastic Maps Server: 7.11+ Kubernetes 环境准备 ECK 需要部署在 Kubernetes 集群中,因此我们首先为下面的实验准备一套 Kubernetes 集群,这里选择通过阿里云 ACK 服务部署 Kubernetes 集群。阿里云容器服务 Kubernetes 版(Alibaba Cloud Container Service for Kubernetes,ACK)提供高性能的容器应用管理服务,支持企业级 Kubernetes 容器化应用的生命周期管理,可以在几分钟内快速部署出一套高可用的 Kubernetes 集群。 《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.1.Elastic Stack 安装部署——3.4.1.8. ECK 安装(2) https://developer.aliyun.com/article/1231279
运维面试题库之Prometheus
Prometheus
Q:什么是Prometheus?
A:Prometheus是一个开源的系统监控和警报工具集,用于收集、存储和查询时间序列数据。
Q:Prometheus的主要组件有哪些?
A:Prometheus由以下主要组件组成:
Prometheus Server:负责收集和存储时间序列数据。Exporters:用于收集特定应用或系统的指标数据,并将其暴露给Prometheus进行抓取。Alertmanager:用于定义和发送警报通知。
Q:Prometheus的数据模型是什么?
A:Prometheus使用时间序列数据模型,其中每个时间序列由唯一的标识符(metric name和一组标签)和对应的时间戳-值对组成。
Q:如何在Prometheus中定义监控指标?
A:可以使用Prometheus的自有查询语言PromQL来定义监控指标。通过指标名称和标签来唯一标识监控指标,并使用各种函数和操作符来进行数据查询和聚合。
Q:如何配置Prometheus进行目标抓取?
A:可以通过Prometheus的配置文件prometheus.yml来定义抓取配置。在配置文件中指定要抓取的目标(如Exporter的地址和端口),并设置抓取频率等参数。
Q:Prometheus如何处理数据存储和保留策略?
A:Prometheus使用本地磁盘存储时间序列数据。数据存储采用分块压缩格式,同时可以配置数据保留策略,以控制数据的存储时间和保留期限。
Q:如何设置警报规则并配置Alertmanager?
A:可以使用Prometheus的配置文件prometheus.yml来定义警报规则,并配置Alertmanager的通知方式和接收者。
Q:Prometheus支持哪些查询操作和聚合函数?
A:Prometheus支持丰富的查询操作和聚合函数,如过滤、计算率、求和、平均值、最大值、最小值等,以便对监控指标进行灵活的数据查询和分析。
Q:什么是Prometheus的服务发现机制?
A:Prometheus提供多种服务发现机制,如静态配置、文件发现、Consul、Kubernetes等,用于自动发现和抓取要监控的目标。
Q:Prometheus的可视化和查询界面是什么?
A:Prometheus提供一个内置的可视化和查询界面,称为Prometheus Web UI,可以在浏览器中访问,并通过PromQL进行数据查询和展示。
Q:什么是Prometheus的推模式(Push)和拉模式(Pull)抓取?
A:Prometheus的推模式抓取是指被监控的目标主动向Prometheus发送指标数据,而拉模式抓取是Prometheus主动从目标中拉取指标数据。
Q:如何在Prometheus中配置持久化存储?
A:可以使用Prometheus的--storage.tsdb.path参数来配置持久化存储路径,以便将时间序列数据持久化保存在磁盘上。
Q:Prometheus是否支持高可用性(HA)部署?如果是,如何实现?
A:是的,Prometheus支持高可用性部署。可以通过使用多个Prometheus实例并结合使用服务发现和联邦(Federation)来实现高可用性。
Q:什么是Prometheus的Alertmanager?它的作用是什么?
A:Prometheus的Alertmanager是用于处理和发送警报通知的组件。它能够根据预定义的警报规则接收来自Prometheus的警报,并根据配置的通知方式发送警报通知。
Q:什么是Prometheus的持续查询(Continuous Queries)?
A:Prometheus的持续查询是预定义的查询语句,定期计算和聚合时间序列数据,并将结果存储在新的时间序列中,以供后续查询和展示使用。
【夜莺监控】管理Kubernetes组件指标(下)
指标简介指标清单指标类型说明workqueue_adds_totalCounterWorkqueue 处理的 Adds 事件的数量。workqueue_depthGaugeWorkqueue 当前队列深度。workqueue_queue_duration_seconds_bucketHistogram任务在 Workqueue 中存在的时长。memory_utilization_byteGauge内存使用量,单位:字节(Byte)。memory_utilization_ratioGauge内存使用率=内存使用量/内存资源上限,百分比形式。cpu_utilization_coreGaugeCPU 使用量,单位:核(Core)。cpu_utilization_ratioGaugeCPU 使用率=CPU 使用量/内存资源上限,百分比形式。rest_client_requests_totalCounter从状态值(Status Code)、方法(Method)和主机(Host)维度分析 HTTP 请求数。rest_client_request_duration_seconds_bucketHistogram从方法(Verb)和 URL 维度分析 HTTP 请求时延。Queue 指标名称PromQL说明Workqueue 入队速率sum(rate(workqueue_adds_total{job="ack-kube-controller-manager"}[$interval])) by (name)无Workqueue 深度sum(rate(workqueue_depth{job="ack-kube-controller-manager"}[$interval])) by (name)无Workqueue 处理时延histogram_quantile($quantile, sum(rate(workqueue_queue_duration_seconds_bucket{job="ack-kube-controller-manager"}[5m])) by (name, le))无资源指标名称PromQL说明内存使用量memory_utilization_byte{container="kube-controller-manager"}内存使用量,单位:字节。CPU 使用量cpu_utilization_core{container="kube-controller-manager"}*1000CPU 使用量,单位:毫核。内存使用率memory_utilization_ratio{container="kube-controller-manager"}内存使用率,百分比。CPU 使用率cpu_utilization_ratio{container="kube-controller-manager"}CPU 使用率,百分比。QPS 和时延名称PromQL说明Kube API 请求 QPSsum(rate(rest_client_requests_total{job="ack-scheduler",code=~"2.."}[$interval])) by (method,code)sum(rate(rest_client_requests_total{job="ack-scheduler",code=~"3.."}[$interval])) by (method,code)sum(rate(rest_client_requests_total{job="ack-scheduler",code=~"4.."}[$interval])) by (method,code)sum(rate(rest_client_requests_totaljob="ack-scheduler",code=~"5.."}[$interval])) by (method,code)对 kube-apiserver 发起的 HTTP 请求,从方法(Method)和返回值(Code) 维度分析。 | | Kube API 请求时延 | histogram_quantile($quantile, sum(rate(rest_client_request_duration_seconds_bucket{job="ack-kube-controller-manager"[$interval])) by (verb,url,le)) | 对 kube-apiserver 发起的 HTTP 请求时延,从方法(Verb)和请求 URL 维度分析。 |KubeSchedulerScheduler 监听在10259端口,依然通过 Prometheus Agent 的方式采集指标。指标采集(1)编辑 Prometheus 配置文件apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'controller-manager'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-controller-manager;https-metrics
- job_name: 'scheduler'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-scheduler;https
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'然后配置 Scheduler 的 Service。apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: kube-scheduler
name: kube-scheduler
namespace: kube-system
spec:
clusterIP: None
ports:
- name: https
port: 10259
protocol: TCP
targetPort: 10259
selector:
component: kube-scheduler
sessionAffinity: None
type: ClusterIP将 YAML 的资源更新到 Kubernetes 中,然后使用curl -X POST "http://<PROMETHEUS_IP>:9090/-/reload"重载 Prometheus。但是现在我们还无法获取到 Scheduler 的指标数据,需要把 Scheduler 的bind-address改成0.0.0.0。修改完成过后就可以正常在夜莺UI中查看指标了。导入监控大盘(https://github.com/flashcatcloud/categraf/blob/main/k8s/scheduler-dash.json)。指标简介指标清单指标清单类型说明scheduler_scheduler_cache_sizeGauge调度器缓存中 Node、Pod 和 AssumedPod 的数量。scheduler_pending_podsGaugePending Pod 的数量。队列种类如下:unschedulable:表示不可调度的 Pod 数量。backoff:表示 backoffQ 的 Pod 数量。active:表示 activeQ 的 Pod 数量。 | | scheduler_pod_scheduling_attempts_bucket | Histogram | 调度器尝试成功调度 Pod 的次数,Bucket 阈值为 1、2、4、8、16。 | | memory_utilization_byte | Gauge | 内存使用量,单位:字节(Byte)。 | | memory_utilization_ratio | Gauge | 内存使用率=内存使用量/内存资源上限,百分比形式。 | | cpu_utilization_core | Gauge | CPU 使用量,单位:核(Core)。 | | cpu_utilization_ratio | Gauge | CPU 使用率=CPU 使用量/内存资源上限,百分比形式。 | | rest_client_requests_total | Counter | 从状态值(Status Code)、方法(Method)和主机(Host)维度分析 HTTP 请求数。 | | rest_client_request_duration_seconds_bucket | Histogram | 从方法(Verb)和 URL 维度分析 HTTP 请求时延。 |基本指标指标清单PromQL说明Scheduler 集群统计数据scheduler_scheduler_cache_size{job="ack-scheduler",type="nodes"}scheduler_scheduler_cache_size{job="ack-scheduler",type="pods"}scheduler_scheduler_cache_sizejob="ack-scheduler",type="assumed_pods"}调度器缓存中 Node、Pod 和 AssumedPod 的数量。 | | Scheduler Pending Pods | scheduler_pending_pods{job="ack-scheduler"| Pending Pod 的数量。队列种类如下:unschedulable:表示不可调度的 Pod 数量。backoff:表示 backoffQ 的 Pod 数量。active:表示 activeQ 的 Pod 数量。 | | Scheduler 尝试成功调度 Pod 次数 | histogram_quantile(interval])) by (pod, le)) | 调度器尝试调度 Pod 的次数,Bucket 阈值为 1、2、4、8、16。 |资源指标指标清单PromQL说明内存使用量memory_utilization_byte{container="kube-scheduler"}内存使用量,单位:字节。CPU 使用量cpu_utilization_core{container="kube-scheduler"}*1000CPU 使用量,单位:毫核。内存使用率memory_utilization_ratio{container="kube-scheduler"}内存使用率,百分比。CPU 使用率cpu_utilization_ratio{container="kube-scheduler"}CPU 使用率,百分比。QPS 和时延指标清单PromQL说明Kube API 请求 QPSsum(rate(rest_client_requests_total{job="ack-scheduler",code=~"2.."}[$interval])) by (method,code)sum(rate(rest_client_requests_total{job="ack-scheduler",code=~"3.."}[$interval])) by (method,code)sum(rate(rest_client_requests_total{job="ack-scheduler",code=~"4.."}[$interval])) by (method,code)sum(rate(rest_client_requests_totaljob="ack-scheduler",code=~"5.."}[$interval])) by (method,code)调度器对 kube-apiserver 发起的 HTTP 请求,从方法(Method)和返回值(Code) 维度分析。 | | Kube API 请求时延 | histogram_quantile($quantile, sum(rate(rest_client_request_duration_seconds_bucket{job="ack-scheduler"[$interval])) by (verb,url,le)) | 调度器对 kube-apiserver 发起的 HTTP 请求时延,从方法(Verb)和请求 URL 维度分析。 |EtcdEtcd 是 Kubernetes 的存储中心,所有资源信息都是存在在其中,它通过2381端口对外提供监控指标。指标采集由于我这里的 Etcd 是通过静态 Pod 的方式部署到 Kubernetes 集群中的,所以依然使用 Prometheus Agent 来采集指标。(1)配置 Prometheus 的采集配置apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'controller-manager'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-controller-manager;https-metrics
- job_name: 'scheduler'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-scheduler;https
- job_name: 'etcd'
kubernetes_sd_configs:
- role: endpoints
scheme: http
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;etcd;http
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'然后增加 Etcd 的 Service 配置。apiVersion: v1
kind: Service
metadata:
namespace: kube-system
name: etcd
labels:
k8s-app: etcd
spec:
selector:
component: etcd
type: ClusterIP
clusterIP: None
ports:
- name: http
port: 2381
targetPort: 2381
protocol: TCP部署 YAML 文件,并重启 Prometheus。如果获取不到指标,需要修改 Etcd 的listen-metrics-urls配置为0.0.0.0。image.png导入监控大盘(https://github.com/flashcatcloud/categraf/blob/main/k8s/etcd-dash.json)。指标简介指标清单指标类型说明cpu_utilization_coreGaugeCPU 使用量,单位:核(Core)。cpu_utilization_ratioGaugeCPU 使用率=CPU 使用量/内存资源上限,百分比形式。etcd_server_has_leaderGaugeetcd member 是否有 Leader。1:表示有主节点。0:表示没有主节点。 | | etcd_server_is_leader | Gauge | etcd member 是否是 Leader。1:表示是。0:表示不是。 | | etcd_server_leader_changes_seen_total | Counter | etcd member 过去一段时间切主次数。 | | etcd_mvcc_db_total_size_in_bytes | Gauge | etcd member db 总大小。 | | etcd_mvcc_db_total_size_in_use_in_bytes | Gauge | etcd member db 实际使用大小。 | | etcd_disk_backend_commit_duration_seconds_bucket | Histogram | etcd backend commit 延时。 Bucket 列表为:**[0.001 0.002 0.004 0.008 0.016 0.032 0.064 0.128 0.256 0.512 1.024 2.048 4.096 8.192]**。 | | etcd_debugging_mvcc_keys_total | Gauge | etcd keys 总数。 | | etcd_server_proposals_committed_total | Gauge | raft proposals commit 提交总数。 | | etcd_server_proposals_applied_total | Gauge | raft proposals apply 总数。 | | etcd_server_proposals_pending | Gauge | raft proposals 排队数量。 | | etcd_server_proposals_failed_total | Counter | raft proposals 失败数量。 | | memory_utilization_byte | Gauge | 内存使用量,单位:字节(Byte)。 | | memory_utilization_ratio | Gauge | 内存使用率=内存使用量/内存资源上限,百分比形式。 |基础指标名称PromQL说明etcd 存活状态etcd_server_has_leaderetcd_server_is_leader == 1 |etcd member 是否存活,正常值为 3。etcd member 是否是主节点,正常情况下,必须有一个 Member 为主节点。 | | 过去一天切主次数 | changes(etcd_server_leader_changes_seen_totaljob="etcd"}[1d])过去一天内 etcd 集群切主次数。 | | 内存使用量 | memory_utilization_byte{container="etcd"| 内存使用量,单位:字节。 | | CPU 使用量 | cpu_utilization_corecontainer="etcd"}*1000CPU 使用量,单位:毫核。 | | 内存使用率 | memory_utilization_ratio{container="etcd"| 内存使用率,百分比。 | | CPU 使用率 | cpu_utilization_ratio{container="etcd"} | CPU 使用率,百分比。 | | 磁盘大小 |etcd_mvcc_db_total_size_in_bytesetcd_mvcc_db_total_size_in_use_in_bytes |etcd backend db 总大小。etcd backend db 实际使用大小。 | | kv 总数 | etcd_debugging_mvcc_keys_total | etcd 集群 kv 对总数。 | | backend commit 延迟 | histogram_quantile(0.99, sum(rate(etcd_disk_backend_commit_duration_seconds_bucket{job="etcd"}[5m])) by (instance, le)) | db commit 时延。 | | raft proposal 情况 |rate(etcd_server_proposals_failed_total{job="etcd"}[1m])etcd_server_proposals_pending{job="etcd"}etcd_server_proposals_committed_total{job="etcd"} - etcd_server_proposals_applied_total{job="etcd"} |raft proposal failed 速率(分钟)。raft proposal pending 总数。commit-apply 差值。 |kubeletkubelet 工作节点的主要组件,它监听两个端口:10248和10250。10248是监控检测端口,10250是系统默认端口,通过它的/metrics接口暴露指标。指标采集这里依然通过 Prometheus Agent 的方式采集 kubelet 的指标。(1)修改 Prometheus 的配置文件apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'controller-manager'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-controller-manager;https-metrics
- job_name: 'scheduler'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-scheduler;https
- job_name: 'etcd'
kubernetes_sd_configs:
- role: endpoints
scheme: http
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;etcd;http
- job_name: 'kubelet'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-kubelet;https
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'然后配置 kubelet 的 Service 和 Endpoints,如下:apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: kubelet
name: kube-kubelet
namespace: kube-system
spec:
clusterIP: None
ports:
- name: https
port: 10250
protocol: TCP
targetPort: 10250
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
labels:
k8s-app: kubelet
name: kube-kubelet
namespace: kube-system
subsets:
- addresses:
- ip: 192.168.205.128
- ip: 192.168.205.130
ports:
- name: https
port: 10250
protocol: TCP这里是自定义的 Endpoints,添加了需要监控的节点。然后部署 YAML 文件并重启 Prometheus Agent,即可在夜莺 UI 中查询到具体的指标。导入监控大盘(https://github.com/flashcatcloud/categraf/blob/main/inputs/kubelet/dashboard-by-ident.json)。指标简介指标清单# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
gc的时间统计(summary指标)
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
goroutine 数量
# HELP go_threads Number of OS threads created.
# TYPE go_threads gauge
os的线程数量
# HELP kubelet_cgroup_manager_duration_seconds [ALPHA] Duration in seconds for cgroup manager operations. Broken down by method.
# TYPE kubelet_cgroup_manager_duration_seconds histogram
操作cgroup的时长分布,按照操作类型统计
# HELP kubelet_containers_per_pod_count [ALPHA] The number of containers per pod.
# TYPE kubelet_containers_per_pod_count histogram
pod中container数量的统计(spec.containers的数量)
# HELP kubelet_docker_operations_duration_seconds [ALPHA] Latency in seconds of Docker operations. Broken down by operation type.
# TYPE kubelet_docker_operations_duration_seconds histogram
操作docker的时长分布,按照操作类型统计
# HELP kubelet_docker_operations_errors_total [ALPHA] Cumulative number of Docker operation errors by operation type.
# TYPE kubelet_docker_operations_errors_total counter
操作docker的错误累计次数,按照操作类型统计
# HELP kubelet_docker_operations_timeout_total [ALPHA] Cumulative number of Docker operation timeout by operation type.
# TYPE kubelet_docker_operations_timeout_total counter
操作docker的超时统计,按照操作类型统计
# HELP kubelet_docker_operations_total [ALPHA] Cumulative number of Docker operations by operation type.
# TYPE kubelet_docker_operations_total counter
操作docker的累计次数,按照操作类型统计
# HELP kubelet_eviction_stats_age_seconds [ALPHA] Time between when stats are collected, and when pod is evicted based on those stats by eviction signal
# TYPE kubelet_eviction_stats_age_seconds histogram
驱逐操作的时间分布,按照驱逐信号(原因)分类统计
# HELP kubelet_evictions [ALPHA] Cumulative number of pod evictions by eviction signal
# TYPE kubelet_evictions counter
驱逐次数统计,按照驱逐信号(原因)统计
# HELP kubelet_http_inflight_requests [ALPHA] Number of the inflight http requests
# TYPE kubelet_http_inflight_requests gauge
请求kubelet的inflight请求数,按照method path server_type统计
注意与每秒的request数区别开
# HELP kubelet_http_requests_duration_seconds [ALPHA] Duration in seconds to serve http requests
# TYPE kubelet_http_requests_duration_seconds histogram
请求kubelet的请求时间统计,按照method path server_type统计
# HELP kubelet_http_requests_total [ALPHA] Number of the http requests received since the server started
# TYPE kubelet_http_requests_total counter
请求kubelet的请求数统计,按照method path server_type统计
# HELP kubelet_managed_ephemeral_containers [ALPHA] Current number of ephemeral containers in pods managed by this kubelet. Ephemeral containers will be ignored if disabled by the EphemeralContainers feature gate, and this number will be 0.
# TYPE kubelet_managed_ephemeral_containers gauge
当前kubelet管理的临时容器数量
# HELP kubelet_network_plugin_operations_duration_seconds [ALPHA] Latency in seconds of network plugin operations. Broken down by operation type.
# TYPE kubelet_network_plugin_operations_duration_seconds histogram
网络插件的操作耗时分布 ,按照操作类型(operation_type)统计
如果 --feature-gates=EphemeralContainers=false,否则一直为0
# HELP kubelet_network_plugin_operations_errors_total [ALPHA] Cumulative number of network plugin operation errors by operation type.
# TYPE kubelet_network_plugin_operations_errors_total counter
网络插件累计操作错误数统计,按照操作类型(operation_type)统计
# HELP kubelet_network_plugin_operations_total [ALPHA] Cumulative number of network plugin operations by operation type.
# TYPE kubelet_network_plugin_operations_total counter
网络插件累计操作数统计,按照操作类型(operation_type)统计
# HELP kubelet_node_name [ALPHA] The node's name. The count is always 1.
# TYPE kubelet_node_name gauge
node name
# HELP kubelet_pleg_discard_events [ALPHA] The number of discard events in PLEG.
# TYPE kubelet_pleg_discard_events counter
PLEG(pod lifecycle event generator) 丢弃的event数统计
# HELP kubelet_pleg_last_seen_seconds [ALPHA] Timestamp in seconds when PLEG was last seen active.
# TYPE kubelet_pleg_last_seen_seconds gauge
PLEG上次活跃的时间戳
# HELP kubelet_pleg_relist_duration_seconds [ALPHA] Duration in seconds for relisting pods in PLEG.
# TYPE kubelet_pleg_relist_duration_seconds histogram
PLEG relist pod时间分布
# HELP kubelet_pleg_relist_interval_seconds [ALPHA] Interval in seconds between relisting in PLEG.
# TYPE kubelet_pleg_relist_interval_seconds histogram
PLEG relist 间隔时间分布
# HELP kubelet_pod_start_duration_seconds [ALPHA] Duration in seconds for a single pod to go from pending to running.
# TYPE kubelet_pod_start_duration_seconds histogram
pod启动时间(从pending到running)分布
kubelet watch到pod时到pod中contianer都running后
(watch各种source channel的pod变更)
# HELP kubelet_pod_worker_duration_seconds [ALPHA] Duration in seconds to sync a single pod. Broken down by operation type: create, update, or sync
# TYPE kubelet_pod_worker_duration_seconds histogram
pod状态变化的时间分布, 按照操作类型(create update sync)统计
worker就是kubelet中处理一个pod的逻辑工作单位
# HELP kubelet_pod_worker_start_duration_seconds [ALPHA] Duration in seconds from seeing a pod to starting a worker.
# TYPE kubelet_pod_worker_start_duration_seconds histogram
kubelet watch到pod到worker启动的时间分布
# HELP kubelet_run_podsandbox_duration_seconds [ALPHA] Duration in seconds of the run_podsandbox operations. Broken down by RuntimeClass.Handler.
# TYPE kubelet_run_podsandbox_duration_seconds histogram
启动sandbox的时间分布
# HELP kubelet_run_podsandbox_errors_total [ALPHA] Cumulative number of the run_podsandbox operation errors by RuntimeClass.Handler.
# TYPE kubelet_run_podsandbox_errors_total counter
启动sanbox出现error的总数
# HELP kubelet_running_containers [ALPHA] Number of containers currently running
# TYPE kubelet_running_containers gauge
当前containers运行状态的统计
按照container状态统计,created running exited
# HELP kubelet_running_pods [ALPHA] Number of pods that have a running pod sandbox
# TYPE kubelet_running_pods gauge
当前处于running状态pod数量
# HELP kubelet_runtime_operations_duration_seconds [ALPHA] Duration in seconds of runtime operations. Broken down by operation type.
# TYPE kubelet_runtime_operations_duration_seconds histogram
容器运行时的操作耗时
(container在create list exec remove stop等的耗时)
# HELP kubelet_runtime_operations_errors_total [ALPHA] Cumulative number of runtime operation errors by operation type.
# TYPE kubelet_runtime_operations_errors_total counter
容器运行时的操作错误数统计(按操作类型统计)
# HELP kubelet_runtime_operations_total [ALPHA] Cumulative number of runtime operations by operation type.
# TYPE kubelet_runtime_operations_total counter
容器运行时的操作总数统计(按操作类型统计)
# HELP kubelet_started_containers_errors_total [ALPHA] Cumulative number of errors when starting containers
# TYPE kubelet_started_containers_errors_total counter
kubelet启动容器错误总数统计(按code和container_type统计)
code包括ErrImagePull ErrImageInspect ErrImagePull ErrRegistryUnavailable ErrInvalidImageName等
container_type一般为"container" "podsandbox"
# HELP kubelet_started_containers_total [ALPHA] Cumulative number of containers started
# TYPE kubelet_started_containers_total counter
kubelet启动容器总数
# HELP kubelet_started_pods_errors_total [ALPHA] Cumulative number of errors when starting pods
# TYPE kubelet_started_pods_errors_total counter
kubelet启动pod遇到的错误总数(只有创建sandbox遇到错误才会统计)
# HELP kubelet_started_pods_total [ALPHA] Cumulative number of pods started
# TYPE kubelet_started_pods_total counter
kubelet启动的pod总数
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
统计cpu使用率
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
允许进程打开的最大fd数
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
当前打开的fd数量
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
进程驻留内存大小
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
进程启动时间
# HELP rest_client_request_duration_seconds [ALPHA] Request latency in seconds. Broken down by verb and URL.
# TYPE rest_client_request_duration_seconds histogram
请求apiserver的耗时统计(按照url和请求类型统计verb)
# HELP rest_client_requests_total [ALPHA] Number of HTTP requests, partitioned by status code, method, and host.
# TYPE rest_client_requests_total counter
请求apiserver的总次数(按照返回码code和请求类型method统计)
# HELP storage_operation_duration_seconds [ALPHA] Storage operation duration
# TYPE storage_operation_duration_seconds histogram
存储操作耗时(按照存储plugin(configmap emptydir hostpath 等 )和operation_name分类统计)
# HELP volume_manager_total_volumes [ALPHA] Number of volumes in Volume Manager
# TYPE volume_manager_total_volumes gauge
本机挂载的volume数量统计(按照plugin_name和state统计
plugin_name包括"host-path" "empty-dir" "configmap" "projected")
state(desired_state_of_world期状态/actual_state_of_world实际状态)KubeProxyKubeProxy 主要负责节点的网络管理,它在每个节点都会存在,是通过10249端口暴露监控指标。指标采集(1)配置 Prometheus 配置apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'controller-manager'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-controller-manager;https-metrics
- job_name: 'scheduler'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-scheduler;https
- job_name: 'etcd'
kubernetes_sd_configs:
- role: endpoints
scheme: http
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;etcd;http
- job_name: 'kubelet'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-kubelet;https
- job_name: 'kube-proxy'
kubernetes_sd_configs:
- role: endpoints
scheme: http
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-proxy;http
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'然后配置 KubeProxy 的 Service。apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: proxy
name: kube-proxy
namespace: kube-system
spec:
clusterIP: None
selector:
k8s-app: kube-proxy
ports:
- name: http
port: 10249
protocol: TCP
targetPort: 10249
sessionAffinity: None
type: ClusterIP将 YAML 文件部署到集群中并重启 Prometheus Agent。然后就可以看到其监控指标了(如果没有采集到指标,查看 kube-proxy 的10249端口是否绑定到127.0.0.1了,如果是就修改成0.0.0.0,通过kubectl edit cm -n kube-system kube-proxy修改metricsBindAddress即可。)。image.png导入监控大盘(https://github.com/flashcatcloud/categraf/blob/main/inputs/kube_proxy/dashboard-by-ident.json)。指标简介指标清单# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
gc时间
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
goroutine数量
# HELP go_threads Number of OS threads created.
# TYPE go_threads gauge
线程数量
# HELP kubeproxy_network_programming_duration_seconds [ALPHA] In Cluster Network Programming Latency in seconds
# TYPE kubeproxy_network_programming_duration_seconds histogram
service或者pod发生变化到kube-proxy规则同步完成时间指标含义较复杂,参照https://github.com/kubernetes/community/blob/master/sig-scalability/slos/network_programming_latency.md
# HELP kubeproxy_sync_proxy_rules_duration_seconds [ALPHA] SyncProxyRules latency in seconds
# TYPE kubeproxy_sync_proxy_rules_duration_seconds histogram
规则同步耗时
# HELP kubeproxy_sync_proxy_rules_endpoint_changes_pending [ALPHA] Pending proxy rules Endpoint changes
# TYPE kubeproxy_sync_proxy_rules_endpoint_changes_pending gauge
endpoint 发生变化后规则同步pending的次数
# HELP kubeproxy_sync_proxy_rules_endpoint_changes_total [ALPHA] Cumulative proxy rules Endpoint changes
# TYPE kubeproxy_sync_proxy_rules_endpoint_changes_total counter
endpoint 发生变化后规则同步的总次数
# HELP kubeproxy_sync_proxy_rules_iptables_restore_failures_total [ALPHA] Cumulative proxy iptables restore failures
# TYPE kubeproxy_sync_proxy_rules_iptables_restore_failures_total counter
本机上 iptables restore 失败的总次数
# HELP kubeproxy_sync_proxy_rules_last_queued_timestamp_seconds [ALPHA] The last time a sync of proxy rules was queued
# TYPE kubeproxy_sync_proxy_rules_last_queued_timestamp_seconds gauge
最近一次规则同步的请求时间戳,如果比下一个指标 kubeproxy_sync_proxy_rules_last_timestamp_seconds 大很多,那说明同步 hung 住了
# HELP kubeproxy_sync_proxy_rules_last_timestamp_seconds [ALPHA] The last time proxy rules were successfully synced
# TYPE kubeproxy_sync_proxy_rules_last_timestamp_seconds gauge
最近一次规则同步的完成时间戳
# HELP kubeproxy_sync_proxy_rules_service_changes_pending [ALPHA] Pending proxy rules Service changes
# TYPE kubeproxy_sync_proxy_rules_service_changes_pending gauge
service变化引起的规则同步pending数量
# HELP kubeproxy_sync_proxy_rules_service_changes_total [ALPHA] Cumulative proxy rules Service changes
# TYPE kubeproxy_sync_proxy_rules_service_changes_total counter
service变化引起的规则同步总数
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
利用这个指标统计cpu使用率
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
进程可以打开的最大fd数
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
进程当前打开的fd数
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
统计内存使用大小
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
进程启动时间戳
# HELP rest_client_request_duration_seconds [ALPHA] Request latency in seconds. Broken down by verb and URL.
# TYPE rest_client_request_duration_seconds histogram
请求 apiserver 的耗时(按照url和verb统计)
# HELP rest_client_requests_total [ALPHA] Number of HTTP requests, partitioned by status code, method, and host.
# TYPE rest_client_requests_total counter
请求 apiserver 的总数(按照code method host统计)最后夜莺监控 Kubernetes 官方(https://flashcat.cloud/categories/kubernetes%E7%9B%91%E6%8E%A7%E4%B8%93%E6%A0%8F/)已经整理了专栏,我这里仅仅是做了加工整理以及测试,不论是指标整理还是监控大盘,社区都做的很到位了,拿来即用。参考文档[1] https://help.aliyun.com/document_detail/441320.html?spm=a2c4g.444711.0.0.15046e9958T2TG
【夜莺监控】管理Kubernetes组件指标(上)
开始之前Kubernetes 是一个简单且复杂的系统,简单之处在于其整体架构比较简单清晰,是一个标准的 Master-Slave 模式,如下:但是,它又是一个复杂的系统,不论是 Master 还是 Slave,都有多个组件组合而成,如上图所示:Master 组件apiserver:API 入口,负责认证、授权、访问控制、API 注册与发现等scheduler:负责资源调度controller-manager:维护集群状态Slave 组件kubelet:维护容器生命周期、CSI 管理以及 CNI 管理kube-proxy:负责服务发现和负载均衡container runtime(docker、containerd 等):镜像管理、容器运行、CRI 管理等数据库组件Etcd:保存集群状态,与 apiserver 保持通信对于如此复杂的简单系统,要时刻掌握里内部的运行状态,是一件挺难的事情,因为它的覆盖面非常的广,主要涉及:操作系统层面:Kubernetes 是部署在操作系统之上的,操作系统层面的监控非常重要。Kubernetes 本身:Kubernetes 涉及相当多的组件,这些组件的运行状态关乎整个集群的稳定性。Kubernetes 之上的应用:Kubernetes 是为应用提供运行环境的,企业的应用系统都是部署在集群中,这些应用的稳定关乎企业的发展。还有其他的比如网络、机房、机柜等等底层支柱。要监控的非常多,SLI 也非常多。不过,这篇文章只讨论 Kubernetes 本身的监控,而且只讨论如何在夜莺体系中来监控它们。对于 Kubernetes 本身,主要是监控其系统组件,如下:image.png!! Ps:这里不在介绍夜莺监控是怎么安装的,如果不清楚的可以看《【夜莺监控】初识夜莺》这篇文章,本次实验也是使用是这篇文章中的安装方式。KubeApiServerApiServer 是 Kubernetes 架构中的核心,是所有 API 是入口,它串联所有的系统组件。为了方便监控管理 ApiServer,设计者们为它暴露了一系列的指标数据。当你部署完集群,默认会在default名称空间下创建一个名叫kubernetes的 service,它就是 ApiServer 的地址。# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 309d你可以通过curl -s -k -H "Authorization: Bearer $token" https://10.96.0.1:6443/metrics命令查看指标。其中$token是通过在集群中创建 ServerAccount 以及授予相应的权限得到。所以,要监控 ApiServer,采集到对应的指标,就需要先授权。为此,我们先准备认证信息。创建 namespacekubectl create ns flashcat创建认证授权信息创建0-apiserver-auth.yaml文件,内容如下:---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: categraf
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/metrics
- nodes/stats
- nodes/proxy
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics", "/metrics/cadvisor"]
verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: categraf
namespace: flashcat
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: categraf
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: categraf
subjects:
- kind: ServiceAccount
name: categraf
namespace: flashcat上面的内容主要是为categraf授予查询相关资源的权限,这样就可以获取到这些组件的指标数据了。指标采集指标采集的方式有很多种,建议通过自动发现的方式进行采集,这样是不论是伸缩、修改组件都无需再次来调整监控方式了。夜莺支持Prometheus Agent的方式获取指标,而且 Prometheus 在服务发现方面做的非常好,所以这里将使用Prometheus Agent方式来采集 ApiServer 的指标。(1)创建 Prometheus 配置apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'上面的内容主要是通过endpoints的方式主动发现在default名称空间下名字为kubernetes且端口为https的服务,然后将获取到的监控指标传输给夜莺服务端http://192.168.205.143:17000/prometheus/v1/write(这个地址根据实际情况做调整)。(2)部署 Prometheus AgentapiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-agent
namespace: flashcat
labels:
app: prometheus-agent
spec:
replicas: 1
selector:
matchLabels:
app: prometheus-agent
template:
metadata:
labels:
app: prometheus-agent
spec:
serviceAccountName: categraf
containers:
- name: prometheus
image: prom/prometheus
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--web.enable-lifecycle"
- "--enable-feature=agent"
ports:
- containerPort: 9090
resources:
requests:
cpu: 500m
memory: 500M
limits:
cpu: 1
memory: 1Gi
volumeMounts:
- name: prometheus-config-volume
mountPath: /etc/prometheus/
- name: prometheus-storage-volume
mountPath: /prometheus/
volumes:
- name: prometheus-config-volume
configMap:
defaultMode: 420
name: prometheus-agent-conf
- name: prometheus-storage-volume
emptyDir: {}其中--enable-feature=agent表示启动的是 agent 模式。然后将上面的所有 YAML 文件部署到 Kubernetes 中,然后查看 Prometheus Agent 是否正常。# kubectl get po -n flashcat
NAME READY STATUS RESTARTS AGE
prometheus-agent-78c8ccc4f5-g25st 1/1 Running 0 92s然后可以到夜莺UI查看对应的指标。获取到了指标数据,后面就是合理利用指标做其他动作,比如构建面板、告警处理等。比如夜莺Categraf提供了 ApiServer 的仪表盘(https://github.com/flashcatcloud/categraf/blob/main/k8s/apiserver-dash.json),导入后如下:但是,不论是做面板也好,还是做告警也罢,首先都要对 ApiServer 的指标有一个清晰的认识。下面做了一些简单的整理。指标简介以下指标来自阿里云 ACK 官方文档,我觉得整理的比较全,比较细,就贴了一部分。想要了解更多的可以到官方网站去查看。指标清单指标类型解释apiserver_request_duration_seconds_bucketHistogram该指标用于统计 APIServer 客户端对 APIServer 的访问时延。对 APIServer 不同请求的时延分布。请求的维度包括 Verb、Group、Version、Resource、Subresource、Scope、Component 和 Client。Histogram Bucket 的阈值为:**{0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60}**,单位:秒。apiserver_request_totalCounter对 APIServer 不同请求的计数。请求的维度包括 Verb、Group、Version、Resource、Scope、Component、HTTP contentType、HTTP code 和 Client。apiserver_request_no_resourceversion_list_totalCounter对 APIServer 的请求参数中未配置 ResourceVersion 的 LIST 请求的计数。请求的维度包括 Group、Version、Resource、Scope 和 Client。用来评估 quorum read 类型 LIST 请求的情况,用于发现是否存在过多 quorum read 类型 LIST 以及相应的客户端,以便优化客户端请求行为。apiserver_current_inflight_requestsGaugeAPIServer 当前处理的请求数。包括 ReadOnly 和 Mutating 两种。apiserver_dropped_requests_totalCounter限流丢弃掉的请求数。HTTP 返回值是**429 'Try again later'**。apiserver_admission_controller_admission_duration_seconds_bucketGauge准入控制器(Admission Controller)的处理延时。标签包括准入控制器名字、操作(CREATE、UPDATE、CONNECT 等)、API 资源、操作类型(validate 或 admit)和请求是否被拒绝(true 或 false)。Bucket 的阈值为:**{0.005, 0.025, 0.1, 0.5, 2.5}**,单位:秒。apiserver_admission_webhook_admission_duration_seconds_bucketGauge准入 Webhook(Admission Webhook)的处理延时。标签包括准入控制器名字、操作(CREATE、UPDATE、CONNECT 等)、API 资源、操作类型(validate 或 admit)和请求是否被拒绝(true 或 false)。Bucket 的阈值为:**{0.005, 0.025, 0.1, 0.5, 2.5}**,单位:秒。apiserver_admission_webhook_admission_duration_seconds_countCounter准入 Webhook(Admission Webhook)的处理请求统计。标签包括准入控制器名字、操作(CREATE、UPDATE、CONNECT 等)、API 资源、操作类型(validate 或 admit)和请求是否被拒绝(true 或 false)。cpu_utilization_coreGaugeCPU 使用量,单位:核(Core)。cpu_utilization_ratioGaugeCPU 使用率=CPU 使用量/内存资源上限,百分比形式。memory_utilization_byteGauge内存使用量,单位:字节(Byte)。memory_utilization_ratioGauge内存使用率=内存使用量/内存资源上限,百分比形式。upGauge服务可用性。1:表示服务可用。0:表示服务不可用。 |关键指标名称PromQL说明API QPSsum(irate(apiserver_request_total[$interval]))APIServer 总 QPS。读请求成功率sum(irate(apiserver_request_total{code=~"20.*",verb=~"GET|LIST"}[interval]))APIServer 读请求成功率。写请求成功率sum(irate(apiserver_request_total{code=~"20.*",verb!~"GET|LIST|WATCH|CONNECT"}[interval]))APIServer 写请求成功率。在处理读请求数量sum(apiserver_current_inflight_requests{requestKind="readOnly"})APIServer 当前在处理读请求数量。在处理写请求数量sum(apiserver_current_inflight_requests{requestKind="mutating"})APIServer 当前在处理写请求数量。请求限流速率sum(irate(apiserver_dropped_requests_total[$interval]))Dropped Request Rate。资源指标名称PromQL说明内存使用量memory_utilization_byte{container="kube-apiserver"}APIServer 内存使用量,单位:字节。CPU 使用量cpu_utilization_core{container="kube-apiserver"}*1000CPU 使用量,单位:豪核。内存使用率memory_utilization_ratio{container="kube-apiserver"}APIServer 内存使用率,百分比。CPU 使用率cpu_utilization_ratio{container="kube-apiserver"}APIServer CPU 使用率,百分比。资源对象数量max by(resource)(apiserver_storage_objects)max by(resource)(etcd_object_counts) | Kubernetes 管理资源数量,不同版本名称可能不同。 |QPS 和时延名称PromQL说明按 Verb 维度分析 QPSsum(irate(apiserver_request_total{verb=~"verb"}[interval]))by(verb)按 Verb 维度,统计单位时间(1s)内的请求 QPS。按 Verb+Resource 维度分析 QPSsum(irate(apiserver_request_total{verb=~"resource"}[$interval]))by(verb,resource)按 Verb+Resource 维度,统计单位时间(1s)内的请求 QPS。按 Verb 维度分析请求时延histogram_quantile(interval])) by (le,verb))按 Verb 维度,分析请求时延。按 Verb+Resource 维度分析请求时延histogram_quantile(interval])) by (le,verb,resource))按 Verb+Resource 维度,分析请求时延。非 2xx 返回值的读请求 QPSsum(irate(apiserver_request_total{verb=~"GET|LIST",resource=~"resource",code!~"2.*"}[interval])) by (verb,resource,code)统计非 2xx 返回值的读请求 QPS。非 2xx 返回值的写请求 QPSsum(irate(apiserver_request_total{verb!~"GET|LIST|WATCH",verb=~"resource",code!~"2.*"}[$interval])) by (verb,resource,code)统计非 2xx 返回值的写请求 QPS。KubeControllerManagerControllerManager 也是 Kubernetes 的重要组件,它负责整个集群的资源控制管理,它有许多的控制器,比如 NodeController、JobController 等。ControllerManager 的监控思路和 ApiServer 一样,都使用 Prometheus Agent 进行采集。指标采集ControllerManager 是通过10257的/metrics接口进行指标采集,要访问这个接口同样需要相应的权限,不过我们在采集 ApiServer 的时候创建过相应的权限,这里就不用创建了。(1)添加 Prometheus 配置 在原有的 Prometheus 采集配置中新增一个 job 用于采集 ControllerManager,如下:apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'controller-manager'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-controller-manager;https-metrics
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'由于我的集群里没有相应的 endpoints,所以需要创建一个,如下:apiVersion: v1
kind: Service
metadata:
annotations:
labels:
k8s-app: kube-controller-manager
name: kube-controller-manager
namespace: kube-system
spec:
clusterIP: None
ports:
- name: https-metrics
port: 10257
protocol: TCP
targetPort: 10257
selector:
component: kube-controller-manager
sessionAffinity: None
type: ClusterIP将 YAML 的资源更新到 Kubernetes 中,然后使用curl -X POST "http://<PROMETHEUS_IP>:9090/-/reload"重载 Prometheus。但是现在我们还无法获取到 ControllerManager 的指标数据,需要把 ControllerManager 的bind-address改成0.0.0.0。然后就可以在夜莺 UI 中查看指标了。然后可以导入https://github.com/flashcatcloud/categraf/blob/main/k8s/cm-dash.json的是数据大盘。指标简介指标清单指标类型说明workqueue_adds_totalCounterWorkqueue 处理的 Adds 事件的数量。workqueue_depthGaugeWorkqueue 当前队列深度。workqueue_queue_duration_seconds_bucketHistogram任务在 Workqueue 中存在的时长。memory_utilization_byteGauge内存使用量,单位:字节(Byte)。memory_utilization_ratioGauge内存使用率=内存使用量/内存资源上限,百分比形式。cpu_utilization_coreGaugeCPU 使用量,单位:核(Core)。cpu_utilization_ratioGaugeCPU 使用率=CPU 使用量/内存资源上限,百分比形式。rest_client_requests_totalCounter从状态值(Status Code)、方法(Method)和主机(Host)维度分析 HTTP 请求数。rest_client_request_duration_seconds_bucketHistogram从方法(Verb)和 URL 维度分析 HTTP 请求时延。Queue 指标名称PromQL说明Workqueue 入队速率sum(rate(workqueue_adds_total{job="ack-kube-controller-manager"}[$interval])) by (name)无Workqueue 深度sum(rate(workqueue_depth{job="ack-kube-controller-manager"}[$interval])) by (name)无Workqueue 处理时延histogram_quantile($quantile, sum(rate(workqueue_queue_duration_seconds_bucket{job="ack-kube-controller-manager"}[5m])) by (name, le))无资源指标名称PromQL说明内存使用量memory_utilization_byte{container="kube-controller-manager"}内存使用量,单位:字节。CPU 使用量cpu_utilization_core{container="kube-controller-manager"}*1000CPU 使用量,单位:毫核。内存使用率memory_utilization_ratio{container="kube-controller-manager"}内存使用率,百分比。CPU 使用率cpu_utilization_ratio{container="kube-controller-manager"}CPU 使用率,百分比。QPS 和时延名称PromQL说明Kube API 请求 QPSsum(rate(rest_client_requests_total{job="ack-scheduler",code=~"2.."}[$interval])) by (method,code)sum(rate(rest_client_requests_total{job="ack-scheduler",code=~"3.."}[$interval])) by (method,code)sum(rate(rest_client_requests_total{job="ack-scheduler",code=~"4.."}[$interval])) by (method,code)sum(rate(rest_client_requests_totaljob="ack-scheduler",code=~"5.."}[$interval])) by (method,code)对 kube-apiserver 发起的 HTTP 请求,从方法(Method)和返回值(Code) 维度分析。 | | Kube API 请求时延 | histogram_quantile($quantile, sum(rate(rest_client_request_duration_seconds_bucket{job="ack-kube-controller-manager"[$interval])) by (verb,url,le)) | 对 kube-apiserver 发起的 HTTP 请求时延,从方法(Verb)和请求 URL 维度分析。 |KubeSchedulerScheduler 监听在10259端口,依然通过 Prometheus Agent 的方式采集指标。指标采集(1)编辑 Prometheus 配置文件apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-agent-conf
labels:
name: prometheus-agent-conf
namespace: flashcat
data:
prometheus.yml: |-
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: 'controller-manager'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-controller-manager;https-metrics
- job_name: 'scheduler'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
insecure_skip_verify: true
authorization:
credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: kube-system;kube-scheduler;https
remote_write:
- url: 'http://192.168.205.143:17000/prometheus/v1/write'然后配置 Scheduler 的 Service。apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: kube-scheduler
name: kube-scheduler
namespace: kube-system
spec:
clusterIP: None
ports:
- name: https
port: 10259
protocol: TCP
targetPort: 10259
selector:
component: kube-scheduler
sessionAffinity: None
type: ClusterIP将 YAML 的资源更新到 Kubernetes 中,然后使用curl -X POST "http://<PROMETHEUS_IP>:9090/-/reload"重载 Prometheus。但是现在我们还无法获取到 Scheduler 的指标数据,需要把 Scheduler 的bind-address改成0.0.0.0。修改完成过后就可以正常在夜莺UI中查看指标了。导入监控大盘(https://github.com/flashcatcloud/categraf/blob/main/k8s/scheduler-dash.json)。