[클러스터][파일] GFS 로 구현하는 클러스터 파일 시스템 환경 구축 하기 – 아랑

#### GFS 로 구현하는 클러스터 파일 시스템 환경 구축 하기 ####

작성일 : 2005 년 11월 3일

작성자 : 서 진우/ 시스존 ( alang@syszone.co.kr )

1. GFS 란 ..

GFS 는 sistina 의 gfs project 에서 개발하여 진행하다 근래에 들어 Redhat 에 그 권한을

인수하여 진행되고 있는 클러스터 파일 시스템의 하나이다.

클러스터 파일 시스템은 분산된 클러스터 노드 환경에서 동일한 파일 시스템 이미지를 제공

하는 기능으로 구성과 동작 방식에 따라 GFS, DRBD, PVFS, Luster, InterMezzo, AFS 등

다양한 파일 시스템이 존재한다.

GFS 는 단일 불륨에 대한 접근을 분산 노드에서 Loacl Device 와 같은  block 방식으로 접근

이 가능하게 해 주는 파일 시스템 이다. 이는 Local 하드에 다중 프로세스가 동일 파일 시스템

을 동시에 접근하는 구조와 유사하게 작동된다. 일반적인 구성에서는 분산 시스템에 SAN 이나

SCSI 인터페이스를 통한 DAS 의 경우 하나의 호스트에서 볼륨을 잡고 있으면 다른 호스트에서

의 접근을 차단 혹은 read 권한으로만 접근이 가능하게 한다. 이는 파일에 대한 Locking 문제

를 고려하여 원천적으로 차단하지만 GFS 의 경우는 분산된 시스템에 GFS 의 dlm 혹은 gulm_lock

을 이용하여 별도의 lock manage system 기능을 보유하고 있기 때문에 분산환경에서도 단일

볼륨에 대한 다중 접근이 가능하게 되는 것이다.

GFS 프로젝트가 Redhat 에 종속 되면서 다소 Redhat 의 RHCS 구성에 의존하는 바가 크지만..

여전히 GNU 정책에 의해 Source 는 공개되어 지고 있기에 굳에 Redhat 의 방식으로 진행할

필요는 없다.

여기에서는 최대한 Redhat 의 Cluster Suite 의 의존성과는 별도로 구성하는 법에 대해

알아 보고 다양한 구성에 대한 접근을 해 보고자 한다.

GFS 의 자세한 기술적 사항은 아래 사이트에서 참조가 가능하다.

http://gfs.wikidev.net/Installation

http://gfs.wikidev.net/GNBD_installation#Starting_the_services_.28DLM.2C_CCSD.2C_FENCE.29

http://www.redhat.com/docs/manuals/csgfs/

http://code.ximeta.com/cgi-bin/trac.cgi/wiki/HowToGFS

https://open.datacore.ch/DCwiki.open/Wiki.jsp?page=GFS

http://sources.redhat.com/cluster

2. GFS 설치 환경 준비

GFS 관련 Package 는 http://sources.redhat.com/cluster 에서 다운 받을 수 있으며, Redhat 의

RHCS 에 의해 RPM 으로 패키징 된 binary 를 이용해도 된다.

기본적으로 Redhat RPM 으로 설치 하는 방법에 대해 알아보도록 하자.

설치에 필요한 패키지는 다음과 같다.

* 먼저 Redhat 에서 제공하는 kernel 과 kernel Source ( ES4 부터는 kernel-devel 에 포함 )

를 설치 한다. GFS 는 kernel 과의 의존성이 강하기 때문에 RPM 이나 SRPM 으로 설치 시 해당

패키지에 맞는 kernel 이 설치 되어져 있어야 한다. 아래 제시하는 버전의 패키지는 모두

2.6.9-11.ELsmp 버전에 맞게 build 되어 있다.

* GFS 관련 기본 환경 구성 패키지

# rpm -Uvh magma-1.0.0-0.i686.rpm

# rpm -Uvh magma-devel-1.0.0-0.i686.rpm

# rpm -Uvh ccs-1.0.0-0.i686.rpm

# rpm -Uvh ccs-devel-1.0.0-0.i686.rpm

# rpm -Uvh gulm-1.0.0-0.i686.rpm

# rpm -Uvh gulm-devel-1.0.0-0.i686.rpm

# rpm -Uvh magma-plugins-1.0.0-0.i386.rpm

# rpm -Uvh cman-kernel-2.6.9-36.0.i686.rpm

# rpm -Uvh cman-1.0.0-0.i686.rpm

# rpm -Uvh dlm-kernel-2.6.9-34.0.i686.rpm

# rpm -Uvh dlm-1.0.0-0.i686.rpm

# rpm -Uvh dlm-devel-1.0.0-0.i686.rpm

# rpm -Uvh perl-Net-Telnet-3.03-3.noarch.rpm

# rpm -Uvh fence-1.32.1-0.i686.rpm

# rpm -Uvh gnbd-kernel-2.6.9-8.27.i686.rpm

# rpm -Uvh gnbd-1.0.0-0.i686.rpm

* GFS 관련 패키지

# rpm -Uvh GFS-kernel-2.6.9-35.5.i686.rpm

# rpm -Uvh GFS-6.1.0-0.i386.rpm

# rpm -Uvh device-mapper-1.01.01-1.RHEL4.i386.rpm

# rpm -Uvh lvm2-2.01.08-1.0.RHEL4.i386.rpm

# rpm -Uvh lvm2-cluster-2.01.09-5.0.RHEL4.i386.rpm

# rpm -Uvh iddev-2.0.0-0.i686.rpm

# rpm -Uvh iddev-devel-2.0.0-0.i686.rpm

* RHCS 관련 패키지 ( Redhat 의 의존성을 피하고 싶을 경우는 굳이 설치 할 필요는 없음 )

rgmanager-1.9.34-1.i386.rpm   ;; cluster resource 관련 프로그램

system-config-cluster-1.0.12-1.0.noarch.rpm ;; CCS 설정 프로그램

ipvsadm-1.24-6.i386.rpm  ;; LVS admin tool ;; 부하분산 핵심 제어 명령 프로그램

3. GFS 환경 구축

여기서는 가징 기본저인 형태의 GFS 클러스터 환경을 구축해 보도록 하자.

먼저 SAN 혹은 SCSI 형태의 Interface를 제공하는 Storage 에 클러스터 노드를 2대를 준비

하여 구축 하도록 한다.

       ———–                         ————

      |  Node 1   |                       |  Node 2    |

       ———–                         ————

            |                                    |

            |  SCSI/HBA                          |  SCSI/HBA

            |                                    |

             ————————————

                            |   |

                     ——————

                    |                  |

                    |      Storage     |

                    |                  |

                     ——————                

Node1 ip address : 192.168.123.116

Node2 ip address : 192.168.123.117

위와 같이 node1 과 node2 에서 SCSI 나 HBA Card 를 이용하여 DAS 형태로 하나의 Storage

의 단일 볼륨에 mount 하여 read/write 가 모두 가능하게 클러스터 파일 시스템 환경을

구성하고자 한다.

먼저 node1, node2 에 /etc/hosts 파일을 설정하도록 한다.

[node1]# vi /etc/hosts

———————————————————————————-

192.168.123.116                node01

192.168.123.117         node02

———————————————————————————-

[node2]# vi /etc/hosts

———————————————————————————-

192.168.123.116         node01

192.168.123.117         node02

———————————————————————————

그런 후 GFS node 간의 시간을 동기화 한다. 시간 동기화는 NTP 혹은 /etc/xinet.d/time

등을 이용해서 동기화 할 수 있다. 또한 rdate를 cron에 걸어 놓고 원자 시계를 기준으로

동기화 해도 된다. 몇 분 정도의 오차는 시스템에 큰 영향을 주지 못하지만 몇 시간의

오차가 날 경우 시스템의 성능과 안정성에 큰 무리를 줄 수 있다.

이제 본격적으로 GFS 설정에 들어 간다. 제일 먼저 설정해야 할 것은 ccs 설정이다.

GFS 의 구성 요소를 정의하는 설정으로 ccsd 데몬에 의해 제어 되며, RHCS의 기본 클러스터

설정 관리 프로그램으로 사용되어진다. ccs 설정은 위에서 얘기한 system-config-cluster

란 패키지를 설치하면 X 상에서 User Interface 로 간단히 설정 할 수 있다. 하지만 이 설정

은 Redhat 에서 제공하는 RHCS 에서 제어하는 다양한 Resource 를 모두 다루는 tool 로

GFS 만을 이용할 경우에는 다소 복잡한 요소를 내재하고 있다. 여기서는 GFS 설정에 맞게

ccs 설정을 해보도록 한다.

먼저 node01, node02 에 /etc 밑에 cluster 란 폴더를 생성한다.

[node01]# mkdir /etc/cluster

[node02]# mkdir /etc/cluster

그런 후 node01, node02 동일한 내용의 cluster.conf 파일을 /etc/cluster 폴더 밑에 생성한다.

# vi /etc/cluster/cluster.conf

———————————————————————————–

<?xml version=”1.0″?>

<cluster name=”cluster” config_version=”1″>

<cman>

</cman>

<clusternodes>

<clusternode name=”node01″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”human” ipaddr=”node01″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node02″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”human” ipaddr=”node02″/>

                </method>

        </fence>

</clusternode>

</clusternodes>

<fence_devices>

        <device name=”human” agent=”fence_manual”/>

</fence_devices>

</cluster>

———————————————————————————–

cluster.conf 는 xml 형식으로 제공 되며 ccsd 명령으로 반영 시킨다.

주요 설정으로 cluster name, clusternode name, device name, 등이 있고, 항목으로는

<cman>, <clusternodes>, <fence>, <fence_devices> 등이 있다.

cluster name 은 노드간의 클러스터 그룹을 정의하는 것으로 하나의 클러스터 그룹을 대표하는

name 이라 생각하면된다.

clusternode name 은 실제 cluster 를 구성하는 node 의 hostname 을 적어 주면 된다.

device name 은 해당 fence device 적어 주면 되는데 여기서는 별도의 fencing system 이

없기에human 이라 적어 주도록 한다.

fencing system 은 특정 노드에 대해 문제가 발생했을때 문제노드에 리소스 접근을 차단하여

정상적인 상황과 문제 상황에 대한 리소스 접근의 분리를 통해 리소스의 일관성을 유지해 주는

시스템이다. 흔히 SAN Switch 나 APIC 시스템의 경우 문제가 발생하면 SAN Switch 에서 문제

서버의 Port 를 차단하여 문제가 발생한 서버로는 데이터 접근을 원천적으로차단하거나 APIC

와 같이 시스템 파워를 차단해 버리는 시스템이다.  

<cman> 은 cluster management 설정 항목으로 RHCS 에서 기본 제공하는 cluster 의 resource

를 management 할때 사용되는 통신 프로그램이다. GFS 만으로 이용할 경우는 별도의 설정이

필요하진 않는다.

이밖에 많은 설정이 있는데 이는 RHCS 의 문서를 살펴 보면 된다.

node01, node02 에 cluster.conf 파일을 모두 생성하면 일차적인 GFS 설정이 완료된다.

이제 수동으로 GFS 환경에 필요한 데몬과 GFS 파일 시스템을 생성해 보도록 하자.

아래 진행 사항은 node01, node02 모두 동일 하다.

우선 GFS 에 대한 modules 를 적재한다.

# depmod -a

# modprobe dm-mod

# modprobe gfs

# modprobe lock_dlm

GFS 관련 데몬을 실행한다.

# ccsd

# cman_tool join

# fence_tool join

별 다른 에러가 없으면 GFS 환경을 위한 모든 준비가 완료되었다.

간단한 테스트로 정상적인 작동 유무를 확인하자.

[node01]# ccs_test connect

Connect successful.

Connection descriptor = 1

[node01]# ccs_test get node ‘//cluster/@name’

Get successful.

Value = <cluster>

[node01]# cat /proc/cluster/nodes

Node  Votes Exp Sts  Name

   1    1    2   M   node01

   2    1    2   M   node02

[node01]# cat /proc/cluster/services

[node01]# cat /proc/cluster/dlm_stats

[node01]# cman_tool status

정상적으로 동작함을 확인 후 GFS 파일 시스템을 생성하도록 한다.

먼저 fdisk 로 node01 과 node02 에서 Storage의 디스크가 동일하게 인식이 되는지를 확인한다.

[node01]# fdisk -l

————————————————————————————-

Disk /dev/hda: 82.3 GB, 82348277760 bytes

255 heads, 63 sectors/track, 10011 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

/dev/hda1   *           1          13      104391   83  Linux

/dev/hda2              14         144     1052257+  83  Linux

/dev/hda3             145         666     4192965   82  Linux swap

/dev/hda4             667       10011    75063712+   5  Extended

/dev/hda5            1776       10011    66155638+  83  Linux

-> Storage volume <-

Disk /dev/sda: 749.3 GB, 749356449792 bytes

255 heads, 63 sectors/track, 91104 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

————————————————————————————-

[node02]# fdisk -l

————————————————————————————-

Disk /dev/hda: 82.3 GB, 82348277760 bytes

255 heads, 63 sectors/track, 10011 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

/dev/hda1   *           1          13      104391   83  Linux

/dev/hda2              14         144     1052257+  83  Linux

/dev/hda3             145         666     4192965   82  Linux swap

/dev/hda4             667       10011    75063712+   5  Extended

/dev/hda5            1776       10011    66155638+  83  Linux

-> Storage volume <-

Disk /dev/sda: 749.3 GB, 749356449792 bytes

255 heads, 63 sectors/track, 91104 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

————————————————————————————-

이제 node01 에서 fdisk 를 통해 Storage volume 에 partition 을 생성하도록 한다.

그런 후 fdisk -l 로 node01, node02 에서 변경된 volume 이 동일하게 적용 되었는지를 확인한다.

[node01]# fdisk -l

————————————————————————————-

Disk /dev/sda: 749.3 GB, 749356449792 bytes

255 heads, 63 sectors/track, 91104 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

/dev/sda1               1       91104   731792848+  83  Linux

————————————————————————————-

[node02]# fdisk -l

————————————————————————————-

Disk /dev/sda: 749.3 GB, 749356449792 bytes

255 heads, 63 sectors/track, 91104 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

/dev/sda1               1       91104   731792848+  83  Linux

————————————————————————————-

이제 node01, node02 에서 partprobe 명령어를 통해 갱신된 partition 구조를 시스템에서 인식

하도록 적용시킨다.

[node01]# partprobe

[node02]# partprobe

그런 후 GFS 파일 시스템을 생성하도록 한다.

생성 방식은 다음과 같다.

# gfs_mkfs -p lock_dlm -t <cluster name>:<File System Name> -j <journals number> <block device>

위 환경에서는 다음과 같이 생성한다.

[node01] gfs_mkfs -p lock_dlm -t cluster:enfs -j 2  /dev/sda1

<cluster name> 은 /etc/cluste/cluster.conf 에 정의된 cluster name 이다.

<File System Name> 은 해당 볼륨을 정의하는 의미를 가지면 된다.

<journals number> 는 실제 GFS로 구성되어지는 노드 수를 의미한다.

<block device> 는 각 partition 의 device name 으로 보면 된다.

파일 시스템 생성은 node01, node02 중 하나의 노드에서만 해주면 된다.

이제 GFS 파일 시스템에 mount 를 해보도록 하자.

[node01]# mkdir /gfs

[node02]# mkdir /gfs

[node01]# mount -t gfs /dev/sda1 /gfs

[node02]# mount -t gfs /dev/sda1 /gfs

이제 node01, node02 의 /gfs 디렉토리에 각각 파일을 생성,삭제 하면서 디스크의 일관성이 유지

되는지를 확인해 보도록 한다.

혹 NFS 와 무슨 차이가 있냐!! 라는 질의가 있는데 이는 성능이나 데이터 일관성 유지 측면에서

엄청난 차이가 있다. bonne++ 툴을 이용해서 디스크의 읽기/쓰기 성능을 확인해 보면 NFS 와는

엄청난 차이가 있을 것이다. 간단히 확인 하는 방법으로 hdparm 을 이용하여 read buffer 성능

을 측정해 보아도 된다.

NFS 의 경우가 보통 Gigabit 환경에서 17M/sec 정도로 나타난다.

GFS 의 경우는 SAN 의 경우 170M/sec, SCSI 의 경우 100M/sec 정도의 성능이 나온다.

또한 확장성에서 NFS 의 경우 실제 서비스 환경에서 10~15대의 서버가 접속하면, 성능, 안정성

에서 더 이상의 확장이 힘들게 되는데 GFS 의 경우는 300노드 이상의 확장이 가능하다.

지금까지 GFS 관련 프로그램을 설치 하고, GFS 파일 시스템 생성하여 시스템에 Mount 까지

시키는 방법에 대해 알아 보았다.

이제 GFS 의 Init 환경을 제어하는 방법에 대해 알아 보자.

실제 GFS 는 Locking 문제를 해결하기 위해 DLM 이란 Locking system을 사용하고, Fencing 까지

고려되어 있기에 정상적인 start step 과 stop step 을 파악하고 있어야 한다.

그렇지 못하면 시스템이 다운되거나 관리적 목적으로 reboot 할 경우 마다 복작한 파일 시스템

환경 구성에 대한 절차를 반복해야 할 것이다. 이것을 자동으로 제어 할 수 있는 initscripts

를 만들어 제어 해야 한다.

먼저 GFS 의 start/stop 절차에 대해 파악하도록 하자.

* GFS Starting 절차

# modprobe dm-mod

# modprobe gfs

# modprobe lock_dlm

# ccsd

# cman_tool join

# fence_tool join

# mount -t gfs /dev/sda1 /gfs

* GFS Stop 절차

# umount /gfs

# fence_tool leave

# cman_tool leave

# killall ccsd

# rmmod lock_dlm

# rmmod gfs

# rmmod dm-mod

혹 fence_tool, cman_tool 이 정상적으로 leave 되지 않을 경우 force 란 옵션으로 강제로

종료 할 수 있다.

위의 과정을 적절한 scripts 를 이용하여 통합적으로 제어할 수 있는 initscripts 를 만들도록

한다.

# vi /etc/rc.d/init.d/gfs

——————————————————————————————

#!/bin/bash

#

#

#

# description: mount/unmount gfs filesystems configured in /etc/fstab

#

#              

### BEGIN INIT INFO

# Provides:  

### END INIT INFO

. /etc/init.d/functions

[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster

#

# This script’s behavior is modeled closely after the netfs script.

#

GFSFSTAB=`cat /etc/fstab | grep gfs | awk ‘{print $2}’`

GFSMTAB=$(LC_ALL=C awk ‘!/^#/ && $3 ~ /^gfs/ && $2 != “/” { print $2 }’ /proc/mounts)

# See how we were called.

case “$1” in

  start)

        if [ -n “$GFSFSTAB” ]

        then

                #load_module lock_harness MODULE_LOCK_HARNESS

                #load_module crc32        MODULE_CRC32

                modprobe lock_dlm

                modprobe gfs

                action $”Mounting GFS filesystems: ” mount -a -t gfs

        fi

        touch /var/lock/subsys/gfs

        ;;

  

  stop)

        if [ -n “$GFSMTAB” ]

        then

                sig=

                retry=6

                remaining=`LC_ALL=C awk ‘!/^#/ && $3 ~ /^gfs/ && $2 != “/” {print $2}’ /proc/mounts`

                while [ -n “$remaining” -a “$retry” -gt 0 ]

                do

                        action $”Unmounting GFS filesystems: ” umount -a -t gfs

                        if [ $retry -eq 0 ]

                        then

                                action $”Unmounting GFS filesystems (lazy): ” umount -l -a -t gfs

                                break

                        fi

                        sleep 2

                        remaining=`LC_ALL=C awk ‘!/^#/ && $3 ~ /^gfs/ && $2 != “/” {print $2}’ /proc/mounts`

                        [ -z “$remaining” ] && break

                        /sbin/fuser -k -m $sig $remaining >/dev/null

                        sleep 10

                        retry=$(($retry – 1))

                        sig=-9

                done

        fi

        modprobe -r gfs

        modprobe -r lock_dlm

        rm -f /var/lock/subsys/gfs

        ;;

  status)

        if [ -f /proc/mounts ]

        then

                [ -n “$GFSFSTAB” ] && {

                     echo $”Configured GFS mountpoints: ”

                     for fs in $GFSFSTAB; do echo $fs ; done

                }

                [ -n “$GFSMTAB” ] && {

                      echo $”Active GFS mountpoints: ”

                      for fs in $GFSMTAB; do echo $fs ; done

                }

        else

                echo “/proc filesystem unavailable”

        fi

        ;;

  restart)

        $0 stop

        $0 start

        ;;

  reload)

        $0 start

        ;;

  *)

        echo $”Usage: $0 {start|stop|restart|reload|status}”

        exit 1

esac

exit 0

—————————————————————————————-

위 Scripts 를 사용하기 위해서는 gfs mount 정보를 /etc/fstab 에 적용을 해야 한다.

# vi /etc/fstab

—————————————————————————————-

/dev/sda1               /gfs                    gfs     defaults        0 0

—————————————————————————————-

아래와 같은 방식으로 gfs file system 의 mount/umount 를 쉽게 관리 할 수 있을 것이다.

[node01]# /etc/rc.d/init.d/gfs start|stop|restart|status

[node02]# /etc/rc.d/init.d/gfs start|stop|restart|status

[node01]# df -Th

—————————————————————————————–

Filesystem    Type    Size  Used Avail Use% Mounted on

/dev/hda2     ext3   1012M  135M  826M  15% /

/dev/hda1     ext3     99M   11M   83M  12% /boot

none         tmpfs   1014M     0 1014M   0% /dev/shm

/dev/hda9     ext3     63G   85M   59G   1% /home

/dev/hda5     ext3    3.0G  1.4G  1.5G  48% /usr

/dev/hda7     ext3    2.0G   85M  1.8G   5% /usr/local

/dev/hda6     ext3    3.0G   65M  2.8G   3% /var

/dev/sda1      gfs   1012M  135M  826M  15% /gfs

——————————————————————————————

지금까지 SCSI/SAN 방식의 Share Storage 에  GFS를 이용하여 분산 시스템 환경에서 단일 파일

시스템 이미지 환경을 구성하는 방법에 대해 알아 보았다.

지금까지의설명은 가장 기본적인 구성으로 구현한 것이다.

다음 장에서는 GNBD 를 이용하여 SCSI/SAN Storage 가 아닌,  일반적인 네트워크 파일 서버를

이용하여 GFS 클러스터 파일 시스템 환경 구축에 대해 알아 보도록 하자.

4. GNBD 를 이용한 GFS 환경 구축

GNBD는 네트워크를 통해 떨어진 remote hosts 의 block device 를 network block device 를

통해 마치 local device 처럼 인식하여 데이터의 접근을 local disk 와 유사한 방식으로 접근

하게 된다.

네트워크 환경에서 remote sytem의 파일 시스템에 접근 하는 방식은 많이 있지만(FTP,WEB,NFS.)

local device 처럼 접근하는 방법과는 그 성능에서 차이가 많이 난다.

NBD 를 이용하는 대표적인파일 시스템으로 DRBD 가 있는데 이는 NBD 와 Soft Raid 를 혼합해서

만든 파일 시스템으로 주로 HA 시스템의 필요한 클러스터 파일 시스템으로 사용되어진다.

하지만 DRBD 로 제공되는 block device의 경우 하나의 호스트에서 mount 를 하고 있으면,

다른 나머지 호스트에서는 접근 하지 못하는단점이 있다.

이에 비해 GNBD 와 GFS 를 이용하면 GNBD 를 제공하는 시스템의 파일 시스템에 여러 호스트에서

접근이 가능하다. 즉 GNBD 를 이용하면 SAN Switch 환경의 SAN Storage 에 FC 를 통해 여러

노드에서 접근이 가능하게 하는 거와 같은 효과를 볼수 있다.

물런 하드웨어적으로 구성된 환경에 비해 성능은 떨어지나 NFS 와 같은 일반적인 네트워크

서비스 환경 보다  월등한 성능을 보장하며, 하드웨어 구성의 환경  보다 확장성을 가지고

고가의 장비가 필요하지 않는 점에서 매우 유용한 방식이라 할 수 있다.

또한 SAN/SCSI + RAID + GFS + GNBD 를 이용하면 성능, 확장성등을 모두 최적화 시키는 설계도

가능하다.

이장에서는 GNBD 를 이용한 기본적인 클러스터 파일 시스템 환경 구축에 대해 설명할 것이다.

아래는 가장 기본적인 GNBD 를 이용한 클러스터 파일 시스템 설계이다.

GNBD 로 구성된 환경이 제공하는 효과는 앞에서 다른 하드웨어 환경에서의 효과와 동일하다.

즉 Node03 의 하드 디스크를 Node01, Node02 에서 로컬에 붙어 있는 DAS 처럼 인식하게 된다.

하지만 SCSI/FC 같은 고가 장비를 이용하는게 아닌 일반적인 네트워크 환경에서 구현이 된다는

차이가 있다.

                  Mount                                     Mount

         ————-                             ————-

        |   Node01    | GFS File System           |   Node02    | GFS File System

         ————-                             ————-

               |  GNBD Client                            | GNBD Client

               |                                         |

      —————————————————————-

                    Gigabit Network Switch 환경

      —————————————————————-

                                   |

                                   |   GNBD Server

                              ————

                             |   Node03   |  GFS File System

                              ————

                                       Disk Volume

이제 위 구성과 같이 GNBD 와 GFS 를 이용한 저가 비용으로 구축이 가능한  클러스터 파일

시스템 환경을 구현해 보자.

기본적인 설치 패키지는 GFS 와 동일하다.

앞서 다룬 GFS 에서 설치 한 모든 패키지를 설치 하도록한다.

GNBD 역시 GFS 를 통한 클러스터 파일 시스템 환경을 이루기 때문에 초기 준비 단계는 GFS의

모든 과정과 동일 하다.

GFS에서 거론한 모든 패키지를 설치 한 후 GNBD 관련 패키지를 설치 하도록 한다.

GNBD 패키지는 Node01, Node02, Node03 서버에 동일하게 설치 한다.

# rpm -Uvh gnbd-kernel-2.6.9-8.27.i686.rpm

# rpm -Uvh gnbd-1.0.0-0.i686.rpm

그런 후 /etc/cluster/cluster.conf 에 node03 에 대한 항목을 추가 한다.

설정의 방식은 GFS 와 동일하다.

# vi /etc/cluster/cluster.conf

——————————————————————————————-

<?xml version=”1.0″?>

<cluster name=”cluster” config_version=”1″>

<cman>

</cman>

<clusternodes>

<clusternode name=”node01″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”human” ipaddr=”node01″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node02″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”human” ipaddr=”node02″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node03″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”human” ipaddr=”node03″/>

                </method>

        </fence>

</clusternode>

</clusternodes>

<fence_devices>

        <device name=”human” agent=”fence_manual”/>

</fence_devices>

</cluster>

——————————————————————————————–

모든 노드에 cluster.conf 파일을 동기화 한다.

그런 후 모든 노드에 먼저 GFS 관련 모듈과 데몬을 시작한다.

# depmod -a

# modprobe dm-mod

# modprobe gfs

# modprobe lock_dlm

# ccsd

# cman_tool join

# fence_tool join

그런 후 GNBD 모듈을 적재한다.

# modprobe gnbd

이제 GNBD Server ( node03 ) 에서 gnbd_serv 데몬을 실행한다.

[node03]# gnbd_serv -v

그런 후 GNBD 로 GNBD Client 에 제공한 Disk Block Device 를 export 시킨다.

[node03]# gnbd_export -v -e gnbd0 -d /dev/sda1

정상적으로 등록 되었는지 확인 한다.

[node03]# gnbd_export -v -l

Server[1] : gnbd0

——————————

      file : /dev/sda1

   sectors : 19551042

  readonly : no

    cached : no

   timeout : 60

이제 GNBD Client ( node01, node02 ) 노드에서 서버의 export 된 정보를 import 시킨다.

[node01]# gnbd_import -v -i node03

[node02]# gnbd_import -v -i node03

정상적으로 import 된지 확인 한다.

[node01]# gnbd_import -v -l

Device name : gnbd0

———————-

    Minor # : 0

  Proc name : /dev/gnbd0

     Server : n003

       Port : 14567

      State : Close Connected Clear

   Readonly : No

    Sectors : 19551042

[node02]# gnbd_import -v -l

Device name : gnbd0

———————-

    Minor # : 0

  Proc name : /dev/gnbd0

     Server : n003

       Port : 14567

      State : Close Connected Clear

   Readonly : No

    Sectors : 19551042

정상적으로 import 된거을 확인하면  /dev/gnbd/gnbd0 이란 디바이스 파일이 생성되어 있을

것이다.

[node01]# ll /dev/gnbd/gnbd0

brw-r–r–  1 root root 251, 0 Oct  7 13:46 /dev/gnbd/gnbd0

이제 /dev/gnbd/gnbd0 device 를 local device 처럼 사용이 가능하다.

Gnbd 서버로 가서 gfs file system 을 생성한다.

[node03]# gfs_mkfs -p lock_dlm -t cluster:gnbdfs -j 3 /dev/sda1

This will destroy any data on /dev/hda6.

Are you sure you want to proceed? [y/n] y

GNBD Server 에서 GFS local block device 에 mount 한다.

[node03]# mount -t gfs /dev/sda1 /gfs

이제 GNBD Client 에서 Mount 를 시킨다.

[node01]# mount -t gfs /dev/gnbd/gnbd0 /gfs

[node02]# mount -t gfs /dev/gnbd/gnbd0 /gfs

[node01]# df -Th | grep /gfs

/dev/gnbd/gnbd0    gfs  9.0G   20K  9.0G   1% /gfs

[node02]# df -Th | grep /gfs

/dev/gnbd/gnbd0    gfs  9.0G   20K  9.0G   1% /gfs

[node03]# df -Th | grep /gfs

/dev/sda1            gfs 9.0G   20K  9.0G   1% /gfs

이것으로 node01, node02 시스템에서 node03 의 sda1 device 를 마치 DAS 방식의 Storage 처럼

사용하게 된다. 물런 node03 에서도 sda1 의 block 을 GFS 를 통해 사용이 가능하다.

실제 GNBD 의 경우 Gigabit 환경에서 40M/Sec 정도의 성능이 나온다. 이는 동일 환경에서의

NFS 에 비해 2배 이상의 성능이라 볼수 있다.

또한 확장성에서 역시 10배 이상의 효과가 있다고 한다.

마지막으로 GFS+GNBD 상의 시스템에서 안정하게 시스템을 종료하는 방법에 대해 알아보자.

GFS 의 경우에는 위에서 제시한 /etc/rc.d/init.d/gfs 스크립터를 이용하여 안전하게 종료할수

있지만 GNBD 의 경우는 다른다. 실제 GNBD 간의 통신이 이루어 지기 때문에 이 부분을 무시한채

시스템을 리부팅을 하게 되면 시스템 shutdown 과정에서 멈추게 된다.

아래 스크립터로 안전하게 시작과 종료를 제어 하도록 한다.

*** gnbd_start.sh  

—————————————————————————————-

#!/bin/sh

GNBD_SERVER=”node03″

GNBD_NAME=”gnbd0″

GFS_MOUNT=”/gfs”

modprobe dm-mod

modprobe gfs

modprobe lock_dlm

modprobe gnbd

ccsd

cman_tool join

fence_tool join

sleep 2

gnbd_import -v -i $GNBD_SERVER

mount -t gfs /dev/gnbd/$GNBD_NAME $GFS_MOUNT

echo “GNBD Start complete …”

—————————————————————————————–

*** gnbd_stop.sh

—————————————————————————————–

#!/bin/sh

GNBD_NAME=”gnbd0″

GFS_MOUNT=”/gfs”

GFS_PID=`lsof /gfs | grep -v PID | awk ‘{print $2}’`

kill -9 `echo $GFS_PID` &> /dev/null

umount $GFS_MOUNT

# /etc/rc.d/init.d/clvmd stop

killall fenced

gnbd_import -r $GNBD_NAME

fence_tool leave

cman_tool leave force

killall ccsd

rmmod gnbd

rmmod lock_dlm

rmmod gfs

rmmod dm-mod

echo “GNBD Stop complete …”

—————————————————————————————–

*** gnbd_server_start.sh

—————————————————————————————–

#!/bin/sh

GNBD_SERVER=”node03″

GNBD_NAME=”gnbd0″

GFS_DEV=”/dev/sda1″

modprobe dm-mod

modprobe gfs

modprobe lock_dlm

modprobe gnbd

ccsd

cman_tool join

fence_tool join

sleep 2

gnbd_serv -v

gnbd_export -v -e $GNBD_NAME -d $GFS_DEV

echo “GNBD Server Start complete …”

—————————————————————————————–

*** gnbd_server_stop.sh

—————————————————————————————–

#!/bin/sh

GNBD_NAME=”gnbd0″

# /etc/rc.d/init.d/clvmd stop

killall fenced

gnbd_export -R

killall gnbd_serv

cman_tool leave force

killall ccsd

rmmod gnbd

rmmod lock_dlm

rmmod gfs

rmmod dm-mod

echo “GNBD Server Stop complete …”

—————————————————————————————–

5. GFS,GNBD 와 CLVM 를 이용한 클러스터 볼륨 관리하기

CLVM는 Cluster Logical Volume Manager 로 분산 된 시스템의 볼륨을 단일 하게 관리해 주는

볼륨메니저의 일종이다. 이는 리눅스의 lvm 기반위에서 동작하며, lvm2, device-mapper 프로그램

이 설치 되어 있어야 가능하다. Redhat RPM Package로는 lvm2-cluster 란 이름으로 배포되어진다.

아래의 구축 방안은 위에서 다룬 GFS 와 GNBD를 기반으로 GNBD 에서 제공하는 Network Block

Device기능을 이용하여 분산 노드의 디스크들을 LVM 으로 묶어 하나의 대형 볼륨으로 만들어

관리하는 방법에 대해 설명한다.

즉 네트워크 상에 분산된 시스템의 개별 디스크를 하나의 대형 볼륨으로 만들어 관리하는

설계 구조이다.

          

         ———–        ———-        ———

        |  node01   |      |  node02  |      |  node03 |

         ———–        ———-        ———

              | GFS              | GFS            | GFS

              | GNBD(client)     | GNBD(client)   | GNBD(client)

              | CLVM             | CLVM           | CLVM    

——————————————————————————–

                         Gigabit Network 환경

——————————————————————————–

                      | CLVM               | CLVM

                      | GNBD(server)       | GNBD(server)

               ————–        ————–

              |   node04     |      |    node05    |

              |  50G volume  |      |  50G volume  |

               ————–        ————–

위 구성에서 node04,node05에서 각각 50GByte 크기의 디스크를 gnbd를 이용하여 node01,02,03

에서 사용할 수 있도록 구성한 후, node01,02,03에서 LVM2 와 CLVM 을 이용하여 node04,05의  

gnbd device를 하나로 취합함으로 node01,02,03에서는 node04,05에서 제공된 전체 디스크 용량

인 100GByte 를 하나의 볼륨으로 인식하여 마운트해서 사용이 가능하다.

이와 같은 방식으로 GNBD 서버 노드를 계속 확장 시켜 나간다면, 분산된 노드의 디스크를 이용

하여 거대한 클러스터 볼륨을 구성할 수 있게 된다.

또한 LVM 의 기능을 이용하면, 볼륨노드 추가 시 서비스를 정지하지 않고도 가능함으로 관리나

불륨 확장시 시스템의 안정성을 극대화 할수도 있을 것이다.

그럼 구체적인 설치 방법에 대해 알아보자.

먼저 앞에서 다룬 방식으로 GNBD 환경을 구성한다.

– GFS + GNBD 관련 패키지 설치

– cluster.conf 파일 설정 및 구성

# vi /etc/cluster/cluster.conf

——————————————————————————————

<?xml version=”1.0″?>

<cluster name=”cluster” config_version=”1″>

<cman>

</cman>

<clusternodes>

<clusternode name=”node01″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”gnbd” ipaddr=”node01″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node02″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”gnbd” ipaddr=”node02″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node03″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”gnbd” ipaddr=”node03″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node04″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”gnbd” ipaddr=”node04″/>

                </method>

        </fence>

</clusternode>

<clusternode name=”node05″ votes=”1″>

        <fence>

                <method name=”single”>

                        <device name=”gnbd” ipaddr=”node05″/>

                </method>

        </fence>

</clusternode>

</clusternodes>

<fence_devices>

        <device name=”human” agent=”fence_manual”/>

        <device name=”gnbd”  agent=”fence_gnbd” option=”multipath” servers=”node04 node05″/>

</fence_devices>

</cluster>

—————————————————————————————–

# ensync /etc/cluster/cluster.conf

– GFS + GNBD 모듈 탑재 및 관련 데몬 구동  

node01,02,03,04,05에서 동일하게 적용

# depmod -a

# modprobe dm-mod

# modprobe gfs

# modprobe lock_dlm

# ccsd

# cman_tool join

# fence_tool join

# modprobe gnbd

– GNBD Server 데몬 실행

node04 에 적용

# /sbin/gnbd_serv -v

# gnbd_export -v -e gnbd1 -d /dev/sda6

node05 에 적용  

# /sbin/gnbd_serv -v

# gnbd_export -v -e gnbd2 -d /dev/sda6

– GNBD Client 데몬 설행

node01,02,03,04,05 에 적용

# gnbd_import -v -i node04

# gnbd_import -v -i node05

– CLVM 데몬 실행

node01,02,03,04,05 에 적용

# /etc/rc.d/init.d/clvmd start

– LVM2 구성

node01 에서 실행

# partprobe

# pvcreate /dev/gnbd/gnbd1 /dev/gnbd/gnbd2        -> physical volume 생성

# vgcreate vg0 /dev/gnbd/gnbd1 /dev/gnbd/gnbd2    -> volume group 생성

# lvcreate -L 100G -n lvm0 vg0                    -> logical volume 생성

– LVM2 구성 확인

node01,02,03,04,05 에서 아래 방식으로 node01 에서 적용한 볼륨 구성이 동기화가 되었는지

확인한다.

# pvdisplay           ->  physical volume 구성 확인

# vgdisplay           ->  volume group 구성 확인

# lvdisplay           ->  logical volume 구성 확인

– GFS 파일 시스템 구성

node01 에서 GFS 로 파일 시스템을 포맷한다.

# gfs_mkfs -p lock_dlm -t cluster:enfs -j 5 /dev/vg0/lvm0

– GFS mount

모든 노드에서 아래와 같이 gfs 파일 시스템에 mount 를 한다.

# mount -t gfs /dev/vg0/lvm0   /gfs

# df

# df -h

————————————————————————————

Filesystem            Size  Used Avail Use% Mounted on

/dev/hda2             2.9G  289M  2.5G  11% /

/dev/hda1              99M   14M   81M  15% /boot

none                  249M     0  249M   0% /dev/shm

/dev/hda3             9.7G  2.6G  6.7G  28% /usr

/dev/mapper/vg0-lvm0   99G  432M   98G   1% /gfs

————————————————————————————

참고 사항 :

* LVM2 의 사용방법은 기존의 LVM 과 동일하다.  

* LVM 은 기본적으로 디스크를 하나로 묶을때 Span 방식으로 취합이 된다.

raid-0 의 striping 으로 취합될 경우 특정 디스크에 문제가 발생했을 경우 모든 볼륨이

깨어지게 되는데 span 방식의 경우 문제 발생 디스크 상의 저장된 정보만 상실하게 됨으로

나름대로의 안정성이 보장된다고 볼수 있다.

또한 현재는 개발 되지 않았지만, 향후 Raid-1 방식과 raid-5 방식의 array 구성을 lvm2에

포함시킬 계획을 가지고 있음으로 더욱 효율적인 볼륨을 구성할 수 있을 것이다.

6. Soft Raid 와 GNBD 를 이용한 고가용성 GFS 환경 구축하기

GNBD 구성 후 하나의 GNBD Client  에서 soft raid1 을 잡고..gfs 포맷을 한다.

그런 후 다른 GNBD Client 에 raid1 을 다시 묶는다..

*****  GFS + GNBD + DRBD 를 이용한 2 node Active/Active HA

– node04,node05 에 GFS, GNBD 환경 구축

node04 : gnbd0 ( export name )

node05 : gnbd1 ( export name )

node04 -> import node04, node05

node05 -> import node04, node05

– node04, node05 DRBD 구성

node04, node05 : /etc/drbd.conf

———————————————————————————–

skip {

}

resource dr0 {

  protocol C;

  incon-degr-cmd “echo ‘!DRBD! pri on incon-degr’ | wall ; sleep 60 ; halt -f”;

  startup {

    degr-wfc-timeout 120;    # 2 minutes.

  }

  disk {

    on-io-error   detach;

  }

  net {

  }

  syncer {

    rate 10M;

    group 1;

  }

  on node04 {

    device     /dev/drbd0;

    disk       /dev/gnbd/gnbd0;

    address    192.168.123.114:7788;

    meta-disk  internal;

  }

  on node05 {

    device    /dev/drbd0;

    disk      /dev/gnbd/gnbd1;

    address   192.168.123.115:7788;

    meta-disk internal;

  }

}

~

————————————————————————————–

node04 # drbdadm primary all

node04 # gfs format

node04 # mount -t gfs /dev/drbd0 /gfs

node05 # mount -t gfs /dev/gnbd/gnbd0 /gfs

실제 node05 에서는 gfs,gnbd 로 node04 의 resource 에 mount

node04 에 문제 발생 시 heartbeat 를 이용하여 gnbd1 에 drbd primary 권한을 넘기로

node05 에서는 자기 자신의 gnbd1 에 mount

gnbd0 -> gnbd1 로 network mirroring 이 되므로 디스크는 동일 환경 유지

7. GFS 관리 하기

      Section 5.1 Making a File System

      Section 5.2 Mounting a File System

      Section 5.3 Unmounting a File System

      Section 5.4 GFS Quota Management

      Section 5.5 Growing a File System

      Section 5.6 Adding Journals to a File System

      Section 5.7 Direct I/O

      Section 5.8 Data Journaling

      Section 5.9 Configuring atime Updates

      Section 5.10 Suspending Activity on a File System

      Section 5.11 Displaying Extended GFS Information and Statistics

      Section 5.12 Repairing a File System

      Section 5.13 Context-Dependent Path Names

– GFS Kernel 과 SW 업그레이드 하기

GFS는 kernel에 의존되는 바가 크기 때문에 반드시 해당 커널에 맞는 패키지를 가지고

업그레이드를 해야 한다.

Redhat에서 배포하는 Src,rpm 으로 rebuild 를 하다보면 여러가지 의존성에 의해 문제가

발생하는데 이는 Redhat 에서 배포하는 패지지 개개별로 모두 다른 패키지들과의 의존성

을 가지고 있기 때문에다.

아래 순으로 build 를 하며, build 가 완료되면 다음것을 build 하기 전에 설치를 하고

난 후 build를 해야 정상적으로 rpm building 이 되어진다.

kernel-2.6.9-22.0.1.EL.i686.rpm

kernel-devel-2.6.9-22.0.1.EL.i686.rpm

kernel-utils-2.4-13.1.69.i386.rpm

mkinitrd-4.2.1.6-1.i386.rpm

magma-1.0.1-4.i686.rpm magma-devel-1.0.1-4.i686.rpm

ccs-1.0.2-0.i686.rpm ccs-devel-1.0.2-0.i686.rpm

gulm-1.0.4-0.i686.rpm gulm-devel-1.0.4-0.i686.rpm

magma-plugins-1.0.2-0.i386.rpm

cman-kernel-2.6.9-39.8.i686.rpm

cman-1.0.2-0.i686.rpm cman-devel-1.0.2-0.i686.rpm

dlm-kernel-2.6.9-37.9.i686.rpm

dlm-1.0.0-5.i686.rpm dlm-devel-1.0.0-5.i686.rpm

fence-1.32.6-0.i686.rpm

gnbd-kernel-2.6.9-9.14.i686.rpm

gnbd-1.0.1-1.i686.rpm

GFS-kernel-2.6.9-42.2.i686.rpm

GFS-6.1.2-0.i386.rpm

device-mapper-1.01.04-1.0.RHEL4.i386.rpm

lvm2-2.01.14-2.0.RHEL4.i386.rpm

lvm2-cluster-2.01.14-1.0.RHEL4.i386.rpm

iddev-2.0.0-3.i686.rpm iddev-devel-2.0.0-3.i686.rpm

이와 같이 src.rpm 의 building 과 설치가 완료되면, 현재 서비스 중인 gfs 관련 패키지를

모두 정지 한 후 리부팅 시 자동으로 gfs 가 구동되지 않도록 한다.

chkconfig –level 3 gfs off

chkconfig –level 3 cman off

chkconfig –level 3 lock_gulmd off

chkconfig –level 3 clvmd off

chkconfig –level 3 ccsd off

chkconfig –level 3 fenced off

*****   GNBD  stop 절차

umount /gfs

sleep 2

gnbd_import -r gnbd0

killall clvmd

fence_tool leave

killall fenced

sleep 2

cman_tool leave force

killall ccsd

rmmod gnbd

rmmod lock_dlm

rmmod gfs

rmmod dm-mod

**** GFS Stop 절차

umount /gfs

fence_tool leave

cman_tool leave

killall ccsd

rmmod lock_dlm

rmmod gfs

rmmod dm-mod

**** /etc/fstab 확인

/etc/fstab에 gfs 관련 마운트 정보를 입력해 두었다면 주석 처리를 한다.

*** 리부팅 ( rebooting )

**** GNBD Start 절차 (서버)

modprobe dm-mod

modprobe gfs

modprobe lock_dlm

modprobe gnbd

ccsd

cman_tool join

fence_tool join

gnbd_serv -v

gnbd_export -v -e gnbd0 -d /dev/hda4

**** GNBD Start 절차 (클라언트)

modprobe dm-mod

modprobe gfs

modprobe lock_dlm

modprobe gnbd

ccsd

cman_tool join

fence_tool join

gnbd_import -v -i node03

mount -t gfs /dev/gnbd/gnbd0 /gfs

**** GFS init start

chkconfig –level 3 gfs on

chkconfig –level 3 cman on

chkconfig –level 3 clvmd on

chkconfig –level 3 ccsd on

chkconfig –level 3 fenced on

8. GFS 의 적용 범위 및 고급 구성

서진우

서진우

슈퍼컴퓨팅 전문 기업 클루닉스/ 상무(기술이사)/ 정보시스템감리사/ 시스존 블로그 운영자

You may also like...

페이스북/트위트/구글 계정으로 댓글 가능합니다.