Архив автора: admin

Мониторинг журнала контейнеров на основе Graylog

Docker log




Когда контейнер запускается, он фактически является подпроцессом docker deamon. Docker daemon может получить стандартный вывод процесса в контейнере, а затем обработать его через собственный модуль LogDriver. LogDriver поддерживает множество способов и по умолчанию записывает в локальные файлы. Его также можно отправить в системный журнал и т. Д.







Docker по умолчанию соберет стандартный вывод приложения в файл json.log и построчно сохранит данные в формате JSON. Формат файла следующий:




{"log":"root@74205cdc7b53dd:/#lsrn","stream":"stdout","time":"xxx.155834526Z"}{"log":"root@74205cdc7b53dd:/#lsrn","stream":"stdout","time":"xxx.255834528Z"}




Этот метод хранения журналов в Docker можно настроить, указав драйвер журнала при запуске контейнера. Поддерживаются следующие драйверы журнала:







Управление журналом Graylog




Graylog — это инструмент управления полными журналами с открытым исходным кодом с функциями, аналогичными ELK. Docker изначально поддерживает протокол graylog, а Graylog также официально поддерживает Docker, которые могут быть легко соединены. Graylog официально предоставляет Dockerfile для развертывания системы ведения журнала в Docker, а также предоставляет файл docker-compose.yml для быстрого развертывания всего стека Graylog.
Подробное содержимое можно просмотреть по адресу http://docs.graylog.org/en/3.1/pages/installation/docker.html.







Развертывание Graylog




1. Создайте каталог graylog в текущем каталоге пользователя в качестве рабочего каталога для развертывания:




$ mkdir graylog

$ cd graylog




2. Инициализируйте каталог и файлы конфигурации




$ mkdir -p ./graylog/config

$ cd ./graylog/config

$ wget https://raw.githubusercontent.com/Graylog2/graylog-docker/3.1/config/graylog.conf

$ wget https://raw.githubusercontent.com/Graylog2/graylog-docker/3.1/config/log4j2.xml

 

 # Кроме того, поскольку Graylog определяет пользователей и группы пользователей с идентификатором 1100,

 # Причина Graylog может сообщить о недостаточных разрешениях ошибки каталога конфигурации при запуске, которая может быть решена с помощью следующей команды

chown -R 1100:1100 ./graylog/config




3. Измените файл конфигурации. Файл graylog.conf, полученный на предыдущем шаге, является конфигурацией по умолчанию, предоставленной официальным лицом. Пользователи могут конфигурировать в соответствии со своими потребностями. Например, часовой пояс в конфигурации по умолчанию — часовой пояс UTC, который можно изменить на часовой пояс Китая




root_timezone = Asia/Shanghai




4. Подготовьте файл docker-compose.yml




version: '3'

services:

  # MongoDB: https://hub.docker.com/_/mongo/

  mongo:

    image: mongo:3

    networks:

      - graylog

    volumes:

      - mongo_data:/data/db

  # Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/6.x/docker.html

  elasticsearch:

    image: docker.elastic.co/elasticsearch/elasticsearch:7.5.0

    volumes:

      - es_data:/usr/share/elasticsearch/data

    environment:

      - http.host=0.0.0.0

      - transport.host=localhost

      - network.host=0.0.0.0

      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"

    ulimits:

      memlock:

        soft: -1

        hard: -1

    deploy:

      resources:

        limits:

          memory: 1g

    networks:

      - graylog

  # Graylog: https://hub.docker.com/r/graylog/graylog/

  graylog:

    image: graylog/graylog:3.1

    volumes:

      - graylog_journal:/usr/share/graylog/data/journal

      - ./graylog/config:/usr/share/graylog/data/config

    environment:

      # CHANGE ME (must be at least 16 characters)!

      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper

      # Password: admin

      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918

      - GRAYLOG_HTTP_EXTERNAL_URI=http://192.168.0.103:9000/

    networks:

      - graylog

    depends_on:

      - mongo

      - elasticsearch

    ports:

      # Graylog web interface and REST API

      - 9000:9000

      # Syslog TCP

      - 1514:1514

      # Syslog UDP

      - 1514:1514/udp

      # GELF TCP

      - 12201:12201

      # GELF UDP

      - 12201:12201/udp

networks:

  graylog:

    driver: bridge

# Volumes for persisting data, see https://docs.docker.com/engine/admin/volumes/volumes/

volumes:

  mongo_data:

    driver: local

  es_data:

    driver: local

  graylog_journal:

    driver: local




5. Запустите «docker-compose up», чтобы запустить службу. После того, как служба запустится нормально, вы можете получить доступ к веб-интерфейсу graylog через http: // ip: 9000. Пользователь по умолчанию — admin / admin.




img




Коллекция журналов конфигурации Graylog




Сбор журналов Graylog осуществляется путем определения входных данных. Вы можете выбрать вход для сбора журналов на вкладке Система на странице веб-управления Graylog.







После входа на страницу ввода выберите тип ввода, такой как определение ввода GELF UDP:







После завершения выбора нажмите «Lanch new input», чтобы ввести подробную конфигурацию ввода, а после ее завершения сохраните.







Если после сохранения все в порядке, вход перейдет в состояние RUNNING, а затем вы сможете отправить данные на этот вход. Нажмите «Stop input», вход остановится, прием данных прекратится, и «Stop input» станет «Начать ввод», нажмите «Пуск», когда вам нужно принять данные.







Настройте Docker-контейнер для отправки данных в Graylog




При настройке контейнера Docker для отправки данных в Graylog, вы можете добавить следующие параметры при запуске команды docker run для запуска контейнера:




docker run --log-driver=gelf 

 --log-opt gelf-address = udp: // адрес серого журнала: 12201 

 --log-opt tag = <текущий тег службы контейнера, используемый для классификации при запросах graylog> 

<IMAGE> <COMMAND>




Конкретные примеры:




docker run -d 

--log-driver=gelf 

--log-opt gelf-address=udp://localhost:12201 

--log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}" 

busybox sh -c 'while true; do echo "Graylog test message"; sleep 10; done;'




Если контейнер запускается командой docker-compose, вы можете добавить следующую конфигурацию в файл docker-compose.yml:




logging:

  driver:"gelf"

  options:

    GELF-адрес: "UDP: // адрес серого журнала: 12201"

         тег: «Контейнерный сервисный тег»




Конкретные примеры:




version: '2'

services:

  nginx:

    image: nginx:latest

    ports:

      - "80:80"

    logging:

      driver: "gelf"

      options:

        gelf-address: "udp://localhost:12201"

        tag: nginx-service




После настройки отправки журнала вы можете искать информацию журнала на вкладке Поиск







Источник: https://russianblogs.com/article/1206672753/



Конфигурация карты мира Graylog

В процессе использования graylog для сбора журналов нетрудно обнаружить, что существует «Карта мира», показывающая географическое местоположение. Если вы просто нажмете на позицию на картинке ниже, 99% не покажет вам нужную карту, и появится красное сообщение об ошибке (оставшиеся 1% на самом деле не будут успешными ^). Так как же открыть эту «карту мира»? Следующее содержание этой статьи будет представлено подробно.




Настроить геолокацию








Скачать базы данных MaxMind City
GeoIP2 City DatabaseиGeoLite2 City DatabaseВы можете выбрать одну загрузку, эту загрузкуGeoLite2 CityБаза данных, как показано ниже:







Настройте базу данных
1. Разархивируйте загруженный сжатый пакет.
2. В зависимости от способа установки изменитеGeoLite2-City.mmdbПоместите файл в нужное место. Я установил Graylog в форме RPM. Нажмите «Система-> Конфигурации» в веб-интерфейсе Graylog. Вы можете увидеть размещение файлов по умолчанию, как показано ниже:







Следовательно,GeoLite2-City.mmdbПоложить в/etc/graylog/server/Под каталогом.




3. Обновить процессор географического местоположения. Нажмите «Система-> Конфигурации» в веб-интерфейсе graylog и нажмите кнопку «Обновить» на рисунке ниже:





Установите флажок Включить, проверьте размещение файлов и нажмите кнопку «Сохранить», чтобы сохранить конфигурацию.







Настройте процессоры GeoIP Resolver
Нажмите кнопку «Обновить», чтобы обновить конфигурацию:







Переместите строку GeoIP Resolver, установите в качестве последнего обработчика сообщений распознаватель GeoIP, включите GeoIP Resolver и нажмите кнопку «Сохранить», чтобы сохранить настройки:







тест
На этом этапе настройка завершена. Graylog начнет искатьСодержит только Поле адреса IPv4 или IPv6 и извлечение его географического местоположения в<field>_geolocationПоле. Короче если у вас есть полеfield1Если содержимое является только IP-адресом, graylog сохранит географическое местоположение на основе IP-адреса этого поля.field1_geolocationДюйм




Давайте проверим это ниже:
1. Нажмите «System-> Inputs», чтобы создать ввод типа Raw / Plaintext TCP.










2. Отправьте тестовое сообщение.




[vagrant@graylogTest1 graylog]$ nc -w2 192.168.2.124 5555 <<< '8.8.8.8'




Вы можете увидеть эффект, показанный на следующем рисунке:







Поле сообщения на рисунке выше содержит только IP-адрес, и затем Graylog будет расширен в соответствии с этим IP-адресом.message_city_namemessage_country_code、 message_geolocationТри поля




Если ваш IP-адрес не существует один в каком-либо поле, вы можете использовать Extractor для извлечения IP-адреса для сохранения в виде поля, а затем Graylog может определить географическое местоположение. Как показано на рисунке ниже, поле сообщения содержит адрес 9.9.9.9. В это время можно извлечь Extractor для извлечения.







Создать Extractor для извлечения IP
Формат адреса ip относительно фиксирован. Мы можем использовать шаблон Grok для сопоставления. Шаблон Grok уже имеет существующие правила сопоставления ip, поэтому нам не нужно писать регулярно.











После завершения, когда мы получаем вышеуказанное сообщение, эффект выглядит следующим образом:







Показать карту








Когда это появляется<field>_geolocationПосле поля нажмите на поле «Карта мира», чтобы увидеть местоположение на карте.










Graylog официальная документацияGeolocationДля подробного ознакомления эта статья является только записью процесса настройки, которая следует за официальной документацией, только для справки.







Источник: https://russianblogs.com/article/5030359514/



2021-08-16T16:00:33
Software

Руководство по настройке установки Graylog

I. Введение в соответствующие компоненты платформы Garylog




  • Graylog-сервер: Graylog получает журналы от различных внутренних приложений и предоставляет интерфейс веб-доступа
  • Graylog Collector Sidecar: отвечает за сбор журналов приложений и отправку их на Graylog-сервер
  • Elasticsearch: используется для индексации и сохранения полученных журналов, производительность зависит от памяти и ввода-вывода жесткого диска
  • MongoDB: отвечает за сохранение информации о конфигурации Graylog, нагрузка не высокая
  • GeoIP_CityDatabase: анализ журналов Ngnix через Graylog, получение IP-адреса посетителя, а затем использование базы данных GeoIP2 для анализа географического местоположения IP.




Сравнение Гарилога и ЭЛК




Сравнение общей архитектуры




  • Graylog: Graylog Collector Sidecar-> Сервер Graylog (пакет ElstaicSearch) -> Веб-страница Graylog
  • ELK:Logstash -> ElasticSearch -> Kibana







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




  • Простота развертывания и обслуживания, простота в использовании и интегрированное решение
  • По сравнению с синтаксисом json от ES синтаксис поиска относительно прост, и результаты поиска можно выделить
  • Встроенное простое оповещение можно вспомнить через веб-API или по электронной почте
  • Может напрямую экспортировать поисковый JSON-файл для облегчения разработки поисковых скриптов, которые вызывают остальные API




Три, диаграмма архитектуры Garylog




Установка одного узла




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







Кластерная установка




Это подходит для производственных сред. Балансировка нагрузки добавляется до того, как несколько узлов Graylog развернуты в кластере. ElasticSearch и MongoDB развернуты. Балансировщик нагрузки может проверить, является ли узел нормальным. Если узел отключен, вы можете удалить узел







В-четвертых, установка и настройка Graylog




1.jdk установка




Версия установки jdk1.8.0_161, процесс установки (опущен)




Установка 2.ElasticSearch




Установочная версия —asticsearch-5.6.11, установлен плагин x-pack, а также инструмент управленияasticsearch-head




Плагин для сегментации китайского словаasticsearch-analysis-ik-5.6.11 ,asticsearch-analysis-pinyin-5.6.11




Обратите внимание, что версия ElasticSearch, соответствующая Graylog2.4, не может быть выше 5.x, иначе она не может быть установлена




Обратите внимание, что версия ElasticSearch, соответствующая Graylog 2.3 и более ранним версиям, не может быть выше 4.x, в противном случае она не может быть установлена




(1) Установить эластичный поиск-5.6.11




Распаковать эластичный поиск-5.6.11.tar.gz, tar -zxf эластичный поиск-5.6.11.tar.gz -C / usr / local




Измените конфигурациюasticsearch.yml следующим образом




path.data:

       - /data/elasticsearch_1

       - /data/elasticsearch_2

       - /data/elasticsearch_3

 

path.logs: /data/elasticsearch_logs

bootstrap.memory_lock: true

network.host: 0.0.0.0

http.port: 9200

xpack.security.audit.enabled: true

xpack.security.authc.accept_default_password: false

indices.store.throttle.max_bytes_per_sec: 150mb

http.cors.allow-headers: Authorization,X-Requested-With,Content-Length,Content-Type

http.cors.enabled: true

http.cors.allow-origin: "*"




Elasticsearch не может быть запущен пользователем root, вам нужно создать новый эластичный пользователь, переключиться на эластичный и запустить




./elasticsearch -d




Посетите http://10.10.10.1:9200/ через браузер и верните информацию, относящуюся кasticsearch, что означает, что запуск прошел успешно




(2) Установите x-pack




bin /asticsearch-plugin установите x-pack, следуйте инструкциям и нажмите Next для установки




(3) установить китайское слово segmenter ik и пиньинь




Перейдите в /usr/local/elasticsearch-5.6.11/plugins и распакуйте файлasticsearch-analysis-ik-5.6.11.zip в каталог ik




Перейдите в /usr/local/elasticsearch-5.6.11/plugins, разархивируйте файлasticsearch-analysis-pinyin-5.6.11.zip в каталог pinyin и перезапустите эластичный поиск




Введите в браузере следующий адрес: если появляется слово сегментация, настройка выполнена успешно.




http://192.168.0.100:9200/_analyze?analyzer=ik&pretty=true&text=helloworld,%E6%AC%A2%E8%BF%8E%E6%82%A8




(4) Установка инструмента управления упругой головкой




Извлеките файлasticsearch-head-master.zip в / usr / local /




chown -R elastic:elastic /usr/local/elasticsearch-head-master

cd /usr/local/elasticsearch-head-master

npm install && nohup npm run start &




Посетите http://10.10.10.1:9100, если появится следующая страница, установка прошла успешно







Установка 3.MongoDB




Используйте кластер Alibaba Cloud MongoDB RDS, версия 3.4, официальная рекомендация — использовать последнюю версию, процесс установки (опущен)




4. Установка Грайлог-сервера




Установочная версия Graylog-2.4.6




rpm -Uvh https://packages.graylog2.org/repo/packages/graylog-2.4-repository_latest.rpm




Установить yum -y установить graylog-server через yum




Измените файл конфигурации vim /etc/graylog/server/server.conf со следующими изменениями:




Используйте pwgen для генерации password_secret плюс пароль pwgen -N 1 -s 96




U9oMoxRYJ0DB4K30SsQPhAeL7237aTTy0kSpLiEbrNNSqGp6sQaJO4zq9fI2I6FEVkpIomGNQMrssj8IQqmgIhTDNrUbQbnk




Добавьте указанный выше ключ в password_secret =




Используйте echo -n 123456 | sha256sum, чтобы сгенерировать пароль для входа, и учетная запись — admin




8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92




Добавьте указанный выше ключ в root_password_sha2 =




Измените часовой пояс root_timezone = UTC на root_timezone = Азия / Шанхай




Измените адрес для прослушивания web и api




rest_listen_uri = http://127.0.0.1:9000/api/ изменен на http://0.0.0.0:9000/graylog/api/




rest_transport_uri = http://192.168.1.1:9000/api/ изменен на https://graylog.example.com/graylog/api/




web_listen_uri = http://127.0.0.1:9000/ изменен на http://0.0.0.0:9000/graylog/




rest_enable_cors = false




Изменить адрес подключения ElasticSearch




elasticsearch_hosts = http://elastic:123456@10.10.10.1:9200




Изменить адрес подключения MongoDB




mongodb_uri = mongodb://graylog:123456@10.10.10.1:3717/graylog




Chkconfig — добавить Graylog-сервер




Добавьте graylog-сервер в системную службу systemctl, включите graylog-server.service




Подсветка результатов поиска allow_highlighting = true




5.Грейлог-коллектор-коляска установка




Перейдите в git-проект сборщика колясок https://github.com/Graylog2/collector-sidecar/releases, чтобы загрузить последнюю стабильную версию.




Установите rpm -i collector-sidecar-0.0.9-1.x86_64.rpm




Измените файл конфигурации collector_sidecar.yml, измените server_url: http://10.10.10.1:9000/graylog/api/, добавьте теги




Проверьте правильность файла конфигурации




graylog-collector-sidecar -configtest -c /etc/graylog/collector-sidecar/collector_sidecar.yml




Graylog-коллектор-коляска -сервисная установка




Запустите сервис systemctl запустите коллектор-коляску




6. Настройте Nginx




server_name graylog.example.com;

location /graylog/ {

            proxy_set_header Host $http_host;

            proxy_set_header X-Forwarded-Host $host;

            proxy_set_header X-Forwarded-Server $host;

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_set_header X-Graylog-Server-URL http://$server_name/api;

            proxy_pass       http://127.0.0.1:9000/graylog/;

        }

 

location /graylog/api/ {

            proxy_set_header Host $http_host;

            proxy_set_header X-Forwarded-Host $host;

            proxy_set_header X-Forwarded-Server $host;

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_pass       http://127.0.0.1:9000/graylog/api/;

        }




После завершения настройки перезапустите nginx и graylog-server.




Источник: https://russianblogs.com/article/404130660/



2021-08-16T15:52:13
Software

Осваиваем мониторинг с Prometheus. Часть 3. Настройка Prometheus server

Prometheus server настраивается через два места: жопу и голову аргументы запуска и конфигурационный файл. Настройку через переменные окружения в Prometheus не завезли и не планируют.







Как долго Prometheus должен хранить метрики




Это зависит от того, как вы будете их использовать. В идеале надо иметь два набора метрик: краткосрочные на пару недель и долгосрочные на несколько месяцев. Первые нужны, чтобы оперативно отслеживать ситуацию, вторые — чтобы видеть тенденцию на больших промежутках времени. Но это большая тема, заслуживающая отдельной статьи, а пока сделаем по-простому. Длительность хранения метрик указывается в аргументах запуска Prometheus. Есть две опции:




--storage.tsdb.retention.time=... определяет как долго Prometheus будет хранить собранные метрики. Длительность указывается так же, как и в PromQL для диапазонного вектора: 30d — это 30 дней. По умолчанию метрики хранятся 15 дней, потом исчезают. К сожалению нельзя одни метрики хранить долго, а другие коротко, как, например, в Graphite. В Prometheus лимит общий для всех.




--storage.tsdb.retention.size=... определяет сколько дискового пространства Prometheus может использовать под метрики. По-моему эта опция удобнее предыдущей: можно указать всё свободное место на диске и получить настолько долгие метрики, насколько это возможно при любом их количестве. На практике однако нельзя указывать свободное место впритык. Дело в том, что у БД метрик есть журнал упреждающей записи (WAL), который в этом лимите не учитывается. Я не понял от чего зависит максимальный размер WAL, поэтому какие-то рекомендации по запасу не могу дать. У меня максимальный размер WAL был 8 ГБ.




Если вы устанавливали Prometheus по моей инструкции без докера, то аргументы запуска вам надо прописать в /etc/systemd/system/prometheus.service в параметре ExecStart, после чего выполнить две команды:




# systemctl daemon-reload
# systemctl restart prometheus




Если же Prometheus работает в докере, то надо внести изменения в docker-compose.yml и переподнять контейнер.




Интервал опроса экспортеров и job name




Давайте взглянем на минимальный конфиг из предыдущей статьи, чтобы вы понимали о чём идёт речь:/etc/prometheus/prometheus.yml




global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
    - targets:
       - localhost:9100
       - anotherhost:9100




scrape_interval — периодичность опроса экспортеров (scrape дословно с английского — это соскабливать, соскребать). В отличие от длительности хранения метрик, может быть разной для разных метрик. Во всех мануалах я встречал цифру в 15 секунд, но почему-то никто не объяснял эту магическую константу. Почему не 2, 5 или 10? В целом так: чем меньше интервал, тем выше будет разрешение графиков и тем больше места потребуется для хранения метрик. Видимо 15 секунд — это золотая середина, найденная опытным путём.




job_name — имя (для Prometheus’а) для данной группы метрик. job_name будет светиться в интерфейсе Prometheus’а на вкладке Targets, а также попадёт в метку job для группы метрик c этих машин:







Как правильно подобрать имя для job_name ? Я пробовал разные варианты и в итоге остановился на простом правиле: называть job’ы в соответствии с экспортерами: node для node_exporter, cadvisor для cadvisor’а и т.д.




После редактирования конфига надо попросить Prometheus’а перечитать свой конфиг. Для этого надо послать ему сигнал SIGHUP одним из способов:




# systemctl reload prometheus
или
$ docker kill --signal=SIGHUP prometheus




Как навесить дополнительных меток хостам




Элементарно!/etc/prometheus/prometheus.yml




scrape_configs:
  - job_name: 'node'
    static_configs:
    - targets:
       - host-a:9100
       - host-b:9100
      labels:
        project: 'boo'
        env: 'prod'

    - targets:
       - host-c:9100
       - host-d:9100
      labels:
        project: 'boo'
        env: 'dev'




Результат в интерфейсе Prometheus:







В запросах будет выглядеть так:




Expression: node_load1
node_load1{env="dev",instance="host-c:9100",job="node",project="boo"}   2.04
node_load1{env="dev",instance="host-d:9100",job="node",project="boo"}   0.8
node_load1{env="prod",instance="host-a:9100",job="node",project="boo"}  1.1
node_load1{env="prod",instance="host-b:9100",job="node",project="boo"}  1.5




Метки можно вешать любые на ваш вкус, не только project и env.




Как убрать номер порта из таргетов




Я не люблю лишнее. Вот зачем мне номер порта в метке instance? Какая от него польза? Он только сообщает, что node_exporter работает на порту 9100, но является ли эта информация полезной? Нет. Поэтому порт надо скрыть:/etc/prometheus/prometheus.yml




...

scrape_configs:
  - job_name: 'node'
    static_configs:
    - targets:
       - localhost:9100
       - anotherhost:9100

    metric_relabel_configs:
      - source_labels: [instance]
        regex: '(.*):9100'
        replacement: '$1'
        target_label: instance




Порт скроется не везде. На вкладке Targets он останется:







А в запросах исчезнет:




Expression: node_load1
1.67node_load1{instance="localhost",job="node"}
0.13node_load1{instance="anotherhost",job="node"}




Кроме одного:




Expression: up
1up{instance="localhost:9100",job="node"}
1up{instance="anotherhost:9100",job="node"}




Service discovery




Service discovery — это автоматическое обнаружение целей. Суть в том, что Prometheus будет получать список целей из какого-то внешнего источника: consul, openstack или что-то ещё. Service discovery — удобная штука, особенно если у вас инфраструктура развёрнута в облаке и машины регулярно рождаются и умирают.




Самый простой service discovery работает на файликах. В конфиге пишем так:/etc/prometheus/prometheus.yml




scrape_configs:
  - job_name: "node"
    file_sd_configs:
    - files:
      - /etc/prometheus/sd_files/*_nodeexporter.yml
      refresh_interval: 1m




Prometheus засунет в джобу node все таргеты из файлов, которые лежат в /etc/prometheus/sd_files/ и оканчиваются на _nodeexporter.yml. Всё это будет работать без перечитывания конфига.




Пример файла с таргетами:/etc/prometheus/sd_files/boo_nodeexporter.yml




- targets:
  - 'host-a:9100'
  - 'host-b:9100'
  labels:
    project: 'boo'
    env: 'prod'

- targets:
  - 'host-c:9100'
  - 'host-d:9100'
  labels:
    project: 'boo'
    env: 'dev'




Удобно держать таргеты разных проектов в разных файлах. В моём примере лишь один проект с названием “boo”, остальные делаются по аналогии. Думаю разберётесь.




Чем отличается перечисление таргетов непосредственно в prometheus.yml от перечисления в отдельных файлах? В первом случае надо давать команду перечитывания конфига при редактировании, а во втором нет.




Источник: https://laurvas.ru/prometheus-p3/



2021-08-16T10:28:17
Software

Осваиваем мониторинг с Prometheus. Часть 2. PromQL и метки

В прошлой статье я говорил, что Prometheus — это не готовое решение, а скорее фреймворк. Чтобы использовать его возможности полноценно, надо разбираться. Что ж, начнём.




PromQL — это про то, как вытаскивать метрики не из экспортеров, а уже из самого Prometheus’а. Например, чтобы узнать сколько ядер у процессора, надо написать:




count(count(node_cpu_seconds_total) without (mode)) without (cpu)




PromQL дословно расшифровывается как Prometheus query language, т.е. язык запросов. Он не имеет ничего общего с SQL, это принципиально другой язык. Поначалу он казался мне каким-то запутанным, а документация не особо помогала. Потихоньку разобрался и мне даже понравилось.







Пробуем простые запросы




Prometheus server хранит все данные в виде временных последовательностей (time series). Каждая временная последовательность определяется именем метрики и набором меток (labels) типа ключ-значение (key-value). Давайте сразу посмотрим несколько примеров в Prometheus web UI. Напомню, он работает на localhost:9090. Чтобы не городить скриншотов, я буду показывать запросы в своём псевдо-терминале, а вы не ленитесь и пробуйте у себя.




Expression: node_load1
0.96node_load1{instance="localhost:9100",job="node"}




node_load1 — имя метрики,
instance и job — имена меток,
localhost:9100 и node — соответствующие значения меток,
0.96 — значение метрики.




Можно запустить какой-нибудь top и убедиться в том, что одноминутный load average на локалхосте действительно равен 0.96.




Если у вас несколько машин, результат будет интереснее:




Expression: node_load1
0.96node_load1{instance="localhost:9100",job="node"}
0.44node_load1{instance="anotherhost:9100",job="node"}




Prometheus разрабатывался так, чтобы наблюдать за группой машин было так же легко, как за одной. И метки этому способствуют. Прежде всего они позволяют фильтровать вывод:




Expression: node_load1{instance='localhost:9100'}
0.96node_load1{instance="localhost:9100",job="node"}

Expression: node_load1{instance!='localhost:9100'}
0.44node_load1{instance="anotherhost:9100",job="node"}

Expression: node_load1{job='node'}
0.96node_load1{instance="localhost:9100",job="node"}
0.44node_load1{instance="anotherhost:9100",job="node"}




Кроме = и != есть ещё совпадение и несовпадение с регулярным выражением: =~!~. Лирическое отступление: мне не нравится одинарное равно для точного сопадения. Это против правил. Должно быть двойное! Эх, молодёжь… А вот разницы в кавычках я не заметил: одинарные и двойные работают одинаково. Да, если задать несколько условий, они будут объединяться логическим И.




Возьмём другой пример. Посмотрим свободное место на дисках:




Expression: node_filesystem_avail_bytes
node_filesystem_avail_bytes{device="/dev/nvme0n1p1",fstype="vfat",instance="localhost:9100",job="node",mountpoint="/boot"}  143187968
node_filesystem_avail_bytes{device="/dev/nvme0n1p2",fstype="ext4",instance="localhost:9100",job="node",mountpoint="/"}      340473708544
node_filesystem_avail_bytes{device="/dev/sda1",fstype="ext4",instance="anotherhost:9100",job="node",mountpoint="/"}         429984710656
node_filesystem_avail_bytes{device="run",fstype="tmpfs",instance="localhost:9100",job="node",mountpoint="/run"}             4120506368
node_filesystem_avail_bytes{device="tmpfs",fstype="tmpfs",instance="localhost:9100",job="node",mountpoint="/tmp"}           4109291520
node_filesystem_avail_bytes{device="tmpfs",fstype="tmpfs",instance="anotherhost:9100",job="node",mountpoint="/run"}         104542208




В байтах получаются огромные непонятные числа, но сейчас не обращайте на это внимания — мы упражняемся в запросах.




Можно получить свободное место в процентах:




Expression: node_filesystem_avail_bytes / node_filesystem_size_bytes * 100
{device="/dev/nvme0n1p1",fstype="vfat",instance="localhost:9100",job="node",mountpoint="/boot"}  54.17850016466805
{device="/dev/nvme0n1p2",fstype="ext4",instance="localhost:9100",job="node",mountpoint="/"}      73.94176693455515
{device="/dev/sda1",fstype="ext4",instance="anotherhost:9100",job="node",mountpoint="/"}         68.54660550632083
{device="run",fstype="tmpfs",instance="localhost:9100",job="node",mountpoint="/run"}             99.96800174897272
{device="tmpfs",fstype="tmpfs",instance="localhost:9100",job="node",mountpoint="/tmp"}           99.69591724179051
{device="tmpfs",fstype="tmpfs",instance="anotherhost:9100",job="node",mountpoint="/run"}         99.83961821311219




tmpfs — это не про диск, уберём его:




Expression: node_filesystem_avail_bytes{fstype!='tmpfs'} / node_filesystem_size_bytes{fstype!='tmpfs'} * 100
{device="/dev/nvme0n1p1",fstype="vfat",instance="localhost:9100",job="node",mountpoint="/boot"}  54.17850016466805
{device="/dev/nvme0n1p2",fstype="ext4",instance="localhost:9100",job="node",mountpoint="/"}      73.94172957355208
{device="/dev/sda1",fstype="ext4",instance="anotherhost:9100",job="node",mountpoint="/"}         68.5466042003818




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




Expression: node_filesystem_avail_bytes{fstype!='tmpfs'} / node_filesystem_size_bytes * 100
или
Expression: node_filesystem_avail_bytes / node_filesystem_size_bytes{fstype!='tmpfs'} * 100




Мы получили свободное место в процентах, но как-то привычнее другая величина — занятое место в процентах:




Expression: 100 - node_filesystem_avail_bytes{fstype!='tmpfs'} / node_filesystem_size_bytes * 100
или
Expression: (1 - node_filesystem_avail_bytes{fstype!='tmpfs'} / node_filesystem_size_bytes) * 100
{device="/dev/nvme0n1p1",fstype="vfat",instance="localhost:9100",job="node",mountpoint="/boot"}  45.82149983533195
{device="/dev/nvme0n1p2",fstype="ext4",instance="localhost:9100",job="node",mountpoint="/"}      26.05827042644792
{device="/dev/sda1",fstype="ext4",instance="anotherhost:9100",job="node",mountpoint="/"}         31.453395799618207




Как видите, можно умножать или делить на скаляр и не важно что это: константа или результат вычисления. Вообще я заметил, что в PromQL действует правило: пиши осмысленные запросы и всё будет хорошо. Не надо пытаться сложить диск с процессором и делить на память.




Агрегация




По меткам можно делать агрегацию. Смысл агрегации в том, чтобы объединить несколько однотипных метрик в одну. Например, посчитать максимальный (или средний) load average среди машин определённой группы.




Expression: foo by (label) (some_metric_name)
или
Expression: foo(some_metric_name) by (label)




Синтаксис непривычный, но вроде ничего. Все эти скобочки являются обязательными, без них работать не будет. Пробуем на нашем load average:




Expression: avg by (job)(node_load1)
0.7{job="node"}

Expression: max by (job)(node_load1)
0.96{job="node"}

Expression: min by (job)(node_load1)
0.44{job="node"}

Expression: sum by (job)(node_load1)
1.4{job="node"}

Expression: count by (job)(node_load1)
2{job="node"}




Метки работают как измерения в многомерном пространстве. Агрегация с использованием by как бы схлопывает все измерения, кроме указанного. В примере с node_load1 это не очень заметно, потому что у меня мало меток и хостов. Ок, вот пример получше:




Expression: node_cpu_seconds_total
27687.16node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="idle"}
349.98node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="iowait"}
0node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="irq"}
4.5node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="nice"}
342.47node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="softirq"}
0node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="steal"}
734.43node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="system"}
2386.23node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="user"}
27613.56node_cpu_seconds_total{cpu="1",instance="localhost:9100",job="node",mode="idle"}
328.26node_cpu_seconds_total{cpu="1",instance="localhost:9100",job="node",mode="iowait"}
...




Эта метрика показывает сколько времени каждое ядро работало в каждом режиме. В сыром виде от неё никакого толку, но сейчас это не важно. Важно, что у неё куча меток: cpuinstancejobmode.




Expression: max by (instance) (node_cpu_seconds_total)
18309.45{instance="localhost:9100"}
3655352.98{instance="anotherhost:9100"}

Expression: max by (instance, cpu) (node_cpu_seconds_total)
17623.34{cpu="3",instance="localhost:9100"}
18295.97{cpu="0",instance="localhost:9100"}
3529407.76{cpu="0",instance="anotherhost:9100"}
18252.21{cpu="1",instance="localhost:9100"}
3655379.15{cpu="1",instance="anotherhost:9100"}
18334{cpu="2",instance="localhost:9100"}

Expression: max without (mode) (node_cpu_seconds_total)
3655736.46{cpu="1",instance="anotherhost:9100",job="node"}
18752.74{cpu="2",instance="localhost:9100",job="node"}
18022.19{cpu="3",instance="localhost:9100",job="node"}
18716.18{cpu="0",instance="localhost:9100",job="node"}
3529779.38{cpu="0",instance="anotherhost:9100",job="node"}
18670.74{cpu="1",instance="localhost:9100",job="node"}




Оператор without работает как by, но в другую сторону, по принципу: “что получится, если убрать такую-то метку”. На практике лучше использовать именно without, а не by. Почему? Дело в том, что Prometheus позволяет навесить кастомных меток при объявлении таргетов, например разный env для машин тестового и боевого окружений (как это сделать). При составлении запроса вы заранее не знаете какие дополнительные метки есть у метрики и есть ли они вообще. А если и знаете, то не факт, что их число не изменится в будущем… В любом случае при использовании by все метки, которые не были явно перечислены, пропадут при агрегации. Это скорее всего будет некритично в дашбордах, но будет неприятностью в алертах. Так что лучше подумать дважды, прежде чем использовать by. Попробуйте самостоятельно поиграться с агрегациями и понять как формируется результат. Полный список агрегирующих операторов вы найдёте в документации.




Считаем ядра




В принципе у вас уже достаточно знаний, чтобы самостоятельно посчитать ядра процессора, но я всё равно покажу. Для решения задачи нам нужна метрика node_cpu_seconds_total и оператор count, который показывает сколько значений схлопнулось при агрегации:




Expression: count(node_cpu_seconds_total) without (cpu)
4{instance="localhost:9100",job="node",mode="user"}
2{instance="anotherhost:9100",job="node",mode="iowait"}
2{instance="anotherhost:9100",job="node",mode="softirq"}
2{instance="anotherhost:9100",job="node",mode="system"}
2{instance="anotherhost:9100",job="node",mode="user"}
4{instance="localhost:9100",job="node",mode="system"}
2{instance="anotherhost:9100",job="node",mode="irq"}
4{instance="localhost:9100",job="node",mode="idle"}
4{instance="localhost:9100",job="node",mode="irq"}
4{instance="localhost:9100",job="node",mode="nice"}
4{instance="localhost:9100",job="node",mode="softirq"}
2{instance="anotherhost:9100",job="node",mode="nice"}
4{instance="localhost:9100",job="node",mode="iowait"}
2{instance="anotherhost:9100",job="node",mode="idle"}
2{instance="anotherhost:9100",job="node",mode="steal"}
4{instance="localhost:9100",job="node",mode="steal"}




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




Expression: count(node_cpu_seconds_total) without (mode)
или
Expression: max(node_cpu_seconds_total) without (mode)




Итоговый запрос:




Expression: count(count(node_cpu_seconds_total) without (mode)) without (cpu)
4{instance="localhost:9100",job="node"}
2{instance="anotherhost:9100",job="node"}




Да, мне тоже кажется, что получение простой по смыслу метрики (число ядер) выглядит как-то заковыристо. Как будто мы ухо ногой чешем. Привыкайте.




Мгновенный и диапазонный вектор




Простите, я не смог придумать лучшего перевода. В оригинале это называется instant and range vector. Сейчас мы смотрели только мгновенные вектора, т.е. значения метрик в конкретный момент времени. Почему вообще результат запроса называется вектором? Вспоминаем, что Prometheus ориентирован на работу с группами машин, не с единичными машинами. Запросив какую-то метрику, в общем случае вы получите не одно значение, а несколько. Вот и получается вектор (с точки зрения алгебры, а не геометрии). Возможно, если погрузиться в исходный код Prometheus, всё окажется сложнее, но, к счастью, в этом нет необходимости.




Диапазонный вектор (range vector) — это вектор, который хранит диапазон значений метрики за определённый период времени. Он нужен, когда этого требует арифметика запроса. Проще всего объяснить на графике функции avg_over_time от чего-нибудь. В каждый момент времени она будет вычислять усреднённое значение метрики за предыдущие X минут (секунд, часов…). По-научному это называется “скользящее среднее” (moving average). На словах как-то сложно получается, лучше взгляните на эти 2 графика:







Оранжевый получен из зелёного усреднением за 10 минут. Да, это был мой любимый load average:




Expression: avg_over_time(node_load1{instance='localhost:9100'}[10m])
{instance="localhost:9100",job="node"}  0.23




Собственно, диапазонный вектор — это когда мы дописываем временной интервал в квадратных скобочках. Интервал времени для диапазонного вектора указывается очень по-человечески: 1s — одна секунда, 1m — одна минута, 1h — один час, 1d — день. А что, если нужно указать полтора часа? Просто напишите 90m.




Домашнее задание: посмотрите на графики max_over_time и min_over_time.




Типы метрик




Метрики бывают разных типов. Это важно, потому что для разных типов метрик применимы те или иные запросы.




Шкала (gauge). Самый простой тип метрик. Примеры: количество свободной/занятой ОЗУ, load average и т.д.




Счётчик (counter). Похож на шкалу, но предназначен совершенно для других данных. Счётчик может только увеличиваться, поэтому он подходит только для тех метрик, которые по своей природе могут только увеличиваться. Примеры: время работы CPU в определённом режиме (user, system, iowait…), количество запросов к веб-серверу, количество отправленных/принятых сетевых пакетов, количество ошибок. На практике вас не будет интересовать абсолютное значение счётчика, вас будет интересовать первая производная по времени, т.е. скорость роста этого счётчика, например количество запросов в минуту или количество ошибок за день.




Гистограмма (histogram). Я пока не сталкивался с таким типом, поэтому ничего путного не скажу.




Саммари (summaries). Что-то похожее на гистограммы, но другое.




Смотрим счётчики




Посмотрим счётчики на примере сетевого трафика:




Expression: node_network_receive_bytes_total{instance='localhost:9100'}
node_network_receive_bytes_total{device="br-03bbefe4ab97",instance="localhost:9100",job="node"}  0
node_network_receive_bytes_total{device="docker0",instance="localhost:9100",job="node"}          0
node_network_receive_bytes_total{device="lo",instance="localhost:9100",job="node"}               16121707
node_network_receive_bytes_total{device="vethab0ac76",instance="localhost:9100",job="node"}      0
node_network_receive_bytes_total{device="vethd3da657",instance="localhost:9100",job="node"}      0
node_network_receive_bytes_total{device="wlp3s0",instance="localhost:9100",job="node"}           4442690377




Сырое значение счётчика не несёт никакого смысла, его надо оборачивать функцией rate или irate. Эти функции принимают на вход диапазонный вектор, поэтому правильный запрос выглядит так:




Expression: rate(node_network_receive_bytes_total{device="wlp3s0"}[5m])
node_network_receive_bytes_total{device="wlp3s0",instance="localhost:9100",job="node"}  1210.6877192982456

Expression: irate(node_network_receive_bytes_total{device="wlp3s0"}[5m])
node_network_receive_bytes_total{device="wlp3s0",instance="localhost:9100",job="node"}  1210.6877192982456




В чём разница между rate и irate? Первая функция для вычисления производной берёт весь диапазон (5 минут в нашем случае), а вторая берёт лишь два последних сэмпла из всего диапазона, чтобы максимально приблизиться к мгновенному значению (первоисточник). Собственно, её название расшифровывается как instant rate.




Почему мы берём диапазонный вектор за 5 минут, а не за 1 или 10? Не знаю. Почему-то так делают во всех примерах и в дашборде Node exporter full тоже так. Для rate получается, что чем меньше интервал, тем больше пиков, а чем больше интервал, тем сильнее их сглаживание. Ну, с математикой не поспоришь. Для irate величина диапазона не имеет значения. На самом деле при определённых обстоятельствах всё-таки имеет, но это настолько тонкий нюанс, что на него можно забить.




Другой вопрос: 1210 — это в каких попугаях? Во-первых смотрим исходную метрику, там явно написано bytes. Функция rate делит исходную размерность на секунды, получается байт в секунду. Вообще Prometheus предпочитает стандартные единицы измерения: секунды, метры, ньютоны и т.п. Как в школе на уроках физики.




Считаем загрузку процессора




С памятью, диском и трафиком понятно, а как посмотреть загрузку процессора? Отвечаю. То, что мы привыкли считать загрузкой процессора в процентах на самом деле вот какая штука: сколько времени (в процентном отношении) процессор не отдыхал, т.е. не находился в режиме idle.




Итак, всё начинается с метрики node_cpu_seconds_total. Сначала посмотрим сколько времени процессор отдыхал:




Expression: irate(node_cpu_seconds_total{mode="idle"}[5m])
{cpu="0",instance="anotherhost:9100",job="node",mode="idle"}  0.5654385964909013
{cpu="0",instance="localhost:9100",job="node",mode="idle"}    0.9553684210526338
{cpu="1",instance="anotherhost:9100",job="node",mode="idle"}  0.5772631578931683
{cpu="1",instance="localhost:9100",job="node",mode="idle"}    0.9684912280701705
{cpu="2",instance="localhost:9100",job="node",mode="idle"}    0.9665614035087696
{cpu="3",instance="localhost:9100",job="node",mode="idle"}    0.9668421052631616




Возьмём среднее значение по ядрам и переведём в проценты:




Expression: avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) without (cpu) * 100
{instance="anotherhost:9100",job="node",mode="idle"}  49.67368421054918
{instance="localhost:9100",job="node",mode="idle"}    96.87368421052636




Ну и наконец получим загрузку процессора:




Expression: 100 - avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) without (cpu) * 100
{instance="anotherhost:9100",job="node",mode="idle"}  49.21052631578948
{instance="localhost:9100",job="node",mode="idle"}    3.458771929824593




Любопытно, что сумма всех режимов работы процессора никогда не доходит до 100% времени:




Expression: sum (irate(node_cpu_seconds_total[5m])) without (mode)
{cpu="0",instance="anotherhost:9100",job="node"}  0.9739999999999347
{cpu="0",instance="localhost:9100",job="node"}    0.9991578947368495
{cpu="1",instance="anotherhost:9100",job="node"}  0.9083157894731189
{cpu="1",instance="localhost:9100",job="node"}    0.9985964912280734
{cpu="2",instance="localhost:9100",job="node"}    0.998456140350873
{cpu="3",instance="localhost:9100",job="node"}    0.9983508771929828




Почему так? Хороший вопрос. Я подозреваю, что оставшаяся часть времени уходит на переключение контекста процессора. Получается, что загрузка процессора, полученная по формуле выше, будет чуть-чуть завышенной. В действительности можно не переживать по этому поводу, потому что погрешность получается незначительная. Это просто у меня anotherhost работает на старом процессоре Intel Atom. На нормальных взрослых процессорах погрешность не превышает десятые доли процента.




И это всё?




Думаю, на сегодня достаточно. Да, я рассказал не про все возможности PromQL. Например, за кадром остались операторы ignoring и on, логические and и or а также сдвиг offset. Есть всякие интересности типа производной по времени deriv или предсказателя будущего predict_linear. При желании вы сможете почитать про них в документации: операторы и функции. Я же вернусь к ним, когда мы будем решать практические задачи мониторинга.







Источник: https://laurvas.ru/prometheus-p2/



2021-08-16T10:26:10
Software

Осваиваем мониторинг с Prometheus. Часть 1. Знакомство и установка

Мониторинг — это сбор метрик и представление этих метрик в удобном виде (таблицы, графики, шкалы, уведомления, отчёты). Концептуально его можно изобразить в таком виде:







Метрики — это абстракция, с которой мы имеем дело, когда говорим о мониторинге. Это какие-то числа, описывающие состояние интересующей нас штуковины. Самый простой и понятный мониторинг следит за ресурсами компьютера: загрузкой процессора, памяти, диска, сети. Аналогично можно следить за чем-то более высокоуровневым, вроде количества посетителей на сайте или среднего времени ответа сервера. Для компьютера это один хрен безликие числа.




Мониторинг — это инструмент анализа того, что происходит/происходило в системе. Следовательно, без понимания смысла собранных данных мониторинг вам не особо поможет. И наоборот: в умелых руках это мощный инструмент.




Чем больше компонентов в вашей системе (микросервисов), чем больше нагрузка на неё, чем дороже время простоя, тем важнее иметь хорошую систему мониторинга.




То, что не метрики — то логи. Их тоже надо собирать и анализировать, но это отдельная история со своими инструментами.




Сейчас модно делать мониторинг на основе Prometheus. Так ли он хорош на самом деле? На мой взгляд это лучшее, что сейчас есть из мониторинга. Оговорюсь сразу для тех, кто хочет с этим поспорить: я понимаю, что разным задачам — разные инструменты и где-то больше подходит старый проверенный Nagios. Но в целом лидирует Prometheus.




Prometheus — это не готовое решение в духе “поставил и работает” (привет, Netdata). Это платформа, набор инструментов, позволяющий сделать себе такой мониторинг, какой надо. Фреймворк, если хотите.




Эта статья про знакомство с Prometheus’ом и установку. Потом будет интереснее — про настройку непосредственно мониторинга.







Архитектура Prometheus




Prometheus состоит из отдельных компонентов, которые общаются друг с другом по http. Всё модно-молодёжно, с веб-интерфейсами и настраивается в yaml-конфигах.







  • Prometheus server — центральное звено. Здесь хранятся собранные метрики, плюс имеется простенький веб-интерфейс, чтобы на них смотреть (Prometheus web UI).
  • Агенты, собирающие метрики и предоставляющие их в понятном для Prometheus’а виде. В зависимости от контекста называются экспортерами (exporter) или таргетами (target). Устанавливаются на целевые машины. Типичный представитель — node_exporter — собирает данные о вычислительных ресурсах: загрузку процессора, памяти, диска и т.п. Есть куча других экспортеров. Например, cadvisor собирает данные о контейнерах. Есть экспортеры для Postgres’а, для Nginx’а и т.д. С точки зрения самого Prometheus’а они ничем принципиально не отличаются друг от друга, просто каждый собирает какие-то свои метрики. Можно писать свои экспортеры, если ничего из готового вам не подходит.
  • Alertmanager — уведомлятор. Это он отправит письмо вам на почту, если что-то сломается. Из коробки умеет в почту, Slack, Hipchat, Pagerduty. Сторонними средствами можно прикрутить Telegram и наверное что-то ещё.
  • Grafana строго говоря не является частью Prometheus’а, но все её ставят и официальная документация рекомендует поступать именно так. Показывает красивые графики. Кучка графиков, собранных на одном экране, называется дашбордом (dashboard). Типа такого:







Установка




Все компоненты Prometheus’а написаны на Go и представляют собой статически скомпиленные бинари, не требующие никаких зависимостей кроме libc и готовые запускаться на любой платформе, будь то Debian, Arch или Centos. Установить их можно аж тремя способами:




  • по-старинке через пакетный менеджер,
  • взять готовые бинари с оф. сайта и засунуть их в систему в обход пакетного менеджера,
  • развернуть всё в докер-контейнерах.




Разумеется, у каждого способа есть свои преимущества и недостатки.




Если ставить через пакетный менеджер, то через него же вы будете получать обновления и сможете всё удалить. Однако есть нюанс. У Prometheus’а нет своих собственных репозиториев для популярных дистрибутивов, а официальные репозитории Debian/Ubuntu как всегда отстают от апстрима. Например, сейчас в Debian доступна версия 2.7.1, когда Prometheus уже 2.11.1. Arch Linux — молодец, идёт в ногу со временем.




При установке вручную Prometheus не будет числиться в списках установленного софта и с точки зрения пакетного менеджера его в системе нет. Зато вы сможете обновлять Prometheus отдельно от пакетов. При ручной установке придётся немного побывать в роли установочного скрипта (который есть в пакете), поэтому, если у вас серьёзные намерения — автоматизируйте установку/обновление через какой-нибудь Ansible. Рекомендую взять за основу готовые роли для PrometheusAlertmanagerNode exporterGrafana.




Если ставить Prometheus в докере, то всё про мониторинг будет лежать в одном месте. Можно это хозяйство положить под Git и иметь возможность поднять мониторинг в две команды: git clonedocker-compose up. Но надо писать правильный docker-compose.yml, париться при возникновении сетевых проблем… Короче, вы от одних проблем избавляетесь, а взамен получаете другие. В зависимости от того, с какими вам больше нравится возиться, выбирайте тот или иной вариант установки. Вам понадобятся контейнеры prom/prometheusprom/node_exporterprom/alertmanager. За основу рекомендую взять docker-compose.yml из репозитория docprom.




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




Установка вручную




Расскажу про ручную установку, потому что в основе других способов установки лежат те же действия, только завёрнутые в дополнительную обёртку. Этот способ подойдёт для любых дистрибутивов Linux под управлением systemd (Ubuntu, Debian, Centos, Arch и т.д.)




Установка Prometheus server




Идём на https://github.com/prometheus/prometheus/releases, находим билд под свою платформу (скорее всего это будет linux-amd64). Копипастим ссылку, качаем:




$ wget https://github.com/.../prometheus-2.11.1.linux-amd64.tar.gz
$ tar xf prometheus-*.tar.gz




Раскидываем файлы по ФС, заводим пользователя:




# cd prometheus-*
# cp prometheus promtool /usr/local/bin
# mkdir /etc/prometheus /var/lib/prometheus
# cp prometheus.yml /etc/prometheus
# useradd --no-create-home --home-dir / --shell /bin/false prometheus
# chown -R prometheus:prometheus /var/lib/prometheus




В архиве будут два ненужных каталога: console_libraries/ и consoles/. Их не трогаем.




Создаём systemd-юнит:/etc/systemd/system/prometheus.service




[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Restart=on-failure
ExecStart=/usr/local/bin/prometheus 
  --config.file /etc/prometheus/prometheus.yml 
  --storage.tsdb.path /var/lib/prometheus/
ExecReload=/bin/kill -HUP $MAINPID
ProtectHome=true
ProtectSystem=full

[Install]
WantedBy=default.target




Запускаем Prometheus server:




# systemctl daemon-reload
# systemctl start prometheus
# systemctl status prometheus




В статусе должно быть написано “active (running)” — значит работает. Теперь можно сходить на http://localhost:9090 и полюбоваться на интерфейс Prometheus’а. Пока что он бесполезен, но уже можно потыкать.







Установка node exporter




Node exporter надо раскатать на всех машинах, которые вы хотите мониторить. Устанавливается он аналогично серверу. Берём последний билд с https://github.com/prometheus/node_exporter/releases.




$ wget https://github.com/.../node_exporter-0.18.1.linux-amd64.tar.gz
$ tar xf node_exporter-*.tar.gz
# cd node_exporter-*
# cp node_exporter /usr/local/bin
# useradd --no-create-home --home-dir / --shell /bin/false node_exporter




/etc/systemd/system/node_exporter.service




[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
Type=simple
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter

SyslogIdentifier=node_exporter
Restart=always

PrivateTmp=yes
ProtectHome=yes
NoNewPrivileges=yes

ProtectSystem=strict
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=yes

[Install]
WantedBy=multi-user.target




Важно! Если у вас /home вынесен на отдельный раздел, директиву ProtectHome=yes надо убрать, иначе node exporter будет неправильно показывать оставшееся место на разделе /home.




Запускаем node exporter:




# systemctl daemon-reload
# systemctl start node_exporter
# systemctl status node_exporter




Можно посмотреть как node exporter отдаёт метрики:




$ curl -s http://localhost:9100/metrics
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 7.9825e-05
go_gc_duration_seconds{quantile="0.25"} 7.9825e-05
go_gc_duration_seconds{quantile="0.5"} 7.9825e-05
go_gc_duration_seconds{quantile="0.75"} 7.9825e-05
go_gc_duration_seconds{quantile="1"} 7.9825e-05
go_gc_duration_seconds_sum 7.9825e-05
go_gc_duration_seconds_count 1
...




Пока не пытайтесь что-то понять в выводе. Отдаёт и ладно.




Установка alertmanager




Alertmanager — это про алерты. Первое время алертов у вас не будет, поэтому сейчас его можно не ставить. Но лучше всё-таки поставить, чтобы всё необходимое уже было подготовлено. Идём за дистрибутивом на https://github.com/prometheus/alertmanager/releases.




$ wget https://github.com/.../alertmanager-0.18.0.linux-amd64.tar.gz
$ tar xf alertmanager-*.tar.gz
# cd alertmanager-*
# cp alertmanager /usr/local/bin
# mkdir /etc/alertmanager /var/lib/alertmanager
# cp alertmanager.yml /etc/alertmanager
# useradd --no-create-home --home-dir / --shell /bin/false alertmanager
# chown -R alertmanager:alertmanager /var/lib/alertmanager




/etc/systemd/system/alertmanager.service




[Unit]
Description=Alertmanager for prometheus
After=network.target

[Service]
User=alertmanager
ExecStart=/usr/local/bin/alertmanager 
  --config.file=/etc/alertmanager/alertmanager.yml 
  --storage.path=/var/lib/alertmanager/
ExecReload=/bin/kill -HUP $MAINPID

NoNewPrivileges=true
ProtectHome=true
ProtectSystem=full

[Install]
WantedBy=multi-user.target




Запускаем alertmanager:




# systemctl daemon-reload
# systemctl start alertmanager
# systemctl status alertmanager




Веб-интерфейс alertmanager’а доступен на http://localhost:9093. Пока в нём нет ничего интересного.




Установка Grafana




Если у вас Debian/Ubuntu или Redhat/Centos, лучше установить Grafana из пакета. Ссылочки найдёте в описании под видео на https://grafana.com/grafana/download.




$ wget https://dl.grafana.com/oss/release/grafana_6.3.2_amd64.deb
# dpkg -i grafana_6.3.2_amd64.deb




Запускаем grafana:




# systemctl start grafana
# systemctl status grafana




Prometheus, Node exporter, Alertmanager и Grafana по умолчанию слушают на всех сетевых интерфейсах. При необходимости прикрывайтесь фаерволлом от посторонних глаз.




Первичная настройка




Теперь, когда все компоненты установлены, надо подружить их друг с другом. Сперва минимально настроим Prometheus server:/etc/prometheus/prometheus.yml




global:
  scrape_interval:     15s
  evaluation_interval: 15s

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
       - localhost:9093

scrape_configs:
  - job_name: 'node'
    static_configs:
    - targets:
       - localhost:9100
     # - anotherhost:9100




Пока не буду вдаваться в подробности настройки, этим займёмся в следующих статьях. На текущем этапе надо получить пусть примитивный, но работающий мониторинг. Основное что сейчас стоит знать:




  • Отступы в yml — два пробела. Всегда и везде.
  • scrape_interval — с какой периодичностью Prometheus server будет забирать (scrape) метрики с экспортеров.
  • localhost:9093 и localhost:9100 — адреса alertmanager’а и node exporter’а соответственно. Если у вас другие, замените на правильные. Если у вас node exporter установлен на несколько машин, впишите их все.




Теперь попросим prometheus перечитать конфигурационный файл:




# systemctl reload prometheus




В веб-интерфейсе на странице http://localhost:9090/targets появился первый таргет. Он должен быть в состоянии “UP”.







Поздравляю, мониторинг начал мониторить! Теперь можно пойти на вкладку Graph и запросить какую-нибудь метрику, например node_load1 — это одноминутный load average. Там же можно временной график посмотреть:







В повседневной жизни вы вряд ли будете смотреть графики в этом интерфейсе. Гораздо приятнее смотреть графики в Grafana.




Открываем интерфейс Grafana по адресу http://localhost:3000. Логинимся (admin:admin), при желании меняем пароль. Практически всё в Графане настраивается тут же, через веб-интерфейс. Нажимаем на боковой панели Configuration (шестерёнка) → Preferences:







Идём на вкладку Data Sources, добавляем наш Prometheus:







Теперь добавим готовый дашборд Node exporter full. Это лучший дашборд для старта из всех, что я пересмотрел. Идём Dashboards (квадрат) → Manage → Import.







Вписываем 1860 и убираем курсор из поля ввода, иначе не начнёт импортировать. Дальше указываем data source и жмём import.







Поздравляю, самая скучная часть работы проделана! Теперь вы можете наблюдать за жизнью своих серверов в Графане.




Если у вас серьёзные намерения и вы хотите, чтобы все компоненты автоматически запускались после перезагрузки машины, не забудьте сообщить об этом systemd:




# systemctl enable prometheus
# systemctl enable grafana
# systemctl enable alertmanager
# systemctl enable node_exporter




И это всё?




У нас пока нет алертов, не заведены пользователи в Grafana, мы ничего не понимаем в настройке. Да, наш мониторинг пока очень сырой. Но надо же с чего-то начать! Позже я напишу про настройку, про алерты и многое другое. Всё будет, друзья. Всё будет.




Куда копать дальше?




  • Официальная документация Prometheus. Да, она не супер-подробная, и лично мне многое было непонятно вначале, но заглянуть стоит.
  • Блог Robust Perseption, который ведёт Brian Brazil — один из разработчиков Prometheus’а. Статьи короткие и, на мой взгляд, слишком лаконичные. Хочется больше подробностей, больше примеров.
  • Книга Prometheus up and running за авторством всё того же Brian Brazil. Во многом повторяет статьи блога.




Источник: https://laurvas.ru/prometheus-p1/



2021-08-16T10:23:10
Software