Отслеживание временного, но повторяющегося процесса на сервере Linux

Вопрос или проблема

Я администрирую сервер Ubuntu для своей исследовательской группы. Я недавно заметил, что иногда появляется процесс (с использованием multiprocessing), который появляется на секунду или две и использует все доступные ЦП на системе. Поскольку нам регулярно нужно использовать multiprocessing, это может быть довольно прерывающим.

Проблема в том, что я не могу понять, что именно вызывает процесс или где он запускается. Вот пример того, что я вижу (например, при использовании htop или watch):

root      962212  532  0.0 2759060 91168 ?       Rsl  07:41   0:05 python run.py start-queue

Тем не менее, процесс (и все его «соседи») слишком мимолетны, чтобы успеть определить его по PID и что-то сделать. Также на системе много скриптов run.py, но в домашней директории пользователя root их нет. Я не могу найти какую-либо ссылку на эту команду в службах /etc/systemd/system. Еще более запутанным (по крайней мере для меня) является то, что для пользователя root нет локального python (т.е. which python ничего не возвращает), поэтому я предполагаю, что он работает из виртуальной среды(?). Однако у root также нет установленных conda или venv

Я (по-любительски) пробовал использовать auditd и strace, но не смог придумать что-то полезное. Например, с помощью strace я смог увидеть процессы, которые присоединяются и выходят, но на этом все:

$ sudo strace -f -e execve -p $(pgrep -f 'python run.py start-queue') 2>&1 | tee python_trace.log

$ less python_trace.log
...
strace: Process 965533 attached
strace: Process 965534 attached
strace: Process 965535 attached
[pid 965474] +++ exited with 0 +++
[pid 965473] +++ exited with 0 +++
[pid 965475] +++ exited with 0 +++
...

Действительно ломаю голову над этим!

  • Используйте один из extrace, forkstat или execsnoop[.bpf], чтобы отслеживать все события создания процессов по всей системе. Эти инструменты покажут вам ближайшего родителя каждого fork/exec. (Как extrace, так и forkstat используют “netlink connector” и не требуют от сервера наличия BPF или каких-либо функций трассировки.)

    extrace: https://github.com/leahneukirchen/extrace (использует netlink connector)
    forkstat: https://github.com/ColinIanKing/forkstat (использует netlink connector)
    execsnoop 1: https://github.com/brendangregg/perf-tools/blob/master/execsnoop (использует kprobes)
    execsnoop 2: https://github.com/iovisor/bcc/blob/master/tools/execsnoop.py (использует BPF)

  • Если вам удается заметить процесс в ps, добавьте столбцы UNIT и/или CGROUP, чтобы отобразить, в каком unit systemd и/или в какой kernel cgroup находится процесс. Поскольку процессы обычно не покидают свои cgroup, это должно сообщить вам, какая служба за это отвечает.

    Например, watch "ps -ax -o pid,cmd,unit,cgroup | grep python"
    или watch "ps -C python -o pid,cmd,unit,cgroup".

Ответ или решение

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

Преамбула

Вы столкнулись с ситуацией, когда процесс (в данном случае python run.py start-queue) запускается кратковременно и использует множество ресурсов CPU, что мешает вашим исследованиям. Например, вы заметили его через утилиты htop и watch, но не смогли зафиксировать его достаточно долго, чтобы провести дальнейший анализ.

Решение проблемы

1. Используйте инструменты для отслеживания создания процессов

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

  • extrace: Этот инструмент использует netlink connector для отслеживания событий создания процессов. Для установки вы можете использовать следующую команду:

    git clone https://github.com/leahneukirchen/extrace.git
    cd extrace
    make
    sudo ./extrace
  • forkstat: Аналогично, этот инструмент также использует netlink connector. Установите его аналогичным образом:

    git clone https://github.com/ColinIanKing/forkstat.git
    cd forkstat
    make
    sudo ./forkstat
  • execsnoop (BCC Tools): Этот инструмент предоставит более подробную информацию о процессе благодаря использованию BPF. Сделайте следующее:

    sudo apt install bpfcc-tools
    sudo execsnoop

Эти инструменты помогут вам отслеживать, какой процесс вызывает run.py, и фиксировать его родительский процесс.

2. Используйте команды для мониторинга

Если процесс периодически появляется, вы можете добавить столбцы UNIT и/или CGROUP в ps для отслеживания системных единиц и cgroup процессов. Это позволит определить, к какому сервису относится процесс. Используйте одну из следующих команд:

watch "ps -ax -o pid,cmd,unit,cgroup | grep python"

или

watch "ps -C python -o pid,cmd,unit,cgroup"

Это даст вам возможность увидеть, к какому системному юниту или группе управления относятся процессы python.

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

Обратите внимание на лог-файлы в /var/log/, особенно в syslog и dmesg, чтобы проверить, есть ли там сообщения о запуске процессов. Кроме того, проверьте конфигурацию cron (crontab -e для каждого пользователя), чтобы удостовериться, что скрипт не запланирован для выполнения по расписанию.

4. Дополнительное использование strace

Вы пытались использовать strace, но, возможно, стоит попробовать выполнить его на уровне системы для отслеживания всех создаваемых процессов с указанным именем:

sudo strace -f -e execve -p $(pgrep -o -f 'python run.py start-queue')

Это может дать более детальную информацию в момент запуска процесса.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...