"Плавающий" виртуальный IP средствами bash

Автор skvili, 09 августа 2018, 17:42:09

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

skvili

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

#!/bin/bash
PATH=$PATH:/bin:/sbin
srvs="srv1.some.org srv2.some.org" #Список внутренних web серверов
export lprt="8080" #Порт, который слушает внутренний web
oprt="80" #Порт, на который цепляются армы
ext_ip="10.100.10.10" #Внешний адрес для армов
b_ip1="10.100.10.11" #Внутренний адрес балансировщика 1
b_ip2="10.100.10.12" #Внутренний адрес балансировщика 2
export srv #Адрес внутреннего web
export sshf_pid

chk_blnc(){ #Проверяем доступность $ext_ip и поднимаем локально алиас, если недоступен
if [ -n "$(ping -n -c 1 $ext_ip|grep '100%')" ];then
ifconfig $(echo $(iface_dtct)|awk {'print $1'}):1 inet $ext_ip/24 up
chk_blnc
else
[ -n "$(ip a|grep $ext_ip)" ]&& chk_int_web|| sleep 1 && chk_blnc
fi
}

chk_int_web(){
for srv in $srvs
do
if [ -n "$(curl -Is http://$srv:$lprt|head -1)" ];then #Проверка достпуности порта внутреннего web
[ -n "$sshf_pid" ]&& chk_sshf_pid="$(ps --no-headers $sshf_pid)" #Проверить, жив ли ещё процесс
[ -n "$chk_sshf_pid" -a "$(echo "$chk_sshf_pid"|awk -F ':' {'print $4'})" != "$(resolv)" ]&& kill "$sshf_pid" #Если запущен для другого IP, то убиваем
sleep 1
[ -z "$chk_sshf_pid" ]&& rd_web #Если не запущен, запускаем
fi
done
sleep 1 && chk_blnc #Если запущен, возвращаемся к началу
}

rd_web(){ #Запуск sshf
ssh localhost -N -L $ext_ip:$oprt:$(resolv):$lprt &
sshf_pid="$!"
sleep 1
}

iface_dtct(){ #Определение имени интерфейса и локального ip
for ipa in $b_ip1 $b_ip2;do
iface=$(ip a|grep $ipa|awk {'print $7'})
[ -n "$iface" ]&& echo $iface" "$ipa
done
}

resolv(){ #Резольв хостнейма
ping -n -c 1 $srv|grep from|awk {'print $4'}|sed 's/://g'
}

start(){
###Проверка и настройка авторизации ssh###
! [ -f $HOME/.ssh/id_rsa.pub ]&& ssh-keygen -t rsa -P "" -f $HOME/.ssh/id_rsa
id_rsa=$(cat $HOME/.ssh/id_rsa.pub)
chk_rsa=$(while read line;do [ "$id_rsa" == "$line" ]&& echo "true";done < $HOME/.ssh/authorized_keys)
if [ "$chk_rsa" != true ];then
echo $id_rsa>>$HOME/.ssh/authorized_keys
ssh-keyscan -t rsa -H localhost>>$HOME/.ssh/known_hosts
fi
##########################################
for prcs in $(ps aux|grep 'ssh localhost'|grep -v 'grep'|awk {'print $2'});do kill $prcs;done #Убиваем все локальные туннели
chk_blnc
}

stop(){
for prcs in $(ps aux|grep 'ssh localhost'|grep -v 'grep'|awk {'print $2'});do kill $prcs;done
ifconfig $(echo $(iface_dtct)|awk {'print $1'}):1 inet $ext_ip/24 down
kill $(ps aux|grep 'balancer.sh'|grep -v 'grep'|awk {'print $2'})
exit
}

[ "$1" == "start" ]&& start &
[ "$1" == "stop" ]&& stop

Скрипт в работе уже около трёх недель, никаких нареканий не было, всё работает нормально. Пару раз отваливался, но так как запускается в качестве юнита systemd, то с перезапуском проблем не было.
А теперь вопрос. Почему руководство не желает принимать данный скрипт в качестве окончательного решения и требует реализацию задачи "стандартными методами"? Что может быть нестандартного в ping, ifconfig и ssh? 70 строк простейшего баша предлагают заменить на docker контейнеры c nginx, keepalived и ещё бог знает что, где одних конфигов придётся править больше, чем весь мой скрипт.

endru

Цитата: skvili от 09 августа 2018, 17:42:09Что может быть нестандартного в ping, ifconfig и ssh?
например может банально не совпадать вывод команд. т.е. не универсальный способ решения проблемы.

skvili

Цитата: endru от 10 августа 2018, 03:34:06
Цитата: skvili от 09 августа 2018, 17:42:09Что может быть нестандартного в ping, ifconfig и ssh?
например может банально не совпадать вывод команд. т.е. не универсальный способ решения проблемы.
Спасибо за комментарий. Согласен, но работа скрипта предполагается на относительно однотипных серверах серверах всего с двумя типам ОС, поэтому посчитал этот фактор не значительным.

endru

Да и скрипт не автоматизирован до конца. Что делать с теми у кого нет нужных пакетов? Это тоже нужно проверять - если команда не выполняется, нужно показывать почему она не выполнилась. Давать советы при запуске, или делать автоматическую настройку системы в зависимости от ОС.