Скрипт мониторинга принадлежности процесса в OpenVZ-контейнере из CT0

Материал из Linux Wiki
Перейти к навигацииПерейти к поиску

Скриптик на память, назначение которого было мониторить принадлежность php-процессов, запущенных через fast_cgi внутри контейнера в OpenVZ, при этом сам скрипт запускается из нулевого контейнера и в случае, если совсем уж все плохо - рестартит контейнер.

Основная проблема в том, что PID'ы процессов внутри контейнера мапятся на другие PID'ы "снаружи", поэтому для контроля процессов создается таблица соответствия pid'ов.

Цель скрипта - снимать "потерявшиеся" процессы, возникшие в результате краша процесса Апача (в том случае, когда процесс или целое дерево процессов становится потомками init'a внутри контейнера)

Для проверяемых процессов просматривается имя родительского процесса. Единственный процесс, родитель которого init - процесс Апача, виртуальный (внутренний) PID которого находится в /var/run/apache2.pid, все остальные являются для него дочерними. Соответственно, если это не так - процесс убивается.


#!/bin/bash

# ID контейнера
ctid='107'
# Log
logname='/root/c107check.log'

# Если контейнер выключен - не пытаться работать с процессами
if [ "$(/usr/sbin/vzlist -H $ctid -o status)" != 'running' ]
        then
                exit
        else

# PID корневого Апача "изнутри" контейнера
ravp="$(cat /vz/root/$ctid/var/run/apache2.pid)"
# Создаем таблицу процессов контейнера
# PID_реальный PID_родителя_в_контейнере PID_виртуальный команда
data="$(/root/bin/ovzps $ctid -o pid,command --no-header |
while read pid cmd
        do
        echo $pid $(awk '/^VPid/{vp=$2}; /^PPid/{pp=$2}; END {print pp, vp}' /proc/$pid/status) $cmd
done)"
# Реальный PID init'a в контейнере
initps="$(awk '/ init /{print $1}' <<< "$data")"
# Реальный PID корневого процесса Апача
rarp="$(awk '/'" $initps $ravp "'/{print $1}' <<< "${data}")"
# Создаем список процессов, для которых родительский процесс - init контейнера, исключая корневой процесс Апача
lostprocess="$(
echo "$data" | grep -E "php5-cgi|apache2|ispcp-apache-logger" |
grep -v " $initps $ravp" | awk '/'" $initps "'/{print $1}'
)"
# Если список таких процессов не пустой - убиваем их
        if [ ! -z "${lostprocess}" ]
                then
                echo $(date +%Y.%m.%d" "%H:%M:%S) ${lostprocess} >> "$logname"
        kill -9 ${lostprocess}
        fi

# Проверяем существование корневого процесса Апача. Если после апокалипсиса никто не выжил - перезапускаем контейнер

kill -0 "$rarp" || { /usr/sbin/vzctl restart $ctid ; echo $(date +%Y.%m.%d" "%H:%M:%S) container restarted >> "$logname" ; }

fi

Скрипт ссылается на /root/bin/ovzps, код которого ниже:


#!/bin/bash
ctid=${1:-0}
shift

ps $* -p $(grep -l "^envID:[[:space:]]*$ctid\$" /proc/[0-9]*/status |
        sed -e 's=/proc/\([0-9]*\)/.*=\1=')