준비운동 하기

지난 문서까지 mon을 이용한 클러스터를 만들어보았다. 이번에는 여기서 한 발짝 더 나은 클러스터를 만들어보자!! 그것은 바로 고가용성 클러스터이다. 솔직히 지난번까지 만든 클러스터의 경우 결정적인 결점이 하나 있었다. 그것은 master node가 죽을 경우 클러스터가 마비가 된다는 점이었다. 만일 master node가 죽지 않는다면, 우리는 그야말로 죽지 않는 클러스터를 만들 수 있다. 이번 문서는 방금 설명한 고가용성 클러스터를 만들어 본다.

지금까지는 3대의 컴퓨터로 클러스터를 구축했었다. 하지만 여기서는 1대의 컴퓨터가 더 필요하다. 그 이유는 master node를 받쳐줄 slave node가 필요하기 때문이다. 따라서 여기서는 총 4대의 컴퓨터가 필요하다. slave node의 사양은 다음과 같다.

CPU 펜티엄 II 333
RAM 64MB
OS RedHat 8.0 (Kernel 2.4.18 사용했다)
ETC Lan Card 1장
사용 IP 210.119.108.174

☞ 참고로 이 slave node는 모든 설정을 master node와 동일하게 해야 한다는 것을 염두해두기 바란다.

또한 heartbeat라는 프로그램이 필요하다. 고맙게도(?) RPM용을 지원한다. 따라서 redhat계열에서는 바로 설치가 가능하다.

http://www.ultramonkey.org/download/heartbeat/1.0.2/redhat_8.0/

위의 사이트에서 받으면 된다. 참고로 필자는 다음의 3개의 파일을 받았다.

  1. heartbeat-1.0.2-1.rh.8.0.i386.rpm
  2. heartbear-pils-1.0.2-1.rh.8.0.i386.rpm
  3. heartbeat-stonith-1.0.2-1.rh.8.0.i386.rpm

Heartbeat 설치하기

우선 3개의 파일을 설치해준다.

#rpm -Uvh heartbeat-*

☞ 참고로 필자는 RPM으로 설치했다. 유감스럽게도, 여기선 RPM설치를 위주로 설명하겠다.

우리는 여기서 heartbeat에서 중요한 3개의 파일을 수정해주어야 한다.

'ha.cf , haresources , authkeys' ← 이것들이다!!

우선 RPM으로 설치했다면,

#rpm -q heartbeat -d 

설치가 된 경로가 뜰 것이다. 아마도 /usr/share/doc/heartbeat-1.0.2/ 디렉토리 아래에 모두 설치가 되어있을 것이다. 이 중 3개의 파일을 /etc/ha.d 아래로 복사해준다.

cp ha.cf /etc/ha.d
cp haresources /etc/ha.d
cp authkeys /etc/ha.d

이제는 본격적으로 설정을 잡아보도록 한다.
우선 ha.cf 파일이다.

--------------------/etc/ha.d/ha.cf-----------------------
#
#	There are lots of options in this file.  All you have to have is a set
#	of nodes listed {"node ...}
#	and one of {serial, bcast, mcast, or ucast}
#
#
#       Note on logging:
#       If any of debugfile, logfile and logfacility are defined then they
#       will be used. If debugfile and/or logfile are not defined and
#       logfacility is defined then the respective logging and debug
#       messages will be loged to syslog. If logfacility is not defined
#       then debugfile and logfile will be used to log messges. If
#       logfacility is not defined and debugfile and/or logfile are not
#       defined then defaults will be used for debugfile and logfile as
#       required and messages will be sent there.
#
#	File to write debug messages to
debugfile /var/log/ha-debug
#
#
# 	File to write other messages to
#
logfile	/var/log/ha-log
#
#
#	Facility to use for syslog()/logger 
#
logfacility	local0
#
#
#	A note on specifying "how long" times below...
#
#	The default time unit is seconds
#		10 means ten seconds
#
#	You can also specify them in milliseconds
#		1500ms means 1.5 seconds
#
#
#	keepalive: how long between heartbeats?
#
keepalive 2
#
#	deadtime: how long-to-declare-host-dead?
#
deadtime 5 
#
#	warntime: how long before issuing "late heartbeat" warning?
#	See the FAQ for how to use warntime to tune deadtime.
#
#warntime 10
#
#
#	Very first dead time (initdead)
#
#	On some machines/OSes, etc. the network takes a while to come up
#	and start working right after you've been rebooted.  As a result
#	we have a separate dead time for when things first come up.
#	It should be at least twice the normal dead time.
#
#initdead 120
#
#
#	nice_failback:  determines whether a resource will
#	fail back to its "primary" node, or remain on whatever
#	node is serving it until that node fails.
#
#	The default is "off", which means that it WILL fail
#	back to the node which is declared as primary in haresources
#
#	"on" means that resources only move to new nodes when
#	the nodes they are served on die.  This is deemed as a
#	"nice" behavior (unless you want to do active-active).
#
#nice_failback on
#
#	hopfudge maximum hop count minus number of nodes in config
hopfudge 1
#	
#	serial	serialportname ...
#serial	/dev/ttyS0	# Linux
#serial	/dev/cuaa0	# FreeBSD
#serial	/dev/cua/a	# Solaris
#
#
#	Baud rate for serial ports...
#
#baud	19200
#
#	What UDP port to use for communication?
#
udpport	1001
#
#	What interfaces to heartbeat over?
#
bcast	eth0	# Linux
#bcast	le0	# Solaris
#
#	Set up a multicast heartbeat medium
#	mcast [dev] [mcast group] [port] [ttl] [loop]
#
#	[dev]		device to send/rcv heartbeats on
#	[mcast group]	multicast group to join (class D multicast address
#			224.0.0.0 - 239.255.255.255)
#	[port]		udp port to sendto/rcvfrom (no real reason to differ
#			from the port used for broadcast heartbeats)
#	[ttl]		the ttl value for outbound heartbeats.  this effects
#			how far the multicast packet will propagate.  (0-255)
#	[loop]		toggles loopback for outbound multicast heartbeats.
#			if enabled, an outbound packet will be looped back and
#			received by the interface it was sent on. (0 or 1)
#		
#
#mcast eth0 225.0.0.1 694 1 1
#
#	Set up a unicast / udp heartbeat medium
#	ucast [dev] [peer-ip-addr]
#
#	[dev]		device to send/rcv heartbeats on
#	[peer-ip-addr]	IP address of peer to send packets to
#
#ucast eth0 192.168.1.2
#
#
#	Watchdog is the watchdog timer.  If our own heart doesn't beat for
#	a minute, then our machine will reboot.
#
#watchdog /dev/watchdog
#
#       "Legacy" STONITH support
#       Using this directive assumes that there is one stonith 
#       device in the cluster.  Parameters to this device are 
#       read from a configuration file. The format of this line is:
#
#         stonith <stonith_type> <configfile>
#
#       NOTE: it is up to you to maintain this file on each node in the
#       cluster!
#
#stonith baytech /etc/ha.d/conf/stonith.baytech
#
#       STONITH support
#       You can configure multiple stonith devices using this directive.
#       The format of the line is:
#         stonith_host <hostfrom> <stonith_type> <params...>
#         <hostfrom> is the machine the stonith device is attached
#              to or * to mean it is accessible from any host. 
#         <stonith_type> is the type of stonith device (a list of
#              supported drives is in /usr/lib/stonith.)
#         <params...> are driver specific parameters.  To see the
#              format for a particular device, run:
#           stonith -l -t <stonith_type> 
#
#
#	Note that if you put your stonith device access information in
#	here, and you make this file publically readable, you're asking
#	for a denial of service attack ;-)
#
#
#stonith_host *     baytech 10.0.0.3 mylogin mysecretpassword
#stonith_host ken3  rps10 /dev/ttyS1 kathy 0 
#stonith_host kathy rps10 /dev/ttyS1 ken3 0 
#       
#	Tell what machines are in the cluster
#	node	nodename ...	-- must match uname -n
node	fat81.hslilo.co.kr
node	test.hslilo.co.kr
#
#	Less common options...
#
#	Treats 10.10.10.254 as a psuedo-cluster-member
#
#ping 10.10.10.254
#
#	Started and stopped with heartbeat.  Restarted unless it exits
#				with rc=100
#
#respawn userid /path/name/to/run
---------------------------------------------------

위에 보면 node라는 항목이 있다. 차례대로 처음에 master node , slave node 를 적어주면 된다.
이번엔 authkeys 파일이다.

---------------------/etc/ha.d/authkeys-------------------
auth 1
#1 crc
1 sha1 HI!
#3 md5 Hello!
---------------------------------------------------

이 파일에서 중요한 점은 반드시 퍼미션을 600 으로 해 주어야 한다는 점이다. 이제 마지막으로 haresource 이다.

-------------------/etc/ha.d/haresource--------------------
#문법에 맞게 써야 합니다.
#문법은 아래와 같습니다.
#masternode_name         IP                               DAEMON_NAME
fat81.hslilo.co.kr            210.119.108.177                 punk
---------------------------------------------------

위에서는 master node 의 호스트 네임과 IP를 적어주고 마지막으로 우리가 사용할 스크립트 파일명(:punk)을 적어주면 된다.

☞ 절대 경로를 적어주지 않아도 된다. 자동으로 /etc/rc.d/init.d 아래에 있는 파일을 찾기 때문이다.

다음은 master node 의 heartbeat가 끈어졌거나, 다시 살아났을 때 사용되는 스크립트이다.
아래와 같이 하나 스크립트 파일을 하나 만들어 준다.

-----------------------/etc/ha.d/ipvsadm.sct----------------
echo 1 > /proc/sys/net/ipv4/ip_forward
ifconfig lo:0 210.119.108.173  netmask 255.255.255.255 broadcast 210.119.108.173 up
route add -host 210.119.108.173 dev lo:0
echo 1 > /proc/sys/net/ipv4/conf/all/hidden
echo 1 > /proc/sys/net/ipv4/conf/lo/hidden
---------------------------------------------------

그리고 /etc/ha.d/resource.d/IPaddr 파일을 수정해 주어야 한다.

---------------/etc/ha.d/resource.d/IPaddr--------------------
#!/bin/sh
#
#	$Id: _ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0_ea_b5_ac_ec_b6_95_ed_95_98_ea_b8_b0_2d_e2_91_a2Heartbeat_eb_a5_bc_ec_9d_b4_ec_9a_a9_ed_95_9c_ea_b3_a0_ea_b0_80_ec_9a_a9_ec_84_b1_ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0,v 1.1 2013/06/01 08:44:19 root Exp root $
#
#	This script manages IP alias IP addresses
#
#	It can add an IP alias, or remove one.
#
#	usage: $0 ip-address {start|stop|status|monitor}
#
#	The "start" arg adds an IP alias.
#
#	Surprisingly, the "stop" arg removes one.	:-)
#
#
 
unset LC_ALL; export LC_ALL # Make ifconfig work in France for David Jules :-)
unset LANGUAGE; export LANGUAGE # Make ifconfig work in France for Fabrice :-)
#	make ifconfig work in Austria for Gregor G&ouml;stl
#	I have no idea why the previous fix didn't fix it for him.
LC_MESSAGES=C
export LC_MESSAGES
 
prefix=/usr
exec_prefix=/usr
. /etc/ha.d/shellfuncs
 
IFCONFIG=/sbin/ifconfig
IFCONFIG_A_OPT=
VARLIB=/var/lib/heartbeat
VLDIR=$VARLIB/rsctmp/IPaddr
ROUTE=/sbin/route
SENDARP=$HA_BIN/send_arp
GET_HW_ADDR=$HA_BIN/get_hw_addr
FINDIF=$HA_BIN/findif
USAGE="usage: $0 ip-address {start|stop|status|monitor}";
SYSTYPE="`uname -s`"
 
-------------------- 수정한 부분 -----------------------
ifconfig lo:0 down
-------------------- 수정한 부분 -----------------------
#
#      Find out which alias serves the given IP address
#      The argument is an IP address, and its output
#      is an aliased interface name (e.g., "eth0:0").
#
find_interface_solaris() {
 
  ipaddr="$1";
 
  $IFCONFIG $IFCONFIG_A_OPT | nawk '{if ($0 ~ /.*: / && NR > 1) {print "\n"$0} else {print}}' |
  while read ifname linkstuff
  do
    : ifname = $ifname
    read inet addr junk
    : inet = $inet addr = $addr
    while
      read line && [ "X$line" != "X" ]
    do
      : Nothing
    done
 
    case $ifname in
      *:*)	;;
      *)	continue;;
    esac
 
    #  This doesn't look right for a box with multiple NICs.
    #  It looks like it always selects the first interface on
    #  a machine.  Yet, we appear to use the results for this case too...
    ifname=`echo "$ifname" | sed s'%:$%%'`
 
    case $addr in
      addr:$ipaddr)	echo $ifname; return 0;;
      $ipaddr)	echo $ifname; return 0;;
    esac
  done
  return 1
}
 
#
#	Find out which alias serves the given IP address
#	The argument is an IP address, and its output
#	is an aliased interface name (e.g., "eth0:0").
#
find_interface_generic() {
 
  ipaddr="$1";
 
  $IFCONFIG $IFCONFIG_A_OPT  |
  while read ifname linkstuff
  do
    : Read gave us ifname = $ifname
 
    read inet addr junk
    : Read gave us inet = $inet addr = $addr
 
    while
      read line && [ "X$line" != "X" ]
    do
      : Nothing
    done
 
    case $ifname in
      *:*)	;;
      *)	continue;;
    esac
 
 
    case $SYSTYPE in
      *BSD)
		$IFCONFIG | grep "$ipaddr" -B4 | grep "UP," | cut -d ":" -f 1
		return 0;;
      *)
    		: "comparing $ipaddr to $addr (from ifconfig)"
		case $addr in
		  addr:$ipaddr)	echo $ifname; return 0;;
		  $ipaddr)	echo $ifname; return 0;;
    		esac
		continue;;
    esac
 
 
  done
  return 1
}
 
#
#       Find out which alias serves the given IP address
#       The argument is an IP address, and its output
#       is an aliased interface name (e.g., "eth0:0").
#
find_interface() {
    case $SYSTYPE in
	SunOS)
	 	IF=`find_interface_solaris $BASEIP`
        ;;
      *)
	 	IF=`find_interface_generic $BASEIP`
       ;;
       esac
 
  echo $IF
  return 0;
}
 
#
#	Return the MAC address of the given interface in the form
#	sendarp wants to see it...
#
 
GetMACaddr() {
  case $SYSTYPE in
 
    *BSD|SunOS)
	# Does this catch all types of interfaces on *BSD and SunOS?
	MACtmp=`$IFCONFIG "$1"  |
	fgrep "ether" |  sed  "s/^.*ether  *//"`
	case $MACtmp in
	  ?:*)	MACtmp=0$MACtmp;;
	esac
	ifconfig2sendarp "$MACtmp";;
 
    *)	MACtmp=`$IFCONFIG "$1"  | 
	fgrep "$1" |  sed "s/^.*HWaddr  *//"`
	ifconfig2sendarp "$MACtmp";;
  esac
}
 
 
  # Transform a MACaddr from ifconfig style to sendarp style
 
#HWsed='s%\(..\):\(..\):\(..\):\(..\):\(..\):\(..\).*$%\1\2\3\4\5\6%'
 
#
# This routine should handle any type of interface, but has only been
# tested on ethernet-type NICs.
#
ifconfig2sendarp() {
	echo "$1" | sed "s%:%%g"
}
 
#add_route () {
#  ipaddr="$1"
#  iface="$2"
#
#  case $SYSTYPE in
#    	SunOS)	
#		dev_intf="-interface"
#		;;
#    	*BSD)	
#		dev_intf="-ifp"
#		;;
#    	*)	
#		dev_intf="dev"
#		;;
#  esac
#
#  ha_log "info: $ROUTE -n -add host $ipaddr $dev_intf $iface"
#  $ROUTE -n add -host $ipaddr $dev_intf $iface
#
#  return $?
#}
 
delete_route () {
  ipaddr="$1"
 
  case $SYSTYPE in
	SunOS)
		CMD=""
		;;
	*BSD)
		CMD="$ROUTE -n delete -host $ipaddr"
		;;
 
	*)	
		CMD="$ROUTE -n del -host $ipaddr"
		;;
  esac
 
  ha_log "info: $CMD"
  $CMD
 
  return $?
}
 
delete_interface () {
  ipaddr="$1"
  ifname="$2"
 
  case $SYSTYPE in
	SunOS)
		case `uname -r` in
			5.8)
				CMD="$IFCONFIG $ifname unplumb"
				;;
			*)
				CMD="$IFCONFIG $ifname 0 down"
				;;
		esac
		;;
	*BSD)
		CMD="$IFCONFIG $ifname inet $ipaddr -alias"
		;;
 
	*)
		CMD="$IFCONFIG $ifname down"
		;;
  esac
 
  ha_log "info: $CMD"
  $CMD
 
  return $?
}
 
 
add_interface () {
  ipaddr="$1"
  ifinfo="$2"
  iface="$3"
 
  #
  #	On Linux the Alias is named ethx:y
  #	This will remove the "extra" interface Data 
  #	leaving us with just ethx
  #
  case $SYSTYPE in
    *BSD)
		IFEXTRA=""
		;;
    *)
		IFEXTRA=`echo "$ifinfo" | cut -f2-`
		;;
  esac
 
  case $SYSTYPE in
    SunOS)
		case `uname -r` in
		  5.8)
				$IFCONFIG $iface plumb
				CMD="$IFCONFIG $iface inet $ipaddr $IFEXTRA up"
				;;
		  *)
				CMD="$IFCONFIG $iface inet $ipaddr $IFEXTRA up"
				;;
		esac
		;;
 
    *BSD)
		CMD="$IFCONFIG $iface inet $ipaddr netmask 255.255.255.255 alias"
		;;
    *)		
    		CMD="$IFCONFIG $iface $ipaddr $IFEXTRA"	
		;;
  esac
 
  ha_log "info: $CMD"
  $CMD
  rc=$?
 
  case $rc in
    0)
    		;;
    *)
    		echo "ERROR: $CMD failed."
		;;
  esac
 
  return $rc
}
 
#      On Linux systems the (hidden) loopback interface may
#      conflict with the requested IP address. If so, this
#      unoriginal code will remove the offending loopback address
#      and save it in VLDIR so it can be added back in later
#      when the IPaddr is released.
#
remove_conflicting_loopback() {
	ipaddr="$1"
	ifname="$2"
 
	ha_log "info: Removing conflicting loopback $ifname."
	if
	  [ -d "$VLDIR/" ] || mkdir -p "$VLDIR/"
	then
	  : Directory $VLDIR now exists
	else
	  ha_log "ERROR: Could not create \"$VLDIR/\" conflicting" \
	  " loopback $ifname cannot be restored."
	fi
	if 
	  echo $ifname > "$VLDIR/$ipaddr"
	then
	  : Saved loopback information in $VLDIR/$ipaddr
	else
	  ha_log "ERROR: Could not save conflicting loopback $ifname." \
	  "it will not be restored."
	fi
	delete_interface "$ipaddr" "$ifname"
	# Forcibly remove the route (if it exists) to the loopback.
	delete_route "$ipaddr"
}
 
#      On Linux systems the (hidden) loopback interface may
#      need to be restored if it has been taken down previously
#      by remove_conflicting_loopback()
#
restore_loopback() {
	ipaddr="$1"
 
	if [ -s "$VLDIR/$ipaddr" ]; then
		ifname=`cat "$VLDIR/$ipaddr"`
		ha_log "info: Restoring loopback IP Address " \
			"$ipaddr on $ifname."
		add_interface "$ipaddr" "netmask 255.255.255.255" "$ifname"
		#add_route "$ipaddr" "$ifname"
		rm -f "$VLDIR/$ipaddr"
	fi
}
 
#
#	Remove the IP alias for the requested IP address...
#
ip_stop() {
  BASEIP=`echo $1 | sed s'%/.*%%'`
  IF=`find_interface $BASEIP`
 
  case $SYSTYPE in
	*BSD)
		if $IFCONFIG $IFCONFIG_A_OPT | \
			grep "inet.*[: ]$BASEIP " >/dev/null 2>&1; then
			continue;
		else
			exit 0
		fi;;
 
	Linux)
		if [ -z "$IF" ]; then
    			: Requested interface not in use
    			exit 0
		else
			case $IF in
			  lo*)
				: Requested interface is on loopback
				exit 0
				;;
			esac
  		fi;;
	*)
		if [ -z "$IF" ]; then
    			: Requested interface not in use
    			exit 0
  		fi;;
  esac
 
  if
    [ -x $HA_RCDIR/local_giveip ]
  then
    $HA_RCDIR/local_giveip $*
  fi
 
  delete_route "$BASEIP"
  delete_interface "$BASEIP" "$IF"
  rc=$?
 
  case $SYSTYPE in
	*BSD|SunOS)	;;
	Linux)
		restore_loopback "$BASEIP"
		# remove lock file...
		rm -f "$VLDIR/$IF";;
 
	*)	# remove lock file...
		rm -f "$VLDIR/$IF";;
  esac
 
  case $rc in
    	0) 
		ha_log "info: IP Address $BASEIP released"
		;;
    	*) 	
		ha_log "WARN: IP Address $BASEIP NOT released"
		;;
  esac
  return $rc
}
 
 
#
#	Find an unused interface/alias name for us to use for new IP alias
#	The argument is an IP address, and the output
#	is an aliased interface name (e.g., "eth0:0", "dc0", "le0:0").
#
find_free_interface() {
  if
    [ ! -d $VLDIR ]
  then
    mkdir -p $VLDIR
  fi
  BASEIP=`echo $1 | sed s'%/.*%%'`
  if
    NICINFO=`$FINDIF $1`
  then
    : OK
  else
    lrc=$?
    ha_log "ERROR: unable to find an interface for $BASEIP"
    return $lrc
  fi
 
  nicname=`echo "$NICINFO" | cut -f1`
  nicinfo=`echo "$NICINFO" | cut -f2-`
  if
    [ "X$nicname" = "X" ]
  then
    ha_log "ERROR: no interface found for $BASEIP"
    return 1;
  fi
 
  NICBASE="$VLDIR/$nicname"
  touch "$NICBASE"
 
  case $SYSTYPE in
	SunOS)
		IFLIST=`$IFCONFIG $IFCONFIG_A_OPT | \
			grep "^$nicname:[0-9]" | sed 's%: .*%%'`
		;;
	*)
		IFLIST=`$IFCONFIG $IFCONFIG_A_OPT | \
			grep "^$nicname:[0-9]" | sed 's% .*%%'`
		;;
  esac
 
  IFLIST=" `echo $IFLIST` "
 
  case $SYSTYPE in
       SunOS)
		j=1
		;;
	*)
		j=0
		;;
  esac
 
  case $SYSTYPE in
	*BSD)
		echo $nicname;
		return 0;;
 
	*)
  	while
    	  [ $j -lt 512 ]
  	do
    	    case $IFLIST in
	      *" "$nicname:$j" "*)	;;
	      *)			
		NICLINK="$NICBASE:$j"
		if
		  ln "$NICBASE" "$NICLINK"
		then
		  echo "$nicname:$j	$nicinfo"
		  return 0
		fi;;
	    esac
            j=`expr $j + 1`
	done;;
  esac
  return 1
}
 
 
#
#	Add an IP alias for the requested IP address...
#
#	It could be that we already have taken it, in which case it should
#	do nothing.
#
 
ip_start() {
  #
  #	Do we already service this IP address?
  #
  case `ip_status $1` in
    *unning*)   exit 0;
  esac
 
  BASEIP=`echo $1 | sed s'%/.*%%'`
 
  case $SYSTYPE in
    Linux)
		CURRENTIF=`find_interface "$BASEIP"`
       		case $CURRENTIF in
         	  lo*)
            		remove_conflicting_loopback "$BASEIP" "$CURRENTIF"
            		;;
            	  *)	;;
    		esac ;;
    *)		;;
  esac
 
  if IFINFO=`find_free_interface $1`; then
  	: OK got interface [$IFINFO] for $1
  else
  	exit 1
  fi
  IF=`echo "$IFINFO" | cut -f1`
 
  if
    [ -x $HA_RCDIR/local_takeip ]
  then
    $HA_RCDIR/local_takeip $*
  fi
 
  add_interface "$BASEIP" "$IFINFO" "$IF"
  rc=$?
  case $rc in
    0)
    		;;
    *)
		return $rc
		;;
  esac
 
  # add_route $BASEIP $IF
 
  TARGET_INTERFACE=`echo $IF | sed 's%:.*%%'`
 
  MACADDR=`$GET_HW_ADDR "$TARGET_INTERFACE"`
 
  if [ "X$MACADDR" = "X" ]; then
	ha_log "ERROR: Could not locate obtain hardware address" \
		"for $TARGET_INTERFACE"
	exit 1
  fi
 
  ha_log "info: Sending Gratuitous Arp for $BASEIP on $IF [$TARGET_INTERFACE]"
 
  for j in 1 2 3 4 5
  do
	ha_log "$SENDARP $TARGET_INTERFACE ${BASEIP} ${MACADDR} ${BASEIP} ffffffffffff"
	$SENDARP $TARGET_INTERFACE ${BASEIP} ${MACADDR} ${BASEIP} ffffffffffff \
   	||	ha_log "ERROR: Could not send gratuitous arp"
        sleep 2
  done &
}
 
ip_status() {
  BASEIP=`echo $1 | sed -e s'%/.*%%'`
  IF=`find_interface $BASEIP`
 
  case $SYSTYPE in
    *BSD)
	if
		$IFCONFIG $IFCONFIG_A_OPT | grep "inet.*[: ]$BASEIP " >/dev/null 2>&1
	then
		echo "running"
	else
		echo "stopped"
	fi;;
 
    Linux)		
	if
		[ -z "$IF" ]
	then
		echo "stopped"
	else
		case $IF in
		  lo*)
			echo "loopback"
			;;
		  *)
			echo "running"
			;;
		esac
	fi;;
    *)		
	if
		[ -z "$IF" ]
	then
		echo "stopped"
	else
		echo "running"
	fi;;
  esac
}
 
#
#	Determine if this IP address is really being served, or not.
#	Note that we don't distinguish if *we're* serving it locally...
#
ip_monitor() {
  BASEIP=`echo $1 | sed s'%/.*%%'`
  OPTS=" -c 1 -w1 -q"
  for j in 1 2 3
  do
    if
      /bin/ping $OPTS $BASEIP >/dev/null 2>&1
    then
      echo "OK"
      return 0
    fi
  done
  echo "down"
  return 1
}
 
usage() {
  echo $USAGE >&2
  echo "$Id: _ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0_ea_b5_ac_ec_b6_95_ed_95_98_ea_b8_b0_2d_e2_91_a2Heartbeat_eb_a5_bc_ec_9d_b4_ec_9a_a9_ed_95_9c_ea_b3_a0_ea_b0_80_ec_9a_a9_ec_84_b1_ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0,v 1.1 2013/06/01 08:44:19 root Exp root $"
}
 
#
#	Add or remove IP alias for the given IP address...
#
 
if
  [ $# -eq 1 ]
then
  case $1 in
    info)	cat <<-!INFO
	Abstract=IP address takeover
	Argument=IP address OR IP address/broadcast address OR IP address/broadcast address/netmaskbits
	Description:
	An IPaddr resource is an IP address which is to be taken over by \\
	the owning node.  An argument is required, and is of this form:
	    nnn.nnn.nnn.nnn/bbb.bbb.bbb.bbb
	Where nnn.nnn.nnn.nnn is the IP address to be taken over, and\\
	bbb.bbb.bbb.bbb is the broadcast address to be used with this address.
 
	Since IPaddr is the "default" resource type, it is not necessary\\
	to prefix the IP address by "IPaddr::".
	This allows IPaddr::192.2.4.63 to be abbreviated as 192.2.4.63.
	!INFO
	exit 0;;
  esac
fi
if
  [ $# -ne 2 ]
then
  usage
  exit 1
fi
 
case $2 in
  start)	ip_start $1;;
------------------------ 수정한 부분 -------------------
  stop)		ip_stop $1
		/etc/ha.d/ipvsadm.sct;;
------------------------ 수정한 부분 -------------------
  status)	ip_status $1;;
  monitor)	ip_monitor $1;;
  *)		usage
 		exit 1
		;;
esac
---------------------------------------------------

위에서 두 군데를 추가해주었다. 잘 확인하기 바란다. 그리고 이전 문서 봤던 punk 파일을 보기로 하자!!

-------------------------/etc/rc.d/init.d/punk---------------
#!/bin/sh
#
# load balancer daemon scripts
#
PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH
IPVSADM=/sbin/ipvsadm
MON=/usr/local/mon/mon
RETVAL=0
#Source function library.
. /etc/rc.d/init.d/functions
case "$1" in
        start)
        if [ -x $IPVSADM ]
        then
	echo 1 > /proc/sys/net/ipv4/ip_forward
	ifconfig eth0:1 210.119.108.173 netmask 255.255.255.255 broadcast 210.119.108.173 up
	route add -host 210.119.108.173 dev eth0:1
	echo 1 > /proc/sys/net/ipv4/conf/all/hidden
	echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
        $IPVSADM -A -t 210.119.108.173:80 -s wlc 
        $IPVSADM -a -t 210.119.108.173:80 -r 210.119.108.170 -g
        $IPVSADM -a -t 210.119.108.173:80 -r 210.119.108.175 -g
        echo -n "started loadbalancer daemon:"
        daemon  $MON -f -c /etc/mon/mon.cf
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/punk
        echo
        fi
        ;;
        stop)
        if [ -x $IPVSADM ]
                then
                echo -n "punk daemon stopping..."
                $IPVSADM -C
                ifconfig eth0:0 down
                killproc mon
                rm -f /var/lock/subsys/punk
                killall http.monitor
                echo -n "punk daemon killed"
                echo
        fi
        ;;
        *)
        echo "Usage : punk {start|stop}"
                exit 1
esac
exit 0
---------------------------------------------------

이번에는 /etc/rc.d/init.d/heartbeat 파일을 수정해준다.

---------------/etc/rc.d/init.d/heartbeat----------------------
#!/bin/sh
#
#	$Id: _ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0_ea_b5_ac_ec_b6_95_ed_95_98_ea_b8_b0_2d_e2_91_a2Heartbeat_eb_a5_bc_ec_9d_b4_ec_9a_a9_ed_95_9c_ea_b3_a0_ea_b0_80_ec_9a_a9_ec_84_b1_ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0,v 1.1 2013/06/01 08:44:19 root Exp root $
#
# heartbeat     Start high-availability services
#
# Author:       Alan Robertson	<alanr@unix.sh>
#
#		This script works correctly under SuSE, Debian,
#		Conectiva, Red Hat and a few others.  Please let me know if it
#		doesn't work under your distribution, and we'll fix it.
#		We don't hate anyone, and like for everyone to use
#		our software, no matter what OS or distribution you're using.
#
# chkconfig: 2345 75 05
# description: Startup script high-availability services.
# processname: heartbeat
# pidfile: /var/run/heartbeat.pid
# config: /etc/ha.d/ha.cf
#
### BEGIN INIT INFO
# Description: heartbeat is a basic high-availability subsystem.
#	It will start services at initialization, and when machines go up
#	or down.  This version will also perform IP address takeover using
#	gratuitous ARPs.  It works correctly for a 2-node configuration,
#	and is extensible to larger configurations.
#	
#	It implements the following kinds of heartbeats:
#		- Bidirectional Serial Rings ("raw" serial ports)
#		- UDP/IP broadcast (ethernet, etc)
#		- UDP/IP multicast (ethernet, etc)
#		- Unicast heartbeats
#		- "ping" heartbeats (for routers, switches, etc.)
#	   	(to be used for breaking ties in 2-node systems
#		 and monitoring networking availability)
#
# Short-Description: High-availability services.
# Required-Start: $network $time $syslog
# Required-Stop: $network $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO
 
 
HA_DIR=/etc/ha.d; export HA_DIR
CONFIG=$HA_DIR/ha.cf
. $HA_DIR/shellfuncs
 
LOCKDIR=/var/lock/subsys
RUNDIR=/var/run
 
if
  [ -r /etc/SuSE-release ]
then
  # rc.status is new since SuSE 7.0
  [ -r /etc/rc.status ] && . /etc/rc.status
  . /etc/rc.config
 
  # Determine the base and follow a runlevel link name.
  base=${0##*/}
  link=${base#*[SK][0-9][0-9]}
 
  # Force execution if not called by a runlevel directory.
  test "$link" = "$base" && START_HEARTBEAT=yes
  test "$START_HEARTBEAT" = yes || exit 0
fi
if
  [ -z "$rc_done" ]
then
  rc_done="Done."
  rc_failed="Failed."
  rc_skipped="Skipped."
fi
 
 
# exec 2>>/var/log/ha-debug
 
#	This should probably be it's own autoconf parameter
#	because RH has moved it from time to time...
#	and I suspect Conectiva and Mandrake also supply it.
 
DISTFUNCS=/etc/rc.d/init.d/functions
PROC_HA=$HA_BIN/ha.o
SUBSYS=heartbeat
INSMOD=/sbin/insmod
US=`uname -n`
 
# Set this to a 1 if you want to automatically load kernel modules
USE_MODULES=1
 
[ -x $HA_BIN/heartbeat ] || exit 0
 
#
#	Some environments like it if we use their functions...
#
if
  [ ! -x $DISTFUNCS ]
then
  # Provide our own versions of these functions
  status() {
	$HA_BIN/heartbeat -s
  }
  echo_failure() {
      EchoEsc " Heartbeat failure [rc=$1]. $rc_failed"
      return $1
  }
  echo_success() {
	: Cool!  It started!
      EchoEsc "$rc_done"
  }
else
  . $DISTFUNCS
fi
 
#
#	See if they've configured things yet...
#
if
  [ ! -f $CONFIG ]
then
  EchoNoNl "Heartbeat not configured: $CONFIG not found."
  echo_failure 1
  exit 0
fi
 
init_watchdog() {
  if
    [  -f /proc/devices -a  -x $INSMOD ]
  then
    init_watchdog_linux
  fi
}
 
#
#	Install the softdog module if we need to
#
init_watchdog_linux() {
#
# 	We need to install it if watchdog is specified in $CONFIG, and
#	/dev/watchdog refers to a softdog device, or it /dev/watchdog
#	doesn't exist at all.
#
#	If we need /dev/watchdog, then we'll make it if necessary.
#
#	Whatever the user says we should use for watchdog device, that's
#	what we'll check for, use and create if necessary.  If they misspell
#	it, or don't put it under /dev, so will we.
#	Hope they do it right :-)
#
#
  insmod=no
  # What do they think /dev/watchdog is named?
  MISCDEV=`grep ' misc$' /proc/devices | cut -c1-4`
  MISCDEV=`Echo $MISCDEV`
  WATCHDEV=`ha_parameter watchdog`
  WATCHDEV=`Echo $WATCHDEV`
  if
    [ "X$WATCHDEV" != X ]
  then
    : Watchdog requested by $CONFIG file
  #
  #	We try and insmod the module if there's no dev or the dev exists
  #	and points to the softdog major device.
  #
    if
      [ ! -c "$WATCHDEV" ]
    then
      insmod=yes
    else
      case `ls -l "$WATCHDEV" 2>/dev/null` in
      *$MISCDEV,*)
	    insmod=yes;;
      *)	: "$WATCHDEV isn't a softdog device (wrong major)" ;;
      esac
    fi
  else
    : No watchdog device specified in $CONFIG file.
  fi
  case $insmod in
    yes)
      if
        grep softdog /proc/modules >/dev/null 2>&1 
      then
        : softdog already loaded
      else
        $INSMOD softdog >/dev/null 2>&1
      fi;;
  esac
  if
    [ "X$WATCHDEV" != X -a ! -c "$WATCHDEV" -a $insmod = yes ]
  then
    minor=`cat /proc/misc | grep watchdog | cut -c1-4`
    mknod -m 600 $WATCHDEV c $MISCDEV $minor
  fi
} # init_watchdog_linux()
 
 
#
#	Start the heartbeat daemon...
#
 
start_heartbeat() {
  if
    ERROR=`$HA_BIN/heartbeat 2>&1`
  then
    : OK
  else
    return $?
  fi
}
 
 
#
#	Start Linux-HA
#
 
StartHA() {
  EchoNoNl "Starting High-Availability services: "
  $HA_BIN/ResourceManager verifyallidle
  if
    [ $USE_MODULES = 1 ]
  then
    #	Create /dev/watchdog and load module if we should
    init_watchdog
  fi
  rm -f $RUNDIR/ppp.d/*
  if
    [  -f $HA_DIR/ipresources -a ! -f $HA_DIR/haresources ]
  then
    mv $HA_DIR/ipresources $HA_DIR/haresources
  fi
  #	Start heartbeat daemon
  if
    start_heartbeat
  then
    echo_success
    return 0 
  else
    RC=$?
    echo_failure $RC
    if [ ! -z "$ERROR" ]; then
      Echo
      Echo "$ERROR"
    fi 
    return $RC
  fi
}
 
#
#	Ask heartbeat to stop.  It will give up its resources...
#
StopHA() {
  EchoNoNl "Stopping High-Availability services: "
 
  if
    $HA_BIN/heartbeat -k &> /dev/null	# Kill it
  then
    echo_success
    return 0
  else
    RC=$?
    echo_failure $RC
    return $RC
  fi
}
 
StatusHA() {
  $HA_BIN/heartbeat -s
}
 
StandbyHA() {
  nice_failback=`ha_parameter nice_failback | tr "on" "ON"`
  echo "nice_failback: $nice_failback"
  if
    [ "$nice_failback" = "ON" ]
  then
    if
      StatusHA >/dev/null 2>&1
    then
      Echo "Attempting to enter standby mode."
      Echo
      EchoNoNl "Attempting to enter standby mode"
      if
        $HA_BIN/hb_standby
      then
        # It's impossible to tell how long this will take.
        echo_success
      else
        echo_failure $?
      fi
    else
       Echo "Heartbeat is not currently running."
    fi
  else
    Echo "Standby mode requires that nice_failback be enabled."
    Echo "nice_failback is not enabled.  Cannot enter standby mode."
  fi
}
 
#
#	Ask heartbeat to restart.  It will *keep* its resources
#
ReloadHA() {
  EchoNoNl "Reloading High-Availability services: "
 
  if
    $HA_BIN/heartbeat -r # Restart, and keep your resources
  then
    echo_success
    return 0
  else
    RC=$?
    echo_failure $RC
    return $RC
  fi
}
 
RunStartStop() {
  # Run pre-startup script if it exists
  if
    [  -f $HA_DIR/resource.d/startstop ]
  then
    $HA_DIR/resource.d/startstop  "$@"
  fi
}
 
RC=0
# See how we were called.
 
case "$1" in
  start)
	RunStartStop pre-start
	StartHA
	RC=$?
	Echo
	if
	  [ $RC -eq 0 ]
	then
	  [ ! -d $LOCKDIR ] && mkdir -p $LOCKDIR
	  touch $LOCKDIR/$SUBSYS
	fi
	RunStartStop post-start $RC
	;;
 
  standby)
	StandbyHA
        RC=$?;;
 
  status)
	StatusHA
	RC=$?;;
 
  stop)
	RunStartStop "pre-stop"
	StopHA
	RC=$?
	Echo
        if
          [ $RC -eq 0 ]
        then
          rm $LOCKDIR/$SUBSYS
        fi
        RunStartStop post-stop $RC
 
--------------------- 추가한 부분 ---------------------
	/etc/ha.d/ipvsadm.sct
	;;
--------------------- 추가한 부분  ---------------------
 
  restart)
        sleeptime=`ha_parameter deadtime`
	StopHA
	Echo
	EchoNoNl Waiting to allow resource takover to complete:
	sleep $sleeptime
	sleep 10 # allow resource takeover to complete (hopefully).
	echo_success
	Echo
	StartHA
	Echo
	;;
 
  force-reload|reload)
	ReloadHA
	Echo
	RC=$?
	;;
 
  *)
	Echo "Usage: $0 {start|stop|status|restart|reload|force-reload}"
	exit 1
esac
 
exit $RC
#
#
#  $Log: _ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0_ea_b5_ac_ec_b6_95_ed_95_98_ea_b8_b0_2d_e2_91_a2Heartbeat_eb_a5_bc_ec_9d_b4_ec_9a_a9_ed_95_9c_ea_b3_a0_ea_b0_80_ec_9a_a9_ec_84_b1_ed_81_b4_eb_9f_ac_ec_8a_a4_ed_84_b0,v $
#  Revision 1.1  2013/06/01 08:44:19  root
#  180.71.93.73;;fat81;;
#
#  Revision 1.2  2010/06/27 05:54:14  root
#  210.57.241.80;;fat81;;
#
#  Revision 1.1  2010/06/27 05:53:56  root
#  210.57.241.80;;fat81;;
#
#  Revision 1.3  2008/12/23 06:49:03  root
#  203.247.145.9;;fat81;;
#
#  Revision 1.2  2008/12/23 06:47:59  root
#  203.247.145.9;;fat81;;
#
#  Revision 1.1  2008/12/19 22:42:44  root
#  116.37.209.248;;fat81;;
#
#  Revision 1.1  2007/09/17 17:19:31  root
#  125.129.164.238;;fat81;;
#
#  Revision 1.25.2.1  2003/03/12 18:24:50  lars
#  Syncing 1.0.x series with CVS head in preparation for 1.0.2 release.
#
#  Revision 1.27  2003/02/21 13:41:01  alan
#  Minor comment changes to the heartbeat init script.
#
#  Revision 1.26  2003/02/20 01:26:42  horms
#  Fixed problem with Description: feild.
#  Tuomo Soini reported an undisclosed problem with the current format
#  on an undisclosed version of Redhat. The change appears not to
#  go against LSB 1.3.0[*] which Alan modified this file to conform with the
#  other day.
#
#  [*] http://www2.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/initscrcomconv.html
#
#  Revision 1.25  2003/02/19 17:50:20  alan
#  Fixed a minor comment bug pointed out by LMB.
#
#  Revision 1.24  2003/02/18 04:32:09  alan
#  Added some comments to the heartbeat init script necessary for LSB
#  compatibility.
#
#  Revision 1.23  2002/10/21 10:17:18  horms
#  hb api clients may now be built outside of the heartbeat tree
#
#  Revision 1.22  2002/10/15 13:41:31  alan
#  Switched heartbeat over to use the GSource library functions.
#  Added the standby capability to the heartbeat init script
#  Changed the proctrack library code to use cl_log() instead of g_log().
#  Removed a few unused header files.
#
#  Revision 1.21  2002/10/11 03:13:09  horms
#  Minor cleanup of output from a "restart"
#
#  Revision 1.20  2002/10/09 18:37:07  msoffen
#  Left call directly to startstop script instead of the wrapper function.
#
#  Revision 1.19  2002/10/09 18:35:54  msoffen
#  Created pre-start, pre-stop, post-stop, and pre-stop constructs in startstop and
#  moved startstop to documents (to not override).
#
#  Revision 1.18  2002/09/20 02:13:20  horms
#  Tidied up the output for the restart and reload targets.
#  This follows what is done for start and stop.
#  Works fine on RedHat 7.2. Hopefully it won't break anything/much else.
#
#  Revision 1.17  2002/09/10 15:54:57  msoffen
#  Added call on startup (if startstop scrip exists) to startstop script (not
#  resource based - heartbeat startup/shutdown based).
#
#  Revision 1.16  2002/08/12 14:37:53  msoffen
#  Replaced the last echononl with EchoNoNl.
#
#  Revision 1.15  2002/04/03 20:02:21  alan
#  Made the init starting and stopping priorities into autoconf variables.
#  They default to 75 and 5 respectively.  They should probably be overridden for
#  SuSE in the ConfigureMe script.
#
#  Revision 1.14  2002/04/02 19:40:36  alan
#  Failover was completely broken because of a typo in the configure.in file
#  Changed the run level priorities so that heartbeat starts after
#  drbd by default.
#  Changed it so that heartbeat by default runs in init level 5 too...
#
#  Fixed a problem which happened when both nodes started about simultaneously.
#  The result was that hb_standby wouldn't work afterwards.
#
#  Raised the debug level of some reasonably verbose messages so that you can
#  turn on debug 1 and not be flooded with log messages.
#
#  Changed the code so that in the case of nice_failback there is no waiting for
#  the other side to give up resources, because we negotiate this in advance.
#  It gets this information through and environment variable.
#
#  Revision 1.13  2002/03/21 02:03:00  alan
#  Added locking to the assignment of interfaces in IPaddr.
#
#  Revision 1.12  2002/03/05 21:13:06  alan
#  Put in fix suggested by Jo&atilde;o Miguel P. S&aacute; <joao-m-sa@ptinovacao.pt>
#  to use grave accents instead of the silly bash notation.
#
#  Revision 1.11  2001/11/26 14:04:41  horms
#  Log to stdout that <path>/ha.cf is missing if init script exits for that reason.
#  (Horms)
#
#  Revision 1.10  2001/10/25 16:12:06  alan
#  Put in a portability change on path names...
#
#  Revision 1.9  2001/10/25 15:00:27  alan
#  Put in naming patch from Matt Soffen for heartbeat.in
#
#  Revision 1.8  2001/10/24 20:46:29  alan
#  A large number of patches.  They are in these categories:
#  	Fixes from Matt Soffen
#  	Fixes to test environment things - including changing some ERRORs to
#  		WARNings and vice versa.
#  	etc.
#
#  Revision 1.7  2001/10/13 09:42:51  alan
#  Incorporated a small patch from Matt Soffen
#
#  Revision 1.6  2001/10/07 03:58:10  alan
#  Fixed up the 'echo' code in rc script so that it's portable.
#  The 'shellfuncs' function library now have Echo EchoEsc and EchoNoNl functions
#  in it.  They are supposed to work on any OS.
#
#  Revision 1.5  2001/10/05 22:56:01  alan
#  Added another missing portability feature...
#
#  Revision 1.4  2001/10/05 22:48:05  alan
#  Fixed the spelling of the echoesc and echononl shell functions.
#
#  Revision 1.3  2001/10/05 22:38:06  alan
#  Put in some code to make us more portable.
#
#  Revision 1.2  2001/06/28 20:35:00  alan
#  Patch from Juri to install our scripts with paths patched appropriately.
#
#  Revision 1.1  2001/06/28 14:21:40  alan
#  Added heartbeat.in and removed 2 Makefile.in's as per Juri Haberland
#  Ypdated .cvsignore files...
#
#  Revision 1.1  2001/05/09 23:21:21  mmoerz
#  autoconf & automake & libtool changes
#
#  * following directories have been added:
#
#    - config	will contain autoconf/automake scripts
#    - linux-ha	contains config.h which is generated by autoconf
#  		will perhaps some day contain headers which are used throughout
#  		linux-ha
#    - replace	contains as the name implies replacement stuff for targets
#  		where specific sources are missing.
#
#  * following directories have been added to make a split up between c-code
#    and shell scripts and to easy their installation with automake&autoconf
#
#    - heartbeat/init.d		containment of init.d script for heartbeat
#    - heartbeat/logrotate.d	containment of logrotate script for heartbeat
#
#    - ldirectord/init.d		similar to heartbeat
#    - ldirectord/logrotate.d	similar to heartbeat
#
#  * general changes touching the complete repository:
#
#    - all Makefiles have been replaced by Makefile.ams.
#
#    - all .cvsingnore files have been enhanced to cope with the dirs/files
#      that are added by automake/autoconf
#      Perhaps it would be a nice idea to include those files, but the sum
#      of their size if beyond 100KB and they are likely to vary from
#      automake/autoconf version.
#      Let's keep in mind that we will have to include them in distribution
#      .tgz anyway.
#
#    - in dir replace setenv.c was placed to available on platform where
#      putenv() has to be used since setenv is depricated (better rewrite
#      code -> to be done later)
#
#  * following changes have been made to the files of linux-ha:
#
#    - all .cvsignore files have been changed to ignore files generated by
#      autoconf/automake and all files produced during the build-process
#
#    - heartbeat/heartbeat.c:	added #include <config.h>
#
#    - heartbeat/config.c:		added #include <config.h>
#
#  * following files have been added:
#     - Makefile.am: see above
#     - configure.in: man autoconf/automake file
#     - acconfig.h: here are additional defines that are needed for
#  		 linux-ha/config.h
#     - bootstrap: the shell script that 'compiles' the autoconf/automake script
#  		into a useable form
#     - config/.cvsignore: no comment
#     - doc/Makefile.am: no comment
#     - heartbeat/Makefile.am: no comment
#     - heartbeat/lib/Makefile.am: no comment
#     - heartbeat/init.d/.cvsignore: no comment
#     - heartbeat/init.d/heartbeat: copy of hearbeat/hearbeat.sh
#     - heartbeat/init.d/Makefile.am: no comment
#     - heartbeat/logrotate.d/.cvsignore: no comment
#     - heartbeat/logrotate.d/Makefile.am: no comment
#     - heartbeat/logrotate.d/heartbeat: copy of hearbeat/heartbeat.logrotate
#     - heartbeat/rc.d/Makefile.am: no comment
#     - heartbeat/resource.d/Makefile.am: no comment
#     - ldirectord/Makefile.am: no comment
#     - ldirectord/init.d/Makefile.am: no comment
#     - ldirectord/init.d/.cvsignore: no comment
#     - ldirectord/init.d/ldiretord: copy of ldirectord/ldirectord.sh
#     - ldirectord/logrotate.d/Makefile.am: no comment
#     - ldirectord/logrotate.d/.cvsignore: no comment
#     - ldirectord//ldiretord: copy of ldirectord/ldirectord.logrotate
#     - linux-ha/.cvsignore: no comment
#     - replace/.cvsignore: no comment
#     - replace/setenv.c: replacement function for targets where setenv is missing
#     - replace/Makefile.am: no comment
#     - stonith/Makefile.am: no comment
#
#  Revision 1.35  2001/02/25 18:45:59  alan
#  Changed the watchdog code to use the new ha_parameter function.
#
#  Revision 1.34  2001/02/25 18:39:58  alan
#  Added code to sleep for "enough" seconds during a restart to ensure that
#  takeover happens like it should.
#
#  Revision 1.33  2001/02/07 07:10:20  alan
#  Added code to verify that all resources are idle when starting heartbeat.
#
#  Revision 1.32  2000/12/23 05:08:59  horms
#  Cleaned up debian flims
#
#  Revision 1.31  2000/12/20 16:54:41  alan
#  Changed "restart" in heartbeat to actually do a stop followed by a start.
#  Reload still does the no-failover reload operation.
#
#  Revision 1.30  2000/11/25 13:07:44  alan
#  Fixed a minor bug in the heartbeat startup script for SuSE.
#  Replaced the makefile with a correct version after it was slammed with
#  a new/old version by someone who is Debianizing it.
#
#  Revision 1.29  2000/11/17 13:28:46  alan
#  Made the code slightly more SuSE-friendly in its messages.
#  Increased the release number :-)
#
#  Revision 1.28  2000/08/01 12:25:59  alan
#  Yet another few comment changes...
#
#  Revision 1.27  2000/08/01 12:25:05  alan
#  More political comment changes...
#
#  Revision 1.26  2000/08/01 12:21:55  alan
#  Some comment changes.
#
#  Revision 1.25  2000/06/21 04:34:48  alan
#  Changed henge.com => linux-ha.org and alanr@henge.com => alanr@suse.com
#
#  Revision 1.24  2000/06/12 22:07:59  alan
#  Spelling correction in a comment.
#
#  Revision 1.23  2000/06/12 22:06:30  alan
#  Finished updating the code for restart.
#
#  Revision 1.22  2000/06/12 22:03:11  alan
#  Put in a fix to the link status code, to undo something I'd broken, and also to simplify it.
#  I changed heartbeat.sh so that it uses the -r flag to restart heartbeat instead
#  of stopping and starting it.
#
#  Revision 1.21  2000/06/12 06:11:09  alan
#  Changed resource takeover order to left-to-right
#  Added new version of nice_failback.  Hopefully it works wonderfully!
#  Regularized some error messages
#  Print the version of heartbeat when starting
#  Hosts now have three statuses {down, up, active}
#  SuSE compatability due to Friedrich Lobenstock and alanr
#  Other minor tweaks, too numerous to mention.
#
#  Revision 1.20  2000/04/27 12:50:20  alan
#  Changed the port number to 694.  Added the pristene target to the ldirectord
#  Makefile.  Minor tweaks to heartbeat.sh, so that it gives some kind of
#  message if there is no configuration file yet.
#
#  Revision 1.19  2000/04/24 07:08:13  horms
#  Added init script to ldirectord, fixed hearbeat.sh to work with RH6.2 again, heartbeat.sh now aborts if /etc/ha.d/ha.cf is not present. Added sample ldirectord.cf.
Moved logging directives to the top of the sample ha.cf.
Incremented version in master Makefile to 0.4.7apre2. KERNELDIRS now don't get any treatment in the master makefile,
this is to fix a bug (introduced by me) with using an emty  in a for i in  under some shells
#
#  Revision 1.18  2000/04/24 06:34:45  horms
#  Made init work cleanly with RH 6.2 again
#
#  Revision 1.17  2000/04/23 13:16:17  alan
#  Changed the code in heartbeat.sh to no longer user RH's daemon or
#  killproc functions.
#
#  Revision 1.16  2000/04/03 08:26:29  horms
#
#
#  Tidied up the output from heartbeat.sh (/etc/rc.d/init.d/heartbeat)
#  on Redhat 6.2
#
#  Loging to syslog if a facility is specified in ha.cf is instead of
#  rather than as well as file logging as per instructions in ha.cf
#
#  Fixed a small bug in shellfunctions that caused logs to syslog
#  to be garbled.
#
#  Revision 1.15  1999/11/11 06:02:43  alan
#  Minor change to make heartbeat default enabled on startup.
#
#  Revision 1.14  1999/11/11 05:48:52  alan
#  Added code to start up heartbeat automatically.
#
#  Revision 1.13  1999/10/19 13:55:36  alan
#  Changed comments about being red hat compatible
#  Also, changed heartbeat.c to be both SuSE and Red Hat compatible in it's -s
#  output
#
#  Revision 1.12  1999/10/19 01:56:51  alan
#  Removed the sleep between shutdown and startup, since that's now in
#  heartbeat itself.
#
#  Revision 1.11  1999/10/19 01:49:10  alan
#  Put in a sleep between stop and start in restart to make it more reliable.
#
#  Revision 1.10  1999/10/10 19:45:21  alanr
#  Changed comment
#
#  Revision 1.9  1999/10/05 05:17:49  alanr
#  Added -s (status) option to heartbeat, and used it in heartbeat.sh...
#
#  Revision 1.8  1999/10/05 04:35:26  alanr
#  Changed it to use the new heartbeat -k option to shut donw heartbeat.
#
#  Revision 1.7  1999/10/04 03:12:39  alanr
#  Shutdown code now runs from heartbeat.
#  Logging should be in pretty good shape now, too.
#
#  Revision 1.6  1999/10/04 01:47:22  alanr
#  Fix the problem reported by Thomas Hepper with the code for loading the watchdog
#  device correctly.
#
#  Revision 1.5  1999/10/03 03:14:04  alanr
#  Moved resource acquisition to 'heartbeat', also no longer attempt to make the FIFO, it's now done in heartbeat.  It should now be possible to start it up more readily...
#
#  Revision 1.4  1999/10/02 17:48:08  alanr
#  Put back call to init_fifo.  Thanks to Thomas Hepper
#
#  Revision 1.3  1999/10/02 04:59:22  alanr
#  FreeBSD mkfifo cleanup
#
#  Revision 1.2  1999/09/23 15:53:13  alanr
#
#  First version to work :-)
#  Got this first version to work...
#
#  Revision 1.1.1.1  1999/09/23 15:31:24  alanr
#  High-Availability Linux
#
#  Revision 1.12  1999/09/14 23:07:09  alanr
#  another comment change...
#
#  Revision 1.11  1999/09/14 23:05:13  alanr
#  comment change...
#
#  Revision 1.10  1999/09/14 22:32:50  alanr
#  Put in Thomas Hepper's fix for killproc.
#  Lots of other changes I think...
#
#  Revision 1.9  1999/09/07 04:46:34  alanr
#  made it exit with proper return codes.
#  Also, moved things around according to the FHS...
#
#  Revision 1.8  1999/08/22 04:10:37  alanr
#  changed the name of this file to heartbeat.sh.
#  Also moved the change log to the end of the file...
#
#  Revision 1.7  1999/08/22 04:03:13  alanr
#  Merged this file with the heartbeat script as suggested by Guenther Thomsen
#
#  Revision 1.6  1999/08/21 21:54:12  alanr
#  Restructured the code in preparation for combining this script with the
#  init script under /etc/rc.d/init.d.
#
#  Revision 1.5  1999/08/17 04:34:53  alanr
#  added code to create /dev/watchdog and load softdog if necessary...
#
#
---------------------------------------------------

이제 모든 설정이 끝났다. 참~ 멀고도 험했다. 즐거운 테스트 시간만 남았다.

☞ 여기까지의 설정은 master 와 slave 모두 거의 비슷하다.

우선 master 와 slave 에 각각 heartbeat 를 시작시켜준다. 그리고 read node는 각각의 스크립트를 실행시켜 웹서버를 가동시킨다.

여기서 우리가 체크해보아야 할 것들은 다음과 같다.

  1. master node 와 slave node가 모두 정상일때 각각 둘의 상태 확인 (ex: 네트워크 설정, 로그파일 확인)
  2. master node가 죽었을 때 slave node의 상황 변화 및 이후에 다시 master node가 살아났을 경우 slave node의 상태변화
  3. 2번 상황에서의 로드 밸런싱이 제대로 되는지??

허접한 문서를 읽어준 분들에게 고맙다는 말을 전하고 싶다. 이 문서는 박성곤님의 문서를 많이 참조했음을 알린다. 마지막으로 나의 문서가 많은 도움이 되었기를 바란다.

그래도 안된다면

내가 원래의 문서(.HWP)를 위키형식으로 옮기다보니, 중간에 세팅하는 과정에서 제대로 복사가 안 되었을 수가 있다. 만일 제대로 세팅했음에도 불구하고 제대로 원하는 결과가 나오지 않는다면, 'EditText' 을 눌러서 직접 소스를 보기 바란다. 혹시라도 그 곳에 답이 있을지도.

  • computer/networking/클러스터_구축하기_-_3.heartbeat를_이용한_고가용성_클러스터.txt
  • Last modified: 3 years ago
  • by likewind