Сегодня мы рассмотрим сбор и визуализацию метрик производительности Red Hat Enterprise Linux 8 с помощью инструментов Performance Co-Pilot (PCP), Grafana и Bpftrace, а также новые возможности по контролю производительности, которые появились в веб-консоли RHEL 8.4.
Основы работы
В наших примерах мы будем использовать следующую конфигурацию:
Два сервера RHEL 8.3 (с именами server-1 и server-2).
Grafana версии grafana-6.7.4-3.el8.x86_64.
PCP версии pcp-5.1.1-3.el8.x86_64.
По умолчанию Performance Co-Pilot не устанавливается вместе с RHEL 8, поэтому его надо инсталлировать самостоятельно. Установим его на server-1 и server-2, выполнив на них следующую команду:
yum install pcp-zeroconf -y
После того, как Performance Co-Pilot установлен и запущен, можно посмотреть, какие встроенные метрики производительности он предлагает:
pminfo | wc -l
3101
pminfo | grep kernel | head -n 15
kernel.all.load
kernel.all.intr
kernel.all.pswitch
kernel.all.sysfork
kernel.all.running
kernel.all.blocked
kernel.all.boottime
kernel.all.hz
kernel.all.uptime
kernel.all.idletime
kernel.all.nusers
kernel.all.nroots kernel.all.nsessions
kernel.all.lastpid
kernel.all.runnable
Вывести значения нужной метрики можно командой pmrep:
pmrep kernel.all.load -s 5
k.a.load k.a.load k.a.load
1 minute 5 minute 15 minut
0.020 0.020 0.080
0.020 0.020 0.080
0.020 0.020 0.080
0.020 0.020 0.080
0.020 0.020 0.080
Опция -s 5 в примере выше говорит, что мы хотим вывести на экран только 5 первых значений метрики.
Чтобы метриками могли пользоваться другие приложения, надо включить pmproxy и открыть соответствующий порт на межсетевом экране:
systemctl enable pmproxy
systemctl start pmproxy
firewall-cmd --add-service=pmproxy --permanent
firewall-cmd --reload
Итак, Performance Co-Pilot установлен и настроен, теперь пора заняться Grafana, чтобы перейти к визуализации метрик.
Установим grafana на server-1, выполнив на нем следующие команды:
yum install grafana grafana-pcp -y
systemctl enable grafana-server
systemctl start grafana-server
firewall-cmd –add-service=grafana –permanent
firewall-cmd –reload
Теперь в браузере откроем http://server-1:3000 и залогинимся как пользователь admin с паролем admin. Это пароль по умолчанию и после первого входа его будет предложено заменить на более безопасный.
Далее, в панели слева надо щелкнуть значок с шестеренкой, чтобы перейти в настройки (Configuration), и там щелкнуть Plugins. Теперь в поле поиска вводим «Performance Co-Pilot App», щелкаем это приложение и затем нажимаем Enable.
Опять щелкаем Configuration, затем Data Sources, жмем Add Data Source, наводим курсор на PCP Vector и жмем появившуюся кнопку Select. В открывшейся форме, в секции HTTP вводим «http://localhost:44322» в поле URL, затем жмем Save & Test внизу формы. Если все нормально, то получим сообщение «Data source is working».
В панели слева щелкаем значок с квадратиками (Dashboard), затем Manage и потом PCP Vector Host Overview.
В открывшейся панели увидим графики метрик для сервера server-1, такие как:
CPU Percentage
Load Average
Memory Utilization
Disk Utilization
Per-CPU busy (user/system)
CPU user%,system%,interrupt%,wait%
Scheduler context switches per second and runnable processes.
Memory Used/Cached/Free/Page Fault Rate/Hard Fault Rate
Network throughput in/out
Network drops in/out
Network packets in/out
TCP connections/timeouts/close-waits/time wait/established/listen errors/retransmits
Disk latency/iops/throughput/utilization
Таким образом, мы получили весьма разностороннюю контрольную панель для отслеживания метрик производительности локального хоста в реальном времени.
Мониторинг нескольких хостов
Теперь разберем, как использовать pmseries и Redis, чтобы сохранять данные производительности нескольких хостов и анализировать их в ретроспективе.
Итак, у нас есть два сервера. На server-1 будет выполняться Redis и осуществляться сбор метрик PCP со всех наших хостов (в данном случае двух). Поэтому на server-1 должно быть достаточно места для базы данных Redis. При установке PCP по умолчанию это означает примерно 100 МБ на диске и 200 МБ ОЗУ на каждый контролируемый хост. Механизм, отвечающий за хранение данных в БД Redis, называется pmseries, и чтобы установить его на server-1, подредактируем файл /etc/pcp/pmproxy/pmproxy.conf, чтобы в секции [pmproxy] было прописано следующее:
# support Redis protocol proxying
redis.enabled = true
Затем, в этом же файле, в секции [pmseries] надо прописать:
# allow REST API queries of fast, scalable time series
enabled = true
Далее, чтобы установить, запустить и на постоянку включить Redis на server-1, выполним на нем следующие команды:
yum install redis -y
systemctl start redis
systemctl enable redis
После чего надо перезапустить несколько сервисов:
systemctl restart pmcd pmlogger pmproxy
Всё, теперь server-1 будет писать в базу метрики производительности всех хостов, на которые настроен pmlogger. Пока что pmlogger сконфигурирован только в расчете на server-1, поэтому надо произвести настройку и для server-2.
Для этого на server-2 в файле /etc/sysconfig/pmcd изменим дефолтное значение параметра PMCD_LOCAL с 1 на 0, чтобы разрешить удаленные подключения к сервису pmcd:
# Behaviour regarding listening on external-facing interfaces;
# unset PMCD_LOCAL to allow connections from remote hosts.
# A value of 0 permits remote connections, 1 permits local only.
PMCD_LOCAL=0
Теперь разрешим подключение на уровне сервисов:
firewall-cmd --add-service=pmcd --permanent
firewall-cmd --reload
Еще надо разрешить привязку pcp к портам unreserved:
setsebool -P pcp_bind_all_unreserved_ports on
И наконец, остается перезапустить сервисы pcp:
systemctl restart pmcd pmlogger
Теперь server-2 настроен таким образом, что к нему может подключаться агент pmlogger и запрашивать логи.
Возвращаемся на server-1 и говорим агенту pmlogger, что у нас есть server-2. Для этого открываем файл /etc/pcp/pmlogger/control.d/remote и добавляем туда следующую строку:
server-2 n n PCP_LOG_DIR/pmlogger/server-2 -r -T24h10m -c config.remote
Перезапускаем pmlogger:
systemctl restart pmlogger
После чего для проверки выполним следующие команды:
cd /var/log/pcp/pmlogger/server-2
ls *.0
Если все нормально, то мы увидим файл, заканчивающийся на «.0»:
20200923.16.41.0
Таким образом, мы проверяем, что server-1 может собирать pcp-метрики с server-2.
Теперь возвращаемся в Grafana (http://server-1:3000) и смотрим, как работать с метрикам, собранными через redis.
Щелкаем Configuration, затем Data Sources, затем Add Data Source. Наводим курсор на PCP Redis и жмем появившуюся кнопку Select. В открывшейся форме, в секции HTTP вводим «http://localhost:44322» в поле URL, и затем жмем Save & Test внизу формы. Если все нормально, то получим сообщение «Data source is working».
На этом настройка закончена и пора смотреть, как все работает. Щелкаем значок Dashboard, затем Manage и затем щелкаем опцию PCP Redis Host Overview.
По умолчанию панель PCP Redis Host Overview показывает данные за последние шесть часов, но этот интервал можно укоротить. Метрики следующие:
load average
memory utilization
per-cpu busy (user/sys)
context switches per second
runnable processes
memory (used/cached/free)
network throughput in/out
network drops in/out
network packets in/out
tcp timeouts/listen errors/retransmits
disk latency/iops/throughput/utilization
Как видите, прямо из коробки можно получить уйму полезных данных по всем хостам, метрики которых пишутся в базу данных Redis. Кстати, хост, отображаемый на экране, выбирается с помощью раскрывающегося меню Host в левом верхнем углу. Таким образом, можно вести мониторинг на уровне хостов в реальном времени, а также анализировать данные в ретроспективе.
Вы можете полностью автоматизировать процедуру установки и настройки, сбора и визуализации метрик, воспользовавшись системной ролью ansible – rhel-system-roles.metrics , которая входит в состав дистрибутива:
Углубленный мониторинг с помощью Performance Co-Pilot и Bpftrace
Теперь покажем, как использовать Performance Co-Pilot вместе с bpftrace для визуализации низкоуровневых метрик ядра, которые обычно не видны стандартными средствами Linux. Вообще говоря, если с помощью сценария bpftrace из ядра Linux можно извлечь какое-то значение для карт eBPF (обобщенная структура «ключ-значение, которая используется для хранения данных в программах eBPF), то это все можно визуализировать с помощью Performance Co-Pilot.
Для начала посмотрим, как сконфигурировать наше dev-окружение для работы с bpftrace и Performance Co-Pilot. Итак, Performance Co-Pilot и Grafana у нас уже настроены и работают. Теперь установим на server-1 модуль pcp-pmda-bpftrace, выполним на нем следующие команды:
yum install bpftrace pcp-pmda-bpftrace -y
cd /var/lib/pcp/pmdas/bpftrace
./Install
Проверим, что bpftrace pmda установился правильно, запустив следующую команду:
pmrep bpftrace.scripts.runqlat.data_bytes -s 5
Если все хорошо, то мы должны получить результаты пяти замеров (в микросекундах):
b.s.r.data_bytes
byte/s
N/A
586.165
590.276
588.141
589.113
Теперь, когда bpftrace pmda работает с Performance Co-Pilot, можно начинать интегрировать их вместе с Grafana. Пока что мы разберем это на примере dev-среды, а к продакшну вернемся позже.
Сначала предоставим доступ, создав в пользователя Performance Co-Pilot с именем metrics:
yum install cyrus-sasl-scram cyrus-sasl-lib -y
useradd -r metrics
passwd metrics
saslpasswd2 -a pmcd metrics
chown root:pcp /etc/pcp/passwd.db
chmod 640 /etc/pcp/passwd.db
Команда saslpasswd2 задает пароль, который мы будем использовать, и добавляет пользователя metrics в sasl-группу pmcd, чтобы он имел доступ к данным pcp.
Также надо, чтобы в файле /etc/sasl2/pmcd.conf были две следующие строки:
mech_list: scram-sha-256
sasldb_path: /etc/pcp/passwd.db
Перезапустим pcp:
systemctl restart pmcd
Теперь надо настроить bpftrace pmda так, чтобы этот только что созданный пользователь мог его использовать его. ВНИМАНИЕ: этот шаг предназначен только для целей разработки, но не для продакшн. Для этого отредактируем файл /var/lib/pcp/pmdas/bpftrace/bpftrace.conf , чтобы в секции [dynamic_scripts] были два следующих элемента:
enabled=true
allowed_users=root,metrics
После чего надо переустановить bpftrace pmda:
cd /var/lib/pcp/pmdas/bpftrace
./Remove
./Install
Теперь в браузере можно открыть Grafana (http://server-1:3000) и войти в систему как пользователь admin (пароль которого мы задали выше).
В интерфейсе Grafana щелкните значок Configuration, затем Data Sources, затем Add Data Source, прокрутите вниз до элемента PCP bpftrace, наведите на него курсор и щелкните появившуюся кнопку Select.
В поле URL введите «http://localhost:44322», в поле Auth выберите Basic auth, в появившейся секции Basic Auth Details введите имя пользователя metrics и пароль, заданный ранее через команду saslpasswd2. После чего щелкнитеSave & Test, и, если все нормально, вы должны получить сообщение «Data source is working».
Теперь щелкните значок Dashboards и затем Manage. В списке появится панель с именем PCP bpftrace System Analysis, щелкните ее. Здесь есть несколько метрик. Щелкните стрелку вниз рядом с CPU usage и нажмите Edit. Здесь вы увидите запрос, который представляет собой реальный bpftrace-сценарий, и в данном случае он наполняет bpf-карту @cpu данными по использованию процессора. Grafana просто берет эту bpf-карту и визуализирует ее.
Теперь посмотрим, как можно использовать сценарии bpftrace для визуализации данных ядра, таких как количество pid в секунду, представленных через fork. Для этого есть готовый сценарий pidpersec.bt и его ключевой фрагмент, который нам нужен, следующий:
tracepoint:sched:sched_process_fork
{
@ = count();
}
По сути, этот сценарий считает количество вызовов sched_process_fork и пишет его в карту bpf, которую мы затем визуализируем с помощью Grafana.
Теперь создадим свою панель, которая и будет все это отображать. Возвращаемся на панель PCP bpftrace System Analysis и жмем кнопку Add Panel, после чего на экране появляется новая панель с двумя кнопками, жмем Add Query.
Рядом с надписью Query есть раскрывающийся список, выбираем в нем PCP bpftrace, и в текстовом поле Query A вводим следующий сценарий bpftrace:
tracepoint:sched:sched_process_fork
{
@ = count();
}
Теперь нажимаем конфигурационную кнопку General и задаем имя панели – «Processes Per Second». После чего возвращаемся в основное окно PCP bpftrace System Analysis и видим, что эта метрика появилась на панели. При желании эту панель можно сохранить.
Это всё здорово, но нам пришлось предоставить пользователю grafana доступ к пользователю метрик pcp, и теперь он может запускать в системе любой сценарий bpftrace. Это не страшно в dev-среде, но никак не годится для продакшн. Поэтому нам нужен другой способ предоставлять пользователям наш bpftrace-сценарий, который бы не позволял им запускать любые другие сценарии bpftrace.
Сделать это можно с помощью пакета bpftrace pmda. Сценарии bpftrace, хранящиеся в /var/lib/pcp/pmdas/bpftrace/autostart, загружаются как обычные метрики Performance Co-Pilot в тот момент, когда загружается bpftrace pmda.
Поэтому отредактируем файл /var/lib/pcp/pmdas/bpftrace/autostart/pidpersec.bt следующим образом:
tracepoint:sched:sched_process_fork
{
@ = count();
}
Сохраним его, и затем выполним следующий команды:
cd /var/lib/pcp/pmdas/bpftrace/
./Remove
./Install
pminfo | grep pidpersec
Вывод должен быть примерно такой:
bpftrace.scripts.pidpersec.data.root
bpftrace.scripts.pidpersec.data_bytes
bpftrace.scripts.pidpersec.code
bpftrace.scripts.pidpersec.probes
bpftrace.scripts.pidpersec.error
bpftrace.scripts.pidpersec.exit_code
bpftrace.scripts.pidpersec.pid
bpftrace.scripts.pidpersec.status
Поскольку мы не задали имя нашей bpf-карты, pmda именует ее как root. Именно этого мы и добивались, и теперь мы можем обращаться к ней с запросами:
pmrep bpftrace.scripts.pidpersec.data.root -s 5
И получать ответ вроде такого:
b.s.p.d.root
/s
N/A
3.984
31.049
0.000
0.000
Теперь эти метрики можно взять и визуализировать средствами grafana, не предоставляя grafana-пользователю каких-то особых привилегий, поскольку теперь это стандартные метрики Performance Co-Pilot.
Для этого вернемся в Grafana, щелкнем значок Dashboards, затем Manage, затем PCP Vector Host Overview, затем Add Panel и в новой панели нажмем кнопкуAdd Query.
В раскрывающемся меню рядом с надписью Query выберем PCP Vector и в поле A-запроса введем следующее:
bpftrace.scripts.pidpersec.data.root
Теперь щелкаем значок General и вводим имя «Processes per Second».
Возвращаемся на панель PCP Vector Host Overview и видим там график по bpf-карте, которая генерируется нашим сценарием bpftrace обычным пользователем без каких-то особых разрешений. Теперь все это можно использовать в продакшн.
Именно так связку pcp-pmda-bpftrace можно использовать для предоставления метрик Linux-ядра системе визуализации Grafana.
Надо отметить, что работа через сценарии bpftrace означает, что они будут выполняться все время, постоянную создавая дополнительную нагрузку. Поэтому этот аспект тоже надо контролировать.
Визуализация данных производительности в веб-консоли RHEL 8.4
Ниже мы рассмотрим некоторые из улучшений RHEL 8.4 в плане контроля производительности, которые упрощают поиск и устранение неисправностей, предлагают улучшенную визуализацию, помогают быстрее и лучше оценивать состояние систем.
Новая веб-консоль
Представьте, что у вас есть всего пара минут, чтобы проанализировать текущие или ретроспективные данные производительности процессора, памяти, дисков и сети, оценить степень использования и перегруженности (saturation) этих ресурсов, а также количество ошибок. Возможно ли это?
Да, возможно. Новая веб-консоль RHEL 8.4 позволяет мгновенно увидеть ключевые показатели производительности, быстрее и четче понять, с чего стоит начать устранение проблем, касающихся как локальной системы, так и сетевого окружения.
Метрики производительности можно найти в консоли, в разделе System -> Overview - Usage card. Для просмотра исторических данных необходимо установить пакет cockpit-pcp (см. выше), это можно сделать прямо на экране Usage card.
Новый интерфейс консоли разделен на две секции. В верхней части экрана расположены четыре плитки Usage card, отображающие текущие показатели производительности процессора, памяти, дисков и сети:
На плитке CPU отображается утилизация и перегрузка процессорных ресурсов, а также топ наиболее активных процессов. Плитка памяти показывает, как используется ОЗУ и файл подкачки, а также основные сервисы-потребители памяти. На плитке дисков собраны IO-метрики чтения-записи, а также процент занятых дисковых ресурсов. Плитка сети показывает сетевой ввод-вывод по каждому сетевому интерфейсу.
Нижняя часть экрана, при условии, что у вас установлена и включена коллекция метрик pcp (мы рассматривали это в начале статьи), выглядит примерно так:
Здесь представлены данные производительности, от самых последних до тех, что были собраны несколько недель назад. Слева отображается список событий, которые могут представлять интерес с точки зрения производительности; время событий синхронизируется с часами часам локальной машины.
Четыре диаграммы справа – это визуализация метрик процессора, памяти, дисков и сети. Слева от вертикальной оси отображаются показатели использования, справа – показатели перегруженности (saturation). При наведении курсора на диаграмму появляется подсказка с точным значением в соответствующий момент времени. Эти диаграммы помогают лучше понять, на что обратить внимание при устранении проблем производительности, а также отследить время, когда они стали проявляться.
Диаграммы производительности flame graph
Иногда для того, чтобы локализовать первоисточник проблем производительности, требуется углубиться в детали, которых просто нет в новой веб-консоли RHEL. На этот случай в RHEL есть специальные диаграммы производительности процессора, которые называются flame graphs.
Они позволяют спрофилировать, кто потребляет процессорные циклы, и быстро определить, где именно этих циклов тратится чересчур много. Важный момент: это делается быстро, просто и наглядно, а не через просмотр бесконечных экранов с данными трассировки стека, как раньше.
Прежде чем читать дальше, убедитесь, что у вас на сервере установлены пакеты perf и js-d3-flame-graph.
Собрать данные для flame graph можно с помощью команды perf. Для этого ее надо запустить, как показано ниже, дать поработать, скажем, 30 секунд, и затем остановить сбор данных, нажав Ctrl+C в терминале.
[root@bigdemo1 ~]# perf script record flamegraph -F 99 -g
^C
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 1.194 MB perf.data (3448 samples) ]
Чтобы затем выдать собранные данные в flame graph, надо запустить следующую команду:
[root@bigdemo1 ~]# perf script report flamegraph
Она выдаст на экран следующее:
dumping data to flamegraph.html
Теперь открываем в браузере файл flamegraph.html, и видим там примерно следующее:
Эта диаграмма визуализирует 30 секунд работы процессора, который профилировался командой perf. Если разбирать ее по вертикали снизу-вверх, то мы видим поток стековых трасс. По горизонтали же отложены процессорные циклы, потраченные на тот или иной элемент диаграммы. Стеки уровня ядра имеют оранжевый цвет, а стеки user space – более теплый оттенок.
В самой нижней полоске диаграммы написано root, это корень деревьев стековых фреймов. Двигаясь по диаграмме снизу-вверх, мы видим следующие процессы: SetroubleshootP, mysqld, apache2, 240998, rpm, ksoftirqd, kworker, grafana-server и redis-server.
Если слегка позумить (все фреймы стека можно щелкать), то увидим, что большая часть «красной» активности на хосте относиться к mysqld.