在k8s集群内搭建Prometheus监控平台

基本架构

Prometheus由SoundCloud发布,是一套由go语言开发的开源的监控&报警&时间序列数据库的组合。

Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM、Docker、Kubernetes等。

在这里插入图片描述
Prometheus 主要的组件功能如下:

  • Prometheus Server:server的作用主要是定期从静态配置的targets或者服务发现(主要是DNS、consul、k8s、mesos等)的 targets 拉取数据。
  • Exporter: 主要负责向prometheus server做数据汇报。而不同的数据汇报由不同的exporters实现,比如监控主机有node-exporters,mysql有MySQL server exporter。
  • Pushgateway:Prometheus获得数据的方式除了到对应exporter去Pull,还可以由服务先Push到pushgateway,server再去pushgateway 拉取。
  • Alertmanager:实现prometheus的告警功能。
  • webui:主要通过grafana来实现webui展示。

我们在实际使用的时候的基本流程就是:
各个服务push监控数据到其对应的指标(比如下面提到的Exporter) --> Prometheus Server定时采集数据并存储 --> 配置Grafana展示数据 & 配置告警规则进行告警

Helm部署Prometheus平台

使用helm部署kube-prometheus-stack
helm地址:传送门
github地址:传送门

请添加图片描述

Exporter

要采集目标的监控数据,首先就要在被采集目标地方安装采集组件,这种采集组件被称为Exporter。prometheus.io官网上有很多这种exporter,官方exporter列表。

采集完了怎么传输到Prometheus?

Exporter 会暴露一个HTTP接口,prometheus通过Pull模式的方式来拉取数据,会通过HTTP协议周期性抓取被监控的组件数据。
不过prometheus也提供了一种方式来支持Push模式,你可以将数据推送到Push Gateway,prometheus通过pull的方式从Push Gateway获取数据。

golang应用中接入采集组件

kratos框架

在微服务框架kratos中接入Prometheus采集组件的示例,kratos官方教程:

package main

import (
	"context"
	"fmt"
	"log"

	prom "github.com/go-kratos/kratos/contrib/metrics/prometheus/v2"
	"github.com/go-kratos/kratos/v2/middleware/metrics"
	"github.com/prometheus/client_golang/prometheus/promhttp"

	"github.com/go-kratos/examples/helloworld/helloworld"
	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/go-kratos/kratos/v2/transport/http"
	"github.com/prometheus/client_golang/prometheus"
)

// go build -ldflags "-X main.Version=x.y.z"
var (
	// Name is the name of the compiled software.
	Name = "metrics"
	// Version is the version of the compiled software.
	// Version = "v1.0.0"

	_metricSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Namespace: "server",
		Subsystem: "requests",
		Name:      "duration_sec",
		Help:      "server requests duration(sec).",
		Buckets:   []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.250, 0.5, 1},
	}, []string{"kind", "operation"})

	_metricRequests = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: "client",
		Subsystem: "requests",
		Name:      "code_total",
		Help:      "The total number of processed requests",
	}, []string{"kind", "operation", "code", "reason"})
)

// server is used to implement helloworld.GreeterServer.
type server struct {
	helloworld.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
	return &helloworld.HelloReply{Message: fmt.Sprintf("Hello %+v", in.Name)}, nil
}

func init() {
	prometheus.MustRegister(_metricSeconds, _metricRequests)
}

func main() {
	grpcSrv := grpc.NewServer(
		grpc.Address(":9000"),
		grpc.Middleware(
			metrics.Server(
				metrics.WithSeconds(prom.NewHistogram(_metricSeconds)),
				metrics.WithRequests(prom.NewCounter(_metricRequests)),
			),
		),
	)
	httpSrv := http.NewServer(
		http.Address(":8000"),
		http.Middleware(
			metrics.Server(
				metrics.WithSeconds(prom.NewHistogram(_metricSeconds)),
				metrics.WithRequests(prom.NewCounter(_metricRequests)),
			),
		),
	)
	httpSrv.Handle("/metrics", promhttp.Handler())

	s := &server{}
	helloworld.RegisterGreeterServer(grpcSrv, s)
	helloworld.RegisterGreeterHTTPServer(httpSrv, s)

	app := kratos.New(
		kratos.Name(Name),
		kratos.Server(
			httpSrv,
			grpcSrv,
		),
	)

	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}

最终暴露出一个http://127.0.0.1:8000/metricsHTTP接口出来,Prometheus可以通过这个接口拉取监控数据。

抓取集群外部数据源

背景:在已有的K8s集群中通过helm部署了一个kube-prometheus-stack,用于监控服务器和服务。现在已经将k8s集群中的node、pod等组件接入到prometheus了。还需要将部署在k8s集群外部的其他应用服务接入到prometheus。

prometheus抓取k8s集群外部的数据时,有以下途径:

  • ServiceMonitor
  • Additional Scrape Configuration

ServiceMonitor

ServiceMonitor 是一个CRD,它定义了 Prometheus 应该抓取的服务端点以及抓取的时间间隔。
通过ServiceMonitor监控集群外部的服务,需要配置Service、Endpoints和ServiceMonitor。

现在有一个已经部署到192.168.1.100:8000的后端服务,已经通过/metrics将监控指标暴露出来了。尝试将其接入到prometheus,具体操作如下:

在命令行中输入

$ touch external-application.yaml

$ vim external-application.yaml

然后将下面的yaml文件内容拷贝进去

---
apiVersion: v1
kind: Service
metadata:
  name: external-application-exporter
  namespace: monitoring
  labels:
    app: external-application-exporter
    app.kubernetes.io/name: application-exporter
spec:
  type: ClusterIP
  ports:
  - name: metrics
    port: 9101
    protocol: TCP
    targetPort: 9101
---
apiVersion: v1
kind: Endpoints
metadata:
    name: external-application-exporter
    namespace: monitoring
    labels:
      app: external-application-exporter
      app.kubernetes.io/name: application-exporter
subsets:
- addresses:
  - ip: 192.168.1.100  # 这里是外部的资源列表
  ports:
  - name: metrics
    port: 8000
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: external-application-exporter
  namespace: monitoring
  labels:
    app: external-application-exporter
    release: prometheus
spec:
  selector:
    matchLabels:            # Service选择器
      app: external-application-exporter
  namespaceSelector:        # Namespace选择器
    matchNames:
    - monitoring
  endpoints:
  - port: metrics           # 采集节点端口(svc定义)
    interval: 10s           # 采集频率根据实际需求配置,prometheus默认10s
    path: /metrics          # 默认地址/metrics

保存好文件之后运行命令:

kubectl apply -f external-application.yaml

之后打开prometheus控制台,进入Targets目录。可以看到新增的external-application-exporter显示出来了:

请添加图片描述
请添加图片描述

Additional Scrape Configuration

除了ip加端口提供的HTTP服务以外,我还在其他服务器上部署了可以通过域名访问的HTTPS服务。现在想用同样的方法将其接入进来。

首先尝试修改Endpoints,找到k8s的官方文档,发现Endpoints仅支持ip,也没有配置HTTPS协议的地方。
请添加图片描述
那么我们尝试换一种方式。

第一种方法

首先查阅官方文档,找到关于关于prometheus抓取配置的地方,可以看到,prometheus的抓取配置的关键字是scrape_config
请添加图片描述
我们的prometheus是通过helm部署kube-prometheus-stack得到的,所以我们查看一下该charts的value.yaml文件,看看有无配置。

输入命令:

$ cat values.yaml  | grep -C 20  scrape_config

得到如下结果:
请添加图片描述
从注释中知道,kube-prometheus是通过additionalScrapeConfigs配置抓取策略的。

于是写一个配置文件去更新helm已经部署好的prometheus的release。

$ touch prometheus.yml

$ vim prometheus.yml

将一下内容写入:

prometheus:
  prometheusSpec:
    additionalScrapeConfigs:
      - job_name: external-application-exporter-https
      scrape_interval: 10s
      scrape_timeout: 10s
      metrics_path: /metrics
      scheme: https
      tls_config:
        insecure_skip_verify: true
      static_configs:
        - targets: ["www.baidu.com:443"]

最后更新release:

$ helm upgrade -nmonitoring -f prometheus.yaml prometheus kube-prometheus-stack-40.0.0.tgz

使用prometheus.yaml更新release,其中kube-prometheus-stack-40.0.0.tgz是我在部署prometheus时已经helm pull到本地的chart文件。

我们在prometheus的控制台的Targets目录下可以看到我们新添加的数据源。

到这里其实就可以结束了,但是有一个不好的地方是,每次添加新的域名监控,都需要重新更新helm的release,不是特别方便。

第二种方法

翻一翻prometheus-operator的源码,发现在说明中,有关于抓取配置热更新的教程。简单的概括就是,通过配置secret,来控制prometheus的抓取数据源。secret的内容修改时,可以热更新prometheus的抓取配置。截个图看一下:

请添加图片描述

第一步,生成prometheus-additional.yaml文件

$ touch prometheus-additional.yaml

$ vim prometheus-additional.yaml

prometheus-additional.yaml内容:

- job_name: external-application-exporter-https
  scrape_interval: 10s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: https
  tls_config:
    insecure_skip_verify: true
  static_configs:
    - targets: ["www.baidu.com:443"]

第二步,生成secret

生成用于创建secret的配置文件:

$ kubectl create secret generic additional-scrape-configs --from-file=prometheus-additional.yaml --dry-run=client -oyaml > additional-scrape-configs.yaml

$ cat additional-scrape-configs.yaml

可以看到生成的additional-scrape-configs.yaml内容如下:

apiVersion: v1
data:
  prometheus-additional.yaml: LSBqb2JfbmFtZTogZXh0ZXJuYWwtYXBwbGljYXRpb24tZXhwb3J0ZXItaHR0cHMKICBzY3JhcGVfaW50ZXJ2YWw6IDEwcwogIHNjcmFwZV90aW1lb3V0OiAxMHMKICBtZXRyaWNzX3BhdGg6IC9tZXRyaWNzCiAgc2NoZW1lOiBodHRwcwogIHRsc19jb25maWc6CiAgICBpbnNlY3VyZV9za2lwX3ZlcmlmeTogdHJ1ZQogIHN0YXRpY19jb25maWdzOgogICAgLSB0YXJnZXRzOiBbImNpYW10ZXN0LnNtb2EuY2M6NDQzIl0K
kind: Secret
metadata:
  creationTimestamp: null
  name: additional-scrape-configs

将这段编码解码看一下内容:

$ echo "LSBqb2JfbmFtZTogZXh0ZXJuYWwtYXBwbGljYXRpb24tZXhwb3J0ZXItaHR0cHMKICBzY3JhcGVfaW50ZXJ2YWw6IDEwcwogIHNjcmFwZV90aW1lb3V0OiAxMHMKICBtZXRyaWNzX3BhdGg6IC9tZXRyaWNzCiAgc2NoZW1lOiBodHRwcwogIHRsc19jb25maWc6CiAgICBpbnNlY3VyZV9za2lwX3ZlcmlmeTogdHJ1ZQogIHN0YXRpY19jb25maWdzOgogICAgLSB0YXJnZXRzOiBbImNpYW10ZXN0LnNtb2EuY2M6NDQzIl0K" | base64 -d

得到:

- job_name: external-application-exporter-https
  scrape_interval: 10s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: https
  tls_config:
    insecure_skip_verify: true
  static_configs:
    - targets: ["ciamtest.smoa.cc:443"]

可以确认配置文件生成无误,接着生成secret:

$ kubectl apply -f additional-scrape-configs.yaml -n monitoring

monitoring是prometheus部署所在的命名空间,把它们放到同一个命名空间。

确认secret生成了:

$ kubectl get secret -n monitoring

输出:
请添加图片描述

最后,修改CRD

Finally, reference this additional configuration in your prometheus.yaml CRD.

官方文档让我们修改prometheus的配置
先找到prometheus这个CRD:

$ kubectl get prometheus -n monitoring
NAME                                    VERSION   REPLICAS   AGE
prometheus-kube-prometheus-prometheus   v2.38.0   1          2d18h

然后修改它

$ kubectl edit prometheus prometheus-kube-prometheus-prometheus -n monitoring
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
  labels:
    prometheus: prometheus
spec:
  ...
  additionalScrapeConfigs:
    name: additional-scrape-configs
    key: prometheus-additional.yaml
  ...

最后,在prometheus控制台看一下效果:
请添加图片描述
域名服务已经监控上了,以后想添加其他域名监控,只需要修改secret就行,great!!!

告警

todo

遇到的问题

  1. 更新抓取配置的secret后prometheus的控制台看不到效果
    尝试重启pod:prometheus-prometheus-kube-prometheus-prometheus-0,报错:

ts=2023-07-29T09:30:54.188Z caller=main.go:454 level=error msg=“Error loading config (–config.file=/etc/prometheus/config_out/prometheus.env.yaml)” file=/etc/prometheus/config_out/prometheus.env.yaml err=“parsing YAML file /etc/prometheus/config_out/prometheus.env.yaml: scrape timeout greater than scrape interval for scrape config with job name “external-application-exporter-https””

原因是,自定义指标的配置出错导致prometheus启动失败,scrape_interval和scrape_timeout存在问题

- job_name: external-application-exporter-https
  scrape_interval: 10s
  scrape_timeout: 30s
  metrics_path: /metrics
  scheme: https
  tls_config:
    insecure_skip_verify: true
  static_configs:
    - targets: ["ciamtest.smoa.cc:443"]

需要改成

- job_name: external-application-exporter-https
  scrape_interval: 10s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: https
  tls_config:
    insecure_skip_verify: true
  static_configs:
    - targets: ["ciamtest.smoa.cc:443"]

引用

  1. Grafana & prometheus 入门
  2. Prometheus监控+Grafana+Alertmanager告警安装使用 (图文详解)
  3. Prometheus官方教程
  4. Helm仓库
  5. kube-prometheus项目的Github地址
  6. kratos官方教程
  7. K8s官方文档
  8. prometheus-operator的源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/54443.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux上定位线上CPU飙高

【模拟场景】 写一个java main函数,死循环打印 System.out.println(“111111”) , 将其打成jar包放在linux中执行 1、通过TOP命令找到CPU耗用最厉害的那个进程的PID 2、top -H -p 进程PID 找到进程下的所有线程 可以看到 pid 为 94384的线程耗用cpu …

UM2080F32——32位SoC芯片

UM2080F32是基于ARM Cortex-M0内核的超低功耗、高性能的、单片集成(G)FSK/OOK无线收发机的32位SoC芯片。工作于200MHz~960MHz范围内,支持灵活可设的数据包格式,支持自动应答和自动重发功能,支持跳频操作,支持FEC功能,同…

BugKu CTF(杂项篇MISC)—社工-进阶收集

BugKu CTF(杂项篇MISC)—社工-进阶收集 提 示: flag{小美小区名字拼音} 描 述: 小明当年为了追求小美想尽办法获得小美的地址。直到有一天小美发了一条说说,小明觉得希望来了。(实战改编题,难度降低了。) [外链图片转存失败,源站可能有防盗链机制,建议…

yolov3-tiny原理解析及代码分析

前言 从去年十一月份开始学习yolo神经网络用于目标识别的硬件实现,到现在已经六个月了。一个硬件工程师,C/C基础都差劲的很,对照着darknet作者的源码和网上东拼西凑的原理讲解,一点一点地摸索。刚开始进度很慢,每天都…

pytorch学习——模型选择

一.概念 模型选择是机器学习中的重要环节,它涉及到从各种统计,机器学习或深度学习模型中选取最佳模型的过程。这涉及到许多关键概念,包括偏差与方差,过拟合与欠拟合,训练误差和泛化误差,交叉验证&#xff0…

【计算机网络】传输层协议 -- TCP协议

文章目录 1. TCP协议的引入2. TCP协议的特点3. TCP协议格式3.1 序号与确认序号3.2 发送缓冲区与接收缓冲区3.3 窗口大小3.4 六个标志位 4. 确认应答机制5. 超时重传机制6. 连接管理机制6.1 三次握手6.2 四次挥手 7. 流量控制8. 滑动窗口9. 拥塞控制10. 延迟应答11. 捎带应答12.…

Inkscape 1.3 版开放源代码 SVG 编辑器发布,新增形状生成器工具和许多更改

导读Inkscape 是功能强大的开源、跨平台、免费 SVG(可缩放矢量图形)编辑器,今天已更新到稳定的 1.3 版,这是一个引入新功能和许多改进的重要版本。 Inkscape 1.3 是在 Inkscape 1.2 发布一年零两个月后推出的,它引入了…

python-网络爬虫.regular

regular 正则表达式 (regular expression) 正则表达式(regular expression)描述了一种字符串匹配的模式 (pattern), 可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串 中取出符合某个条件的子串等。 正则表达式是由普通…

学C的第三十一天【通讯录的实现】

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com) 接上期: 学C的第三十天【自定义类型:结构体、枚举、联合】_高高的胖子的博客-CSDN博客 通讯录需求: 实现一个通讯录, 通讯录中存放保存人的信息&#xff1…

SpringBoot中MongoDB的使用

SpringBoot中MongoDB的使用 MongoDB 是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居 多。由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoD…

P1535 [USACO08MAR] Cow Travelling S(dfs+剪枝 or 记忆化搜索)

1:本题暴力做法简单,重点在于我们如何剪枝: :《曼哈顿距离》我们每走一个点就判断,当前点到终点的最短步数是不是小于当前剩余的步数, 如果大于就肯定不符合直接return,或者当步数为0时,当还没到达终点,那…

springSecurity自定义过滤器不生效问题排查

在使用springSecurity过滤器的过程中,由于需要自定义一个过滤器处理数据问题。代码如下: 过滤器定义: public class AuthRequestParamFiler extends GenericFilterBean {private static final CoreLogger LOGGER CoreLoggerFactory.getLog…

Flink - souce算子

水善利万物而不争,处众人之所恶,故几于道💦 目录 1. 从Java的集合中读取数据 2. 从本地文件中读取数据 3. 从HDFS中读取数据 4. 从Socket中读取数据 5. 从Kafka中读取数据 6. 自定义Source 官方文档 - Flink1.13 1. 从Java的集合中读取数据 …

【python】使用Selenium和Chrome WebDriver来获取 【腾讯云 Cloud Studio 实战训练营】中的文章信息

文章目录 前言导入依赖库设置ChromeDriver的路径创建Chrome WebDriver对象打开网页找到结果元素创建一个空列表用于存储数据遍历结果元素并提取数据提取标题、作者、发布时间等信息判断是否为目标文章提取目标文章的描述、阅读数量、点赞数量、评论数量等信息将提取的数据存储为…

【外卖系统】菜品信息分页查询

需求分析 当菜品数据很多时,用分页的形式来展示列表数据 代码开发 页面发送ajax请求,将分页查询参数提交到服务端,获取分页数据页面发送请求,请求服务端进行图片下载,用于页面图片展示 构造分页 注意:…

Java入门指南:Java语言优势及其特点

目录 1. Java语言简介及发展概述 2. Java语言的优势 2.1 可移植性 2.2 面向对象 2.3 安全性 2.4 大量类库 3. Java语言与C/C的区别 4. 初识Java程序入口之main方法 5. 注释、标识符、关键字 5.1 注释 5.2 标识符 5.3 关键字 1. Java语言简介及发展概述 Java是一种面…

iphone备份用什么软件?好用的苹果数据备份工具推荐!

众所周知,如果要将iPhone的数据跟电脑进行传输备份的话,我们需要用到iTunes这个pc工具。但是对于iTunes,不少人都反映这个软件比较难用,用不习惯。于是,顺应时代命运的iPhone备份同步工具就出现了。那iphone备份用什么…

[css]margin-top不起作用问题(外边距合并)

在初学css时&#xff0c;会遇到突然间margin-top不起作用的情况。如下面&#xff1a; 情况一&#xff1a; 代码&#xff1a; <html> <head><style type"text/css"> * {margin:0;padding:0;border:0; }#outer {width:300px;height:300px;backgroun…

数据库—数据库备份(三十四)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 二、数据备份的重要性 三、造成数据丢失的原因 四、备份类型 4.1物理与逻辑角度 4.2数据库备份策略角度 五、常见的备份方法 5.1 物理备份 5.2 使用专用备…

短视频平台视频怎么去掉水印?

短视频怎么去水印&#xff0c;困扰很多人&#xff0c;例如&#xff0c;有些logo水印&#xff0c;动态水印等等&#xff0c;分享操作经验&#xff1a; 抖音作为中国最受欢迎的社交娱乐应用程序之一&#xff0c;已成为许多人日常生活中不可或缺的一部分。在使用抖音过程中&#x…