【原創】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的改造。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM