Prometheus: Alertmanager и blackbox-exporter – проверка срока действия SSL и нотификация в Slack

By | 07/27/2018
 

Основная задача – проверять SSL-сертификаты и уведомлять о том, что срок действия сертификата завершается.

Запуск blackbox-exporter

Все сервисы мониторинг запускаются из Compose-файла, который деплоится на хост мониторинга из Ansible-шаблона roles/monitoring/templates/prometheus-compose.yml.j2.

Добавляем туда ещё один контейнер:

...
  blackbox-exporter:
    image: prom/blackbox-exporter
    command: '--config.file=/config/blackbox.yml'
    # for debug
    #command: '--config.file=/config/blackbox.yml --log.level=debug'
    networks:
      - prometheus
    ports:
      - 9115:9115
    volumes:
      - {{ prometheus_configs_path }}/blackbox-exporter.yml:/config/blackbox.yml

Добавляем минимальный файл настроек blackbox-exporter-а –  roles/monitoring/templates/blackbox-exporter.yml.j2:

modules:
  icmp:
    prober: icmp
    timeout: 5s

  http_200_module:
    prober: http
    timeout: 5s
    http:

Обновляем конфиг самого Prometheus – файл roles/monitoring/templates/prometheus-server-conf.yml.j2:

...
  - job_name: 'blackbox'
    metrics_path: /probe
    params:
      module:
        - http_200_module
        - icmp
    static_configs:
      - targets:
        - http://rtfm.co.ua
        - https://rtfm.co.ua
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox-exporter:9115

Добавляем задачу копирования файла настроек blackbox-exporter на хост:

...
- name: "Copy blackbox-exporter config {{ prometheus_configs_path }}/blackbox-exporter.yml"
  template:
    src: templates/blackbox-exporter.yml.j2
    dest: "{{ prometheus_configs_path }}/blackbox-exporter.yml"
    owner: "{{ prometheus_user }}"
    group: "{{ prometheus_user }}"
...

Деплоим всё на хост мониторинга, проверяем blackbox:

SSL expire

Среди прочих метрик – blackbox возвращает метрику probe_ssl_earliest_cert_expiry, в которой указывается дата окончания действия сертификата в формате UNIX-time:

Можно воспользоваться конвертором https://www.epochconverter.com для проверки данных.

Используя его и функцию time() – можно создать правило, которое далее используем для отправки уведомлений о скором завершении срока действия сертификата, например – за 30 дней:

probe_ssl_earliest_cert_expiry{job="blackbox"} - time() < 86400 * 30

Alertmanager

Следующим шагом – добавим Alertmanager.

Обновляем Compose файл:

alertmanager:
  image: prom/alertmanager
  networks:
    - prometheus
  ports:
    - 9093:9093
  volumes:
    - {{ prometheus_configs_path }}/alertmanager_config.yml:/etc/alertmanager/config.yml
  command:
    - '--config.file=/etc/alertmanager/config.yml'

Добавляем интеграцию Slack. Описано тут>>>.

Создаём файл настроек Alertmanager roles/monitoring/templates/alertmanager_config.yml.j2 – описываем настройки отправки почты и Slack:

global:
  smtp_smarthost: 'mail.domain.tld:25'
  smtp_from: 'alert@domain.tld'
  smtp_auth_username: 'user'
  smtp_auth_password: 'pass'

route:
  repeat_interval: 1h
  receiver: default

receivers:
- name: 'default'
  email_configs:
  - to: 'alert@domain.tld'
  slack_configs:
  - api_url: https://hooks.slack.com/services/T16***ZAj
    title: ":scream: {% raw %}{{ .CommonAnnotations.summary }}{% endraw %}" 
    text: "{% raw %}{{ range .Alerts }}{{ .Annotations.description }}\n{{ end }}{% endraw %}"

В text циклом получаем description алертов.

{ % raw % } и {% endraw %} используем, что бы заэкранировать переменные шаблонизатора Prometheus.

Создаём файл roles/monitoring/templates/alert.rules.j2 с настройками алертов, пока только одно:

groups:
- name: ssl_expiry.rules
  rules:
  - alert: SSLCertExpiringSoon
    expr: probe_ssl_earliest_cert_expiry{job="blackbox"} - time() < 86400 * 30
    for: 10m
    annotations:
      summary: 'SSL expire alert'
      description: "SSL certificate for the {% raw %}{{ $labels.instance }}{% endraw %} will expire soon!"

$labels.instance будет содержать имя домена, для которого сработал алерт.

В задачи добавляем копирование обоих файлов:

...
- name: "Copy Alertmanager config {{ prometheus_configs_path }}/alertmanager_config.yml"
  template:
    src: templates/alertmanager_config.yml.j2
    dest: "{{ prometheus_configs_path }}/alertmanager_config.yml"
    owner: "{{ prometheus_user }}"
    group: "{{ prometheus_user }}"

- name: "Copy Alertmanager alert rules {{ prometheus_configs_path }}/alert.rules"
  template:
    src: templates/alert.rules.j2
    dest: "{{ prometheus_configs_path }}/alert.rules"
    owner: "{{ prometheus_user }}"
    group: "{{ prometheus_user }}"
...

Обновляем файл настроек Prometheus сервера – указываем URL Alertmanager-а, и файл с правилами алертов:

...
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - alertmanager:9093

rule_files:
  - "alert.rules"
...

Обновляем Compose – добавляем маппинг файла алертов:

...
  prometheus-server:
    image: prom/prometheus
    networks:
      - prometheus
    ports:
      - 9090:9090
    volumes:
      - {{ prometheus_configs_path }}/prometheus-server-conf.yml:/etc/prometheus.yml
      - {{ prometheus_configs_path }}/alert.ruls:/etc/alert.rules
      - {{ prometheus_data_path }}:/prometheus/data/
    command:
      - '--config.file=/etc/prometheus.yml'
      - '--web.external-url=https://{{ inventory_hostname }}/prometheus'
    restart: always
...

Деплоим, проверяем:

Готово.