OCFS2 Cluster 구성

1. OCFS2 볼륨 구성 및 마운트

OCFS2 on debian wheezy

1-(1). 시험 환경

Hostname IP OS Kernel OCFS2로 사용할 디스크
ocfs2-fi rst 192.168.0 .221 Debian 7.11 (wheezy) 3.16.7-ckt11-1+deb8u5 (2015-10-09) 100G (/dev/xvdb)
ocfs2-se cond 192.168.0 .222 Debian 7.11 (wheezy) 3.16.7-ckt11-1+deb8u5 (2015-10-09) 100G (/dev/xvdb)

1-(2). OCFS2 관련 패키지 설치

Debian wheezy에서 ocfs2 tool의 최신 버전은 1.6.4입니다. 다음과 같이 ocfs2 관련 패키지를 두 서버(ocfs2-first, ocfs2-second)에 각각 설치합니다.

# apt-get update && apt-get install ocfs2-tools

1-(3). OCFS2 설정

  • OCFS2 1.6 module 2.6.36 이상의 리눅스 커널에 포함되어 있습니다.
  • OCFS2는 두 개의 설정 파일(Cluster layout, Cluster timeout)이 있습니다.

다음 순서로 OCFS2를 설정하겠습니다.

순서 설정 항목 파일 또는 명령어
1 호스트 설정 /etc/hosts
2 Cluster layout 설정 /etc/ocfs2/cluster.conf
3 Cluster timeout 설정 /etc/default/o2cb
4 커널 설정 /etc/sysctl.conf
5 O2CB 시작 /etc/init.d/o2cb online
6 OCFS2 파일 시스템 생성 mkfs.ocfs2
7 OCFS2 파일 시스템 마운트 mount -t ocfs2 /dev/DEVICE /mnt

이제 /etc/hosts 파일을 수정하겠습니다.

1). /etc/hosts 설정

/etc/hosts 파일에 OCFS2 node로 사용할 모든 호스트 정보를 기록합니다. (본 매뉴얼에서는 2개의 OCFS2 node를 사용할 예정이므로 2개의 호스트 정보를 기록했습니다.)

+ 192.168.0.221   ocfs2-first
+ 192.168.0.222   ocfs2-second

왜냐하면 OCFS2를 설정할 때 Cluster layout 설정 파일(/etc/ocfs2/cluster.conf)에서 hostname을 입력해야 하기 때문입니다. 만약 /etc/hosts 파일에 IP 주소와 hostname을 mapping 하지 않은 채, Cluster layout 설정 파일에 hostname을 입력하면 해당 호스트를 찾을 수 없습니다. 그러므로 OCFS2를 사용할 수 없습니다.

2). Cluster layout 설정

Cluster layout 설정 파일은 /etc/ocfs2/cluster.conf에 위치합니다. 만약 /etc/ocfs2/cluster.conf 파일이 존재하지 않으면 파일을 새로 생성해야 합니다.

# vi /etc/ocfs2/cluster.conf

OCFS2 node로 사용할 서버(ocfs2-first, ocfs2-second)의 /etc/ocfs2/cluster.conf 파일에 아래 내용을 각각 기록합니다.

ocfs2-first, ocfs2-second 서버에 아래 내용을 기록합니다. (단, #로 시작하는 주석 설명은 지워야 합니다.)

cluster:
        node_count = 2      # 전체 OCFS2의 node 개수를 입력합니다.
        name = ocfs2        # 임의로 지정합니다. 반드시 node 항목의 name과 같은 호스트 이름을 기록할 필요는 없습니다.

node:
        number = 0
        cluster = ocfs2
        ip_port = 7777
        ip_address = 192.168.0.221
        name = ocfs2-first    # node 서버의 호스트 이름으로 설정해야 합니다.
node:
        number = 1
        cluster = ocfs2
        ip_port = 7777
        ip_address = 192.168.0.222
        name = ocfs2-second   # node 서버의 호스트 이름으로 설정해야 합니다.

3). Cluster timeout 설정

# vi  /etc/default/o2cb

OCFS2 node로 사용할 서버(ocfs2-first, ocfs2-second)의 /etc/default/o2cb 파일에 아래 내용을 각각 기록합니다.

# O2CB_ENABLED: 'true' means to load the driver on boot.
- O2CB_ENABLED=false
+ O2CB_ENABLED=true

# O2CB_BOOTCLUSTER: If not empty, the name of a cluster to start.
O2CB_BOOTCLUSTER=ocfs2

# O2CB_HEARTBEAT_THRESHOLD: Iterations before a node is considered dead.
O2CB_HEARTBEAT_THRESHOLD=31

# O2CB_IDLE_TIMEOUT_MS: Time in ms before a network connection is considered dead.
- O2CB_IDLE_TIMEOUT_MS=30000
+ O2CB_IDLE_TIMEOUT_MS=60000

# O2CB_KEEPALIVE_DELAY_MS: Max. time in ms before a keepalive packet is sent.
O2CB_KEEPALIVE_DELAY_MS=2000

# O2CB_RECONNECT_DELAY_MS: Min. time in ms between connection attempts.
O2CB_RECONNECT_DELAY_MS=2000

간단히 요약하면, ocfs2는 disk heartbeat과 network heartbeat으로 노드의 상태를 체크합니다. 위 설정은 disk heartbeat은 60초, network heartbeat도 60초로 설정된 것입니다. 즉, 60초 동안 디스크 문제가 있거나, 60초 동안 다른 노드에 port 7777에 네트워크 접속이 안되면 문제가 있는 것이고, self-fencing을 하게 됩니다.

자세한 설명은 OCFS2 User’s guide for release 1.6 문서를 참고하세요.

4). 커널 설정

다음과 같이 두 개의 커널 설정을 합니다.

  • kernel.panic_on_oops = 1 : o2cb가 기능하도록 하는 kernel thread가 크래쉬되었을 때, cluster가 hang되지 않도록 kernel oops상태를 panic으로 바꾸어 주어야 합니다.
  • kernel.panic = 30 : kernel panic 상태가 30초 동안 지속될 때 시스템이 자동으로 reboot되게 합니다.
# vi /etc/sysctl.conf

/etc/sysctl.conf 파일에 아래 내용을 기록합니다.

+ kernel.panic_on_oops = 1
+ kernel.panic = 30

sysctl -p 명령을 실행합니다.

root@ocfs2-first:~# sysctl -p
root@ocfs2-second:~# sysctl -p

5). O2CB 시작

o2cb는 OCFS2 를 관장하는 서비스 daemon입니다. cluster.conf에 정의된 포트를 listen 합니다. o2cb를 시작하려면 다음과 같이 online 명령을 주면 됩니다.

root@ocfs2-first:/etc/ocfs2# /etc/init.d/o2cb online
Setting cluster stack "o2cb": OK
Starting O2CB cluster ocfs2: OK
root@ocfs2-second:/etc/ocfs2# /etc/init.d/o2cb online
Setting cluster stack "o2cb": OK
Starting O2CB cluster ocfs2: OK

6). OCFS2 파일 시스템 생성

ocfs2 명령으로 파일시스템을 만들어 마운트 하겠습니다. -T 옵션은 파일시스템의 용도를 지정합니다.

  • mail : 작은 파일이 많은 파일시스템에 적합
  • datafiles : DB 파일 저장용으로 적합
  • vmstore : VM 이미지 파일 저장용으로 적합

아래와 같이 OCFS2 파일 시스템을 생성합니다.

# mkfs.ocfs2 -T vmstore /dev/DEVICE

OCFS2 node로 사용할 서버에 위 명령으로 파일 시스템을 생성합니다.

root@ocfs2-first:~# mkfs.ocfs2 -T vmstore /dev/xvdb
root@ocfs2-second:~# mkfs.ocfs2 -T vmstore /dev/xvdb

7). OCFS2 파일 시스템 마운트

일반적인 마운트 방법과 같습니다.

# mount -t ocfs2 /dev/DEVICE /mnt

그냥 mount 명령으로 해도 됩니다. 어차피 커널에서 파일시스템 타입을 보고 그에 맞는 mount 명령을 하기 때문입니다.

root@ocfs2-first:~# mount -t ocfs2 /dev/xvdb /mnt
root@ocfs2-second:~# mount -t ocfs2 /dev/xvdb /mnt

그러나 위와 같이 명확히 명령을 써 주는 것이 더 낫습니다.

mount 명령으로 어떻게 마운트되었는지 보겠습니다.

root@ocfs2-first:~# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,relatime,size=10240k,nr_inodes=123127,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=99696k,mode=755)
/dev/disk/by-uuid/5322febc-07e2-47c9-a7e2-444ca58ac825 on / type ext4 (rw,relatime,errors=remount-ro,user_xattr,barrier=1,data=ordered)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=394560k)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
+ configfs on /sys/kernel/config type configfs (rw,relatime)
+ ocfs2_dlmfs on /dlm type ocfs2_dlmfs (rw,relatime)
+ /dev/xvdb on /mnt type ocfs2 (rw,relatime,_netdev,heartbeat=local,nointr,data=ordered,errors=remount-ro,coherency=full,user_xattr,acl)
root@ocfs2-second:~# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,relatime,size=10240k,nr_inodes=123127,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=99696k,mode=755)
/dev/disk/by-uuid/5322febc-07e2-47c9-a7e2-444ca58ac825 on / type ext4 (rw,relatime,errors=remount-ro,user_xattr,barrier=1,data=ordered)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=394560k)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
+ configfs on /sys/kernel/config type configfs (rw,relatime)
+ ocfs2_dlmfs on /dlm type ocfs2_dlmfs (rw,relatime)
+ /dev/xvdb on /mnt type ocfs2 (rw,relatime,_netdev,heartbeat=local,nointr,data=ordered,errors=remount-ro,coherency=full,user_xattr,acl)

mount 명령을 보면 위 3개의 마운트가 ocfs2 관련 mount입니다.

  • configfs : ram에 상주하는 cluster layout 설정이 들어 있는 파일시스템
  • ocfs2_dlmfs : 클러스터 내 노드들 간의 파일에 Lock을 관리하는 대한 distributed lock manager 파일시스템
  • /dev/sdg1 : 여러 노드에 동시에 마운트되는 ocfs2 파일시스템

부팅될 때 ocfs2 파일시스템을 마운트하려면, /etc/fstab에 다음과 같이 추가합니다. (/ocfs2 디렉토리가 없으면 /ocfs2 디렉토리를 생성해야 합니다.)

ocfs2-first 서버에서 /etc/fstab을 설정하겠습니다.

root@ocfs2-first:~# vi /etc/fstab
<--SNIP-->
+ /dev/xvdb       /ocfs2          ocfs2   _netdev,defaults        0       0

ocfs2-second 서버에서 /etc/fstab을 설정하겠습니다.

root@ocfs2-second:~# vi /etc/fstab
<--SNIP-->
+ /dev/xvdb       /ocfs2          ocfs2   _netdev,defaults        0       0

위 설정에서 중요한 부분은 _netdev입니다. _netdev는 네트워크가 올라온 후에 mount 하라는 옵션입니다. ocfs2 파일시스템을 마운트 하려면 당연히 network이 되어야 하니 이 옵션은 필수입니다.

1-(4). OCFS2 misc

1) Cluster 상태 조회

service o2cb status 명령으로 Cluster 상태 조회시 설정값, 현재 상태를 확인할 수 있습니다.

root@ocfs2-first:~# service o2cb status
Driver for "configfs": Loaded
Filesystem "configfs": Mounted
Stack glue driver: Loaded
Stack plugin "o2cb": Loaded
Driver for "ocfs2_dlmfs": Loaded
Filesystem "ocfs2_dlmfs": Mounted
Checking O2CB cluster ocfs2: Online
Heartbeat dead threshold = 31
  Network idle timeout: 60000
  Network keepalive delay: 2000
  Network reconnect delay: 2000
Checking O2CB heartbeat: Active
root@ocfs2-second:~# service o2cb status
Driver for "configfs": Loaded
Filesystem "configfs": Mounted
Stack glue driver: Loaded
Stack plugin "o2cb": Loaded
Driver for "ocfs2_dlmfs": Loaded
Filesystem "ocfs2_dlmfs": Mounted
Checking O2CB cluster ocfs2: Online
Heartbeat dead threshold = 31
  Network idle timeout: 60000
  Network keepalive delay: 2000
  Network reconnect delay: 2000
Checking O2CB heartbeat: Active

2) OCFS2 프로세스 확인

자세한 설명은 OCFS2 User’s guide for release 1.6 문서를 참고하세요.

A. user_dlm

노드 당 한 개. dlmfs가 mount될 때 구동되고, dlmfs가 umount될 때 종료되는 process

root@ocfs2-first:~# ps aux | grep user_dlm
root       3254  0.0  0.0      0     0 ?        S<   01:42   0:00 [user_dlm]
root       3732  0.0  0.0  11824   924 pts/4    S+   02:25   0:00 grep user_dlm
root@ocfs2-second:~# ps aux | grep user_dlm
root       3280  0.0  0.0      0     0 ?        S<   01:42   0:00 [user_dlm]
root       3702  0.0  0.0  11824   928 pts/4    S+   02:25   0:00 grep user_dlm
B. o2net

노드 당 한 개. o2cb가 online이 되면 시작되며, offline이 되면 종료되는 단일 process

root@ocfs2-first:~# ps aux | grep o2net
root       3560  0.0  0.0      0     0 ?        S<   01:48   0:00 [o2net]
root       3734  0.0  0.0  11824   924 pts/4    S+   02:26   0:00 grep o2net
root@ocfs2-second:~# ps aux | grep o2net
root       3548  0.0  0.0      0     0 ?        S<   01:50   0:00 [o2net]
root       3705  0.0  0.0  11824   928 pts/4    S+   02:26   0:00 grep o2net
C. o2hb-blahblah

heartbeat 장치 당 한 개. disk heartbeat process로 configfs가 mount될 때 구동되고, umount되면 종료되는 process. heartbeat 영역에 2초마다 쓰기를 하여 disk heartbeat을 체크합니다.

root@ocfs2-first:~# ps aux | grep o2hb
root       3651  0.0  0.0      0     0 ?        S<   02:08   0:00 [o2hb-40DCD99A65]
root       3736  0.0  0.0  11824   924 pts/4    S+   02:28   0:00 grep o2hb
root@ocfs2-second:~# ps aux | grep o2hb
root       3636  0.0  0.0      0     0 ?        S<   02:09   0:00 [o2hb-EE9F6CF876]
root       3707  0.0  0.0  11824   928 pts/4    S+   02:28   0:00 grep o2hb
D. ocfs2_wq
root@ocfs2-first:~# ps aux | grep ocfs2_wq
root       3656  0.0  0.0      0     0 ?        S<   02:08   0:00 [ocfs2_wq]
root       3738  0.0  0.0  11824   932 pts/4    S+   02:29   0:00 grep ocfs2_wq
root@ocfs2-second:~# ps aux | grep ocfs2_wq
root       3641  0.0  0.0      0     0 ?        S<   02:09   0:00 [ocfs2_wq]
root       3709  0.0  0.0  11824   928 pts/4    S+   02:29   0:00 grep ocfs2_wq
E. ocfs2dc
root@ocfs2-first:~# ps aux | grep ocfs2dc
root       3657  0.0  0.0      0     0 ?        S    02:08   0:00 [ocfs2dc]
root       3740  0.0  0.0  11824   924 pts/4    S+   02:30   0:00 grep ocfs2dc
root@ocfs2-second:~# ps aux | grep ocfs2dc
root       3642  0.0  0.0      0     0 ?        S    02:09   0:00 [ocfs2dc]
root       3711  0.0  0.0  11824   928 pts/4    S+   02:30   0:00 grep ocfs2dc
F. dlm_thread
root@ocfs2-first:~# ps aux | grep dlm_thread
root       3658  0.0  0.0      0     0 ?        S    02:08   0:00 [dlm_thread]
root       3742  0.0  0.0  11824   932 pts/4    S+   02:31   0:00 grep dlm_thread
root@ocfs2-second:~# ps aux | grep dlm_thread
root       3643  0.0  0.0      0     0 ?        S    02:09   0:00 [dlm_thread]
root       3713  0.0  0.0  11824   932 pts/4    S+   02:31   0:00 grep dlm_thread
G. dlm_reco_thread
root@ocfs2-first:~# ps aux | grep dlm_reco_thread
root       3659  0.0  0.0      0     0 ?        S    02:08   0:00 [dlm_reco_thread]
root       3744  0.0  0.0  11824   932 pts/4    S+   02:32   0:00 grep dlm_reco_thread
root@ocfs2-second:~# ps aux | grep dlm_reco_thread
root       3644  0.0  0.0      0     0 ?        S    02:09   0:00 [dlm_reco_thread]
root       3715  0.0  0.0  11824   928 pts/4    S+   02:32   0:00 grep dlm_reco_thread
H. dlm_wq
root@ocfs2-first:~# ps aux | grep dlm_wq
root       3660  0.0  0.0      0     0 ?        S<   02:08   0:00 [dlm_wq]
root       3749  0.0  0.0  11824   932 pts/4    S+   02:33   0:00 grep dlm_wq
root@ocfs2-second:~# ps aux | grep dlm_wq
root       3645  0.0  0.0      0     0 ?        S<   02:09   0:00 [dlm_wq]
root       3720  0.0  0.0  11824   928 pts/4    S+   02:34   0:00 grep dlm_wq
I. ocfs2cmt
root@ocfs2-first:~# ps aux | grep ocfs2cmt
root       3662  0.0  0.0      0     0 ?        S    02:08   0:00 [ocfs2cmt]
root       3751  0.0  0.0  11824   924 pts/4    S+   02:34   0:00 grep ocfs2cmt
root@ocfs2-second:~# ps aux | grep ocfs2cmt
root       3647  0.0  0.0      0     0 ?        S    02:09   0:00 [ocfs2cmt]
root       3722  0.0  0.0  11824   932 pts/4    S+   02:34   0:00 grep ocfs2cmt