Benutzer-Werkzeuge

Webseiten-Werkzeuge


loadbalancer_-_bash-skript

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
loadbalancer_-_bash-skript [2015-06-09 10:32:28] – [/root/bin/LB_Stop.sh] manfredloadbalancer_-_bash-skript [2016-04-12 22:50:01] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== LoadBalancer - BASH-Skript ======
 +
 +**__Diese Skripte befinden sich z.Z. noch in der Testphase!__**
 +
 +Vorbereitungen:
 +  > cp /etc/ldirectord.cf /var/tmp/
 +  > aptitude purge ldirectord
 +  > aptitude update && aptitude install ifenslave net-tools ethtool wget ipvsadm
 +  > cp /var/tmp/ldirectord.cf /etc/
 +
 +so werden die neuen Skripte manuell benutzt:
 +  /root/bin/LB_Modus.sh Start
 +  /root/bin/LB_Modus.sh Stop
 +  /root/bin/LB_Modus.sh Check
 +  
 +  /root/bin/LB_Dienst.sh [Start|Restart|Reload]
 +  /root/bin/LB_Dienst.sh [Stop|Halt]
 +
 +
 +=== Beschreibung der einzelnen Skript-Aufrufe ===
 +
 +**''/root/bin/LB_Modus.sh Start''**
 +  - dieser Aufruf fährt die öffentlichen IP's (virtuelle IP's) auf dem lo-IF hoch
 +  - und bindet die internen IP's (realen IP's) an die öffentlichen IP's (virtuelle IP's)
 +
 +**''/root/bin/LB_Modus.sh Stop''**
 +  - dieser Aufruf trennt die internen IP's (realen IP's) von den öffentlichen IP's (virtuelle IP's)
 +  - und fährt die öffentlichen IP's (virtuelle IP's) auf dem lo-IF runter
 +
 +**''/root/bin/LB_Modus.sh Check''**
 +  - dieser Aufruf kontrolliert einmal alle Verbindungen und setzt entsprechend die „Route“
 +
 +**''/root/bin/LB_Dienst.sh [Start|Restart|Reload]''**
 +  - dieser Aufruf führt den Aufruf ''/root/bin/LB_Modus.sh Start'' einmal aus
 +  - leg die Datei ''/run/LB_Dienst.run'' an
 +  - und führt anschließend das Kommando ''/root/bin/LB_Modus.sh Check'' zyklisch aus
 +    - der zyklische Check läuft nur solange, wie die Datei ''/run/LB_Dienst.run'' existiert und in ihr die erwartete Zahl steht
 +
 +**''/root/bin/LB_Dienst.sh [Stop|Halt]''**
 +  - dieser Aufruf löscht die Datei ''/run/LB_Dienst.run''
 +  - und führt anschließend das Kommando ''/root/bin/LB_Modus.sh Stop'' aus
 +
 +===== Skripte =====
 +
 +
 +==== /root/bin/LB_Modus.sh ====
 +
 +<file bash /root/bin/LB_Modus.sh>
 +#!/bin/bash
 +
 +#
 +# Betriebs-Modus
 +#
 +
 +#set -x
 +
 +#==============================================================================#
 +VERSION="v2015060900"
 +
 +#------------------------------------------------------------------------------#
 +### damit auch alle Programme gefunden werden
 +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 +ARBEITSVERZEICHNIS="$(dirname ${0})"
 +
 +#------------------------------------------------------------------------------#
 +### Monitor
 +#
 +# ipvsadm -Ln -c
 +# ipvsadm -Ln --timeout
 +# ipvsadm -Ln --daemon
 +# ipvsadm -Ln --stats
 +# ipvsadm -Ln --rate
 +# ipvsadm -Ln --thresholds
 +# ipvsadm -Ln --persistent-conn
 +#
 +#------------------------------------------------------------------------------#
 +### CFG-Block
 +#
 +# #INTERFACENAME:kunvictorv
 +# virtual=kundenservice.victorvox.de:80
 +#         real=swvictor31lo.oqrm.public:80 gate
 +#         real=swvictor21.oqrm.public:80 gate
 +#         real=swvictor11.oqrm.public:80 gate
 +#         service=http
 +#         request="frei/ldirector.php"
 +#         receive="Servicewelten.kundenservice.victorvox.de.71174"
 +#         scheduler=wlc
 +#         persistent=30
 +#         protocol=tcp
 +#         checktype=negotiate
 +
 +#==============================================================================#
 +#==============================================================================#
 +### Funktionen
 +
 +#------------------------------------------------------------------------------#
 +vorbereitung()
 +{
 +#----------------------------------------------------------------------#
 +### hier werden die CFG-Bloecke in Zeilen umgewandelt
 +###
 +### virtual=www.telco.de:80|real=symshtelco21.oqrm.public:80 gate|real=symshtelco11.oqrm.public:80 gate|real=symshtelco31lo.oqrm.public:80 gate|service=http|request="ldirector.php"|receive="SymfonyWebshop.www.telco.de.72980"|scheduler=wlc|persistent=30|protocol=tcp|checktype=negotiate
 +LDIRECTORD_CF="$(cat /etc/ldirectord.cf | sed 's/^[ \t]*//' | grep -Ev '^$|^#' | tr -s '\n' '|' | sed 's/|virtual=/\nvirtual=/g;s/|[ \t]*/|/g' | fgrep 'virtual=')"
 +export LDIRECTORD_CF
 + 
 +if [ -z "${LDIRECTORD_CF}" ] ; then
 +        echo "In der Datei '/etc/ldirectord.cf' sind keine verwertbaren Verbindungsdaten enthalten."
 +        echo "ABBRUCH!"
 +        exit 1
 +fi
 +
 +### nur zum testen
 +#echo "
 +#LDIRECTORD_CF='${LDIRECTORD_CF}'
 +#"
 +#------------------------------------------------------------------------------#
 +
 +#------------------------------------------------------------------------------#
 +### hier werden die vorgesehenen Interface-Namen ermittelt
 +###
 +### www.telco.de wwwtelco
 +INTERFACENAME="$(cat /etc/ldirectord.cf | grep -FA1 INTERFACENAME | tr -s '\n' '|' | tr -s '#' '\n' | sed 's/:/|/g;s/virtual=//' | awk -F'|' '{print $3,$2}')"
 +export INTERFACENAME
 + 
 +if [ -z "${INTERFACENAME}" ] ; then
 +        echo "In der Datei '/etc/ldirectord.cf' sind keine verwertbaren IF-Label enthalten."
 +        echo "ABBRUCH!"
 +        exit 1
 +fi
 +
 +### nur zum testen
 +#echo "
 +#INTERFACENAME='${INTERFACENAME}'
 +#"
 +#exit 0
 +#------------------------------------------------------------------------------#
 +### hier werden die Hostnamen zu IP's aufgelöst
 +IP_FQDN="$(cat /etc/ldirectord.cf | sed 's/^[ \t]*//' | grep -E '^virtual=|^real=|^fallback=' | sed 's/[=:]/ /g' | awk '{print $2}' | sort | uniq | while read FQDN
 +do
 +        ### hier wird der FQDN in eine IP umgewandelt bzw. die IP uebernommen
 +        IPADR="$(host ${FQDN} | fgrep 'has address' | awk '{print $NF}')"
 +        if [ -z "${IPADR}" ] ; then
 +                IPADR="${FQDN}"
 +        fi
 + 
 +        #----------------------------------------------------------------------#
 +        echo "${IPADR}|${FQDN}"
 +done)"
 +export IP_FQDN
 +
 +### nur zum testen
 +#echo "
 +#IP_FQDN='${IP_FQDN}'
 +#"
 +#exit 0
 +#------------------------------------------------------------------------------#
 +###
 +### der hier ist recht langsam und muss schneller werden
 +###
 +### hier werden die entsprechenden lo:interface-Namen vor die Zeilen gesetzt
 +LDIRECTORD_IFN_CF="$(echo "${LDIRECTORD_CF}" | grep -Ev '^$' | while read ZEILE
 +do
 +        #----------------------------------------------------------------------#
 +        unset BLOCK
 +        BLOCK="$(echo "${ZEILE}" | tr -s '|' '\n')"
 +        VIRTUAL="$(echo "${BLOCK}" | grep -F 'virtual=' | sed 's/virtual=//;s/:[0-9]*//')"
 +        IFNAME="$(echo "${INTERFACENAME}" | grep -E "^${VIRTUAL}" | awk '{print $2}')"
 + 
 +        ### hier wird der FQDN in eine IP umgewandelt bzw. die IP uebernommen
 +        VIPADR="$(echo "${IP_FQDN}" | grep -E "[|]${VIRTUAL}$" | awk -F'|' '{print $1}')"
 + 
 +        #----------------------------------------------------------------------#
 +        echo "${IFNAME}|${VIPADR}|${ZEILE}"
 +done)"
 +export LDIRECTORD_IFN_CF
 +
 +if [ -z "${LDIRECTORD_IFN_CF}" ] ; then
 +        echo "Die Daten aus der Datei '/etc/ldirectord.cf' sind nicht verwertbar."
 +        echo "ABBRUCH!"
 +        exit 1
 +fi
 +
 +#echo "${LDIRECTORD_IFN_CF}" > /tmp/LDIRECTORD_IFN_CF.txt
 +echo "${LDIRECTORD_IFN_CF}" > /tmp/ipvsadm_Cluster.txt
 +#exit 0
 +#------------------------------------------------------------------------------#
 +
 +#------------------------------------------------------------------------------#
 +### hier werden die lo:interface-Namen, die z.Z. montiert sind, ermittelt
 +###
 +
 +IST_IPLOIF="$(ip a show dev lo | awk '/scope global/{print $2,$NF}')"
 +export IST_IPLOIF
 +
 +IST_ALLELOIP="$(echo "${IST_IPLOIF}" | awk '{print $1}')"
 +export IST_ALLELOIP
 +
 +IST_ALLELOIF="$(echo "${IST_IPLOIF}" | awk '{print $2}')"
 +export IST_ALLELOIF
 +
 +}
 +#------------------------------------------------------------------------------#
 +
 +#==============================================================================#
 +### Modus
 +
 +case "${1}" in
 +        [Ss][Tt][Aa][Rr][Tt])
 +                        vorbereitung
 +                        ${ARBEITSVERZEICHNIS}/LB_Start.sh
 +                        echo "${0} ${1}" | logger -t LoadBalancer
 +                        shift
 +                        ;;
 +        [Ss][Tt][Oo][Pp])
 +                        ${ARBEITSVERZEICHNIS}/LB_Stop.sh
 +                        echo "${0} ${1}" | logger -t LoadBalancer
 +                        shift
 +                        ;;
 +        [Cc][Hh][Ee][Cc][Kk])
 +                        vorbereitung
 +                        ${ARBEITSVERZEICHNIS}/LB_Check.sh
 +                        shift
 +                        ;;
 +        [Ss][Tt][Aa][Tt][Uu][Ss])
 +                        ipvsadm -Ln
 +                        echo
 +                        ip a show dev lo | fgrep 'lo:'
 +                        echo
 +                        ps ax | fgrep -v grep | fgrep LB_Dienst
 +                        shift
 +                        ;;
 +        *)
 +                        echo "${0} Start"
 +                        echo "${0} Stop"
 +                        echo "${0} Check"
 +                        shift
 +                        exit 1
 +                        ;;
 +esac
 +</file>
 +
 +==== /root/bin/LB_Start.sh ====
 +
 +<file bash /root/bin/LB_Start.sh>
 +#!/bin/bash
 +
 +#
 +# Start
 +#
 +
 +#set -x
 +
 +#==============================================================================#
 +VERSION="v2015052100"
 +
 +#------------------------------------------------------------------------------#
 +### damit auch alle Programme gefunden werden
 +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 +
 +#------------------------------------------------------------------------------#
 +### dieses Skript kann nicht einzeln gestartet werden
 +
 +if [ -z "${LDIRECTORD_IFN_CF}" ] ; then
 +        ARBEITSVERZEICHNIS="$(dirname ${0})"
 +        echo "
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Start
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Stop
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Check
 +        "
 +        exit 1
 +fi
 +
 +#==============================================================================#
 +### Funktionen
 +
 +#------------------------------------------------------------------------------#
 +ip_out()
 +{
 +if [ -z "$(echo "${1}" | grep -E '[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*')" ] ; then
 +        host ${1} | awk '{print $NF}'
 +else
 +        echo ${1}
 +fi
 +}
 +
 +#------------------------------------------------------------------------------#
 +
 +#------------------------------------------------------------------------------#
 +### hier werden die lo:interface-Namen, die nicht in der CFG-Datei stehen,
 +### entfernt
 +###
 +
 +#echo "
 +#LDIRECTORD_IFN_CF='${LDIRECTORD_IFN_CF}'
 +#"
 +
 +TEMPDATEI="$(mktemp /tmp/LB_Start_XXXXXXXX)"
 +echo "${LDIRECTORD_IFN_CF}" | grep -Ev '^$' | awk -F'|' '{print $2}' | sort | uniq | while read IPNM
 +do
 +        ### egal was es ist, es wird eine IP ausgegeben
 +        ip_out ${IPNM}
 +done | awk '{print " "$1"/"}' > ${TEMPDATEI}
 +#exit
 +
 +#
 +#    inet 10.31.2.178/32 brd 10.31.2.178 scope global lo:kontoch
 +#    inet 193.227.192.234/32 brd 193.227.192.234 scope global lo:lizi_b2c
 +ip addr show dev lo | fgrep "scope global" | fgrep -vf ${TEMPDATEI} | while read ZEILE
 +do
 +        # _INET VIPADR _BR _IP _SCOPE _GLOBAL UEIFLABEL
 +        # oder
 +        # _INET VIPADR _SCOPE _GLOBAL UEIFLABEL
 +        VIPADR="$(echo "${ZEILE}" | awk '{print $2}' | grep -E '[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*')"
 +        _IPADR="$(echo "${VIPADR}" | sed 's#/.*##')"
 +        IFLABEL="$(echo "${ZEILE}" | awk '{print $NF}' | grep -F ':')"
 +
 +        #echo "VIPADR='${VIPADR}'"
 +        if [ -n "${VIPADR}" ] ; then
 +                #echo "================================================================"
 +                ### Verbindungen aus dem LB entfernen
 +                ipvsadm -Ln | fgrep "${_IPADR}:" | awk '{print $2}' | while read VIPPORT
 +                do
 +                        ipvsadm -Lnt "${VIPPORT}" | grep -F '> ' | grep -E '[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*' | awk '{print $2}' | while read RIPPORT
 +                        do
 +                                echo "-e -t ${VIPPORT} -r ${RIPPORT} -w 0
 +                                -d -t ${VIPPORT} -r ${RIPPORT}
 +                                -D -t ${VIPPORT}" | logger -t LoadBalancer
 +
 +                                echo "-e -t ${VIPPORT} -r ${RIPPORT} -w 0
 +                                -d -t ${VIPPORT} -r ${RIPPORT}
 +                                -D -t ${VIPPORT}" | ipvsadm -R #2>/dev/null
 +                        done
 +                done
 +
 +                if [ -n "${IFLABEL}" ] ; then
 +                        echo "ip addr del ${VIPADR} dev lo label ${IFLABEL}" | logger -t LoadBalancer
 +                        ip addr del ${VIPADR} dev lo label ${IFLABEL}
 +                else
 +                        echo "ip addr del ${VIPADR} dev lo" | logger -t LoadBalancer
 +                        ip addr del ${VIPADR} dev lo
 +                fi
 +        fi
 +done
 +
 +rm -f ${TEMPDATEI}
 +
 +#==============================================================================#
 +echo "${LDIRECTORD_IFN_CF}" | while read ZEILE
 +do
 +        #----------------------------------------------------------------------#
 +        #echo "-----------------------------------------------------------------"
 +        unset BLOCK
 +        BLOCK="$(echo "${ZEILE}" | tr -s '|' '\n')"
 +        IFNAME="$(echo "${ZEILE}" | grep -Ev '^$' | awk -F'|' '{print $1}' | head -n1)"
 +        VIPADR="$(echo "${ZEILE}" | grep -Ev '^$' | awk -F'|' '{print $2}' | head -n1)"
 +        VIRTUAL="$(echo "${BLOCK}" | grep -F 'virtual=' | sed 's/virtual=//;s/:[0-9]*//' | awk '{print $1}')"
 + 
 +        ### hier wird (wegen der Einfachheit) der Port von "virtual" auch fuer "real" verwendet
 +        TCPPORTS="$(echo "${BLOCK}" | grep -F 'virtual=' | awk -F':' '{print $NF}' | awk '{print $1}')"
 +        ALLEREALIPS="$(echo "${BLOCK}" | grep -F 'real=' | sed 's/real=//;s/:[0-9]*//' | awk '{print $1}')"
 +        FALLBACK="$(echo "${BLOCK}" | grep -F 'fallback=' | sed 's/fallback=//;s/:[0-9]*//' | awk '{print $1}')"
 +        SCHEDULER="$(echo "${BLOCK}" | grep -F 'scheduler=' | sed 's/scheduler=//' | awk '{print $1}')"
 +        PERSISTENT="$(echo "${BLOCK}" | grep -F 'persistent=' | sed 's/persistent=//;s/["]//g' | awk '{print $1}')"
 +        PROTOCOL="$(echo "${BLOCK}" | grep -F 'protocol=' | sed 's/protocol=//;s/["]//g' | awk '{print $1}')"
 + 
 +        #----------------------------------------------------------------------#
 +        ### hier werden fehlende externe IPs an lo montiert
 +        if [ -n "${IFNAME}" ] ; then
 +                #ip addr | fgrep "${VIPADR}/32"
 +                if [ -z "$(ip addr | fgrep "${VIPADR}/32")" ] ; then
 +                        #------------------------------------------------------#
 +                        # ip addr add 193.227.192.136/32 dev lo label lo:wwwtelco
 +                        # ip addr del 193.227.192.136/32 dev lo label lo:wwwtelco
 +                        ip addr add ${VIPADR}/32 dev lo label lo:${IFNAME}
 + 
 +                        if [ -z "$(ip addr | fgrep "${VIPADR}/32")" ] ; then
 +                                echo "Fehler: ${VIPADR}/32 - lo:${IFNAME}"
 +                        fi
 +                fi
 +        fi
 +
 +        #----------------------------------------------------------------------#
 +        ### hier werden die Server-Verbindungen aktiviert
 +        (for TPORT in ${TCPPORTS}
 +        do
 +                echo "-A -t ${VIPADR}:${TPORT} -s ${SCHEDULER} -p ${PERSISTENT}"
 +                for REAL_IP in ${ALLEREALIPS} ${FALLBACK}
 +                do
 +                        echo "-a -t ${VIPADR}:${TPORT} -r ${REAL_IP}:${TPORT} -m"
 +                        echo "-e -t ${VIPADR}:${TPORT} -r ${REAL_IP}:${TPORT} -w 0"
 +                done
 +        done) | ipvsadm -R 2>/dev/null
 + 
 +done
 +</file>
 +
 +==== /root/bin/LB_Stop.sh ====
 +
 +<file bash /root/bin/LB_Stop.sh>
 +#!/bin/bash
 +
 +#
 +# Stop
 +#
 +
 +#set -x
 +
 +#==============================================================================#
 +VERSION="v2015060900"
 +
 +#------------------------------------------------------------------------------#
 +### damit auch alle Programme gefunden werden
 +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 +RUN="/run/LB_Dienst.run"
 +
 +#==============================================================================#
 +### laufende Auftraege beenden
 +
 +rm -f ${RUN} /tmp/ipvsadm_Check_* /tmp/LB_Check-Dienst_* /tmp/ipvsadm_Cluster.txt
 +
 +#==============================================================================#
 +
 +ipvsadm -Ln | awk '{print $1,$2}' | sed 's/[-][>]//g' | tr -s '\n' ' ' | sed 's/TCP/\nTCP/g' | grep -E '^TCP ' | while read TCP V_IPADR ALLE_REAL_IPS
 +do
 +        #----------------------------------------------------------------------#
 +        VIPADR="$(echo "${V_IPADR}" | sed 's/[:][0-9][0-9]*/ /g;s/[ \t]$//')"
 +        TCPPORTS="$(echo "${V_IPADR}" | awk -F':' '{print $NF}')"
 +        ALLEREALIPS="$(echo "${ALLE_REAL_IPS}" | sed 's/[:][0-9][0-9]*/ /g;s/[ \t]$//')"
 +        #----------------------------------------------------------------------#
 +        ### hier werden die Server-Verbindungen aktiviert
 +        (for TPORT in ${TCPPORTS}
 +        do
 +                for REAL_IP in ${ALLEREALIPS}
 +                do
 +                        echo "-d -t ${VIPADR}:${TPORT} -r ${REAL_IP}:${TPORT}"
 +                done
 +                echo "-D -t ${VIPADR}:${TPORT}"
 +        done) | ipvsadm -R 2>/dev/null
 +done
 +
 +#------------------------------------------------------------------------------#
 +###
 +### hier werden alle lo:interfaces entfernt
 +###
 +
 +ip a show dev lo | awk '/scope global/{print $2,$NF}' | while read LOIP LOIF
 +do
 +#        echo "ip addr del ${LOIP} dev lo label ${LOIF}"
 +        ip addr del ${LOIP} dev lo label ${LOIF}
 +done
 +
 +#==============================================================================#
 +</file>
 +
 +==== /root/bin/LB_Check.sh ====
 +
 +<file bash /root/bin/LB_Check.sh>
 +#!/bin/bash
 +
 +#
 +# Check
 +#
 +
 +#set -x
 +
 +#==============================================================================#
 +VERSION="v2015060900"
 + 
 +#------------------------------------------------------------------------------#
 +### damit auch alle Programme gefunden werden
 +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 +WGETOPTS="-4 -l 0 --no-check-certificate --no-proxy --no-dns-cache --no-cache --no-cookies --no-http-keep-alive --ignore-length --max-redirect=0 --unlink -T 2 -t 1 -nc"
 +
 +#------------------------------------------------------------------------------#
 +#
 +# Die Verbindungsüberprüfung wird auf eine Anzahl von Prozessen verteilt,
 +# die in dieser Variablen gespeichert wird.
 +#
 +# Sollte diese Variable leer sein, wird die Anzahl der CPU-Kerne verwendet.
 +#PROZESSE=8
 +
 +if [ -z "${PROZESSE}" ] ; then
 +        PROZESSE="$(grep -E '^processor' /proc/cpuinfo | wc -l)"
 +fi
 +
 +#------------------------------------------------------------------------------#
 +### dieses Skript kann nicht einzeln gestartet werden
 +
 +if [ -z "${LDIRECTORD_IFN_CF}" ] ; then
 +        ARBEITSVERZEICHNIS="$(dirname ${0})"
 +        echo "
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Start
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Stop
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Check
 +        "
 +        exit 1
 +fi
 +
 +#==============================================================================#
 +### Funktionen
 +
 +#------------------------------------------------------------------------------#
 +ip_out()
 +{
 +if [ -z "$(echo "${1}" | grep -E '[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*')" ] ; then
 +        host ${1} | awk '{print $NF}'
 +else
 +        echo ${1}
 +fi
 +}
 +
 +#------------------------------------------------------------------------------#
 +check_now()
 +{
 +cat "${1}" | while read ZEILE
 +do
 +        #----------------------------------------------------------------------#
 +        #IFNAME="$(echo "${ZEILE}" | grep -Ev '^$' | awk -F'|' '{print $1}' | head -n1)"
 +        VIPADR="$(echo "${ZEILE}" | grep -Ev '^$' | awk -F'|' '{print $2}' | head -n1)"
 +        unset BLOCK
 +        BLOCK="$(echo "${ZEILE}" | tr -s '|' '\n')"
 +        VIRTUAL="$(echo "${BLOCK}" | grep -F 'virtual=' | sed 's/virtual=//;s/:[0-9]*//' | awk '{print $1}')"
 + 
 +        ### hier wird (wegen der Einfachheit) der Port von "virtual" auch fuer "real" verwendet
 +        TPORT="$(echo "${BLOCK}" | grep -F 'virtual=' | awk -F':' '{print $NF}' | awk '{print $1}')"
 +        ALLEREALIPS="$(echo "${BLOCK}" | grep -F 'real=' | sed 's/real=//;s/:[0-9]*//' | awk '{print $1}')"
 +        #FALLBACK="$(echo "${BLOCK}" | grep -F 'fallback=' | sed 's/fallback=//;s/:[0-9]*//' | awk '{print $1}')"
 +        FALLBACK="$(echo "${BLOCK}" | grep -F 'fallback=' | sed 's/fallback=//;' | awk '{print $1}')"
 +        #SCHEDULER="$(echo "${BLOCK}" | grep -F 'scheduler=' | sed 's/scheduler=//' | awk '{print $1}')"
 +        SERVICE="$(echo "${BLOCK}" | grep -F 'service=' | sed 's/service=//;s/["]//g' | awk '{print $1}')"
 +        REQUEST="$(echo "${BLOCK}" | grep -F 'request=' | sed 's/request=//;s/["]//g' | awk '{print $1}')"
 +        RECEIVE="$(echo "${BLOCK}" | grep -F 'receive=' | sed 's/receive=//;s/["]//g' | awk '{print $1}')"
 +        #PERSISTENT="$(echo "${BLOCK}" | grep -F 'persistent=' | sed 's/persistent=//;s/["]//g' | awk '{print $1}')"
 +        #PROTOCOL="$(echo "${BLOCK}" | grep -F 'protocol=' | sed 's/protocol=//;s/["]//g' | awk '{print $1}')"
 + 
 +        #----------------------------------------------------------------------#
 +        ### hier wird die FallBack-Verbindung wieder entfernt
 +
 +        #echo "FALLBACK='${FALLBACK}'" >> /tmp/Check.log ; sync
 +        if [ -z "${FALLBACK}" ] ; then
 +                FB_AUS=""
 +        else
 +                FBEINTAG="$(echo "${FALLBACK}" | awk -F':' '{print $1}')"
 +                FBADR="$(ip_out ${FBEINTAG})"
 +                FBPORT="$(echo "${FALLBACK}" | awk -F':' '{print $2}')"
 +
 +                FB_EIN="-a -t ${VIPADR}:${TPORT} -r ${FBADR}:${FBPORT} -m
 +                -e -t ${VIPADR}:${TPORT} -r ${FBADR}:${FBPORT} -w 1"
 +
 +                FB_AUS="-e -t ${VIPADR}:${TPORT} -r ${FBADR}:${FBPORT} -w 0
 +                -d -t ${VIPADR}:${TPORT} -r ${FBADR}:${FBPORT}"
 +        fi
 + 
 +        #----------------------------------------------------------------------#
 +
 +        (for REAL_IP in ${ALLEREALIPS}
 +        do
 +                TEMP="/tmp/ipvsadm_Check_$(head -c 1000 /dev/urandom | tr -cd '[:alnum:]' | cut -b-12)"
 +
 +                #--------------------------------------------------------------#
 +                ### hier wird der FQDN der REAL-Hosts in eine IP umgewandelt bzw. die IP uebernommen
 +                RIPADR="$(echo "${IP_FQDN}" | fgrep "|${REAL_IP}" | awk -F'|' '{print $1}')"
 +                if [ -z "${RIPADR}" ] ; then
 +                        RIPADR="${REAL_IP}"
 +                fi
 + 
 +                #==============================================================#
 +                ### hier wird der IST-Zustand einer LB-Verbindung zum Real-Server ausgelesen
 +                #echo "3: ipvsadm -Ln | fgrep \"${RIPADR}:${TPORT}\""                                 >> /tmp/Check.log ; sync
 +                #echo "#-> 0: ipvsadm -Ln | fgrep '${RIPADR}:${TPORT}'" >> /tmp/Check.log ; sync
 +                IST_WEIGHT="$(ipvsadm -Lnt ${VIPADR}:${TPORT} | fgrep "${RIPADR}:${TPORT}" | awk '/Route/{sub(".*Route","");print $1}' | head -n 1)"
 +                if [ -z "${IST_WEIGHT}" ] ; then
 +                        IST_WEIGHT="$(ipvsadm -Ln | fgrep "${RIPADR}:${TPORT}" | awk '/Masq/{sub(".*Masq","");print $1}' | head -n 1)"
 +                        if [ "${IST_WEIGHT}" = "1" ] ; then
 +                                IST_WEIGHT="1"
 +                        else
 +                                IST_WEIGHT="0"
 +                        fi
 +                fi
 +
 +                if [ -n "${IST_WEIGHT}" ] ; then
 + 
 +                        #echo "5: RIPADR:TPORT='${RIPADR}:${TPORT}'" >> /tmp/Check.log ; sync
 +                        #------------------------------------------------------#
 +                        if [ "smtp" = "${SERVICE}" ] ; then
 +                                #
 +                                # SMTP
 +                                #
 +                                #echo "----------------------------------------" >> /tmp/Check.log ; sync
 +                                #echo "6: wget ${WGETOPTS} -O ${TEMP} http://${RIPADR}:${TPORT}/${REQUEST}" >> /tmp/Check.log ; sync
 +                                wget -q ${WGETOPTS} -O ${TEMP} http://${RIPADR}:${TPORT}/${REQUEST}
 +                                BEKOMMEN="$(cat ${TEMP} | awk '/^220 /{print $1}' | head -n1 ; rm -f ${TEMP})"
 +                                #echo "BEKOMMEN='${BEKOMMEN}'" >> /tmp/Check.log ; sync
 + 
 +                                if [ "${BEKOMMEN}" = "220" ] ; then
 +                                        if [ "${IST_WEIGHT}" = "0" ] ; then
 +                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 1 (Weight 1)" | logger -t LoadBalancer
 +                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 1"
 +                                        fi
 +                                else
 +                                        if [ "${IST_WEIGHT}" = "1" ] ; then
 +                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 0 (Weight 0)" | logger -t LoadBalancer
 +                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 0"
 +                                        fi
 +                                fi
 +                        else
 +                                #
 +                                # HTTP / HTTPS
 +                                #
 +                                #echo "----------------------------------------" >> /tmp/Check.log ; sync
 +                                #echo "7: wget ${WGETOPTS} -O ${TEMP} ${SERVICE}://${RIPADR}:${TPORT}/${REQUEST}" >> /tmp/Check.log ; sync
 +                                VERBUNDEN="$(wget ${WGETOPTS} -O ${TEMP} ${SERVICE}://${RIPADR}:${TPORT}/${REQUEST} 2>&1 | awk '/connected|verbunden/{print $NF}')"
 +                                #echo "8: VERBUNDEN='${VERBUNDEN}'" >> /tmp/Check.log ; sync
 +
 +                                BEKOMMEN="$(cat ${TEMP} | grep -Ev '^$' | sed 's/^[ \t]//g;s/[ \t]$//g' ; rm -f ${TEMP})"
 +                                #echo "9: BEKOMMEN='${BEKOMMEN}' | RECEIVE='${RECEIVE}'" >> /tmp/Check.log ; sync
 +
 +                                if [ "${VERBUNDEN}" = "connected." -o "${VERBUNDEN}" = "verbunden." ] ; then
 +                                        #echo "- ipvsadm: 1" >> /tmp/Check.log ; sync
 +                                        if [ -z "${RECEIVE}" ] ; then
 +                                                #echo "- ipvsadm: 2" >> /tmp/Check.log ; sync
 +                                                if [ "${IST_WEIGHT}" = "0" ] ; then
 +                                                        echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 1 (Weight 1)" | logger -t LoadBalancer
 +                                                        echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 1"
 +                                                fi
 +                                        else
 +                                                #echo "- ipvsadm: 4" >> /tmp/Check.log ; sync
 +                                                if [ "${RECEIVE}" = "${BEKOMMEN}" ] ; then
 +                                                        #echo "- ipvsadm: 05" >> /tmp/Check.log ; sync
 +                                                        if [ "${IST_WEIGHT}" = "0" ] ; then
 +                                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 1 (Weight 1)" | logger -t LoadBalancer
 +                                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 1"
 +                                                        fi
 +                                                else
 +                                                        #echo "- ipvsadm: 07" >> /tmp/Check.log ; sync
 +                                                        if [ "${IST_WEIGHT}" = "1" ] ; then
 +                                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 0 (Weight 0)" | logger -t LoadBalancer
 +                                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 0"
 +                                                        fi
 +                                                fi
 +                                        fi
 +                                else
 +                                        if [ "${IST_WEIGHT}" = "1" ] ; then
 +                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 0 (Weight 0)" | logger -t LoadBalancer
 +                                                echo "-e -t ${VIPADR}:${TPORT} -r ${RIPADR}:${TPORT} -w 0"
 +                                        fi
 +                                fi
 +                        fi
 +                fi
 +                #==============================================================#
 +                ### FallBack
 +                if [ -n "${FALLBACK}" ] ; then
 +                        IPVSADM_LNT="$(ipvsadm -Lnt ${VIPADR}:${TPORT} | fgrep Route)"
 +                        ROUTE_SUM="$(echo "${IPVSADM_LNT}" | sed 's/.*Route//' | awk '{z=$1;s+=z}END{print s}')"
 +                        ROUTE_CL="$(echo "${IPVSADM_LNT}" | grep -Fv "> ${FBADR}:" | sed 's/.*Route//' | awk '{z=$1;s+=z}END{print s}')"
 +                        ROUTE_FB="$(echo "${IPVSADM_LNT}" | grep -F "> ${FBADR}:")"
 +                        if [ "${ROUTE_CL}" -eq "0" ] ; then
 +                                if [ -z "${ROUTE_FB}" ] ; then
 +                                        echo "Added fallback server: ${FBADR}:${FBPORT}" | logger -t LoadBalancer
 +                                        echo "${FB_EIN}"
 +                                fi
 +                        else
 +                                if [ -n "${ROUTE_FB}" ] ; then
 +                                        echo "Deleted fallback server: ${FBADR}:${FBPORT}" | logger -t LoadBalancer
 +                                        echo "${FB_AUS}"
 +                                fi
 +                        fi
 +                fi
 + 
 +        done) | ipvsadm -R #2>/dev/null
 +done
 +
 +rm -f ${1}
 +
 +### wenn Schluss ist, dann muss auch Schluss sein
 +if [ "${STARTZEIT}" != "$(cat ${RUN} 2>/dev/null)" ]
 +then
 +        echo "Ende von ${STARTZEIT}"
 +        exit 0
 +fi
 +
 +}
 +
 +#==============================================================================#
 +### Run
 +
 +###
 +### Bearbeitung je Cluster
 +### mit mehreren Prozessen
 +### maximale Anzahl der Prozesse = ${PROZESSE}
 +###
 +echo "${LDIRECTORD_IFN_CF}" | nl | while read NR CLUSTER
 +do
 +        #----------------------------------------------------------------------#
 +        ### es duerfen nur max. soviele Prozesse laufen,
 +        ### wie CPU-Kerne im System stecken
 +
 +        ANZAHL_LAUFEN="$(ps alx | fgrep -v grep | fgrep "/bin/bash /root/bin/LB_Check.sh" | wc -l)"
 +        #echo "ANZAHL_LAUFEN=${ANZAHL_LAUFEN}"
 +
 +        while (( ${ANZAHL_LAUFEN} >= ${PROZESSE} ))
 +        do
 +                sleep 0.1
 +                ANZAHL_LAUFEN="$(ps alx | fgrep -v grep | fgrep "/bin/bash /root/bin/LB_Check.sh" | wc -l)"
 +                #echo "ANZAHL_LAUFEN=${ANZAHL_LAUFEN}"
 +        done
 +
 +        #----------------------------------------------------------------------#
 +        ### wenn Schluss ist, dann muss auch Schluss sein
 +
 +        while [ "${STARTZEIT}" != "$(cat ${RUN} 2>/dev/null)" ]
 +        do
 +                exit 0
 +        done
 +
 +        #----------------------------------------------------------------------#
 +        ### Start
 +
 +        DATENDATEI="/tmp/ipvsadm_Cluster_Check_${NR}"
 +        echo "${CLUSTER}" > ${DATENDATEI}
 +        ( check_now ${DATENDATEI} ) &
 +done
 +</file>
 +
 +==== /root/bin/LB_Dienst.sh ====
 +
 +<file bash /root/bin/LB_Dienst.sh>
 +#!/bin/bash
 +
 +#
 +# Hintergrunddienst zur Überwachung
 +#
 +# dieses Skript startet/stoppt Verbindungsüberwachung
 +#
 +
 +#==============================================================================#
 +VERSION="v2015060900"
 +
 +#------------------------------------------------------------------------------#
 +### damit auch alle Programme gefunden werden
 +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 +ARBEITSVERZEICHNIS="$(dirname ${0})"
 +RUN="/run/LB_Dienst.run"
 +export RUN
 +STARTZEIT="$(date +'%s')"
 +export STARTZEIT
 +
 +WARTEZEIT="1"                   # Wartezeit zwischen den Checks in Sekunden
 +
 +#==============================================================================#
 +### Funktionen
 +#------------------------------------------------------------------------------#
 +lbstop()
 +{
 +        rm -f ${RUN}
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Stop
 +}
 +
 +#==============================================================================#
 +### Start/Stop
 +
 +case "${1}" in
 +        [Ss][Tt][Aa][Rr][Tt]|[Rr][Ee][Ll][Oo][Aa][Dd])
 +                        AKTION=START
 +                        shift
 +                        ;;
 +        [Ss][Tt][Oo][Pp]|[Hh][Aa][Ll][Tt])
 +                        lbstop
 +                        shift
 +                        ;;
 +        [Rr][Ee][Ss][Tt][Aa][Rr][Tt])
 +                        lbstop
 +                        AKTION=START
 +                        shift
 +                        ;;
 +        [Ss][Tt][Aa][Tt][Uu][Ss])
 +                        ${ARBEITSVERZEICHNIS}/LB_Modus.sh status
 +                        shift
 +                        ;;
 +        *)
 +                        echo "${0} [Start|Restart|Reload]"
 +                        echo "${0} [Stop|Halt]"
 +                        echo "${0} [Status]"
 +                        shift
 +                        exit 1
 +                        ;;
 +esac
 +
 +#------------------------------------------------------------------------------#
 +
 +if [ "${AKTION}" = START ] ; then
 +
 +#======================================================================#
 +echo "
 +#----------------------------------------------------------------------#
 +### checken
 +${ARBEITSVERZEICHNIS}/LB_Modus.sh Start
 +echo "${STARTZEIT}" > ${RUN}
 + 
 +while [ \"${STARTZEIT}\" = \"\$(cat ${RUN} 2>/dev/null)\" ]
 +do
 +        ${ARBEITSVERZEICHNIS}/LB_Modus.sh Check
 +        sleep ${WARTEZEIT}
 +done
 +#----------------------------------------------------------------------#
 +### sauber machen
 +rm -f /tmp/LB_${STARTZEIT}
 +" > /tmp/LB_Check-Dienst_${STARTZEIT}
 +
 +chmod 0755 /tmp/LB_Check-Dienst_${STARTZEIT}
 +screen -dmS LB_Check-Dienst_${STARTZEIT} /tmp/LB_Check-Dienst_${STARTZEIT}
 +#======================================================================#
 +
 +fi
 +
 +#==============================================================================#
 +</file>
 +
 +==== /etc/init.d/lb_dienst ====
 +
 +<file bash /etc/init.d/lb_dienst>
 +#!/bin/sh
 +#
 +### BEGIN INIT INFO
 +# Short-Description: Monitor virtual services provided by LB-Dienst.sh
 +# Provides:          lb_dienst
 +# Required-Start:    $remote_fs $syslog
 +# Required-Stop:     $remote_fs $syslog
 +# Default-Start:     2 3 4 5
 +# Default-Stop:      0 1 6
 +### END INIT INFO
 +#
 +# Author: Yoda
 +#
 +# init script for LB-Dienst.sh
 +#
 +
 +PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 +NAME=LB_Dienst.sh
 +DAEMON="/root/bin/$NAME"
 +CONFIG=""
 +
 +test -x $DAEMON || exit 0
 +
 +test -x /var/lock/subsys || mkdir -p /var/lock/subsys
 +
 +. /lib/lsb/init-functions
 +
 +CONFIG_FILE=""
 +#[ -f "$CONFIG" ] && . "$CONFIG"
 +#CONFIG_FILE="${CONFIG_FILE:=/etc/ldirectord.cf}"
 +
 +test -f ${CONFIG_FILE} 
 +RC=$?
 +if [ $RC -ne 0 ] ; then
 +        log_warning_msg "No configuration file found, doing nothing."
 +        exit 0   
 +fi
 +
 +case "$1" in
 +        start|stop|restart|reload|halt|status)
 +                log_daemon_msg "Running $NAME" "$1"
 +                ##exec "$DAEMON" "$CONFIG_FILE" $1
 +                exec "$DAEMON" $1
 +                RC=$?
 +                log_end_msg $RC
 +                exit $RC
 +        ;;
 +        *)
 +                echo "Usage: /etc/init.d/$NAME" \
 +                        "{start|restart|reload|stop|halt|status}" >&2
 +        exit 1
 +        ;;
 +esac
 +</file>
 +
 +den neuen Dienst bootfest machen:
 +  # chmod 0755 /etc/init.d/lb_dienst
 +  # update-rc.d lb_dienst defaults
 +   Adding system startup for /etc/init.d/lb_dienst ...
 +     /etc/rc0.d/K20lb_dienst -> ../init.d/lb_dienst
 +     /etc/rc1.d/K20lb_dienst -> ../init.d/lb_dienst
 +     /etc/rc6.d/K20lb_dienst -> ../init.d/lb_dienst
 +     /etc/rc2.d/S20lb_dienst -> ../init.d/lb_dienst
 +     /etc/rc3.d/S20lb_dienst -> ../init.d/lb_dienst
 +     /etc/rc4.d/S20lb_dienst -> ../init.d/lb_dienst
 +     /etc/rc5.d/S20lb_dienst -> ../init.d/lb_dienst
 +
 +
 +==== /root/bin/watch.sh ====
 +
 +<file bash /root/bin/watch.sh>
 +#!/bin/bash
 +
 +watch 'uptime; md5sum /etc/ldirectord.cf* ; echo ; ps -ef | fgrep -v "grep" | egrep "ldirectord /etc/ldirectord.cf [sr][te][asl][rto][ta]"; ipvsadm -ln | fgrep "Route   1" | wc -l; echo; fgrep "fallback" /var/log/syslog | tail -n3; ipvsadm -l | fgrep "Route   0";'
 +
 +</file>
 +
 +
 +==== /etc/ldirectord.cf ====
 +
 +<file bash /etc/ldirectord.cf>
 +checktimeout=3
 +checkinterval=10
 +autoreload=yes
 +logfile="local0"
 +quiescent=yes
 +
 +#INTERFACENAME:domain
 +virtual=www.domain.de:80
 +        real=ttshop01.public:80 gate
 +        real=ttshop02.public:80 gate
 +        fallback=fallback01.oqrm.public:80 gate
 +        service=http
 +        request="ldirector.php"
 +        receive="www.domain.de"
 +        scheduler=wlc
 +        persistent=30
 +        protocol=tcp
 +        checktype=negotiate
 +
 +virtual=www.domain.de:443
 +        real=ttshop01.public:443 gate
 +        real=ttshop02.public:443 gate
 +        fallback=fallback01.public:443 gate
 +        service=https
 +        request="ldirector.php"
 +        receive="www.domain.de"
 +        scheduler=wlc
 +        persistent=30
 +        protocol=tcp
 +        checktype=negotiate
 +</file>
 +
 +
 +Die Namensauflösung muss funktionieren, sonst funktioniert garnichts!
 +  > host www.domain.de
 +  www.domain.de has address 203.202.201.200
 +
 +
 +wenn der LB gestartet ist, dann ist die letzte Zeile hier zu sehen (mit dem INTERFACENAME -> ''domain''):
 +  > ip a show dev lo
 +  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
 +      link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 +      inet 127.0.0.1/8 scope host lo
 +      inet 203.202.201.200/32 scope global lo:domain
 +
 +
 +dieser Test, stellt sicher, dass das System kein ro-Dateisystem hat, was bei einem Fehlerhaften System auftreten kann:
 +<file bash /var/www/ldirector.php>
 +<?php
 +$ldirectorPage = "ldirector.html";
 +echo ($temp = tmpfile()) ? file_get_contents($ldirectorPage) : "Keine Schreibrechte!";
 +?>
 +</file>
 +
 +
 +<file bash /var/www/ldirector.html>
 +www.domain.de
 +</file>