【原创】Ingress-Nginx-Controller的Metrics监控源码改造简析
一、背景
目前我们的生产环境一层Nginx已经容器化部署,但是监控并不完善,我们期望其具有Ingress-Nginx-Controller组件上报监控的数据。这样可以建立请求全链路的监控大盘。有利于监控查看关键链路的状态信息,并快速定位问题。因此需要研究Ingress-Nginx-Controller组件的监控机制原理,看是否可以移植到一层nginx上实现metrics监控数据的采集。
二、分析
首先,目前常用的Ingress-Nginx-Controller有两个。一个是K8S官方开源的Ingress-Nginx-Controller,另一个是nginx官方开源的Ingress-Nginx-Controller。我们使用的是K8S官方的版本。
这两个Controller大致的区别如下:
1)K8S官方的Controller也是采用Go语言开发的,集成了Lua实现的OpenResty;而Nginx官方的Ccontroller是集成了Nginx;
2)两者对Nginx的配置不同,并且使用的nginx.conf配置模板也是不一样的,Nginx官方的采用两个模板文件以include的方式配置upstream;K8S官方版本采用Lua动态配置upstream,所以不需要reload。
所以,在pod频繁变更的场景下,采用K8S官方版本不需要reload,影响会更小。
接下来,我们来看K8S官方的Ingress-Nginx-Controller是如何实现Metrics监控数据采集上报的。
根据Ingress-Nginx-Controlleroller内部架构图:

可以知道,Ingress-Nginx-Controller的内部组成部分和通讯机制。这里我们针对Nginx Metrics部分展开分析。于是,我们分析一下Ingress-Nginx-Controller的源码,找到其Metrics的入口。
在ingress-nginx/cmd/nginx/main.go文件中,我们找到了Metrics的入口,如下:


可以看到,当我们访问/metrics路径去获取监控数据时,程序会返回metrics.NewCollector()中采集的数据。继续分析metrics.NewCollector的逻辑。在ingress-nginx/internal/ingress/metrics/main.go文件中,我们可以看到:

这就是metrics真实数据来源的采集入口,我们可以看到一共包含了四部分的数据:NGINXStatus,NGINXProcess,SocketCollector和IngressController。下面,我们看下这四部分数据具体是什么?
1)NGINXStatus

其中nginx.StatusPath就是/nginx_status

由此可知,NGINXStatus的数据就是通过/nginx_status有nginx的status模板采集的数据。
2)NGINXProcess

而NGINXProcess的数据则是通过process_exporter的方式在/proc中采集nginx相关的数据。
3)SocketCollector

而NGINXSocket部分的数据则是监听/tmp/prometheus-nginx.socket这个socket文件来收集的数据。那么这个文件的数据来源是哪里呢?我们grep一下这个文件,发现nginx的lua脚本中有一个monitor.lua文件,就是这个文件采集到nginx的数据后写进去的。

由此可知,NGINXSocket的数据是通过monitor.lua采集的。
4)IngressController

而NGINXController部分的数据则controller对nginx操作状态信息的统计,然后直接上报的。
经过以上的分析,我们知道。ingress-nginx-controller的metrics监控包含了四部分数据:NGINXStatus,NGINXProcess,SocketCollector和IngressController。
其中NGINXStatus和SocketCollector都是在nginx中实现,通过nginx自身的status模板和monitor.lua实现,并通过http或者socket的方式暴露。NGINXProcess和IngressController则是有ingress-controller本身实现。
三、一层Nginx实现类似ingress-nginx-controller的metrics监控
由上面的分析我们可以知道,要使得普通的nginx实例具备Ingress-Nginx-Controller的metrics监控能力,需要将NGINXStatus,NGINXProcess,SocketCollector和IngressController四部分的数据采集能力移植到nginx实例上。
1)NGINXStatus不需要移植,nginx开启status模块,以/nginx_status暴露即可;
2)SocketCollector移植简单,将monitor.lua脚本拷贝到nginx中,简单配置跑起来即可;该部分是SocketCollector监听在/tmp/prometheus-nginx.socket文件,由monitor.lua采集数据后写入。
3)NGINXProcess和IngressController移植较复杂,需要深入分析其源码,从ingress-nginx-controller中剥离出来后单独运行。其中IngressController部分的数据丢弃。
最后,通过抽离移植NGINXStatus,NGINXProcess,SocketCollector三部分监控内容。(代码见:https://github.com/wsjhk/nginx-custom-metrics.git)部署到一层nginx中需要做如下变更:
1)抽离出来的代码编译为ngxcustom-metrics二进制可执行文件,打包到nginx的镜像中,随容器启动一起启动。
2)nginx的配置中需要添加Lua相关代码的部署,具体配置参考源码。
3)Prometheus配置采集一层nginx的metrics监控信息。验证监控数据。
(一层Nginx的容器化实现参考:https://mp.weixin.qq.com/s/q_kTlflDMg6MGyNOq6sVjQ)
3.1)deployment中添加annotation:

3.2)添加job_name采集:
- job_name: 'slb-nginx-pods'
honor_labels: false
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- slb-nginx
tls_config:
insecure_skip_verify: true
relabel_configs:
- target_label: dc
replacement: huadong1
- target_label: cloud
replacement: aliyun
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_ngx_mr_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (.+)
采集到的数据样例如下:

至此,完成了Nginx监控Metrics的改造。
【原创】Ingress-Nginx-Controller的Metrics监控源码改造简析的更多相关文章
- .Net Framework4.5.2 源码命名空间简析
Miscosoft目前除.Net Core开源外,对于.Net4.5.1 , 4.5.2等后续版本同样开源.资源中包含sln,csproj等以方便我们在vs中打开它们,不过我们不能编译它,因为它缺少r ...
- LinkedHashMap结构get和put源码流程简析及LRU应用
原理这篇讲得比较透彻Java集合之LinkedHashMap. 本文属于源码阅读笔记,因put,get调用逻辑及链表维护逻辑复杂(至少网上其它文章的逻辑描述及配图,我都没看明白LinkedHashMa ...
- 【原创】005 | 搭上SpringBoot请求处理源码分析专车
前言 如果这是你第二次看到师长,说明你在觊觎我的美色! 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 专车介绍 该趟专车是开往Spring Boot请求处理源码分析专车,主要用来分析S ...
- 做个简单的Redis监控(源码分享)
Redis监控 Redis 是目前应用广泛的NoSQL,我做的项目中大部分都是与Redis打交道,发现身边的朋友也更多人在用,相对于memcached 来说,它的优势也确实是可圈可点.在随着业务,数据 ...
- nginx在Centos7.5下源码安装和配置
安装nginx 安装nginx依赖包 yum install -y pcre-devel zlib-devel openssl-devel wget gcc tree vim 进入目录/root/se ...
- 做个简单的Redis监控(源码分享)[转载]
Redis监控 Redis 是目前应用广泛的NoSQL,我做的项目中大部分都是与Redis打交道,发现身边的朋友也更多人在用,相对于memcached 来说,它的优势也确实是可圈可点.在随着业务,数据 ...
- Nginx优化之基本安全优化 (隐藏Nginx软件版本号信息,更改源码隐藏Nginx软件名及版本号,更改Nginx服务的默认用户)
一,隐藏Nginx软件版本号信息 查看版本号 curl -I 192.168.0.220 HTTP/1.1 200 OK Server: nginx/1.6.2 #这里清晰的暴露了Web版本号(1.6 ...
- Sentinel Dashboard(基于1.8.1)流控规则持久化到Nacos——涉及部分Sentinel Dashboard源码改造
前言 之前虽然也一直在使用sentinel实现限流熔断功能,但却没有好好整理之前看的源码与资料,今天有时间将之前自己整理过的资料写成一篇博文,或者是是一篇关于Sentinel(基于目前最近版本1.8, ...
- 关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造)
关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造) 摘要:在中文搜索中的标点.符号往往也是有语义的,比如我们要搜索“C++”或是“C#”,我们不希望搜索出来的全是“C”吧?那样对程 ...
随机推荐
- log日志重复输出问题(没弄明白原因)
在别的模块调用定义好的函数 输出的日志出现第一次输出输出一条,第二次输出输出两条...的情况 最后在定义函数处remove了句柄 引用了https://blog.csdn.net/huilan_sam ...
- 6.注册CRT 以及SecureCRT访问
1.什么是 SecureCRT SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录Unix或Linux服务器主 机的软件. 1)准备工作:安装好Se ...
- APP专项测试实战1
首先,如果测试需要用到的话,还是建议一下大家去看下Android-studio的官方文档.文档地址:Documentation | Android 开发者 | Android Develope ...
- [bug] IDEA Maven 项目 Module 不加粗,无法编译
参考 https://blog.csdn.net/qq_42479920/article/details/102859244
- [bug] java.sql.SQLSyntaxErrorException: Table 'mysql.tb_item' doesn't exist
参考 https://zhidao.baidu.com/question/146817103.html
- Linux中find命令用法全汇总,看完就没有不会用的!
Linux中find命令用法全汇总,看完就没有不会用的! 中琦2513 马哥Linux运维 2017-04-10 糖豆贴心提醒,本文阅读时间7分钟 Linux 查找命令是Linux系统中最重要和最 ...
- centOS 7 安装 CUPS 打印服务器,安装映美 FP-730K打印机共享
centOS 7 安装 CUPS 打印服务器,安装映美 FP-730K打印机共享 2017-09-13 16:27:02 mostone 阅读数 3698 版权声明:本文为博主原创文章,遵循CC ...
- Flume 常用配置项
注:以下配置项均为常见配置项,查询详细配置项可以访问 flume 官网 Source 常见配置项 Avro Source 配置项名称 默认值 描述 Channel – type – 组件类型名称,必须 ...
- oepncv实现——图像去水印
功能简介:通过拖动鼠标实现指定区域水印或是斑点的去除. 实现原理:利用opencv鼠标操作setMouseCallback函数框选(左上到右下)需要处理的区域,按下鼠标开始选中,松开鼠标结束,对选中区 ...
- 第三方跨平台进程和系统监控库gopsutil
gopsutil psutil是一个跨平台进程和系统监控的Python库,而gopsutil是其Go语言版本的实现.本文介绍了它的基本使用. Go语言部署简单.性能好的特点非常适合做一些诸如采集系统信 ...