У меня есть сценарий уведомления, запускаемый процессом демона keepalived при изменении его состояния.
Проблема в том, что вывод эха из моего сценария уведомления не отображается в выводе, отображаемом при запуске keepalived с параметром -l (журнал на локальной консоли)
Обычно я мог бы записать этот вывод в файл, и это было бы прекрасным решением, за исключением того, что в этом случае демон keepalived работает в контейнере докера, и я хочу, чтобы демон докера видел журнал всех выходных данных, в том числе из моего уведомления сценарий.
Вот что я пробовал для своего скрипта уведомления:
#!/bin/bash
MY_PPID=$(ps -o ppid= $$)
MY_PPID=${MY_PPID// }
function echo
{
builtin echo $(date +"%b %e %H:%M:%S"): $1 >> /proc/${MY_PPID}/fd/0
}
echo "Notify state=$3"
И вывод keepalived:
Starting VRRP child process, pid=8847
Interface queue is empty
No such interface, ib0
No such interface, ib1
No such interface, docker0
Interface queue is empty
No such interface, ib0
Registering Kernel netlink reflector
No such interface, ib1
No such interface, docker0
Registering Kernel netlink command channel
Registering gratuitous ARP shared channel
Registering Kernel netlink reflector
Initializing ipvs 2.6
Registering Kernel netlink command channel
Opening file '/etc/keepalived/keepalived.conf'.
Configuration is using : 5879 Bytes
Opening file '/etc/keepalived/keepalived.conf'.
Configuration is using : 61747 Bytes
Using LinkWatch kernel netlink reflector...
Using LinkWatch kernel netlink reflector...
VRRP_Instance(vip) Transition to MASTER STATE
VRRP_Instance(vip) Entering MASTER STATE
Opening script file /etc/keepalived/notify.sh
Если бы это сработало, я ожидал увидеть дополнительную строку:
Notify state=MASTER
Но очевидно, что это не сработало. Любые идеи о том, как я могу заставить это работать правильно?
Я думаю, что нашел проблему. MY_PPID больше не существует как процесс. Казалось бы, при выполнении скрипта процесс keepalived выполняет двойную вилку, чтобы отсоединить скрипт. Когда я пишу в fd одного из процессов keepalived, он действительно работает. Я могу получить pid из файла /var/run/keepalived.pid.
Я попробую это и сообщу.
Оказывается, это не работает, потому что keepalived выполняет двойную вилку перед вызовом exec для дочернего скрипта. Следовательно, MY_PPID больше не является допустимым идентификатором процесса.
Решение состоит в том, чтобы получить правильный идентификатор, используя файл /var/run/vrrp.pid.
Это работает:
#!/bin/bash
TYPE=$1
NAME=$2
STATE=$3
# Get PID for keepalive
KA_PID=$(<"/var/run/vrrp.pid")
function echo
{
# Send script output directly to keepalived
builtin echo $(date +"%b %e %H:%M:%S"): "$0": $1 > "/proc/${KA_PID}/fd/1"
}
echo "$TYPE $NAME $STATE"
Зачем /proc/${MY_PPID}/fd/0
? Обычно это консольный вывод ...
Можете ли вы определить файл журнала на /proc/${MY_PPID}/fd/
процесса надзора?