[클러스터] Director Routing LVS Cluster 구축기(아랑)
——————————————————————
무천아랑의 Director Routing LVS Cluster 구축기
작성자 : 서진우 (alang at sysmng.com)
작성일 : 2001년 11월 22일
——————————————————————
1. 시스템 구축 환경
* Master Lvs Server ( real_server 1 ) :
Redhat 7.1 ( kernel 2.4.13 )
랜카드 2개
활당 아이피 3개
– 실제 아이피 : 211.47.64.151 ( eth0 )
– 내부 아이피 : 192.168.0.1 ( eth1 )
– 가상 아이피 : 211.47.64.153 ( eth0:0 )
* Slaver Lvs Server ( real_server 2 ) :
Redhat 7.1 ( kernel 2.4.13 )
랜카드 2개
활당 아이피 3개
– 실제 아이피 : 211.47.64.145 ( eth0 )
– 내부 아이피 : 192.168.0.2 ( eth1 )
– 가상 아이피 : 211.47.64.153 ( lo:0 )
시스템 설계 설명 :
로드 밸런싱 알고리즘 :
두대의 시스템으로 하나를 master lvs 겸 real_server1, 다른하나를 slave lvs
겸 real_server2 로 사용하고자 한다.
master lvs 에서 real 1.2 서버로 스케줄링에 맞추어서 팻킷을 분산 처리 해주
다가 특정 real 이 죽는 경우 master lvs 에서 죽은 real를 팻킷 분산 스케줄에
서 제거 하고, 다시 살아 났을때 자동으로 포함시키는 역활을 한다.
master lvs 가 죽었을때 real 로 작동하던 slave 가 master lvs 권한을 위임받고
master lvs 가 되어서 그 역할을 대신한다. 실제 master 가 살아 나면 자동으로
이를 감지하고 다시 real server 역활로 돌아가게 된다.
디스크 동기화 :
rsync 를 이용하여 Web 데이터와 DB 데이터를 동기화 할것이다.
시스템 구축 설계도
eth0 :211.47.64.151 –허브– eth0 :211.47.64.145
[ Master LVS ] eth1 :192.198.0.1 -closscable- eth1 :192.168.0.2 [ Slave LVS ]
eth0:0 :211.47.64.153 lo:0 :211.47.64.153
필요한 팻키지 :
linux-2.4.13.tar.gz
ipvs-0.9.6.tar.gz
hidden-2.4.5-1.diff
Convert-BER-1.31.tar.gz
Period-1.20.tar.gz
Time-HiRes-01.20.tar.gz
Mon-0.11.tar.gz
fping-linux.tar.gz
mon-0.38.21.tar.gz
heartbeat-0.4.9-1.i386.rpm
rsync-2.4.6-2.i386.rpm
2. 시스템 초기 셋팅
2.1 커널 패치
먼저 커널에 ipvs 패치와 arp 캐싱 문제를 해결하는 패치를 해 주어야 한다.
참고로 ipvs 패치는 http://linuxvirtualserver.org/software/index.html
에 있다. 이곳에서ipvs-0.9.6.tar.gz 를 다운 받는다. 커널은 2.4.13 으로
설치 한다.
ipvs 패치는 로드밸랜싱 서버에만 해주면 되지만 arp 패치는 로드,리얼서버
모두 해준다. 여기서는 시스템 초기 셋팅은 동일하게 해야 한다. 두대가 모
두 lvs, real_server 역활을 해야 하기 때문이다.
IPVS module 의 설치 방법에는 두가지가 있다. 우선 하나는 모듈로 올리는
방법과 커널에 추가 하는 방법이다.
모듈에 올리는 방법 :
// <path-name> 은 ipvs patch directory
cd <path-name>/ipvs
make
make -C ipvsadm
make install
insmod ip_vs_wlc.o
커널에 적재하는 방법 :
/usr/src 디렉토리에 아무 패치가 되지 않은 커널 linux-2.4.13.tar.gz
의 압축을 푼다.
# tar xzvf linux-2.4.13.tar.gz
# tar xzvf ipvs-0.9.6.tar.gz
# cd linux
// ipvs 패치
# cat ../ipvs-0.9.6/linux_kernel_ksyms_c.diff | patch -p1
# cat ../ipvs-0.9.6/linux_net_Makefile.diff | patch -p1
# cat ../ipvs-0.9.6/linux_net_ipv4_Config_in.diff | patch -p1
# cat ../ipvs-0.9.6/linux_ip_fw_compat_c.diff | patch -p1
# cp -rp ../ipvs-0.9.6/ipvs/ net/ipv4
# mv net/ipv4/ipvs/linux_net_ipv4_ipvs_Makefile net/ipv4/ipvs/Makefile
// arp 패치
# cat ../hidden-2.4.5-1.diff | patch -p1
2.2 커널 컴파일
# make menuconfig
Code maturity level options —>
[*] Prompt for development and/or incomplete code/drivers
Networking options —>
//* Networking options 에서 제대로 ipvs 패치가 이루어 졌으면
IP: Netfilter Configuration —>
IP: Virtual Server Configuration —>
이 두가지 항목이 모두 있게 된다. 만일 이 두가지가 없다면 커널패치가
정상적으로 이루어 지지 않은 것이다.
<*> Packet socket
[*] Packet socket: mmapped IO
[*] Kernel/User netlink socket
[*] Routing messages
<*> Netlink device emulation
[*] Network packet filtering (replaces ipchains)
[*] Network packet filtering debugging
[ ] Socket Filtering
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: multicasting
[*] IP: advanced router
[*]IP: policy routing
[*] IP: use netfilter MARK value as routing key
[ ] IP: fast network address translation
[ ]IP: equal cost multipath
[ ]IP: use TOS value as routing key
[ ]IP: verbose route monitoring
[ ]IP: large routing tables
[ ] IP: kernel level autoconfiguration
<*> IP: tunneling
< > IP: GRE tunnels over IP
[*] IP: multicast routing
[ ]IP: PIM-SM version 1 support
[ ]IP: PIM-SM version 2 support
[ ] IP: ARP daemon support (EXPERIMENTAL)
[ ] IP: TCP Explicit Congestion Notification support
[*] IP: TCP syncookie support (disabled per default)
IP: Netfilter Configuration —>
IP: Virtual Server Configuration —>
< > The IPv6 protocol (EXPERIMENTAL)
< > Kernel httpd acceleration (EXPERIMENTAL)
[ ] Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)
—
< > The IPX protocol
< > Appletalk protocol support
———————————————————
IP: Netfilter Configuration —>
<*> Connection tracking (required for masq/NAT)
<*> FTP protocol support
< > Userspace queueing via NETLINK (EXPERIMENTAL)
<*> IP tables support (required for filtering/masq/NAT)
<*> limit match support
<*> MAC address match support
<*> netfilter MARK match support
<*> Multiple port match support
<*> TOS match support
<*> Connection state match support
<*> Unclean match support (EXPERIMENTAL)
<*> Owner match support (EXPERIMENTAL)
<*> Packet filtering
<*> REJECT target support
< > MIRROR target support (EXPERIMENTAL)
<*> Full NAT
<*> MASQUERADE target support
<*> REDIRECT target support
<*> Packet mangling
<*> TOS target support
<*> MARK target support
< > LOG target support
——————————————————-
IP: Virtual Server Configuration —>
<*> virtual server support (EXPERIMENTAL)
[*] IP virtual server debugging
(12) IPVS connection table size (the Nth power of 2)
— IPVS scheduler
<*> round-robin scheduling
<*> weighted round-robin scheduling
<*> least-connection scheduling scheduling
<*> weighted least-connection scheduling
<*> locality-based least-connection scheduling
<*> locality-based least-connection with replication scheduling
— IPVS application helper
< > FTP protocol helper
——————————————————
이와 같이 설정하고 커널 컴파일을 한다.
# make dep
# make clean
# make bzImage
# make modules
# make modules_install
커널 컴파일이 끝나면…새로운 커널이미지를 lilo 에 적용시키고
새로운 커널로 재부팅을 한다.
2.3 네크워크 셋팅
[[[[[[[ Master LVS && Real Server1 ]]]]]]]
# ifconfig eth0 211.47.64.151 netmask 255.255.255.0 up
# route add -host 211.47.64.151 dev eth0
# ifconfig eth1 192.168.0.1 netmask 255.255.255.0 up
# route add -host 192.168.0.1 dev eth1
# ifconfig eth0:0 211.47.64.153 netmask 255.255.255.255 broadcast 211.47.64.153
up
# route add -host 211.47.64.153 dev eth0:0
// arp 캐쉬 제거를 위해서 …
인터넷은 tcp/ip 기반으로 되어 있지만 한번 접속된 서버의 ip 주소에 대한
arp 태쉬라는것이 얼마간 남게 된다. 그래서 그 캐시가 지워지기 전에는 처
음 접속후 arp 캐시를 따라서 접속하게 된다. 때문에 위와 같이 arp 캐시를
숨김으로해서 클라이언트에 arp 캐시가 저장이 된지 않고 매번 서버를 찾도
록 하는 것이다.
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/conf/all/hidden
echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
[[[[[[[ Slave LVS && Real Server2 ]]]]]]]]
# ifconfig eth0 211.47.64.145 netmask 255.255.255.0 up
# route add -host 211.47.64.145 dev eth0
# ifconfig eth1 192.168.0.2 netmask 255.255.255.0 up
# route add -host 192.168.0.2 dev eth1
# ifconfig lo:0 211.47.64.153 netmask 255.255.255.255 broadcast 211.47.64.153 up
# route add -host 211.47.64.153 dev lo:0
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/conf/all/hidden
echo 1 > /proc/sys/net/ipv4/conf/lo/hidden
이와 같이 설정이 모두 무사히 마쳤으면 각 서버 별로 확인을 해본다.
# ifcofig
# route
각 서버의 eth1 의 설정을 유지 하기 위해서는 /etc/rc.d/rc.local 파일에 각각
설정 내용을 추가 하도록 한다.
3. 로드밸런싱 설정
이제 ipvsadm 을 이용하여 클러스터를 시켜 보자
물런 이설정은 로드밸랜싱 서버인 master_server 에만 행한다.
설정에 앞서 ipvsadm 명령어에 사용되는 옵션에 대해 알아보자.
-A : 서비스를 추가 한다.
-s : 스케줄러 선택 ( wlc : weight least connection scheduling )
-a : add server ( -e : EDIT , -d : Delete )
-t : TCP service 추가 ( -u : UDP , -f : Firewall )
-r : 옵션 다음에 Real Server ip address 를 적는다.
-i : 패킷전달 방식 (ip tunneling 방식) , -g : Direct Routing 방식
-w : wlc 방식에서 가중치
[[[[[[[ Master LVS ]]]]]]]
# ipvsadm -A -t 211.47.64.153:80 -s wlc
# ipvsadm -a -t 211.47.64.153:80 -r 192.168.0.1 -g -w 1
# ipvsadm -a -t 211.47.64.153:80 -r 192.168.0.2 -g -w 2
여기서 -w 뒤의 숫자는 요청분배 가중치를 둔것이다. -w 1 은 한번의 요청,
-w 2 는 두번의 요청을 의미하는것으로 위의 설정되로 라면…
1st connection -> 192.168.0.1
2st connection -> 192.168.0.2
3st connection -> 192.168.0.2
4st connection -> 192.168.0.1
5st connection -> 192.168.0.2
6st connection -> 192.168.0.2
7st connection -> 192.168.0.1
이와 같은 순서로 요청이 분배되게 된다.
리얼서버를 몇개를 늘리더라도 master_server 에 ipvsadm 명령어를 통해
리얼서버설정만 추가해 주면된다.
# ipvsadm -a -t 211.47.64.153:80 -r 192.168.0.3 -g -w 2
# ipvsadm -a -t 211.47.64.153:80 -r 192.168.0.4 -g -w 2
# ipvsadm -a -t 211.47.64.153:80 -r 192.168.0.5 -g -w 2
.
.
.
이로써 기본적인 로드 밸런싱(작업분배)은 이루어 진다.
하지만 real_server(앞으로 real 이라하겠다.)중 하나가 죽었도 master_lvs
에서는 스케줄 규칙에 따라 패킷을 죽은 real 에도 정해진 규칙대로 분배하게
된다. 그렇기 때문에 패킷이 죽은 real 로 보내질때는 접속이 되지 않는다.
이를 방지하기 위해서 mon 이란 프로그램을 설치한다. mon 은 정해진 시간마
다 각 real 서버들을 감시 하면서 죽은 real 서버가 발견대면 ipvsadm 에서
죽은 real 서버로 분배대는 작업 규칙을 제거 하여 더이상 작업을 분배하지
않도록 한다. 그리고 죽었던 real 서버가 살아나면 이또한 감지하고 다시 정
해진 작업분배를 계속 하게 된다. 이제 mon 설치 방법에 대하여 알아보도록
하자.
4. mon 으로 고가용성 클러스터링 구축하기
mon 프로그램은 http://www.kernel.org/software/mon/ 에서 다운 받으면 된다.
mon-0.38.21.tar.gz
mon 을 설치하기 위해서는 몇가지 perl 모듈이 필요한데…다음과 같다.
-Time::Period
-Time::HiRes
-Convert::BER
-Mon::*
이는 ftp://ftp.bora.net/pub/CPAN 디렉토리및에서 다운 받을수 있다.
Perl 모듈을 설치 전에 C 헤더 파일에 대응하는 perl 헤더 파일을 만들어야 한다.
# cd /usr/include
# h2ph *.h sys/*.h asm/*.h
xxx.h -> xxx.ph 등의 메세지와 함께 변환이 되어진다.
perl 모듈은 다음과 같은 방법으로 설치 할수 있다.
# tar xzvf Time-Hires-01.20.tar.gz
# cd Time-Hires-01-20
# perl Makefile.PL
# make
# make test
# make install
fping 프로그램 정도는 기본으로 깔아 두세요…
mon 소스를 /usr/local 에 압축을 풀어 모든 파일들을 /usr/local/mon 에 둔다.
# mv /usr/local/mon-0.38 /usr/local/mon
# cd /usr/local/mon
# mkdir /etc/mon
# cp etc/example.cf /etc/mon/mon.cf
# cp etc/auth.cf /etc/mon/auth.cf
이와 같이 옮겼으면 /etc/service 파일을 열어서 mon 이 사용할 포트를 지정해
준다. (제일 끝에다가…)
mon 2583/tcp # MON
mon 2583/udp # MON traps
이제 /etc/mon/mon.cf 를 열어서 간단한 mon 설정 파일을 만들고 테스트 해보자.
# vi /etc/mon/mon.cf
——————————————————————-
cfbasedir = /etc/mon
alertdir = /usr/local/mon/alert.d
mondir = /usr/local/mon/mon.d
maxprocs = 20
histlength = 100
randstart = 30s
authtype = getpwnam
hostgroup node_2 192.168.0.2
watch node_2
service ping
description ping to node_2 group
interval 10s
monitor fping.monitor
period wd {Mon-Fri} hr {7am-10pm}
alert mail.alert alang at sysmng.com
alert page.alert alang at sysmng.com
alert echo.alert “real02 server is down!!”
upalert echo.alert “real02 server is live!!”
——————————————————————–
echo.alert 란 파일은 없으므로 만들어 준다.
# vi /usr/local/mon/alert.d/echo.alert
——————————————————————–
#!/bin/sh
echo “`date`$*” >> /var/log/echo.alert.log;
——————————————————————–
파일 퍼미션은 755 로 둔다.
mon 을 실행 시켜 보자..
/usr/local/mon -f -c /etc/mon/mon.cf
이제 real02 서버의 LAN 선을 뽑아 보자..
/var/log/echo.alert.log 에 real02 server is down 이란 로그가 쌓이게 된다.
이와 같이 되었다면..성공이다..
지금까지는 테스트 였다.. 이제 실질적으로 mon.cf 파일을 설정하여 보자.
# vi /etc/mon/mon.cf
——————————————————————–
cfbasedir = /etc/mon
alertdir = /usr/local/mon/alert.d
mondir = /usr/local/mon/mon.d
maxprocs = 20
histlength = 100
randstart = 30s
authtype = getpwnam
hostgroup node_1 192.168.0.1
hostgroup node_2 192.168.0.2
watch node_1
service http
interval 5s
monitor http.monitor
period wd {Sun-Sat}
alert lvs.alert -P tcp -V 211.47.64.153:80 -R 192.168.0.1 -W 1 -F dr -X down
upalert lvs.alert -P tcp -V 211.47.64.153:80 -R 192.168.0.1 -W 1 -F dr
watch node_2
service http
interval 5s
monitor http.monitor
period wd {Sun-Sat}
alert lvs.alert -P tcp -V 211.47.64.153:80 -R 192.168.0.2 -W 1 -F dr -X down
upalert lvs.alert -P tcp -V 211.47.64.153:80 -R 192.168.0.2 -W 1 -F dr
———————————————————————-
테스트에서 처럼 단순히 ping 으로 real 서버들을 감시하는것이 아니라 http 접속
을 계속 확인하여 httpd 가 정상 작동을 하지 않을때 별도 처리를 해주도록 하였다.
서버가 살아 있다고 하더라도..httpd 데몬이 죽으면 웹서비스는 할수 없기 때문이
다.. 이제는 ..
mon 에서 사용하는 ipvsadm 을 마음대로 제어할수 있는 스크립터를 만들어 보자.
이 mon 에서 계속 감시 하여 real 서버가 죽을때 자동으로 죽은 real 서버로는
작업을 못보내게 하는 스크립터가 되겠다.
# vi /usr/local/mon/alert.d/lvs.alert
———————————————————————
#!/usr/bin/perl
#
# lvs.alert – Linux Virtual Server alert for mon
#
# It can be activated by mon to remove a real server when the
# service is down, or add the server when the service is up.
#
#
use Getopt::Std;
getopts (“s:g:h:t:l:P:V:R:W:F:X:u”);
$ipvsadm = “/sbin/ipvsadm”;
$protocol = $opt_P;
$virtual_service = $opt_V;
$remote = $opt_R;
$status = $opt_X;
if ($status eq “down”){
# <“udp 를 사용 하시려면 이 부분에 프로토콜 체크를 한번 더 하셔야
합니다.”>
system(“$ipvsadm -d -t $virtual_service -r $remote”);
exit 0;
}
else {
$weight = $opt_W;
if ($opt_F eq “nat”) {
$forwarding = “-m”;
}
elsif ($opt_F eq “tun”) {
$forwarding = “-i”;
}
else {
$forwarding = “-g”;
}
if ($protocol eq “tcp”) {
system(“$ipvsadm -a -t $virtual_service -r $remote -w $weight
$forwarding”);
exit 0;
}
else {
system(“$ipvsadm -a -u $virtual_service -r $remote -w $weight
$forwarding”);
exit 0;
}
exit 0;
};
———————————————————————
——
퍼미션을 755 로 준다.
이제 지금까지 만들어 수동으로 하나하나 작업한 환경을 한번에 제어할수 있는
init 스크립트를 만들어 보자
# vi /etc/rc.d/init.d/puck
——————————————————————–
—–
#!/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
#
# ipvs system 설정 부분
#
echo 1 > /proc/sys/net/ipv4/ip_forward
ifconfig eth0:1 211.47.64.153 netmask 255.255.255.255 broadcast 211.47.64.153 up
route add -host 211.47.64.153 dev eth0:1
echo 1 > /proc/sys/net/ipv4/conf/all/hidden
echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
$IPVSADM -A -t 211.47.64.153:80 -s wlc
$IPVSADM -a -t 211.47.64.153:80 -R 192.168.0.1 -g -w 1
$IPVSADM -a -t 211.47.64.153:80 -R 192.168.0.2 -g -w 2
#
# 추가되는 real_server 는 아래에 같은형식으로 추가하면 된다.
# $IPVSADM -a -t 211.47.64.153:80 -R 192.168.0.3 -g -w 2
# $IPVSADM -a -t 211.47.64.153:80 -R 192.168.0.4 -g -w 2
#
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 “puck daemon stopping…”
$IPVSADM -C
ifconfig eth0:0 down
killproc mon
rm -f /var/lock/subsys/punk
killall http.monitor
echo -n “puck daemon killed”
echo
fi
;;
*)
echo “Usage : puck {start|stop}”
exit 1
esac
exit 0
———————————————————————-
이로써 모든 설정이 완료 되었다.
위의 mon 설정에 관련된 사항은 Master_lvs 와 Slave_lvs 에 모든 설정을 일치 시
키면 된다.
이젠 실제 서비스 상황을 확인해 보도록 하자.
시스템에서 일어 나는 변화를 확실하게 하기 위해서 웹서버의 KeepAlive 를 off
시키고 MaxKeepAliveRequest 값을 1 로 변환한다.
인터넷 익스플로러의 도구 -> 인터넷 옵션 -> 임시 인터넷 파일 ->
페이지를 열때 마다 체크
설정을 하고 각 서버마다 각기 다른 초기 화면을 띄워 놓자..
이제 테스트를 한번 해보자 ..
로드 밸랜싱 서버에서
# /etc/rc.d/init.d/puck start
브라우져를 열어서 새로 고침을 할때 마다 인덱스 화면이 변화는가…변환다면..
성공이다..축하한다.
어느 하나의 리얼서버를 죽여 놓고…계속 새로고침을 해보자..죽은 real 서버
의 초기화면을 제외한 다른 서버들의 초기화면들만 스케줄에 따라서 나타나는
지를 확인하라… 죽은 서버를 다시 살리면…한동안은 새로 살아난 서버 화면
만 보일것이다. 이는 wlc 스케줄 방식을 이해하면 금방알수 있다. wlc 방식은
가중치도 줄수 있지만…그와 동시에 각 리얼서버별로 처리 요청 비중을 고려
하여 분배하게 되는 것이다. 즉 한 서버가 죽은 동안 다른 서버에서 요청을
많이 처리 했으므로다른 서버가 자신의 일을 처리해 준만큼 자기도 다른 서버의
일을 대신 처리해준다고 보면된다. 이와 같은 방식은 ipvsadm 으로 요청 처리
사항을 보면 알수 있다.
[root@www1 alert.d]# ipvsadm
IP Virtual Server version 0.2.7 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 211.47.64.153:http wlc
-> 192.168.0.2:http Route 1 5 0
-> 192.168.0.3:http Local 1 5 0
-> 192.168.0.4:http Local 1 5 0
-> 192.168.0.5:http Local 1 4 0
위와 같이 각 real 서버의 분배 가중치와 현재 작업한 처리 분배율이 나와있다.
이로써 mon 을 이용하여 고가용성 클러스터 시스템이 구축되었다. 이는 real 서버
간의 고가용성 클러스터링을 설치한것이고 진작 로드밸랜서인 Master_lvs 가 죽어
버리면 작업분배를 해줄수 없기 때문에 모든 real 서버가 다운된거와 같은 현상이
나타나게 된다. 이 문제를 보안한것이 heartheat 로 Master_lvs 와 Slave_lvs 간
의 고가용성을 지켜주는 것이다.
5. heartbeat 로 LVS 서버의 고가용성 클러스터 구축하기 (Linux High Availability)
mon 이 각 다수의 리얼 노드를 일방적으로 모니터링하는 방면 heartbeat 는 시리얼
라인이나 UDP 포트를 통해 두 노드간에 서버의 상황으로 서로 확인 하게 된다.
서로의 상태를 알려주다가 master 쪽의 서버에서 응답이 없으면 slave 쪽에서 master
에서 잡고 있던 VIP 를 slave 쪽에서 잡고 slave 가 LVS 역활을 대신하게 된는것이다.
이와 같이 VIP 를 이전되고 이를 바로 갱신하기 위해서는 Mac address 가 갱신되어
야 하는데 이를 fake 라는 프로그램이 arp spooping 이라는 기능으로 신속히 라우터
에게 새로운 IP 에대해 갱신토록 하는것이다.
heartbeat 를 설치해 보자. 일단 Master_lvs 와 Slave_lvs 에 모두 설치한다.
http://www.linux-ha.org/ 에서
heartbeat 최신버전을 다운 받는다.
가급적 rpm 을 받는것이 설치하기에 용이하다.
fake 는 arp 를 속여 IP 를 이전하는 소프트웨어 라고 하는데 차후 이에 대해 좀더
세부적으로 끌어 나가야 할 것 같습니다.
어쨌던 heartbeat 에는 fake 의 기능이 들어 있으므로(IPAT) heartbeat 만 설치하여도
작동이 가능합니다.
# rpm -Uvh heartbeat-0.4.9-2.i386.rpm
heartbeat 를 설치하면 /etc/ha.d 라는 디렉토리가 생성된다. 그리고..
/etc/rc.d/init.d/heartbeat 라는 init 파일도 생성이 된다.
실행을 하기 위해서는 몇가지 설정으로 해야 한다.
설정파일은 /etc/ha.d 에 있다.
# cd /etc/ha.d
heartbeat 설정은
ha.cf
haresources
authkeys
의 3가지 중요 설정파일로 이루어 진다.
rpm -q heartbeat -d 라고 하면 설정파일의 샘플파일이
/usr/share/doc/packages/heartbeat 란 디렉토리에 있다는 것을 알수 있다.
샘플 파일을 /etc/ha.d 로 복사한다.
# cp ha.cf /etc/ha.d
# cp haresources /etc/ha.d
# cp authkeys /etc/ha.d
복사가 완료되었으면 다시 /etc/ha.d 디렉토리돌아온다.
/etc/ha.d/ha.cf 설정 내용 ———————————————
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 5
hopfudge 1
udpport 1001
udp eth0
node www1.zzang911.net
node zzang911.net
——————————————————————–
**** Master_lvs 와 Slave_lvs 동일하게 설정
node 는 위에 있는것이 우선권이 주어지는 시스템이다.
우선권이 있는 시스템에 신호가 끊어지면 slave 시스템이 master 의 권한을
위임받게 된다. 그리고..우선권이 있는 시스템에 신호가 다시 돌아오면..slave
는 master 권한을 버리게 된다.
node 설정은 각 시스템의 hostname 으로 해주면 귀찮은 문제는 발생하지 않는다.
/etc/ha.d/authkeys 설정 내용 —————————————–
auth 1
#1 crc
1 sha1 HI!
# md5 Hello!
——————————————————————–
—
위 설정역시 Master_lvs,Slave_lvs 동일하게 하면 되고 중요한것은 이 파일의
퍼미션은 반드시 600 으로 두셔야 작동이 됩니다.
/etc/ha.d/haresource 설정 내용 —————————————
# 설정 형식에 맞게 설정해야 합니다. 설정형식은…
# masternode_name VIP DAEMON_name
www1.zzang911.net 211.47.64.153 puck
——————————————————————–
여기까지 Master_lvs 에 대한 설정은 모두 끝났다. Slave_lvs 설정은 여기까지
동일하게 한뒤 몇가지 추가 수정할거이 남아 있다. 이는 Slave_lvs 가 평소에는
real 서버로서 분배된 작업을 처리하도록 하기 위함이다.
Slave_lvs 가 Master_lvs 로 전환할때 VIP 를 활당 받고 있던 lo:0 이 없어지고
eth0:0 에 VIP 가 활당되어진다. 하지만 실제 Master_lvs 가 살아나서 본연의
real 서버로 돌아가기 위해서는 원래의 설정으로 돌아와야 한다. 그렇게 때문에
몇가지 편법을 사용토록 하겠다. 지금부터의 설정은 Slave_lvs 에만 적용되는
것이다.
먼저 lo:0 를 추가할때 쓰이는 스크립터를 만들도록 한다.
/etc/ha.d/ipvsadm.sct 설정 내용 —————————————
echo 1 > /proc/sys/net/ipv4/ip_forward
ifconfig lo:0 211.47.64.153 netmask 255.255.255.255 broadcast 211.47.64.153 up
route add -host 211.47.64.153 dev lo:0
echo 1 > /proc/sys/net/ipv4/conf/all/hidden
echo 1 > /proc/sys/net/ipv4/conf/lo/hidden
——————————————————————–
ipvsadm.sct 퍼미션을 755 로 둔다.
그런뒤 /etc/ha.d/resource.d/IPaddr 파일을두줄정도 수정한다.
/etc/ha.d/resource.d/IPaddr 수정 내용 ———————————
#!/bin/sh
#
# $Id: IPaddr,v 1.8 2001/02/05 21:43:38 alan Exp $
#
# This script manages IP alias IP addresses
#
# It can add an IP alias, or remove one.
#
# usage: $0 ip-address {start|stop|status}
#
# The “start” arg adds an IP alias.
#
# Surprisingly, the “stop” arg removes one. 🙂
#
#
LC_ALL=en; export LC_ALL # Make ifconfig work in France for David Jules 🙂
. /etc/ha.d/shellfuncs
IFCONFIG=/sbin/ifconfig
ROUTE=/sbin/route
SENDARP=$HA_BIN/send_arp
FINDIF=$HA_BIN/findif
USAGE=”usage: $0 ip-address {start|stop|status}”;
# [[[[[[ 아래 줄에 ifconfig lo:0 down 를 추가 한다. ]]]]]]
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() {
ipaddr=$1;
$IFCONFIG |
while read ifname linkstuff
.
.
.
주절저절~~~~ 거의 마지막 부분으로 …간다.
.
.
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
——————————————————————–
다음 수정 파일은 /etc/rc.d/init.d/puck 이다.
/etc/rc.d/init.d/puck 수정 내용 —————————————-
#!/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:0 211.47.64.153 netmask 255.255.255.255 broadcast 211.47.64.153 up
route add -host 211.47.64.153 dev eth0:0
echo 1 > /proc/sys/net/ipv4/conf/all/hidden
echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
$IPVSADM -A -t 211.47.64.153:80 -s wlc
$IPVSADM -a -t 211.47.64.153:80 -r 192.168.0.1 -g -w 1
$IPVSADM -a -t 211.47.64.153:80 -r 192.168.0.2 -g -w 2
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 “puck daemon stopping…”
$IPVSADM -C
# [[[[ ifdown eth0:0 down 을 아래와 같이 수정 ]]]]]
ifdown eth0
ifup eth0
# [[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]
killproc mon
rm -f /var/lock/subsys/punk
killall http.monitor
echo -n “puck daemon killed”
echo
fi
;;
*)
echo “Usage : puck {start|stop}”
exit 1
esac
exit 0
——————————————————————–
그담에 /etc/rc.d/init.d/heartbeat 파일에 한줄만 추가해 준다.
/etc/rc.d/init.d/heartbeat 수정 내용 ————————————
.
.
거의 마지막 부분으로 가면…
case “$1” in
start)
StartHA
RC=$?
echo
[ $RC -eq 0 ] && touch /var/lock/subsys/$SUBSYS
;;
stop)
StopHA
RC=$?
echo
[ $RC -eq 0 ] && rm -f /var/lock/subsys/$SUBSYS
# [[[[[[[[[[ 이 한줄 추가한다. ]]]]]]]]]]]]]]]]]]]]]]]
/etc/ha.d/ipvsadm.sct
# [[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
;;
status)
status heartbeat
RC=$?
;;
restart)
sleeptime=`ha_parameter deadtime`
StopHA
sleep $sleeptime
sleep 10 # allow resource takeover to complete (hopefully).
StartHA
;;
force-reload|reload)
ReloadHA
RC=$?
;;
*)
echo “Usage: ha {start|stop|status|restart|reload|force-reload}”
exit 1
esac
exit $RC
——————————————————————–
여기까지가 설정의 모든 것이다.
이제 Master_lvs 와 Slave_lvs 의 heartbeat 데몬을 가동시킨다.
# /etc/rc.d/init.d/heartbeat start
이제 High Availability 가 이루어 지는지 테스트를 해보자.
A. 정상적으로 작업분배가 이루어 지는지 테스트를 한다.
B. Master_lvs 의 Lan 선을 뽑아 버린다. 그럼..Slave_lvs 가 Master_lvs 의
권한을 무사히 위임 받는지를 확인한다.
C. 다시 Master_lvs 를 살려 보도록 하자. 그럼..Slave_lvs 가 Master_lvs의
역활을 다시 반납하고 다시 real 서버로 돌아가는지를 확인한다.
D. 다른 노드들도 각각 Lan선을 뽑고 난뒤에도 서비스에 지장이 없는지를 확
인 하도록 한다.
위의 4가지 테스트가 모두 성공적으로 완료 된다면 heartbeat 와 mon 을 이용한
고가용성 시스템 구축이 완성된것이다.
마지막으로 서버 환경에 맞추어서 heartbeat 와 mon 의 데몬 감시 주기 시간을
조절하면 된다.
6. 디스크 동기화
이제 클러스터에 관련된 설정은 끝났다..마지막으로 클러스터 노드들의 데이타
를 동기화 하는 방법에 대해 알아보도록 하자.
클러스터에서 디스크를 동기화하는 방법은 많이 소개가 되어져 있다.
예전에는 거의 NFS 를 이용해 왔었는데 보안과 시스템 로드에서 몇가지 문제점
이 있어서 현재는 많이 사용하진 않는다. 현재에 대두되는 걸로는 rsync,GFS,
pvfs,RAID 등이 있다. 여기서는 가장 간단하면서 경제적이고 부하도 크게 문제
되지 않는 rsync 에 대해서 알아보도록 하겠다.
6.1. rsync 란..?
rsync 는 NT 의 미러링과 같이 특정 하드디스크의 데이타를 그 속성을 유지한체
다른 디스크로 동일하게 복제해주는 역활을 하는 프로그램이다.
rsync 로 이용할수 있는것은 아주 다양한데..주로 클러스터 웹서버의 디스크 동
기화, 미러링 서버의 디스크 동기화, 백업서버의 데이터 백업 등이 있다.
rsync는 rcp와 비슷한 동작을 하는 프로그램으로 rcp보다 더 다양한 옵션이 있고,
더 효율적으로 데이터를 전송합니다. (출발지와 목적지 사이에다른 부분만을 전송)
파일크기의 변화나 시간의 변화등을 이용 동기화를합니다.
주요 특징은 다음과 같습니다.
ㅇ 링크, device, 소유자, 그릅, 허가권 복사 지원
ㅇ GNU tar와 비슷한 exclude, exclude-from 옵션 지원
ㅇ rsh 또는 ssh 등 사용가능
ㅇ root 권한이 필요없음
ㅇ anonymous 또는 인증 rsync 서버 지원(미러링에 유용함)
이제 설치로 넘어가 보도록 하자..
6.2. rsync 설치 방법
redhat 7.1 에는 rsync-2.46-2 버젼이 기본적으로 설치가 되어진다.
만약없다면 http://rsync.samba.org/ftp/rsync/ 에서 최신판을 받아 설치 하면
된다.
설치 방법 :
# rpm -Uvh rsync-2.4.6-2.i386.rpm 혹은 ..
# tar xzvf rsync-2.4.6.tar.gz
# ./configure
# make
# make install
이것으로 설치는 끝난다. configure 에 따른 옵션으로 사용자의 취향에 맞게
설치도 가능하다.
6.3. rsync 서버 설정 방법
rsync 가 사용하는 프로토콜로는 rsh 나 ssh를 사용하거나 특정 포트를 이용하
여 xinetd 데몬으로 제어도 가능하다. 보통 873 포트를 사용한다.
ssh 를 이용한 사용방법과 873 port 를 이용한 사용방법은 다소 차이가 있다.
873 port 사용방법
rsync 를 사용할 리눅스 버젼이 6.x 일경우에는 /etc/inetd.conf 에 다음줄을
추가한다.
rsync stream tcp nowait root /usr/bin/rsync rsyncd –daemon
만일 리눅스 버젼이 7.x 이면…
/etc/xinetd.d/rsync 파일을 만들어 준다.
——————————————————————–
service rsync
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = –daemon
log_on_failure += USERID
}
——————————————————————–
그리고 /etc/services 에 다음 내용이 있는지 확인하고 없으면 추가한다.
rsync 873/tcp # rsync
rsync 873/udp # rsync
그런후 inetd 혹은 xinetd 데몬을 restart 해준다.
이제 /etc/rsyncd.conf 설정 파일을 만들어 준다.
/etc/rsyncd.conf —————————————————–
[home]
path = /home
comment = home data
uid = root
gid = root
use chroot = yes
read only = yes
hosts allow = 210.220.69.2
max connections = 3
timeout 600
——————————————————————–
[home] : 서비스명
path : 전송될 data가 들어 있는 경로
uid : data 를 전송하는 사용자의 uid 기본값은 nobody
gid : data 를 전송하는 사용자의 gid 기본값은 nobody
use chroot : path를 root 디렉토리로 사용. 보안상 필요함.
read only : 읽기전용
(클라이언트에서 서버로 올리는 경우에는 read only= no 로 설정을 해야됩니다. )
hosts allow : 호스트별 접속허용. 기본값은 all host이므로 보안을 유지하
려면 반드시 설정함
max connections : 동시접속자수.
timeout : 클라이언트에서 접근시 타임아웃시간.
anonymous 로 운영하는 경우 설정을 해야 클라이언트가 죽었을 때 서버에서 접속을
해체할 수 있습니다.
이렇게해서 873포트를 쓰는 rsync서버의 설정은 끝났습니다.
6.4. rsync 클라이언트 사용방법
이제 rsync 클라이언트에서 data 를 동기화 하는 방법을 알아보자.
위의 설정이 되어져 있는 서버가 zzang911.net 라고 하자.
물런 rsync 클라이언트는 hosts allow 에서 허락된 ip 를 가져야 한다.
210.220.69.2 에서 zzang911.net 서버의 /home 밑에 있는 data 를 모두 복사해 올
려고 한다면..
# rsync -avz –delete zzang911.net::home /home
위와 같이 하면 된다.
-a 는 아카이브 모드, 심볼릭 링크, 속성, 퍼미션, 소유권등을 보존
-v 는 전송과정을 상세하게 보여준다.
-z 는 전송시 압축을 한다.
–delete 는 zzang911.net 의 /home 밑에 data 를 클라이언트의 /home 디렉토리로
가져오면서 zzang911.net 의 /home 에 없는 data 는 모두 삭제하는 옵션이다.
즉..두 호스트의 data 를 완전 동기화 하는 것이다.
이로써..port 를 이용한 rsync 동기화를 설명하였다. 이제 ssh 를 이용한 방법에
대하여 알아보자.
ssh 나 rsh 를 이용한 방법은 rsyncd 를 설치하고 xinetd 설정이나 rsyncd.conf
같은 설정은 하지 않아도 된다. 그냥..
# rsync -avz -e ssh zzang911.net:/home /home
rsh 를 사용하면.. -e rsh 하면 된다.
ssh 를 이용하면 패스워드를 입력해야 하는데 스크립터를 디스크 동기화를 자동화
할때는 다소 불편한 점이 있다. 이때는 –password-file 옵션을 사용하면 암호파일
의 위치를 지정해 줄수 있다.
이와 같이 rsync 클라이언트 사용법을 cron 등에 등록시켜 주기적으로 data 를 업
데이트 시킴으로써…두 호스트 간의 데이타 동기화를 할수 있다.
6.5. 실제 적용 예제
ssh 를 이용한 방법은즉흥적인 작업에 사용하면 좋고 port 를 이용한 방법은 스크
립터를 이용한 대용량 데이터 전송이나..백업등에 이용하면 좋다.
실제적인 사용 방안에 대해 알아보자. 여기선 port 를 이용한 방법을 사용하겠다.
일단 어떤 시스템을 rsync primary 서버로 이용할건지를 정해야 겠다.
여기서는 master_lvs 에 많은 로드를 주면 안되니깐..ftp 접속으로 데이타를 업로
드 할 서버는 slave_lvs 로 하도록 하겠다.
먼저 Slave_lvs 의 /etc/rsyncd.conf 설정 파일에 옮기고자 하는 데이타를
지정한다.
/etc/rsyncd.conf —————————————————–
[home]
path = /home/zzang/www
comment = home
uid = root
gid = root
use chroot = yes
read only = yes
hosts allow = 192.168.0.1
max connections = 3
timeout 600
[mysql]
path = /usr/local/mysql/var
comment = mysql
uid = root
gid = root
use chroot = yes
read only = yes
hosts allow = 192.168.0.1
max connections = 3
timeout 600
——————————————————————–
이정도 설정한후 192.168.0.1(Master_lvs) 호스트에서 스크립터파일을 하나
만든다.
/root/bin/rsync_sh ————————————————–
rsync -avz –delete 192.168.0.2::home /home/zzang/www
rsync -avz –delete 192.168.0.2::mysql /usr/local/mysql/var
——————————————————————–
이 스크립터 파일에 실행 권한을 주고 실행하면 된다.
그런뒤…cron 에 5분 간격으로 위의 스크립터가 실행되도록 한다.
# crontab -e
———————————————————————
*/5 * * * * /root/bin/rsync_sh
———————————————————————
# /etc/rc.d/init.d/crond restart
이걸로 slave_lvs 로 업로드 되는 데이터들은 5분 간격으로 master_lvs 와
동기화가 되어진다.
이걸로 다이렉트 방식의 리눅스 클러스터링 시스템 구축을 마치겠다.
이는 순수 Open packege 로 이루어진 HA-LVS 구축 방법이다. Redhat 에서는
이런 설계내용을 기반으로 쉽게 구성하고 관리할수 있는 piranha 라는 프로
그램을 지원하고 있다. HOWTO 문서는 다음 사이트에 가보면 알수 있다.
http://www.redhat.com/support/resources/howto/piranha/
그리고..요즘 많이 알려진 package 로는 ultramonkey 라는 cluster package
가 있다.
http://www.au.ultramonkey.org/
이밖에 한국의 클러스터 회사인 클루닉스의 encluster 역시 상용이지만…
클러스터의 대부되는 문제점을 많이 보안한 package 라 할수 있다.
http://clunix.co.kr
이걸로 다이렉트 방식의 리눅스 클러스터링 시스템 구축을 마치겠다.