Heute möchte ich gerne eine Möglichkeit vorstellen die Quelladresse eines Clusters mit Pacemaker zu ändern.
Es gibt bereits ein vorgefertiges OCF-Resource-Agent-Skript namens IPsrcaddr, dieses hat allerdings im Test bei mir nicht zuverlässig funktioniert, sodass ich mich entschied einen eigenen Resource-Agent zu implementieren:
#!/bin/bash
#
# Resource script for source adresses
#
# Description: This script removes and adds source addresses.
#
# Author: Carsten Wolfrum
# License: GNU General Public License (GPL)
# Copyright: (C) NETWAYS GmbH
#
# OCF parameters:
# OCF_RESKEY_srcip
# OCF_RESKEY_interface
#
##########################################################################
# Initialization:
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
##########################################################################
SRCIP=$OCF_RESKEY_srcip
INTERFACE=$OCF_RESKEY_interface
usage() {
cat <<-!
usage: $0 {start|stop|status|monitor|validate-all|meta-data}
action:
start sets new source IP
stop sets main IP as source
status return running if the new source IP is set, not running if main IP is set
methods return the set of commands we support
monitor return TRUE if the IP address is the default outgoing address.
meta-data show meta data message
validate-all validate the instance parameters
!
exit $OCF_ERR_ARGS
}
meta_data()
{
cat <
1.0
This script removes and adds source addresses.
This script removes and adds source addresses.
The new source address.
The new source address.
The interface the new source address is bound on.
The interface the new source address is bound on.
END
exit $OCF_SUCCESS
}
validate_all()
{
INTERFACETEST=$(ip a list dev $INTERFACE)
if [ "$?" != 0 ]; then
echo -n $INTERFACETEST
exit $OCF_ERR_CONFIGURED
fi
IPTEST=$(ip a list dev $INTERFACE | grep $SRCIP)
if [ "$?" != 0 ]; then
echo "IP $SRCIP is not configured on interface $INTERFACE!"
exit $OCF_ERR_CONFIGURED
fi
return $OCF_SUCCESS
}
monitor()
{
SRCTEST=$(ip route | grep $INTERFACE | grep src | grep $SRCIP)
if [ "$?" != 0 ]; then
return $OCF_NOT_RUNNING
fi
return $OCF_SUCCESS
}
status()
{
monitor
}
start()
{
SUBNET=$(ip route | grep $INTERFACE | grep link | grep src | cut -d " " -f 1)
DEFAULTGW=$(ip route |grep default | cut -d " " -f 3)
ip route replace $SUBNET dev $INTERFACE src $SRCIP
ip route replace default via $DEFAULTGW dev $INTERFACE src $SRCIP
}
stop()
{
MAINIP=$(ip a list $INTERFACE | grep inet | head -1 | cut -d " " -f 6 | cut -d "/" -f 1)
SUBNET=$(ip route | grep $INTERFACE | grep link | grep src | cut -d " " -f 1)
DEFAULTGW=$(ip route |grep default | cut -d " " -f 3)
ip route replace $SUBNET dev $INTERFACE src $MAINIP
ip route replace default via $DEFAULTGW dev $INTERFACE
}
case $1 in
start)
validate_all
start
;;
stop)
validate_all
stop
;;
status)
status
;;
monitor)
monitor
;;
validate-all)
validate_all
;;
meta-data)
meta_data
;;
notify|promote|demote)
exit $OCF_ERR_UNIMPLEMENTED
;;
usage) usage
exit $OCF_SUCCESS
;;
*) usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
Dieser Resource-Agent kann z.B. dazu verwendet werden um die Quell-IP von Icinga-Checks zu setzen. Dies hat den Vorteil z.B. im Falle eines 2-Knoten-Cluster nicht beide IPs in Firewall/NRPE-Daemons eintragen zu müssen, es kann dann die Cluster-IP verwendet werden.
Der Resource-Agent muss als ausführbare Datei z.B. namens IPsrcaddr2 in ein Unterverzeichnis von /usr/lib/ocf/resource.d abgelegt werden, z.B. in /usr/lib/ocf/resource.d/custom. Die Konfiguration in Corosync/Pacemaker erfolgt dann mittels:
# crm configure primitive cluster-ip-src ocf:custom:IPsrcaddr2 srcip="QUELLIP" interface="INTERFACE_DER_QUELLIP"
Beim Schwenk auf den aktiven Knoten wird dann die angegebene IP als Quell-IP für ausgehende Verbindungen benutzt, beim Schwenk von diesem Knoten wird wieder die erste konfiguierte IP des angegebenen Interfaces als Quell-IP benutzt.
Danke für den Agenten, funktioniert einwandfrei.