Prometheus Operator自定義監控物件 -- Ingress-Nginx

旧巷g發表於2024-11-26

Prometheus Operator自定義監控物件 -- Ingress-Nginx

一、自定義資源

Prometheus-operator 透過定期迴圈watch apiserver,獲取到CRD資源(比如servicemonitor)的建立或者更新,將配置更新及時應用到執行中的prometheus pod中轉換成標準promethesu配置檔案供prometheus server使用。

各個CRD以及operator之間的關係:

使用CRD做prometheus配置,“匹配” 是一個很重要的細節,詳細匹配關係如圖,任何地方匹配失敗會導致轉化成的標配prometheus檔案無法識別到targets

img

Prometheus Operater 定義瞭如下的四類自定義資源:

  • Prometheus

  • ServiceMonitor

  • Alertmanager

  • PrometheusRule

1.1、Prometheus

Prometheus 自定義資源(CRD)宣告瞭在 Kubernetes 叢集中執行的 Prometheus 的期望設定。包含了副本數量,持久化儲存,以及 Prometheus 例項傳送警告到的 Alertmanagers等配置選項。

每一個 Prometheus 資源,Operator 都會在相同 namespace 下部署成一個正確配置的 StatefulSet,Prometheus 的 Pod 都會掛載一個名為 的 Secret,裡面包含了 Prometheus 的配置。Operator 根據包含的 ServiceMonitor 生成配置,並且更新含有配置的 Secret。無論是對 ServiceMonitors 或者 Prometheus 的修改,都會持續不斷的被按照前面的步驟更新。

示例配置如下

kind: Prometheus
metadata: # 略
spec:
  alerting:
    alertmanagers:
    - name: prometheus-prometheus-oper-alertmanager # 定義該 Prometheus 對接的 Alertmanager 叢集的名字, 在 default 這個 namespace 中
      namespace: default
      pathPrefix: /
      port: web
  baseImage: quay.io/prometheus/prometheus
  replicas: 2 # 定義該 Proemtheus “叢集”有兩個副本
  ruleSelector: # 定義這個 Prometheus 需要使用帶有 prometheus=k8s 且 role=alert-rules 標籤的 PrometheusRule
    matchLabels:
      prometheus: k8s
      role: alert-rules
  serviceMonitorNamespaceSelector: {} # 定義這些 Prometheus 在哪些 namespace 裡尋找 ServiceMonitor
  serviceMonitorSelector: # 定義這個 Prometheus 需要使用帶有 k8s-app=node-exporter 標籤的 ServiceMonitor,不宣告則會全部選中
    matchLabels:
      k8s-app: node-exporter
  version: v2.10.0

1.2、ServiceMonitor

ServiceMonitor 配置

ServiceMonitor 自定義資源(CRD)能夠宣告如何監控一組動態服務的定義。它使用標籤選擇定義一組需要被監控的服務。這樣就允許組織引入如何暴露 metrics 的規定,只要符合這些規定新服務就會被發現列入監控,而不需要重新配置系統。

要想使用 Prometheus Operator 監控 Kubernetes 叢集中的應用,Endpoints 物件必須存在。Endpoints 物件本質是一個 IP 地址列表。通常,Endpoints 物件由 Service 構建。Service 物件透過物件選擇器發現 Pod 並將它們新增到 Endpoints 物件中。

Prometheus Operator 引入 ServiceMonitor 物件,它發現 Endpoints 物件並配置 Prometheus 去監控這些 Pods。

ServiceMonitorSpec 的 endpoints 部分用於配置需要收集 metrics 的 Endpoints 的埠和其他引數。

ServiceMonitor 和發現的目標可能來自任何 namespace:

  • 使用 PrometheusSpec 下 ServiceMonitorNamespaceSelector, 透過各自 Prometheus server 限制 ServiceMonitors 作用 namespece。

  • 使用 ServiceMonitorSpec 下的 namespaceSelector 允許發現 Endpoints 物件的名稱空間。要發現所有名稱空間下的目標,namespaceSelector 必須為空。

spec:
  namespaceSelector:
    any: true

示例配置如下

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: node-exporter # 這個 ServiceMonitor 物件帶有 k8s-app=node-exporter 標籤,因此會被 Prometheus 選中
    name: ingress-nginx
    namespace: monitoring
spec:
  endpoints:
  - interval: 15s       # 定義這些 Endpoints 需要每 15 秒抓取一次
    port: prometheus        # 這邊一定要用svc中 port的name。
  namespaceSelector:
    matchNames:
    - ingress-nginx         # 選定抓取的指定namespace
  selector:
    matchLabels:        # 匹配的抓取標籤
      app.kubernetes.io/component: controller
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
      app.kubernetes.io/version: 1.7.0

1.3、Alertmanager

Alertmanager 配置

Alertmanager 自定義資源(CRD)宣告在 Kubernetes 叢集中執行的 Alertmanager 的期望設定。它也提供了配置副本集和持久化儲存的選項。

每一個 Alertmanager 資源,Operator 都會在相同 namespace 下部署成一個正確配置的 StatefulSet。Alertmanager pods 配置掛載一個名為 的 Secret, 使用 alertmanager.yaml key 對作為配置檔案。

當有兩個或更多配置的副本時,Operator 可以高可用性模式執行Alertmanager例項。

示例配置如下:

kind: Alertmanager #  一個 Alertmanager 物件
metadata:
  name: prometheus-prometheus-oper-alertmanager
spec:
  baseImage: quay.io/prometheus/alertmanager
  replicas: 3      # 定義該 Alertmanager 叢集的節點數為 3
  version: v0.17.0

1.4、PrometheusRule

PrometheusRule 配置

PrometheusRule CRD 宣告一個或多個 Prometheus 例項需要的 Prometheus rule。

Alerts 和 recording rules 可以儲存並應用為 yaml 檔案,可以被動態載入而不需要重啟。

示例配置如下:

kind: PrometheusRule
metadata:
  labels: # 定義該 PrometheusRule 的 label, 顯然它會被 Prometheus 選中
    prometheus: k8s
    role: alert-rules
  name: prometheus-k8s-rules
spec:
  groups:
  - name: k8s.rules
    rules: # 定義了一組規則,其中只有一條報警規則,用來報警 kubelet 是不是掛了
    - alert: KubeletDown
      annotations:
        message: Kubelet has disappeared from Prometheus target discovery.
      expr: |
        absent(up{job="kubelet"} == 1)
      for: 15m
      labels:
        severity: critical

1.5、配置間的匹配總結

ServiceMonitor 注意事項

  • ServiceMonitor 的 label 需要跟prometheus中定義的serviceMonitorSelector一致。

  • ServiceMonitor 的 endpoints 中 port 時對應k8s service資源中的 portname , 不是 port number。

  • ServiceMonitor 的 selector.matchLabels 需要匹配 k8s service 中的 label。

  • ServiceMonitor 資源建立在 prometheus 的 namespace 下,使用 namespaceSelector 匹配要監控的 k8s svc 的 ns。

  • servicemonitor 若匹配多個 svc ,會發生資料重複。

二、抓取自定義資源 -- Ingress-nginx(Helm)

2.1、暴露ingress的監控埠

透過 helm 部署維護的 ingress-nginx

vim values.yaml

metrics:
    port: 10254
    portName: metrics
    # if this port is changed, change healthz-port: in extraArgs: accordingly
    enabled: true
    service:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "10254"
···
    prometheusRule:
      enabled: true
      additionalLabels: {}
      namespace: "monitoring"
 ...     
     serviceMonitor:
      enabled: true
      additionalLabels: {}
      annotations: {}
      
#新增報警規則
...      
     prometheusRule:
      enabled: true
      additionalLabels:
        namespace: "monitoring"
      rules:
      # # These are just examples rules, please adapt them to your needs
        - alert: NGINXConfigFailed
          expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0
          for: 1s
          labels:
            severity: critical
          annotations:
....

預設情況下nginx-ingress的監控指標埠為10254,監控路徑為其下的/metrics。調整配置ingress-nginx的配置檔案,開啟service及pod的10254埠。

更新:

helm upgrade ingress-nginx ./ingress-nginx -f ./ingress-nginx/values.yaml  -n ingress-nginx

檢視驗證指標資料:

image-20241126145838100

2.2、手動新增serviceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
    name: ingress-nginx
    namespace: monitoring
spec:
  endpoints:
  - interval: 15s
    port: metrics
  namespaceSelector:
    matchNames:
    - ingress-nginx
  selector:
    matchLabels:
      app.kubernetes.io/component: controller
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/managed-by: Helm
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
      app.kubernetes.io/version: 1.11.1
      helm.sh/chart: ingress-nginx-4.11.1
      
# 在對應的ns中建立角色
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-k8s
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
  
  
  # 繫結角色 prometheus-k8s 角色到 Role
  ---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-k8s-ingress
subjects:
- kind: ServiceAccount
  name: prometheus-k8s
  namespace: monitoring
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus-k8s
驗證:
# kubectl get -n monitoring servicemonitors.monitoring.coreos.com 
NAME                      AGE
ingress-nginx             5d1h

image-20241126153215861

相關借鑑:prometheus-operator入門使用上篇之ServiceMonitor - 尹正傑 - 部落格園

Prometheus Operator自定義監控物件 -- Ingress-Nginx - 知乎

相關文章