GFS2 + GNBD + DRBD + HEARTBEAT 설치
GFS2 + GNBD + DRBD + HEARTBEAT 설치
아침에 일찍 출근하여 두시간씩 남는 시간을 이용하여 구성을 해보고 싶었던 것이 있었다.
클러스터링 파일 시스템을 사용해 보고 싶어서 일단 검색을 해보니 역시나 국내에는 자료가 맘에 드는게 없었다.
결국 구글의 힘을 빌려 검색을 하였으나 대부분의 자료가 redhat 에서 그냥 rpm으로 설치를 하라는 몇줄 안되는 간단한 설명만 있었다. debian 을 사용하고 있는 상황에서 redhat 으로 다시 설치하기도 귀찮고 남들이 쉽게 하는 방법으로 만들기 싫었다. 남들이 잘 하지 않는 방법으로 해보자고 결심을 하고 수 많은 try and error 를 경험하고 결국 만들어졌다.
생각보다 많은 시간을 쏟았다.
다른 사람들은 그 시간을 줄여서 다른 더 좋은 곳에 사용하길 바라면서 이 문서를 포스팅 한다.
GFS2 필요성
GFS2를 필요로 하는 곳은 대부분 클러스터링을 구성하였을 때 뒷 단에서 스토리지에 어떤 파일 시스템을 사용 할 찌의 선택에서 좋은 결과물을 가져다 준다. 물론 NFS 를 사용하면 되지 않겠느냐는 이야기를 할 수 있다. 하지만 GFS는 퍼포먼스에서 NFS 보다 좋은 결과를 얻을 수 있다. 보통 SAN 이나 NAS 등을 이용하여 파일시스템이 클러스터링 지원되는지 여부를 체크하지 않고 사용하는 경우를 가끔 볼 수 있는데 매우 위험하다. 클러스터링 환경에서 공유로 파일을 사용을 한다면 반드시 클러스터링이 지원되는 파일 시스템을 사용해야 한다.
클러스터링이 지원되는 파일 시스템의 예로는 GFS2, OCFS2, PVFS 등 이외에도 여러 가지가 있으나 최근 주목을 받고 있는 것은 위 파일 시스템들이다.
준비
구성하기 위해서는 기본적으로 서버가 3대가 필요하다.
이중 두대는 DRBD를 이용하여 데이터를 저장하고 있는 스토리지의 역활로 사용을 하게 되고 나머지 한 대는 여기에 access 하여 사용하는 client 로 사용을 할 계획이다. 서버 하드웨어 스펙은 용도에 맞게 적당히 마련하면 된다.
여기서는 테스트 장비이므로 Cel 급으로 준비를 하였다.
dongho7, dongho8
CPU : Celeron(R) 2.66GHz 256K Cache
RAM : 512M
HDD : SATA 80G
ETHERNET : RTL8139, RTL8169
dongho9
CPU : Pentium(R) III CPU family 1133MHz
RAM : 1G
OS 는 debian etch 버전으로 기본 설치를 한 다음에 진행을 하면 된다.
아래는 간략히 설치한 구성도 이다.
서버 두대는 랜 카드를 두장을 이용하여 하나는 DRBD 용도의 SYNC 를 위해서 사용을 한다.
다른 랜 카드는 외부와 통신을 하면서 Heartbeat 를 통해 VIP 가 관리가 된다.
마지막으로 Client 는 이 VIP 랑 통신을 하면서 Server 단이 하나 죽더라도 서비스를 지속적으로 할 수 있게 된다.
|
설치 파일 준비
설치는 debian etch에서 기본적으로 제공 되는 패키지는 apt-get 을 이용하여 설치를 하고 없거나 호환이 되지 않는 경우 Source 로 받아서 설치를 진행을 하도록 한다.
우선 패키지를 최신 버전으로 업데이트를 한다.
dongho9:~# apt-get update |
그리고 설치를 진행 하면서 필요한 의존성 파일들이 있다.
미리 설치를 한다.
dongho9:~# apt-get install binutils bzip2 cpp cpp-4.1 flex gcc gcc-4.1 libc6-dev libncurses5-dev libslang2-dev libssp0 libvolume-id-dev linux-kernel-headers make libxml2 libxml2-dev libreadline5-dev |
다음은 현재 설치되어 있는 패키지 리스트 이다.
debian 설치를 하다 보면 아무래도 현재 설치 되어 있는 패키지의 리스트가 이 테스트 환경과 다른 상황일 수 있다.
dongho9:~# dpkg -l |grep ^ii|awk ‘{print $2}’|xargs |
이제 본격적으로 필요한 Source 파일들을 받는다.
먼저 커널이다.
dongho9:~# cd /usr/src 100%[========================================>] 49,452,289 2.76M/s ETA |
그리고 openais 를 다운로드 받는다.
http://www.openais.org 에서 받을 수 있다.
dongho9:/usr/src# wget ftp://ftp%40openais.org:downloads@openais.org/downloads/openais– 0.80.3/openais-0.80.3.tar.gz [ <=> ] 478,936 249.55K/s |
cluster 프로그램은 redhat 사이트에서 받는다.
dongho9:/usr/src# wget ftp://sources.redhat.com/pub/cluster/releases/cluster-2.03.07.tar.gz 100%[========================================>] 1,751,728 420.93K/s ETA |
설치
커널 부터 설치 한다.
커널 컴파일시에 모듈 지원이 가능 하도록 컴파일을 하고 어차피 아래 gfs2 등의 관련 모듈은 Source 컴파일 하여 후에 다시 새로운 버전으로 모듈로 설치를 하게 될 것이다. 설치가 완료 되면 부트 로드에 적용을 하고
dongho9:/usr/src# tar jxvf linux-2.6.26.3.tar.bz2 Broadcast message from root@dongho9 (pts/0) (Sat Sep 20 The system is going down for reboot NOW! |
openais 를 설치한다.
설치시에 QUICKSTART 파일을 한번쯤 읽어 보면 도움이 된다.
Makefile 에서 DESTDIR=/usr/local 로 되어 있는 부분을 DESTDIR=/ 로 변경을 하고 진행을 하자.
그래야 후에 /usr/local/usr/sbin 이렇게 설치가 되는 것을 방지 할 수 있다.
그냥 두고 설치를 하면 후에 path 를 추가로 등록을 해야 하는 번거로움이 발생한다.
설치가 끝나고 인증키를 만들면 /etc/ais 디렉토리에 생성이 된다.
dongho9:/usr/src# tar zxvf openais-0.80.3.tar.gz |
마지막으로 cluster 를 설치를 진행 한다.
dongho9:/usr/src# tar zxvf cluster-2.03.07.tar.gz Checking tree: nothing to do Checking kernel: Building against OpenAIS Whitetank The following fence agents will be build on this system: NOTE: xvm will build only if –enable_xen has been specified Completed Makefile configuration |
설치를 마치면 다음과 같은 파일들이 설치 된 것을 확인 할 수 있다.
dongho9:~# ls -lt /usr/sbin |more |
여기 까지 설치를 세군데 서버 모두에서 동일하게 진행을 한다.
이제 DRBD 를 설치 한다.
DRBD 는 dongho7,dongho8 두 서버간에 연동을 할 것이므로 dongho7,8 두 서버에서만 설치를 진행 한다.
소스 파일을 다운로드 받아서 압축을 풀고 설치를 진행 하다 보면 에러를 만나게 된다.
dongho7:/usr/src# wget http://oss.linbit.com/drbd/8.2/drbd-8.2.6.tar.gz 100%[====================================>] 335,382 127.79K/s dongho7:/usr/src# tar zxvf drbd-8.2.6.tar.gz |
패치가 필요하다.
아래와 같이 patch 파일을 만들어 패치를 하고 진행을 하면 된다.
dongho7:/usr/src# cat patch-drbd_main if (minor_table) { if (!drbd_proc) { |
패치를 적용 시키고 다시 컴파일을 한다.
dongho7:/usr/src# cd drbd-8.2.6 dongho7:/usr/src/drbd-8.2.6# make clean all Module build was successful. dongho7:/usr/src/drbd-8.2.6# make install |
HeartBeat 를 설치한다.
HeartBeat 도 마찬가지로 dongho7,8 두 서버에서만 설치를 한다.
편하게 apt-get 을 이용하여 설치를 한다.
dongho7:~# apt-get install heartbeat-2 |
설정
우선 /etc/init.d/cman 스크립트가 redhat 용으로 만들어져 있어 이를 수정이 좀 필요하다. 그리고 데몬 시작시에 start-stop-daemon 를 사용하도록 되어 있지 않고 기존 redhat 의 /etc/init.d/functions 의 정의된 함수를 이용해서 사용을 하도록 되어 있어 redhat 의 /etc/init.d/functions 를 복사해서 사용하는게 편리하다. functions 에서는 한가지 initlog 프로그램은 logger 라는 프로그램으로 대체해서 사용하도록 수정을 해서 사용을 했다.
아래는 수정한 functions 파일이다.
dongho9:/etc/init.d# vi functions # Make sure umask is sane # First set up a default search path. # Get a sane screen width if [ -f /etc/sysconfig/i18n -a -z “${NOLOCALE:-}” ] ; then # Read in our configuration if [ “${BOOTUP:-}” != “verbose” ]; then # Check if $pid (could be plural) are running
# Save basename. # See if it’s already running. Look *only* at the pid file. [ -n “${pid:-}” -a -z “${force:-}” ] && return # make sure it doesn’t core dump anywhere; while this could mask # Echo daemon # And start it up. # A function to stop a program. notset=0 # Save basename. # Find pid. # Kill it. # Remove pid file if any. # A function to find the pid of a program. Looks *only* at the pidfile # Test syntax. # First try “/var/run/*.pid” files # A function to find the pid of a program. # Test syntax. # First try “/var/run/*.pid” files # Next try “pidof” status() { # Test syntax. # First try “pidof” # Next try “/var/run/*.pid” files echo_success() { echo_failure() { echo_passed() { echo_warning() { # Log that something succeeded # Log that something failed # Log that something passed, but may have had errors. Useful for fsck # Log a warning # Run some action. Log its output. # returns OK if $1 contains $2 # Confirm whether we really want to run this service while : ; do |
그리고 /etc/init.d/cman 스크립트의 경우 경로가 debian 의 패키지 설치된 것과 다른게 있으며 cluster 소스 컴파일 하여 설치된 것은 /usr/sbin/ 아래에 명령이 설치가 되어 있어 이 부분을 수정이 필요하다. 아래 수정된 버전이다.
dongho9:/etc/init.d# cat cman . /etc/init.d/functions [ -f /etc/sysconfig/cman ] && . /etc/sysconfig/cman # CMAN_CLUSTER_TIMEOUT — amount of time to wait for joinging a cluster # CMAN_QUORUM_TIMEOUT — amount of time to wait for a quorate cluster on # CMAN_SHUTDOWN_TIMEOUT — amount of time to wait for cman to become a # FENCED_START_TIMEOUT — amount of time to wait for starting fenced # NET_RMEM_DEFAULT — minimum value for rmem_default. If this is set # NET_RMEM_MAX — minimum value for rmem_max. If this is set # FENCE_JOIN — boolean value used to control whether or not this node [ -z “$LOCK_FILE” ] && LOCK_FILE=”/var/lock/cman” [ -n “$CLUSTERNAME” ] && cman_join_opts=”-c $CLUSTERNAME” [ -n “$NODENAME” ] && cman_join_opts+=” -n $NODENAME” load_modules() start_configfs() start_ccsd() start_cman() if [ $CMAN_QUORUM_TIMEOUT -gt 0 ]
current_runlevel=$(/sbin/runlevel 2>/dev/null | awk ‘{ print $2 }’ 2>/dev/null) echo -n ” Starting qdiskd… “
start_fence() start_fence_xvmd() xend_bridged_net_enabled() { current_runlevel=$(/sbin/runlevel 2>/dev/null | awk ‘{ print $2 }’ 2>/dev/null) /sbin/chkconfig –levels “$current_runlevel” xend 2>/dev/null if [ ! -f /etc/xen/xend-config.sxp ]; then egrep “^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(‘)?[[:blank:]]*network-bridge([[:blank:]]*\)|[[:blank:]]+)” /etc/xen/xend-config.sxp >&/dev/null xend_bridged_net_start() { /sbin/modprobe netbk >& /dev/null fence_xvmd_enabled() # # return 0 #<<<<<<< HEAD:cman/init.d/cman.in value=”$(cat /proc/sys/net/core/rmem_default)” value=”$(cat /proc/sys/net/core/rmem_max)” fence_join_enabled() start() xend_bridged_net_enabled echo -n ” Loading modules… “ echo -n ” Mounting configfs… “ echo -n ” Setting network parameters… “ echo -n ” Starting ccsd… “ echo -n ” Starting cman… “ start_qdiskd echo -n ” Starting daemons… “ if fence_join_enabled; then if fence_xvmd_enabled; then return 0 stop_configfs() stop_ccsd() pid=$(cat /var/run/cluster/ccsd.pid) sleep 1 stop_cman() stop_daemons() stop_fence() stop_fence_xvmd() [ -z “`pidof fence_xvmd`” ] stop() if fence_xvmd_enabled; then if fence_join_enabled; then echo -n ” Stopping cman… “ # stop_daemons echo -n ” Stopping ccsd… “ echo -n ” Unmounting configfs… “ return 0 cmanstatus() fence_xvmd_enabled || return 0 return 0 rtrn=1 # See how we were called. restart|reload) status) *) exit $rtrn |
openais 의 설정 파일도 수정을 한다.
bindnetaddr: 192.168.2.0 를 자신의 아이피 대역 network address로 적는다.
dongho9:/etc/ais# vi openais.conf totem { logging { amf { |
/etc/hosts 에 서버들을 등록을 한다.
dongho9:/etc# vi /etc/hosts |
여기까지는 세군데 서버에서 동일하게 모두 설정을 한다.
그리고 아래 cluster.conf 는 한 서버에서만 설정을 하고 나머지 서버들은 빈 디렉토리만 만들어 놓으면 된다.
dongho9:~# mkdir /etc/cluster <fence_daemon post_join_delay=”60″> <clusternodes> </clusternodes> |
우선 여까지 잘 돌아 가는지 체크를 하고 DRBD 와 Heartbeat 를 연동해 본다.
먼저 cman 스크립트를 이용하여 데몬이 잘 뜨는지 모든 노드에서 데몬을 시작해 본다.
그리고 정상적으로 잘 join 되어서 도는지 등을 체크해 본다.
dongho9:~# /etc/init.d/cman start dongho9:~# cman_tool nodes dongho9:~# cman_tool services dongho9:~# cman_tool status dongho9:~# clustat Member Name ID Status |
기본적으로 잘 돌아가는 것을 확인하였으니 일단 데몬을 내리고 후속 작업에 들어 간다.
dongho9:~# /etc/init.d/cman stop |
DRBD 설정을 한다.
먼저 비어 있는 파티션 혹은 깨도 되는 파티션을 정해서 다음의 conf 파일을 만든다.
dongho7:~# cat /etc/drbd.conf } on dongho7 { |
이제 meta data 를 만든다.
dongho7:~# drbdadm create-md cluster2 Found some data Do you want to proceed? v07 Magic number not found –== Creating metadata ==– The counter works anonymously. It creates a random number to identify * If you wish to opt out entirely, simply enter ‘no’. Success |
DRBD 데몬을 두 서버 모두 start 시킨다.
dongho7:~# /etc/init.d/drbd start dongho7:~# cat /proc/drbd |
이제 초기 원본 서버를 정해서 데이터를 동기화를 해야 한다.
이때 만약 데이터가 들어 있는 상태라면 동기화 방향에 주의해야 한다.
가급적 백업을 받아 놓고 진행을 하도록 한다.
아래 명령은 원본 서버에서만 한번 실행을 하면 된다.
dongho7:~# drbdadm — –overwrite-data-of-peer primary cluster2 |
동기화가 완료 되면 상태가 UpToDate 상태로 양쪽 서버 모두 표시가 된다.
dongho7:~# cat /proc/drbd |
drbd.conf 에서 옵션을 allow-two-primaries; 주었었다.
GFS2 로 사용시에는 allow-two-primaries; 옵션이 있을 때 primary/primary 로 사용이 가능 하다.
두 노드를 모두 primary 로 만들어 보자.
dongho8 서버에서 primary 로 추가 선언을 하면 된다.
하지만 Heartbeat 와 연동하여 primary/secondary 형태로 사용을 할 계획 이므로 꼭 primary/primary 로 사용할 필요는 없다.
단지 GFS2 에서 지원이 가능 하다는 것을 보여준 것이다.
dongho8:~# drbdadm primary cluster2 |
파일 시스템을 만들어 보자.
만들때 사용하는 옵션은 다음과 같다.
mkfs -t gfs2 -p lock_dlm -t <clustername>:<fsname> -j <#journals> <blockdev>
clustername 은 cluster.conf 에서 주었던 이름을 동일하게 사용을 하면 된다.
fsname 은 중복 되지 않게 마음데로 만들면 된다.
journals 는 노드수 혹은 그 이상으로 만들면 된다.
아래 작업은 primary 서버에서만 한번 작업을 하면 된다.
dongho7:~# gfs2_mkfs -p lock_dlm -t donghocluster:donghodrbd -j 3 /dev/drbd1 Are you sure you want to proceed? [y/n] y Device: /dev/drbd1 |
이제 HeartBeat를 통해서 resource 를 제어하도록 설정을 해보자.
HeartBeat 를 통해 기본적으로 DRBD를 제어 하면서 gnbdserv 를 띄워서 gnbd_export 를 할 예정이다.
양쪽 서버에서 authkeys, ha.cf, resources 파일을 만든다.
주의 할점은 node 이름에는 uname -n 값의 이름을 적는다. 그리고 node 순서는 자신의 서버 부터 적는다.
dongho7:/etc/ha.d# cat authkeys dongho7:/etc/ha.d# cat ha.cf keepalive 1 node dongho7 dongho7:/etc/ha.d# cat haresources |
그리고 다음과 같이 gnbdserv 스크립트를 양족 서버에서 모두 만든다.
gnbdserv 를 heartbeat 에서 제어를 해서 사용을 할 수 있도록 /etc/ha.d/resource.d/gnbdserv 파일을 만든다.
dongho7:/etc/ha.d/resource.d# cat gnbdserv CMD=$1 case “$CMD” in exit 0
|
이제 양쪽 서버에서 heartbeat 데몬을 시작해 보자.
그리고 gnbd_export 가 정상적으로 잘 되었는지 살펴 보자.
dongho7:~# /etc/init.d/heartbeat start dongho7:~# gnbd_export -v -l |
이제는 정상적으로 failover 가 되어서 넘어가는지 살펴 보자.
dongho7번 에서 heartbeat 데몬을 restart 를 했을때 vip 와 resource 가 넘어가는지 살펴 보자.
아래처럼 아이피 및 gnbd_export 가 dongho8번으로 넘어가서 잘 작동 되는 것을 확인 할 수 있다.
dongho7:~# /etc/init.d/heartbeat restart Waiting to allow resource takeover to complete: Starting High-Availability services: dongho8:~# ip addr show dongho8:~# gnbd_export -v -l |
마지막으로 dongho9 번 에서 gnbd_import 를 해서 사용을 해보자.
dongho9:~# modprobe gnbd dongho9:~# mount dongho9:~# gfs2_tool journals /mnt/gfs dongho9:~# gfs2_tool df /mnt/gfs Type Total Used Free use% |
gnbd_import 로 gfs2 파일시스템을 마운트 한 곳에서 아래 처럼 파일을 1000개 정도 만드는 동안 failover 를 시켜보도록 한다.
정상적으로 문제 없이 파일이 만들어 지는지 살펴 본다.
정상적으로 1000개 모두 파일이 만들어 진 것을 테스트 해 보았다.
dongho9:/mnt/gfs/test# ls dongho9:/mnt/gfs/test# ls -1 |wc -l |
하지만 실질적으로는 세션은 끊어졌다가 붙게 된다.
다음의 커널 로그를 살펴 볼 수 있다.
dongho9:/mnt/gfs/test# dmesg |tail -5 |
이로서 이중화된 GFS2 gnbd server 를 기반으로 gnbd client 에서 동일한 내용이 담긴 파일 시스템을 동시에 여러 노드에서 마운트하여 서비스가 가능한 구조가 된다. 보통은 heartbeat 에서 haresources 를 설정을 할때 관련된 서비스를 전체적으로 heartbeat 에서 관리를 하도록 만들지만 failover 시에 빠르게 넘기기 위해서 gnbd_export 하는 부분만 사용을 하였다. 바람직한 방법은 아니나 테스트 목적에서는 빨리 결과를 볼 수 있어서 그렇게 만들었다.