Prometheus: моніторинг ендпоінтів в Kubernetes з blackbox-exporter

Автор |  10/12/2022
 

Про blackbox-exporter я вже колись писав, див. Prometheus: Alertmanager и blackbox-exporter – проверка срока действия SSL и нотификация в Slack, але там було чисто про моніторинг SSL-сертіфікатів, та й було то давно, та й сетапилось все без Кубернетісу та Хельму.

Цього разу трохи детальніше про його сетап і можливості.

Отже, blackbox-exporter – це експортер, який вміє моніторити різноманітні ендпоінти – це можуть бути або якісь URL-и в інтернеті, ваші LoadBalancer-и в Амазоні, або Services в Кубернетесі, такі як MySQL або PostgreSQL бази данних.

Вміє виводити статистику по швидкості відповіді HTTP, коди відповідей, інформацію по SSL-сертіфікатах тощо.

Що будемо робити:

  • за допомогую Helm розгорнемо kube-prometehus-stack в Minikube
  • додамо сам експортер
  • налаштуємо моніторинг ендпоінтів за допомогую ServiceMonitors, які будуть створені через конфіг blackbox-exporter
  • подивимось на основні probes, якими він опитує ендпоінти

Поїхали.

Запуск Kube Prometheus Stack

Робити будемо в мінікубі, куди встановимо Prometheus Operator із Helm-репозіторія.

Запускаємо сам Мінікуб:

[simterm]

$ minikube start

[/simterm]

Додаємо репозіторій чартів Prometheus:

[simterm]

$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update

[/simterm]

Створюємо неймспейс:

[simterm]

$ kubectl create ns monitoring

[/simterm]

Встановлюємо kube-prometheus-stack:

[simterm]

$ helm -n monitoring install prometheus prometheus-community/kube-prometheus-stack

[/simterm]

Чекаємо декілька хвилин, поки всі поди стануть Running:

[simterm]

$ kubectl -n monitoring get pod
NAME                                                     READY   STATUS            RESTARTS      AGE
alertmanager-prometheus-kube-prometheus-alertmanager-0   1/2     Running           1 (25s ago)   44s
prometheus-grafana-599dbccb79-zlklx                      2/3     Running           0             57s
prometheus-kube-prometheus-operator-689dd6679c-s66vp     1/1     Running           0             57s
prometheus-kube-state-metrics-6cfd96f4c8-84j26           1/1     Running           0             57s
prometheus-prometheus-kube-prometheus-prometheus-0       0/2     PodInitializing   0             44s
prometheus-prometheus-node-exporter-2h542                1/1     Running           0             57s

[/simterm]

Знаходимо Сервіс Прометеусу:

[simterm]

$ kubectl -n monitoring get svc
NAME                                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
alertmanager-operated                     ClusterIP   None             <none>        9093/TCP,9094/TCP,9094/UDP   7s
prometheus-grafana                        ClusterIP   10.97.79.182     <none>        80/TCP                       20s
prometheus-kube-prometheus-alertmanager   ClusterIP   10.106.147.39    <none>        9093/TCP                     20s
prometheus-kube-prometheus-operator       ClusterIP   10.98.222.45     <none>        443/TCP                      20s
prometheus-kube-prometheus-prometheus     ClusterIP   10.107.26.113    <none>        9090/TCP                     20s
...

[/simterm]

Прокидуємо порт через port-forward:

[simterm]

$ kubectl -n monitoring port-forward svc/prometheus-kube-prometheus-prometheus 9090:9090

[/simterm]

Відкриваємо http://localhost:9090, та перевіряємо, що все працює:

Запуск blackbox-exporter

Його чарт є в тому ж репозиторії, тож просто встановлюємо експортер:

[simterm]

$ helm -n monitoring upgrade --install prometheus-blackbox prometheus-community/prometheus-blackbox-exporter

[/simterm]

Перевіряємо под:

[simterm]

$ kk -n monitoring get pod
NAME                                                              READY   STATUS    RESTARTS        AGE
prometheus-blackbox-prometheus-blackbox-exporter-6865d9b44h546j   1/1     Running   0               27s
...

[/simterm]

Blackbox тримає свій конфіг в ConfigMap-і, яка підключається до поду і передає дефолтні параметри. Див. тут>>>.

[simterm]

$ kk -n monitoring get cm prometheus-blackbox-prometheus-blackbox-exporter -o yaml
apiVersion: v1
data:
  blackbox.yaml: |
    modules:
      http_2xx:
        http:
          follow_redirects: true
          preferred_ip_protocol: ip4
          valid_http_versions:
          - HTTP/1.1
          - HTTP/2.0
        prober: http
        timeout: 5s

[/simterm]

Власне, тут ми і бачимо модулі, точніше поки що один, який використвує prober http, який виконує HTTP-запроси до targets, які ще треба додати.

Blackbox та ServiceMonitor

Для того, щоб додати ендпоінти, котрі ми хочемо моніторити, можна використовувати ServiceMonitor, див. конфіг тут>>>.

Чомусь ніде в нагуглених гайдах цей момент толком не описаний, хоча він дуже зручний: в конфіг Блекбоксу додаємо список таргетів, а Блекбокс створює ServiceMonitor для кожного з них, і Prometheus починає їх моніторити.

Створюємо файл blackbox-exporter-values.yaml, в якому додаємо поки що один ендпоінт – просто перевірити, чи воно взагалі працює:

serviceMonitor:
  enabled: true
  defaults:
    labels:
      release: prometheus
  targets:
    - name: google.com
      url: https://google.com

Якщо не вказано інше, то Блекбокс використвує дефолтні значення із values.yaml чарту, в данному випадку це буде модуль http_2xx, який виконує GET запрос, та перевіряє код відповіді: якщо отримано 200 – то перевірка пройдена, якщо інший – то фейл.

Оновлюємо Helm-реліз з новим конфігом:

[simterm]

$ helm -n monitoring upgrade --install prometheus-blackbox prometheus-community/prometheus-blackbox-exporter -f blackbox-exporter-values.yaml

[/simterm]

Перевіряємо, чи створився ServiceMonitor

[simterm]

$ kk -n monitoring get servicemonitor
NAME                                                          AGE
prometheus-blackbox-prometheus-blackbox-exporter-google.com   4m43s

[/simterm]

Перевіряємо в Targets самого Прометеусу:

Для кожного Target, який ми вказуємо в конфігурації Блекбоксу, додається окрема scrape job в Прометеусі:

І перевіряємо метріки Блекбоксу:

Основна метрика, яку використую особисто я – це probe_success, яка власне говорить чи пройдена перевірка:

Тут в лейблу target через metricRelabelings підставляється значення з name, яке ми вказали для таргету Блекбокса, а в instance – його URL.

Моніторинг внутрішніх ендпоінтів

Чудово – ми сходили на Гугол, і він робить.

А як щодо перевірки ендпоінтів всередині кластеру?

Візьмемо приклад з nginx із документації Kubernetes, тільки задеплоїмо Под та Сервіс до власного неймпейсу, а не до default.

Створюємо неймспейс:

[simterm]

$ kk create ns test-ns
namespace/test-ns created

[/simterm]

Маніфест з подом та Сервісом, лише додаємо свій Namespace:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: test-ns
  labels:
    app.kubernetes.io/name: proxy
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: test-ns
spec:
  selector:
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: http-web-svc

Деплоїмо:

[simterm]

$ kk apply -f testpod-with-svc.yaml 
pod/nginx created
service/nginx-service created

[/simterm]

Перевіряємо:

[simterm]

$ kk -n test-ns get all
NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   0          23s

NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/nginx-service   ClusterIP   10.106.58.247   <none>        80/TCP    23s

[/simterm]

Оновлюємо конфіг Blackbox:

serviceMonitor:
  enabled: true
  defaults:
    labels:
      release: prometheus
  targets:
    - name: google.com
      url: https://google.com
    - name: nginx-test
      url: nginx-service.test-ns.svc.cluster.local:80

Оновлюємо сетап екпортеру:

[simterm]

$ helm -n monitoring upgrade --install prometheus-blackbox prometheus-community/prometheus-blackbox-exporter -f blackbox-exporter-values.yaml

[/simterm]

Перевіряємо СервісМонітори ще раз:

[simterm]

$ kk -n monitoring get servicemonitor
NAME                                                          AGE
prometheus-blackbox-prometheus-blackbox-exporter-google.com   12m
prometheus-blackbox-prometheus-blackbox-exporter-nginx-test   5s

[/simterm]

І за хвилину – можемо перевіряти probe_success:

Взагалі, не обов’язково вказувати повний URL у вигляді nginx-service.test-ns.svc.cluster.local – достатньо буде servicename.namespace, тобто nginx-service.test-ns, але повний URL як на мене виглядає більш наочно в лейблах та алертах.

Модулі Blackbox Exporter

Все виглядає чудово, поки ми опитуємо звичайний HTTP-ендпоінт, який завжди віддає код 200.

Що як треба перевірити інші коди?

Створимо власний модуль, використвуючи probes Блекбоксу:

config:
  modules:
    http_4xx:
      prober: http
      timeout: 5s
      http:
        method: GET
        valid_status_codes: [404, 405]
        valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
        follow_redirects: true
        preferred_ip_protocol: "ip4"
serviceMonitor:
  enabled: true
  defaults:
    labels:
      release: prometheus
  targets:
    - name: google.com
      url: https://google.com
    - name: nginx-test
      url: nginx-service.test-ns.svc.cluster.local:80
    - name: nginx-test-404
      url: nginx-service.test-ns.svc.cluster.local:80/404
      module: http_4xx

Тут в modules задаємо ім’я нового модуля – http_4xx, який пробер він має викорисовувати – http, і параметри для цього пробера – яким саме запитом перевіряємо, і які коди відповіді будемо вважати правильними.

Далі, в Таргетах для nginx-test-404 явно вказуємо використання модулю http_4xx.

Тестування модулів

Окремо подивимось як саме можемо перевірити – чи буде модуль працювати так, як ми розраховуємо.

Все просто – запускаємо тестовий под, і curl-ом з опцією -I дивимось на відповідь ендпоінта.

Якшо перевіряємо TCP-коннект – то telnet.

Отже, створюємо под з Убунтою, підключаємось до нього – запускаємо всередені bash:

[simterm]

$ kk -n monitoring run pod --rm -i --tty --image ubuntu -- bash

[/simterm]

Встановлюємо curl та telnet:

[simterm]

root@pod:/# apt update && apt -y install curl telnet

[/simterm]

Та дивимось – чи працє URL nginx-service.test-ns.svc.cluster.local:80/404:

[simterm]

root@pod:/# curl -I nginx-service.test-ns.svc.cluster.local:80/404
HTTP/1.1 404 Not Found

[/simterm]

404 – як ми і очікували.

Оновлюємо Блекбокс з новим конфігом:

[simterm]

$ helm -n monitoring upgrade --install prometheus-blackbox prometheus-community/prometheus-blackbox-exporter -f blackbox-exporter-values.yaml

[/simterm]

Перевіримо його ConfigMap – чи додався модуль http_4xx, який ми вказали в нашому файлу конфіга:

[simterm]

$ kk -n monitoring get cm prometheus-blackbox-prometheus-blackbox-exporter -o yaml
apiVersion: v1
data:
  blackbox.yaml: |
    modules:
      http_2xx:
        http:
          follow_redirects: true
          preferred_ip_protocol: ip4
          valid_http_versions:
          - HTTP/1.1
          - HTTP/2.0
        prober: http
        timeout: 5s
      http_4xx:
        http:
          follow_redirects: true
          method: GET
          preferred_ip_protocol: ip4
          valid_http_versions:
          - HTTP/1.1
          - HTTP/2.0
          valid_status_codes:
          - 404
          - 405
        prober: http
        timeout: 5s

[/simterm]

І перевіряємо Прометеус:

probe_success{target="nginx-test-404"} == 1 – все робить.

TCP Connect і моніторинг баз данних

Ще один модуль, котрий дуже часто використовуємо – TCP, який просто намагається відкрити TCP-сессію на вказанний URL та порт. Підходить для перевірок баз данних та будь-яких інших не-HTTP-ресурсів.

Запустимо MySQL:

[simterm]

$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install mysql bitnami/mysql

[/simterm]

Знаходимо його Сервіс:

[simterm]

$ kk get svc
NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes       ClusterIP   10.96.0.1      <none>        443/TCP    20h
mysql            ClusterIP   10.99.71.124   <none>        3306/TCP   40s
mysql-headless   ClusterIP   None           <none>        3306/TCP   40s

[/simterm]

Оновлюємо конфіг Blackbox:

config:
  modules:
    ...
    tcp_connect:
      prober: tcp
serviceMonitor:
  ...
  targets:
    ...
    - name: mysql
      url: mysql.default.svc.cluster.local:3306
      module: tcp_connect

Деплоїмо, і перевіряємо:

Prometheus alerting

За альортінг особливо писати й нема чого – все стандартно, як будь-які інші алерти Прометеусу.

Наприклад ми моніторимо Сервіси Apache Druid з таким алертом (скрін з конфігу Terraform з деякими змінними):

Просто перевіряємо, що probe_success != 1.

Посилання по темі