Введение

Ни для кого не секрет, что на текущий момент регуляторы занимаются активным внедрением отечественных операционных систем на базе Linux/Unix в инфраструктуры государственных компаний. Это создает головную боль для рядовых пользователей, привыкших к интуитивно понятному интерфейсу Windows, работающих с соответствующими текстовыми редакторами и привычными за годы программами, а также для сетевых инженеров, годами работающих с Windows инфраструктурой. Перед ними стоят задачи миграции сервисов на другую ОС и, часто, обучение пользователей работе в новой среде.

Как правило, рано или поздно система приходит к равновесному состоянию: часть пользователей работает на рабочих станциях Windows, специалисты — на Unix-подобных операционных системах. Наша инфраструктура становится гетерогенной, и для её устойчивой работы важно обеспечить мониторинг.

В этой статье мы рассмотрим достоинства и недостатки популярных систем мониторинга, а также развернем их в гетерогенной среде Windows-Linux.

Немного теории

Что дает мониторинг?

1. Вовремя обнаружить проблемы

2. Оценить производительность серверов и хостов и не дать им "упасть"

3. Обнаружить аномальную активность и среагировать на попытки вторжения

4. Анализировать тренды и своевременно планировать оптимизацию хостов и сети

5. Подготовить отчеты и аналитику для руководства, чтобы аргументированно доказать необходимость в денежных инвестициях

Как и всегда выбор средства зависит от задач. Сравним систему Zabbix с Prometheus (для визуализации метрик будем использовать Graphana ).

Zabbix

Преимущества:

1. Полное решение из одного источника: Zabbix является комплексным решением, которое предлагает мониторинг, оповещения и построение отчетов в одной системе.

2. Готовность к использованию из коробки: Имеет множество предустановленных шаблонов и интеграций, что облегчает его настройку и развертывание.

3. Сбор данных в реальном времени: Поддерживает длинные задержки между запросами и может отслеживать данные в реальном времени.

4. Поддержка различных типов данных: Может работать с агентами для различных платформ, поддерживать SNMP, IPMI, JMX, и др.

5. Разветвлённая система оповещений: Поддержка различных каналов уведомлений и гибких условий срабатывания триггеров.

Недостатки:

1. Сложность настройки: Несмотря на наличие шаблонов, интеграции и адаптация для специфических нужд могут требовать значительных усилий.

2. Хранение данных: Использует реляционные БД для хранения данных, что в больших масштабах может требовать серьёзных ресурсов.

3. Масштабируемость: На больших объемах данных может возникнуть проблема масштабируемости и производительности.

Prometheus + Grafana

Через http запросы сервер собирает метрики с клиентов и экспортеров
Через http запросы сервер собирает метрики с клиентов и экспортеров

Преимущества:

1. Модульность и гибкость: Prometheus отвечает за сбор, хранение и обработку метрик, тогда как Grafana используется для их визуализации, обеспечивая гибкость в выборе инструментов.

2. Хорошая масштабируемость: Prometheus разработан для сбора метрик на больших и динамических системах, обеспечивая высокую производительность и масштабируемость.

3. Мощный язык запросов: PromQL позволяет выполнять сложные аналитические задачи и получать необходимую информацию из собранных метрик.

4. Интеграция с облачными сервисами: Поддержка для облаков и контейнерных сред, таких как Kubernetes.

5. Сообщество и экосистема: Большая экосистема и сильное сообщество разработчиков и пользователей.

Недостатки:

1. Кратковременное хранение данных: Преимущественно ориентирован на кратковременное хранение данных, хотя интеграция с внешними хранилищами позволяет решить эту проблему.

2. Отсутствие интегрированной системы оповещений: Хотя Prometheus включает механизм alertmanager, он меньше интегрирован по сравнению с Zabbix.

3. Сложность настройки и эксплуатации: Нужно настраивать и администрировать два или больше отдельных компонента (Prometheus и Grafana) плюс Alertmanager.

Практика

Последовательно развернем системы в соответствии с со схемами

Zabbix и его агенты
Zabbix и его агенты
Связка Prometheus и Grafana
Связка Prometheus и Grafana

Zabbix

Установить Zabbix сервер очень просто. На официальном сайте есть конфигуратор со всеми необходимыми командами с помощью которых можно подготовить Linux хост, подробно рассматривать этот вопрос не будем.

Конфигурация сервера

Если мы хотим автоматизировать процесс подключения агентов к серверу, группировать их по типу операционной системы и привязывать к конкретным шаблонам, то следует настроить авторегистрацию. Для этого проходим в:

Оповещение - действие - действие авторегистрации

Создать - имя - autoreg_linux
Условия - Метаданные узлов сети - содержит - Linux
Операции:

  1. Добавить узел сети

  2. Активировать узел сети

  3. Отправить сообщение пользователям: Admin через все способы оповещения

  4. Добавить в группы узлов сети: Station_linux

  5. Присоединить к шаблонам: Linux by Zabbix agent

Создать - имя - autoreg_windows
Условия - Метаданные узлов сети - содержит - Windows
Операции:

  1. Добавить узел сети

  2. Активировать узел сети

  3. Отправить сообщение пользователям: Admin через все способы оповещения

  4. Добавить в группы узлов сети: Station_Windows

  5. Присоединить к шаблонам: Windows by Zabbix agent

Не забываем заранее создать соответствующие группы.

Подготовка хостов - Linux

Установка в ручном режиме так же проста как сервера.

Давайте лучше рассмотрим, как произвести установку централизованно в автоматическом режиме. Я использую Puppet и Ansible для этих целей. Первый для поддержки долговременной инфраструктуры, где хосты не являются рабочими машинами и периодически могут быть недоступны, второй преимущественно для виртуальных хостов и серверов.

Почему так? Puppet использует агентов на хостах, периодически сверяющих конфигурацию системы с конфигурацией на сервере. Сверка происходит регулярно и рано или поздно все машины будут приведены к единообразию. Для Ansible же важно чтобы хост в текущий момент времени был включен и готов принять автономный пакет python который ему шлет сервер. Агентов у Ansibe нет, что является его преимуществом и одновременно недостатком в определенных случаях.

В нашем случаем используем Ansible и для работы мы должны создать 3 каталога со своей структурой:

  • инвентарь (как создавать подробно описал в статье)

  • роль

  • плейбук

Из особенностей укажем в глобальных переменных адрес сервера Zabbix. Заранее извиняюсь, если непривычно, но для компактности и без того длинной статьи укажу все команды и комментарии в кодовой строке в таком вот специфичном формате:

touch inventory/group_vars/all.yml
#>
---
zabbix_server_addr: 192.168.2.101
#<>

Роль

mkdir roles
# создание каталогов роли
ansible-galaxy role init roles/zabbix_agent

# редактируем:
roles/zabbix_agent/tasks/main.yml
#>
---
- name: Add repo Zabbix
  ansible.builtin.template:
    src: zabbix.list.j2
    dest: /etc/apt/sources.list.d/zabbix.list
    owner: root
    group: root
    mode: '0644'

- name: Add Zabbix GPG Key
  ansible.builtin.copy:
    src: zabbix-official-repo.gpg
    dest: /etc/apt/trusted.gpg.d/
    owner: root
    group: root
    mode: '0644'
  notify: Update_apt_cache

- name: Install Zabbix
  ansible.builtin.apt:
    name: zabbix-agent
    state: present

- name: Config Zabbix-agent
  ansible.builtin.template:
    src: zabbix_agentd.conf.j2
    dest: /etc/zabbix/zabbix_agentd.conf
    owner: zabbix
    group: zabbix
    mode: '0755'
  vars:
    current_hostname: "{{ ansible_facts.hostname }}"

- name: Ensure log directory exists
  ansible.builtin.file:
    path: /var/log/zabbix
    state: directory
    owner: zabbix
    group: zabbix
    mode: '0755'

- name: Start, autostart Zabbix-agent
  ansible.builtin.service:
    name: zabbix-agent
    state: restarted
    enabled: true

# --- тест службы
- name: Pause
  ansible.builtin.pause:
    seconds: 3
  tags: test

- name: Test service status
  ansible.builtin.systemd:
    name: zabbix-agent
    state: started
  register: service_status
  tags: test

- name: Message service fail
  ansible.builtin.fail:
    msg: "Служба не запущена!"
  when: service_status.status.ActiveState != 'active'

- name: Message service success
  ansible.builtin.debug:
    msg: "Служба запущена успешно!"
  when: service_status.status.ActiveState == 'active'

#<>

touch roles/zabbix_agent/templates/zabbix.list.j2
#>
# Generate for Ansible
{% for repo in zabbix_agent__repo %}
{{ repo }}
{% endfor %}
#<>

roles/zabbix_agent/defaults/main.yml
#>
---
zabbix_agent__repo:
  - deb https://repo.zabbix.com/zabbix/6.4/debian bookworm main
  - deb-src https://repo.zabbix.com/zabbix/6.4/debian bookworm main
#<>

# переносим ключ репозитория в роль
cp /etc/apt/trusted.gpg.d/zabbix-official-repo.gpg roles/zabbix_agent/files/

# обработчик
roles/zabbix_agent/handlers/main.yml
#>
---
# обновление кеша пакетного менеджера
- name: Update_apt_cache
  ansible.builtin.apt:
    update_cache: true
#<>

# шаблон конфига zabbix agent
touch roles/zabbix_agent/templates/zabbix_agentd.conf.j2
#>
# Generate for Ansible
PidFile=/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server={{ zabbix_server_addr }} 
ServerActive={{ zabbix_server_addr }}
Hostname={{ current_hostname }}
# Include=/etc/zabbix/zabbix_agentd.d/*.conf
HostMetadataItem=system.uname
#<>

Что делает роль:

  1. Подключает репозитории через шаблон и добавляет соответствующий ключ, который нужно загрузить заранее (он появится у вас при установке zabbix сервера)

  2. Устанавливает агента и конфигурирует также через шаблон jinja (в конфигурации агента строка HostMetadataItem=system.uname позволяет службе авторегистрации сервера понять с какой операционной системой ему работать)

  3. Проверяет что служба агента работает без ошибок.

Не забываем открыть порт 10050 на хосте и 10051 на сервере.

Плейбук

mkdir playbooks
touch playbooks/zabbix.yml
playbooks/zabbix.yml
#>
- name: Zabbix
  hosts: station
  roles:
    - zabbix_agent
#<>

После запуска плейбука указанные хосты появятся на нашем сервере подключатся к необходимым шаблонам.

Подготовка хостов - Windows

Качаем пакет msi с официального сайта, проверяем чтобы версия установщика совпадала с версией сервера. Распространять пакет удобнее всего через групповые политики домена Active Directory, подробно описывать не буду, так как это момент простой и материалов на эту тему много. Скажу лишь, что перед распространением наш пакет msi необходимо модифицировать с применением редактора Orca. Можно править и конфигурационной файл, но лично мне такой способ нравится больше.

Для этого в таблицу Property вводим строки со значениями:
SERVER = 192.168.2.101
SERVERACTIVE = 192.168.2.101
LISTENPORT = 30001

редактируем выделенные строки нашими значениями
редактируем выделенные строки нашими значениями

Не забываем что для авторегистрации на сервере нам нужно передать метаданные в конфигурационный файл агента, для этого готовим скрипт и организуем его запуск чрез групповые политики

Обновляем политики, убедимся что нужные порты открыты и идем на сервер

Станции успешно подключены
Станции успешно подключены

Prometheus + Grafana

Тут все немного сложнее, поскольку Prometheus предназначен больше для легковесного запуска в контейнерах, для запуска в качестве сервера мониторинга нам нужно создать службы для работы соответствующих исполняемых файлов, подключить необходимые компоненты для оповещений. Руками делать все это крайне долго, развернем сервер через Ansible с помощью роли

mkdir roles
# создание каталогов роли
ansible-galaxy role init roles/prometheus_server

# редактируем:
roles/prometheus_server/tasks/main.yml
#>
---
# Promrtheus
- name: Create Prometheus directory
  ansible.builtin.file:
    path: /etc/prometheus
    state: directory
    mode: '0755'

- name: Download Prometheus
  ansible.builtin.get_url:
    url: "{{ prometheus_server__url }}"
    dest: "{{ prometheus_server__archive_path }}"
    mode: '0644'
    force: no

- name: Extract Prometheus
  ansible.builtin.unarchive:
    src: "{{ prometheus_server__archive_path }}"
    dest: /tmp/
    remote_src: true

- name: Move Prometheus binaries
  ansible.builtin.copy:
    src: "{{ prometheus_server__extract_path }}/{{ item }}"
    dest: /usr/local/bin/
    mode: '0755'
    remote_src: true
  with_items:
    - prometheus
    - promtool

- name: Move Prometheus configs
  ansible.builtin.copy:
    src: "{{ prometheus_server__extract_path }}/{{ item }}"
    dest: /etc/prometheus/
    remote_src: true
    mode: '0644'
  with_items:
    - consoles
    - console_libraries

- name: Create Prometheus user
  ansible.builtin.user:
    name: prometheus
    shell: /bin/false

- name: Change ownership of Prometheus directories
  ansible.builtin.file:
    path: /etc/prometheus
    owner: prometheus
    group: prometheus
    recurse: true

- name: Create Prometheus directory
  ansible.builtin.file:
    path: /var/lib/prometheus/
    state: directory
    mode: '0755'
    owner: prometheus
    group: prometheus

# Alertmanager
- name: Create configuration directory Alertmanager
  ansible.builtin.file:
    path: /etc/alertmanager
    state: directory
    mode: '0755'

- name: Download Alertmanager
  ansible.builtin.get_url:
    url: "{{ prometheus_server__alertmanager_url }}"
    dest: "{{ prometheus_server__alertmanager_archive_path }}"
    mode: '0644'

- name: Extract Alertmanager
  ansible.builtin.unarchive:
    src: "{{ prometheus_server__alertmanager_archive_path }}"
    dest: /tmp/
    remote_src: true

- name: Move Alertmanager binaries
  ansible.builtin.copy:
    src: "{{ prometheus_server__alertmanager_extract_path }}/{{ item }}"
    dest: /usr/local/bin/
    mode: '0755'
    remote_src: true
  with_items:
    - alertmanager
    - amtool

- name: Create Alertmanager user
  ansible.builtin.user:
    name: alertmanager
    shell: /bin/false

- name: Change ownership of Alertmanager directories
  ansible.builtin.file:
    path: /etc/alertmanager
    owner: alertmanager
    group: alertmanager
    recurse: true

- name: Create Alertmanager directory
  ansible.builtin.file:
    path: /var/lib/alertmanager/
    state: directory
    mode: '0755'
    owner: alertmanager
    group: alertmanager

# config files 
- name: Deploy config alert_rules
  ansible.builtin.copy:
    src: "files/{{ item }}"
    dest: /etc/prometheus/
    owner: prometheus
    group: prometheus
    mode: '0644'
  with_items:
    - alert_rules.yml

- name: Deploy config prometheus
  ansible.builtin.template:
    src: "prometheus.yml.j2"
    dest: /etc/prometheus/prometheus.yml
    owner: prometheus
    group: prometheus
    mode: '0644'

- name: Deploy config alertmanager
  ansible.builtin.template:
    src: "alertmanager.yml.j2"
    dest: /etc/alertmanager/alertmanager.yml
    owner: alertmanager
    group: alertmanager
    mode: '0644'

# service
- name: Template Prometheus service
  ansible.builtin.template:
    src: templates/prometheus.service.j2
    dest: /etc/systemd/system/prometheus.service
    mode: '0644'

- name: Template Alertmanager service
  ansible.builtin.template:
    src: templates/alertmanager.service.j2
    dest: /etc/systemd/system/alertmanager.service
    mode: '0644'

- name: Reload systemd
  ansible.builtin.systemd:
    daemon_reload: true

- name: Enable and restart Prometheus service
  ansible.builtin.systemd:
    name: prometheus
    enabled: true
    state: restarted

- name: Enable and restart Alertmanager service
  ansible.builtin.systemd:
    name: alertmanager
    enabled: true
    state: restarted

# --- tests
- name: Pause
  ansible.builtin.pause:
    seconds: 3
  tags: test

- name: Test service status prometheus
  ansible.builtin.systemd:
    name: prometheus
    state: started
  register: service_status_prometheus
  tags: test

- name: Test service status alertmanager
  ansible.builtin.systemd:
    name: alertmanager
    state: started
  register: service_status_alertmanager
  tags: test

- name: Message service fail prometheus
  ansible.builtin.fail:
    msg: "Служба не запущена! - prometheus"
  when: service_status_prometheus.status.ActiveState != 'active'

- name: Message service fail alertmanager
  ansible.builtin.fail:
    msg: "Служба не запущена! - alertmanager"
  when: service_status_alertmanager.status.ActiveState != 'active'

- name: Message service success prometheus
  ansible.builtin.debug:
    msg: "Служба запущена успешно! - prometheus"
  when: service_status_prometheus.status.ActiveState == 'active'

- name: Message service success alertmanager
  ansible.builtin.debug:
    msg: "Служба запущена успешно! - alertmanager"
  when: service_status_prometheus.status.ActiveState == 'active'
#<>

# создаем шаблоны служб и конфигурационных файлов prometheus и alertmanager
roles/prometheus_server/templates/alertmanager.service.j2
#>
[Unit]
Description=AlertManager Service
After=network.target

[Service]
User=alertmanager
ExecStart=/usr/local/bin/alertmanager \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/var/lib/alertmanager

Restart=always

[Install]
WantedBy=multi-user.target
#<>

roles/prometheus_server/templates/alertmanager.yml.j2
#>
   route:
     group_by: ['alertname', 'instance', 'severity']
     group_wait: 20s
     group_interval: 20s
     repeat_interval: 12h
     receiver: 'telepush'
   
   receivers:
     - name: 'telepush'
       webhook_configs:
         - url: '{{ prometheus_server__url_telepush }}'
           http_config: {}  
   
   inhibit_rules:
     - source_match:
         severity: 'critical'
       target_match:
         severity: 'warning'
       equal: ['alertname', 'dev', 'instance']
#<>

roles/prometheus_server/templates/prometheus.service.j2
#>
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus/ 

[Install]
WantedBy=multi-user.target
#<>

roles/prometheus_server/templates/prometheus.yml.j2
#>
global:
  scrape_interval: 20s
  evaluation_interval: 10s

rule_files:
  - alert_rules.yml
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - localhost:9093

# server
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

# --- lup
  - job_name: 'linux'
    static_configs:
      - targets: ['192.168.2.101:9100']
      - targets: ['192.168.2.103:9100']

# windows
  - job_name: 'windows'
    static_configs:
      - targets: ['192.168.2.100:9182']
      - targets: ['192.168.2.102:9182']
#<>

# внутренние переменные роли для создания ссылок для скачивания и директорий размещени файлов
roles/prometheus_server/vars/main.yml
#>
---
prometheus_server__url: "{{ prometheus_server__repo }}/v{{ prometheus_server__version }}/prometheus-{{ prometheus_server__version }}.linux-amd64.tar.gz"
prometheus_server__repo: "https://github.com/prometheus/prometheus/releases/download"
prometheus_server__archive_path: "/tmp/prometheus-{{ prometheus_server__version }}.linux-amd64.tar.gz"
prometheus_server__extract_path: "/tmp/prometheus-{{ prometheus_server__version }}.linux-amd64"

prometheus_server__alertmanager_url: "https://github.com/prometheus/alertmanager/releases/download/{{ prometheus_server__alertmanager_filename }}.tar.gz"
prometheus_server__alertmanager_filename: "v{{ prometheus_server__alertmanager_version }}/alertmanager-{{ prometheus_server__alertmanager_version }}.linux-amd64"
prometheus_server__alertmanager_archive_path: "/tmp/alertmanager-{{ prometheus_server__alertmanager_version }}.linux-amd64.tar.gz"
prometheus_server__alertmanager_extract_path: "/tmp/alertmanager-{{ prometheus_server__alertmanager_version }}.linux-amd64"
#<>

# обработчик для обновления кеша пакетного менеджера
roles/prometheus_server/handlers/main.yml
#>
---
- name: Update_apt_cache
  ansible.builtin.apt:
    update_cache: true
#<>

# конфиг с правилами алертменеджера разместил в директрии files из за ошибок при работе с шаблонами (нужно экранировать определенные символы, решил не мучать себя этим, тем более переменных не передаю)
roles/prometheus_server/files/alert_rules.yml
#>
groups:
  - name: Critical alerts  
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute.'
          summary: Instance {{ $labels.instance }} down
#<>

# ну и в дефолте разместил переменные которые можно переопределить при запуске плейбуков
roles/prometheus_server/defaults/main.yml
#>
---
prometheus_server__version: "2.54.0"
prometheus_server__alertmanager_version: "0.27.0"
#<>

В моем случае оповещение работает через телеграмм, поэтому добавляем в инвентарь файл sinventory/secrets.yml с переменной "prometheus_server__url_telepush" c url для связи с телеграмм ботом telepush. Не забываем шифровать данный файл с помощью Ansible Vailt. Как это делать, можно подсмотреть тут.

Оповещения о работе хостов в моем случае выглядят так.

Настройка станций Linux

Для настройки станций нужна роль, создающая службы для работы исполняемых файлов и устанавливающая Node Exporter

mkdir roles
# создание каталогов роли
ansible-galaxy role init roles/prometheus_nodeexporter

# редактируем:
roles/prometheus_nodeexporter/tasks/main.yml
#>
- name: Skip
  when: ansible_os_family != 'Debian'
  block:
    - name: Message
      ansible.builtin.debug:
        msg: "Skipping tasks ."

- name: Install Node Exporter
  when: ansible_os_family == 'Debian'
  block:
    - name: Download Node Exporter
      ansible.builtin.get_url:
        url: "{{ prometheus_nodeexporter_url }}"
        dest: "/tmp/node_exporter.tar.gz"
        mode: '0644'

    - name: Extract Node Exporter
      ansible.builtin.unarchive:
        src: "/tmp/node_exporter.tar.gz"
        dest: "/usr/local/bin"
        remote_src: true

    - name: Move Node Exporter binaries
      ansible.builtin.copy:
        src: /usr/local/bin/node_exporter-{{ prometheus_nodeexporter__exporter_version }}.linux-amd64/node_exporter
        dest: /usr/local/bin/node_exporter
        owner: root
        group: root
        mode: '0755'
        remote_src: true

    - name: Template service
      ansible.builtin.template:
        src: node_exporter.service.j2
        dest: /etc/systemd/system/node_exporter.service
        mode: '0644'

    - name: Reload systemd
      ansible.builtin.systemd:
        daemon_reload: true

    - name: Enable and start Node Exporter service
      ansible.builtin.systemd:
        name: node_exporter
        enabled: true
        state: restarted

    - name: Clean up
      ansible.builtin.file:
        path: /tmp/node_exporter.tar.gz
        state: absent

    # --- тест службы
    - name: Pause
      ansible.builtin.pause:
        seconds: 3
      tags: test

    - name: Test service status
      ansible.builtin.systemd:
        name: node_exporter
        state: started
      register: service_status
      tags: test

    - name: Message service fail
      ansible.builtin.fail:
        msg: "Служба не запущена!"
      when: service_status.status.ActiveState != 'active'

    - name: Message service success
      ansible.builtin.debug:
        msg: "Служба запущена успешно!"
      when: service_status.status.ActiveState == 'active'
#<>

roles/prometheus_nodeexporter/templates/node_exporter.service.j2
#>
[Unit]
Description=Node Exporter

[Service]
User=nobody
ExecStart=/usr/local/bin/node_exporter

[Install]
WantedBy=default.target
#<>

roles/prometheus_nodeexporter/vars/main.yml
#>
---
prometheus_nodeexporter_url: "https://github.com/prometheus/node_exporter/releases/latest/download/{{ prometheus_nodeexporter_file }}"
prometheus_nodeexporter_file: "node_exporter-{{ prometheus_nodeexporter__exporter_version }}.linux-amd64.tar.gz"
#<>

roles/prometheus_nodeexporter/files/prometheus.yml
#>
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
#<>

roles/prometheus_nodeexporter/defaults/main.yml
#>
---
prometheus_nodeexporter__exporter_version: "1.8.2"
#<>

Настройка станций Windows

Просто качаем msi последнего Windows Exporter с github и устанавливаем через GPO.

Не забываем открыть порт 9182 на Windows станциях через gpo. Можно для теста сделать это командой PowerShell.

New-NetFirewallRule -DisplayName "Allow Port 9182" -Direction Inbound -Protocol TCP -LocalPort 9182 -Action Allow

Graphana

Ставится просто через пакет с официального сайта.

sudo apt-get install -y apt-transport-https software-properties-common wget
wget https://dl.grafana.com/oss/release/grafana_8.4.2_amd64.deb
sudo dpkg -i grafana_8.4.2_amd64.deb
sudo systemctl enable grafana-server; systemctl start grafana-server
sudo apt --fix-broken install
sudo ufw allow 3000/tcp

Заходим в http://localhost:3000

Логин и пароль по умолчанию в Grafana: **admin : admin**

Для подключения Prometheus ищем в консоли Grafana - Connections - Data sources - Add data source - Prometheus - http://localhost:9090 - Save & Test

Как язык запросов PromQL (Prometheus Query Language) тут писать не буду, но он крайне мощный. Это точно тема отдельной статьи.

Поэтом просто импортируем дашборд из библиотеки:

Dashboard - Import dashbord - Data Source: Prometheus

Для Windows мне понравился - id 20763

Для Linux - id 11074

В нашем случае полезно будет в перспективе модифицировать дашборд из готовых, сделав источником не только Node Exporter, но и Windows Exporter, чтобы наблюдать за всеми станциями разом.

Prometheus и приложения

Отдельно хочу отметить что prometheus имеет множество клиентских библиотек. Например в приложении, разработанном мной на Python для инвентарного учета технических средств

я собираю такие вот метрики:

Такого мониторинга мне достаточно для отслеживания активности пользователей. Какие объекты в каком объеме создаются, ошибки авторизации и активность пользователей.
Такого мониторинга мне достаточно для отслеживания активности пользователей. Какие объекты в каком объеме создаются, ошибки авторизации и активность пользователей.

Выводы

Обе системы мониторинга имеют свои преимущества и недостатки, "идеального" решения как всегда нет.


Zabbix - комплексное решение с мощной системой оповещения и поддержкой множества стандартов из коробки, но менее гибок в работе с метриками.

Prometheus - обладает отличной масштабируемостью, гибок, удобен для контейнерных или облачных технологий, а также приложений, однако сложнее в настройке.

Комментарии (25)


  1. ky0
    24.10.2024 15:14

    TLDR:

    Часто появляются и исчезают сущности? -- нет --> Zabbix
    |
    да
    |
    V
    Не Zabbix


    1. Dron_Ch Автор
      24.10.2024 15:14

      Именно так


  1. saboteur_kiev
    24.10.2024 15:14

    Почему нельзя испоьзовать Zabbix с Графаной?
    Графана не часть прометеуса и отлично живет без него


    1. j_larkin
      24.10.2024 15:14

      Да и с заббиксом прекрасно дружит


    1. Dron_Ch Автор
      24.10.2024 15:14

      Так как целью статьи было сравнить prometheus и zabbix в контексте минимальной работоспособности и Zabbix уже имеет встроенную систему визуализацию дашбордов, в данном примере мы к нему не подключаем Grafana. А так да, подключить можно без проблем.


      1. saboteur_kiev
        24.10.2024 15:14

        Так прометеус вроде тоже имеет простенькую систему визуализации дашбордов, в этом плане тогда минимально можно пробовать без графаны вообще?

        А в целом, мне прометеус не нравится по трем причинам. Во-первых изначальная архитектура усложнена и не слишком гибка. Точнее гибкость есть, но она обеспечивается сложнее, чем в других мониторинговых системах.
        Популярность прометеуса достигнута была в осномном тем, что он из коробки работает с некоторыми популярными наборами метрик, в результате многие просто по инструкции его ставят в виде next-next-completed, но не понимают ни что под капотом ни как оно работает ни как его кастомайзить. А кастомайзить его сложнее, чем другие мониторинговые системы...

        К сожалению, мой опыт работы с прометеусом в основном на уровне proof of concept, поэтоум я могу сильно ошибаться, и ищу статьи где наглядно бы подтвердили или опровергли мое мнение.


        1. NekoYos
          24.10.2024 15:14

          Комплексно реализованный прометей+графана+алертменеджер на практике оказался более гибким чем заббикс. Можно и заббикс с графаной реализовать, но как будет оно работь с тоной метрик по сравнении с прометеем? Хотя в таких случаях еще лучше будет victoriametrics


          1. Dron_Ch Автор
            24.10.2024 15:14

            Мне нравится что он легковеснее, меньше ресурсов ест


          1. saboteur_kiev
            24.10.2024 15:14

            А без заббикса и без прометея?
            У меня так работает достаточно неплохо


            1. NekoYos
              24.10.2024 15:14

              А метрики куда собираются?


              1. saboteur_kiev
                24.10.2024 15:14

                В инфлюкс. Графана с инфлюксом, и для метрик отлично. Приложение само кидает метрики в инфлюкс, что умеет делать благодаря библиотеке micrometers, никаких лишних прослоек.


  1. Dron_Ch Автор
    24.10.2024 15:14

    .


  1. AlexGluck
    24.10.2024 15:14

    А почему не заббикс+Виктория-Метрикс?

    Графана сверху закрывает вопрос визуализации.


  1. nakamura
    24.10.2024 15:14

    Мудохался собрать конфиг с Fortigate генератором для Grafana , нажал один раз apt-update, все слетело.


  1. PrinceKorwin
    24.10.2024 15:14

    А что можете посоветовать для мониторинга небольшого решения: одна БД (postgresql), nginx, и с пяток запущенных процессов (даже не докер)?

    Все крутится на дохлой vps с 1Гб оперативке.

    Есть какое-то не жрущее и простое решение для мониторинга подобных небольших инсталляций?


    1. Dron_Ch Автор
      24.10.2024 15:14

      Prometheus как раз и подойдет, мониторить службы будет удобно


    1. saboteur_kiev
      24.10.2024 15:14

      заббикс, mmonit, sensu, grafana и пару скриптов. Все зависит от того, насколько вы скриптописатель, разработчик и с какой системой работали.

      Графана стала практически де-факто визуализатором разных метрик, но она может брать данные из любой базы. Вроде для постгреса бесплатный коннектор даже.
      Наполнять данные для графаны надо чем-то, тут разные есть варианты, начиная от банальных шелл/перл/питон скриптов, и вплоть до прямого обращенгия приложения в базу. Мониторинг вообще такое общее слово, что без детализации можно сотни предположений делать


    1. ThingCrimson
      24.10.2024 15:14

      Возможно Вам подойдёт Munin? Достаточно простое клиент-серверное решение; мало жрущее; хранение и визуализация на RRD построена. Я для дома и небольших инсталляций таким пользуюсь лет 15, доволен.


  1. Belkau77
    24.10.2024 15:14

    Полезная тема и статья, плюсую.
    Технические спецификации и код можно было бы вынести в drop-down чтобы было не так тяжело листать (из оформительского).
    но в целом все гуд


    1. Dron_Ch Автор
      24.10.2024 15:14

      спасибо, учту


  1. 321785
    24.10.2024 15:14

    Для таких как вы поясню, единственно интуитивно понятный для человека интерфейс - это женская грудь, и при этом всё равно часто случаются сбои. Всему остальному НАДО учиться.


  1. PetyaUmniy
    24.10.2024 15:14

    Кратковременное хранение данных

    Странное заявление. У prometheus плотность хранения примерно 1-2 байта на семпл. А у zabbix сколько? Сдается мне что значительно хуже.
    Касательно downsampling - в некотором роде справедливо. Но так же справедливо считать thanos, где он есть, вариантом prometheus.

    Нужно настраивать и администрировать два или больше отдельных компонента (Prometheus и Grafana) плюс Alertmanager

    Вы так же упустили максимально близкий к zabbix случай, когда нет alertmanager. А алерты конфигурируются не в коде prometheus, а навозюкиваются мышкой в grafana. Что может быть проще для новичков. Уверен в grafana тоже достаточно много интеграций.
    А еще prometheus способен работать в режиме agent mode (и даже в отличии от zabbix докачивать 2 часа метрик после падения связи), и в таком случае не требуются отталкивающее многих в небольших инсталяциях централизованное динамическое SD. Я, например, поступаю именно так. У меня не слишком много инстансов (примерно 200) и они находятся в паре десятков не связанных сетей за NAT. Просто раскладываю с помощью ansible prometheus agent (45Mb RSS) на каждый инстанс и делаю везде одинаковый (за исключением лейблов инстанса) статический конфиг с remote write и docker SD. А там уж какие контейнеры были подняты на хосте - то и "скребется".


    1. Dron_Ch Автор
      24.10.2024 15:14

      То есть Prometheus на инстансах создают изолированные базы метрик и высылают их корневому серверу в http запросах?


      1. PetyaUmniy
        24.10.2024 15:14

        Да. Плюс минус так.
        Как я понимаю создается неполноценный инстанс tsdb в котором не работает compaction и в котором данные удаляются после успешной доставки.


  1. Dron_Ch Автор
    24.10.2024 15:14

    .