Алгоритм действий состоит из следующих шагов:
1.Настройка PHP-FPM на отдачу статусной страницы
2.Настройка Nginx на поддержку статусной страницы PHP-FPM
3.Запуск PHP-FPM-экспортера для сбора метрик с PHP-FPM и отдачи их Prometheus-у
4.Настройка Prometheus-а для сбора метрик с PHP-FPM-экспортера
5.Импортирование/настройка dashboard Grafana для визуализации метрик
6.Настрйка правил Prometheus для мониторинга PHP-FPM показателей
Описание собираемых параметров с помощью статусной страницы в PHP-FPM изложено ранее в статье
1.Настройка PHP-FPM на отдачу статусной страницы
1 |
# nano php-fpm/php-fpm.d/www.conf |
1 2 3 |
pm.status_path = /fpm_status ping.path = /fpm_ping ping.response = pong |
Перезапускаем php-fpm контейнер,чтобы применились настройки
1 |
# docker-compose restart php-fpm |
В данном случае каталог php-fpm.d в Docker-контейнер монтируется с хоста через volume, поэтому достаточно перезапусить контейнер. Если этот каталог копируется при сборке образа в Dockerfile-е, тогда необходимо пересобирать образ контейнера заново и запускать контейнер с новым образом
2.Настройка Nginx на поддержку статусной страницы PHP-FPM
Добавляем поддержку php-fpm URL-а в дефолтном хосте
Важно разрешит доступ к статусной странице Nginx для docker-подсети( 172.16.0.0/12)
Запрос на php-fpm контейнер будет идти с nginx-контейнера,который проксирует запрос при поступлении на nginx запроса типа /fpm_status или /fpm_ping
1 |
# nano nginx/sites/default.conf |
1 2 3 4 5 6 7 8 9 |
location ~ ^/fpm_(status|ping)$ { allow 127.0.0.1; allow 172.16.0.0/12; deny all; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; include fastcgi_params; fastcgi_pass php-upstream; } |
Проверяем синтаксис конфигурационного файла nginx
1 |
# docker-compose exec nginx nginx -t |
Перегружаем nginx
1 |
# docker-compose exec nginx nginx -s reload |
Заходим в любой контейнер, который находится в одной сети с nginx-контейнером + имеет установленный curl и проверяем доступность статусной страницы PHP-FPM путем отправки запроса на установленный ранее location в Nginx
Например, выполним запрос с самого php-fpm-контейнера
1 |
# docker-compose exec php-fpm curl http://nginx/fpm_status |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
pool: www process manager: dynamic start time: 14/Aug/2019:15:10:22 +0000 start since: 104288 accepted conn: 5549 listen queue: 0 max listen queue: 0 listen queue len: 128 idle processes: 2 active processes: 1 total processes: 3 max active processes: 3 max children reached: 0 slow requests: 0 |
3.Запуск PHP-FPM-экспортера для сбора метрик с PHP-FPM и отдачи их Prometheus-у
Если не используется docker-compose
php-fpm-экспортер запускаем в той же docker-сети, в которой и запущен nginx-контейнер,чтобы средствами Docker-а экспортер смог разименовать имя nginx-контейнера в его IP-адрес и подключиться по этому IP-адресу для отправки на него запроса для получения статусной страницы php-fpm http://nginx/fpm_status
1 |
# docker run -d -p 10.103.90.1:9114:8080 --name php-fpm-exporter --network laradock_frontend php-fpm-exporter --endpoint http://nginx/fpm_status --addr 0.0.0.0:8080 |
Если используется docker-compose
В данном случае nginx-exporter добавим в docker-compose, с помощью которого запущенны различные приложения, включая nginx, куда направляет свой запрос php-fpm-экспортер для сбора метрик
Добавляем php-fpm-exporter в docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
### PHP-FPM Exporter ######################################### php-fpm-exporter: image: bakins/php-fpm-exporter:v0.6.1 container_name: php-fpm-exporter restart: unless-stopped command: ["--endpoint", "http://nginx/fpm_status", "--addr", "0.0.0.0:8080"] ports: - "10.103.90.1:9114:8080" networks: - frontend #mem_limit: 128m # for docker-compose v2 only #mem_reservation: 64m # for docker-compose v2 only logging: driver: "json-file" options: max-size: "5m" |
В качестве command передаются пару аргументов:
1 |
--endpoint |
– URL, по которому доступна статусная страница PHP-FPM( для которой мы настраивали соответственно Nginx и PHP-FPM) (по дефолту используется «http://127.0.0.1:9000/status»)
1 |
--addr |
– на каких сетевых интерфейсах и порте слушать запросы для сбора метрик с php-fpm-экспортера( по умолчанию используется «127.0.0.1:8080»)
Мне необходимо прокинуть порт,на котором слушает запросы php-fpm-exporter(дефолтный 8080) наружу на, например, туннельный IP-адрес(10.103.90.1) и на порт, например,9114, чтобы Prometheus смог подключиться к с php-fpm-экспортеру для сбора метрик с него.
Проверка синтаксиса docker-compose.yml файла
1 |
# docker-compose config |
Создание и запуск php-fpm-exporter сервиса
1 |
# docker-compose up -d php-fpm-exporter |
Проверка корректности запуска php-fpm-exporter
1 |
# docker-compose ps | grep php-fpm-exporter |
1 |
php-fpm-exporter /php-fpm-exporter --endpoi ... Up 10.103.90.1:9114->8080/tcp |
1 |
# netstat -nlptu | grep 9114 |
1 |
tcp 0 0 10.103.90.1:9114 0.0.0.0:* LISTEN 2445/docker-proxy |
Проверка доступности метрик с php-fpm-exporter-а
1 |
# curl 10.103.90.1:9114/metrics | grep -vE "^#" |
1 2 3 4 5 6 7 8 9 10 11 |
phpfpm_accepted_connections_total 3769 phpfpm_active_max_processes 3 phpfpm_listen_queue_connections 0 phpfpm_listen_queue_length_connections 128 phpfpm_listen_queue_max_connections 0 phpfpm_max_children_reached_total 0 phpfpm_processes_total{state="active"} 1 phpfpm_processes_total{state="idle"} 2 phpfpm_scrape_failures_total 0 phpfpm_slow_requests_total 0 phpfpm_up 1 |
С мониторинг хоста
1 |
# curl 10.103.90.1:9114/metrics |
Получаем такой же успешный ответ
4.Настройка Prometheus-а для сбора метрик с PHP-FPM-экспортера
Добавляем php-fpm-экпортер в service discovery файл
1 |
# nano prometheus/sd/targets-php-fpm-exporter.yml |
1 2 3 4 5 6 7 |
… - targets: - f3.mydomain.com:9114 labels: env: staging job: php-fpm-exporter … |
Подключаем этот service discovery файл в Prometheus
1 |
# nano prometheus/prometheus.yml |
1 2 3 4 5 6 |
… - job_name: 'php-fpm-exporter' file_sd_configs: - files: - sd/targets-php-fpm-exporter.yml … |
Проверка синтаксиса конфиг.файла Prometheus и файлов с правилами
1 |
# (cd /home/myusername/monstack && ../prometheus-2.10.0.linux-amd64/promtool check config ./prometheus/prometheus.yml && echo OK || echo FAIL) |
Перечитываем конф.файл Prometheus
1 |
# curl -X POST https://adminuser:adminpassword@prometheus.mydomain.com/-/reload |
После чего проверяем в Prometheus наличие новой цели для мониторинга
Prometheus->Status->Target->
5.Импортирование/настройка dashboard Grafana для визуализации метрик
В Grafana импортируем dashboard отсюда
https://grafana.com/grafana/dashboards/3901
Я изменил импортированный по вышеуказанной ссылке дашбоард
PHP-FPM-dashboard.zip
6.Настрйка правил Prometheus для мониторинга PHP-FPM показателей
Добавление нескольких правил для мониторинга PHP-FPM
1.Запущен ли PHP-FPM (php-fpm_is_running)
2.Относительное увеличение обработанных запросов(свидетельствует об увеличении полезной нагрузки/атаки DOS/DDOS и т.д.)(php-fpm_high_number_accepted_connections)
3.Увеличение параметра максимального количества подключений(php-fpm_number_maximun_active_processes)
4.Увеличение параметра достижения лимита количества дочерних процессов(php-fpm_max_children_reached_total)
1 |
# nano prometheus/services_rules.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
groups: - name: php-fpm rules: - alert: php-fpm_is_running expr: phpfpm_up == 0 for: 30s labels: severity: critical annotations: summary: "Critical: PHP-FPM is down on the host {{ $labels.instance }}." description: "PHP-FPM has been down for more than 30 seconds" - alert: php-fpm_high_number_accepted_connections expr: rate(phpfpm_accepted_connections_total[5m]) > 30 for: 3m labels: severity: critical annotations: description: "Critical: PHP-FPM high number accepted connections(30con/s) on the host {{ $labels.instance }} for more than 3 minutes" summary: "PHP-FPM number active connections is {{ $value }}" - alert: php-fpm_number_maximun_active_processes expr: increase (phpfpm_active_max_processes[30s]) > 0 for: 10s labels: severity: warning annotations: description: "Warning: PHP-FPM number maximum of active processes is increasing on the host {{ $labels.instance }} for the last 30 seconds" summary: "PHP-FPM number maximum active processes is increasing" - alert: php-fpm_max_children_reached_total expr: increase (phpfpm_active_max_processes[30s]) > 0 for: 10s labels: severity: critical annotations: description: "Critical: PHP-FPM number max children reached total is increasing on the host {{ $labels.instance }} for the last 30 seconds" summary: "PHP-FPM number max children reached total is increasing" |
Источник:
https://github.com/bakins/php-fpm-exporter
https://github.com/bakins/php-fpm-exporter/releases
https://grafana.com/grafana/dashboards/3901