Перебирал несколько ролей в Ansible Galaxy для установки и настройки Prometheus – но в конце-концов решил делать всё по-своему.
Будем использовать Docker Compose, который будет запускать сам Prometheus и node_exporter
.
Содержание
Роль Docker Compose
Начнём с добавления роли docker-compose
.
В корне репозитория создаём каталог roles/docker-compose/tasks
:
[simterm]
$ mkdir -p roles/docker-compose/tasks
[/simterm]
Создаём файл roles/docker-compose/tasks/main.yml
:
- name: Installing docker compose pip: name: docker-compose state: present
pip
устанавливается из роли common
:
[simterm]
$ cat roles/common/tasks/main.yml - name: Update APT apt: update_cache: yes - name: Install python-apt package: name: python-apt state: latest - name: Install python-pip package: name: python-pip state: latest
[/simterm]
Добавляем вызов docker-compose
в provision.yml
, сейчас полностью он выглядит так:
- hosts: all become: true roles: - role: common - role: jnv.unattended-upgrades unattended_mail: [email protected] # - role: jaywink.letsencrypt # letsencrypt_domain: "{{ inventory_hostname }}" # letsencrypt_email:[email protected] # letsencrypt_request_www: false # letsencrypt_pause_services: nginx - role: nginx nginx_allow_kiev_ip: 194.***.***.45 nginx_allow_berlin_ip: 37.***.***.130 - role: mongrelion.docker - role: docker-compose
Роль letsencrypt
закомментирована, что бы не вызывать её каждый раз, т.к. Lets Encrypt перестанет выполнять авторизацию вообще с сообщением “Error creating new cert :: too many certificates already issued for exact set of domains“.
Есть повод переписать и эту роль, и добавить проверку наличия сертификата перед тем, как вызывать certbot-auto
.
Пушим:
[simterm]
$ git add provision.yml && git commit -m "docker compose install" && git push
[/simterm]
Запускаем Jenkins:
... TASK [docker-compose : Installing docker compose] ****************************** sudo -H -S -n changed: [dev.monitoring.domain.ms] PLAY RECAP ********************************************************************* dev.monitoring.domain.ms : ok=25 changed=5 unreachable=0 failed=0 [Pipeline] } [Pipeline] // stage [Pipeline] } $ docker stop --time=1 17711b30159a4f21ec5dce3cb5e7d03dabf5b0c4afa0c178e8df97d3290b126d $ docker rm -f 17711b30159a4f21ec5dce3cb5e7d03dabf5b0c4afa0c178e8df97d3290b126d [Pipeline] // withDockerContainer [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS
Проверяем на сервере:
[simterm]
root@jm-monitoring-dev-vm:~# docker-compose --version docker-compose version 1.16.1, build 6d1ac219
[/simterm]
Роль Prometheus сервера
Следующим шагом – создадим свою роль для установки и запуска Prometheus сервера.
Создаём каталоги:
[simterm]
$ mkdir -p roles/prometheus/{tasks,handlers,files,vars}
[/simterm]
files
В каталог files
добавим compose-файл для запуска.
Создаём roles/prometheus/files/docker-compose.yml
(v2, т.к. Ansible модуль docker_service
3 версию (пока) не поддерживает):
version: '2' services: prometheus: image: prom/prometheus expose: - 9090 ports: - 9090:9090
vars
Перед тем, как создать tasks
– добавим несколько переменных в файл roles/prometheus/vars/main.yml
:
prometheus_user: prometheus prometheus_group: prometheus prometheus_home: /opt/prometheus
tasks
Переходим к tasks
, для запуска Docker Compose используем docker_service
модуль.
Потребуется:
- создать пользователя
- создать каталог для файлов Prometheus
- скопировать
docker-compose.yml
- запустить контейнер
Создаём roles/prometheus/tasks/main.yml
:
- name: Create Prometheus user user: name: "{{ prometheus_user }}" shell: /bin/false groups: "{{ prometheus_group }}" - name: Create Prometheus Opt directory file: path: "{{ prometheus_home }}" state: directory owner: "{{ prometheus_user }}" group: "{{ prometheus_group }}" mode: 0775 recurse: yes - name: Copy compose file copy: src: files/docker-compose.yml dest: "{{ prometheus_home }}/docker-compose.yml" owner: "{{ prometheus_user }}" group: "{{ prometheus_group }}" - name: Start Prometheus service docker_service: project_src: "{{ prometheus_home }}"
Добавляем роль в provision.yml
:
... - role: prometheus
Вроде всё ОК – сохраняем, пушим:
[simterm]
$ git status roles/prometheus/ On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) roles/prometheus/files/ roles/prometheus/tasks/ roles/prometheus/vars/ $ git add -A && git commit -m "prometheus role" && git push
[/simterm]
Запускаем Jenkins:
... TASK [prometheus : Create Prometheus user] ************************************* ok: [dev.monitoring.domain.ms] sudo -H -S -n TASK [prometheus : Create Prometheus Opt directory] **************************** sudo -H -S -n ok: [dev.monitoring.domain.ms] TASK [prometheus : Copy compose file] ****************************************** sudo -H -S -n sudo -H -S -n ok: [dev.monitoring.domain.ms] TASK [prometheus : Start Prometheus service] *********************************** sudo -H -S -n changed: [dev.monitoring.domain.ms] PLAY RECAP ********************************************************************* dev.monitoring.domain.ms : ok=5 changed=1 unreachable=0 failed=0 [Pipeline] } [Pipeline] // stage [Pipeline] } $ docker stop --time=1 980dfa37ed7ce303810a73b2c5389d5dd1cd97696e63fd0aa0ee0bd73d52a36e $ docker rm -f 980dfa37ed7ce303810a73b2c5389d5dd1cd97696e63fd0aa0ee0bd73d52a36e [Pipeline] // withDockerContainer [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS
Проверяем на сервере:
[simterm]
root@jm-monitoring-dev-vm:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 78c35a2e8fc4 prom/prometheus "/bin/prometheus -..." About a minute ago Up 8 seconds 0.0.0.0:9090->9090/tcp prometheus_prometheus_1
[/simterm]
Файл настроек:
[simterm]
root@jm-monitoring-dev-vm:~# docker exec -ti 78c35a2e8fc4 cat /etc/prometheus/prometheus.yml # my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Attach these labels to any time series or alerts when communicating with # external systems (federation, remote storage, Alertmanager). external_labels: monitor: 'codelab-monitor' # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: # - "first.rules" # - "second.rules" # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ['localhost:9090']
[/simterm]
Каталог:
[simterm]
root@jm-monitoring-dev-vm:~# ls -l /opt/prometheus/ total 4 -rwxrwxr-x 1 prometheus prometheus 120 Sep 29 11:48 docker-compose.yml
[/simterm]
Пользователь:
[simterm]
root@jm-monitoring-dev-vm:~# id prometheus uid=999(prometheus) gid=998(prometheus) groups=998(prometheus)
[/simterm]
Готово.
Продолжаем.
Роль node_exporter
node_exporter
можно запустить либо как сервис на хост-системе, либо – контейнером из того же docker-compose.yml
, который используется для запуска самого Prometheus, используя образ node-exporter
.
Пример запуска контейнером можно посмотреть тут>>>, но т.к. всё-таки он не относится к самому стеку prometheus-сервера, а является “внешним” сервисом (как по мне, ибо экспортёров будет много) – то пока запустим его сервисом на хосте.
Для node_exporter
– вполне работает вариант из Ansible Galaxy – UnderGreen.prometheus-node-exporter.
Обновляем requirements.yml
:
- src: jnv.unattended-upgrades - src: mongrelion.docker - src: jaywink.letsencrypt - src: UnderGreen.prometheus-node-exporter
И provision.yml
:
... - role: UnderGreen.prometheus-node-exporter prometheus_node_exporter_config_flags: 'web.listen-address': '127.0.0.1:9100' 'log.level': 'info'
Сохраняем, запускаем Jenkins билд, проверяем метрики node_exporter
на сервере:
[simterm]
root@jm-monitoring-dev-vm:~# curl -s localhost:9100/metrics | head # HELP go_gc_duration_seconds A summary of the GC invocation durations. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 0 go_gc_duration_seconds{quantile="0.25"} 0 go_gc_duration_seconds{quantile="0.5"} 0 go_gc_duration_seconds{quantile="0.75"} 0 go_gc_duration_seconds{quantile="1"} 0 go_gc_duration_seconds_sum 0 go_gc_duration_seconds_count 0 # HELP go_goroutines Number of goroutines that currently exist.
[/simterm]
Добавление target
Теперь переходим к настройке самого Prometheus.
Что бы получать метрики с node_exporter
– нам надо добавить новый target
в конфиг prometheus.yml
.
В каталоге roles/prometheus/files/
создаём файл prometheus.yml
, и в него добавляем таргет localhost:9100
:
global: scrape_interval: 15s evaluation_interval: 15s external_labels: monitor: 'jm-dev-monitor' rule_files: # - "first.rules" # - "second.rules" scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - targets: ['localhost:9100']
Далее – это конфиг необходимо скопировать на сервер мониторинга.
В roles/prometheus/vars/main.yml
добавляем переменную prometheus_home
:
... prometheus_configs: /etc/prometheus
В roles/prometheus/tasks/main.yml
добавляем создание директории для файлов настроек Prometheus и копирование файла prometheus.yml
, содержимое tasks/main.yml
сейчас получается следующим:
- name: Create Prometheus user user: name: "{{ prometheus_user }}" shell: /bin/false groups: "{{ prometheus_group }}" - name: Create Prometheus Opt directory file: path: "{{ prometheus_home }}" state: directory owner: "{{ prometheus_user }}" group: "{{ prometheus_group }}" mode: 0775 recurse: yes - name: Create Prometheus config directory file: path: "{{ prometheus_configs }}" state: directory owner: "{{ prometheus_user }}" group: "{{ prometheus_group }}" mode: 0775 recurse: yes - name: Copy Prometheus config copy: src: files/prometheus.yml dest: "{{ prometheus_configs }}/prometheus.yml" owner: "{{ prometheus_user }}" group: "{{ prometheus_group }}" - name: Copy compose file copy: src: files/docker-compose.yml dest: "{{ prometheus_home }}/docker-compose.yml" owner: "{{ prometheus_user }}" group: "{{ prometheus_group }}" - name: Start Prometheus service docker_service: project_src: "{{ prometheus_home }}"
Теперь – надо запамить prometheus.yml
в контейнер при запуске.
Prometheus по умолчанию ищет файл в /etc/prometheus
– добавляем в docker-compose.yml
новый volume
:
... volumes: - /etc/prometheus/:/etc/prometheus/
Что бы Prometheus мог обращаться к localhost хоста как localhost саого контейнера – устанавливает тип сети host
(см. network_mode
)
В результате docker-compose.yml
получается сейчас таким:
version: '2' services: prometheus: network_mode: "host" image: prom/prometheus expose: - 9090 ports: - 9090:9090 volumes: - /etc/prometheus/:/etc/prometheus/
Вроде ОК – пушим, запускаем билд Jenkins и проверяем targets
:
Метрики в graphs
:
В целом – на это пока всё.
Далее надо будет:
- обновить Azure Resource group – добавить подключение диска, в котором будут хранится данные Prometheus
- добавить Grafana
- добавить и настроить Alertmanager
- cAdvisor или
container-exporter
для мониторинга Docker на самом хосте мониторинга - и наконец-то начать подключать внешние хосты сервисы под мониторинг
Вроде всё…