GlusterFS 는 분산 파일 시스템으로써 여러 대의 서버를 클러스터로 구성하여 대용량의 데이터를 분산 저장하고 관리할 수 있는 기술입니다. RAID 와 같이 각각의 노드에 데이터를 따로 저장하거나 (Distributed), 복제 저장하거나 (Replicated), 분산 저장 (Disperse) 이 가능합니다. GlusterFS 는 Redhat 이 개발하고 오픈 소스로 제공되며, 다양한 용도의 분산 스토리지 및 파일 공유에 이용됩니다.
본 매뉴얼에서의 테스트 환경은 CentOS 7 이며, 다양한 볼륨 구성을 예제로 다루었습니다.
CentOS 6 또는 8 버전은 설치 방법에 약간 차이가 있으니 아래 Documents 를 참고해 주세요.
https://wiki.centos.org/SpecialInterestGroup/Storage/gluster-Quickstart
[사전 작업]
각 노드에 추가 Disk 를 연결하고 /data 디렉토리로 마운트 했습니다.
그리고 각 마운트 디렉토리 안에 gv0 이라는 Brick 디렉토리를 생성해 두었습니다.
Brick 디렉터리는 GlusterFS 볼륨에서 데이터를 저장하는 디렉터리를 뜻합니다.
- /data/gv0
1. GlusterFS 서버 구축
1) hostname 설정
호스트 명을 변경합니다.
# hostnamectl set-hostname gnode1 // 1번 노드에서
# hostnamectl set-hostname gnode2 // 2번 노드에서
# hostnamectl set-hostname gnode3 // 3번 노드에서
(모든 노드에서)
호스트를 등록 합니다.
# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain gnode1 192.168.10.20 gnode2 192.168.10.30 gnode3 |
위는 gnode1 의 hosts 내용인데, 자신의 노드는 따로 행을 추가하지 말고 127.0.0.1 라인에 기록해 둡니다.
gnode2, gnode3 노드에서의 hosts 는 각각 다음과 같습니다.
127.0.0.1 localhost localhost.localdomain gnode2 192.168.10.10 gnode1 192.168.10.30 gnode3 |
127.0.0.1 localhost localhost.localdomain gnode3 192.168.10.10 gnode1 192.168.10.20 gnode2 |
2) 패키지 설치
GlusterFS 설치를 위한 Repository 를 등록해줍니다.
등록은 yum 로 간단히 할 수 있습니다.
# yum -y install centos-release-gluster
GlusterFS 패키지를 설치합니다.
# yum -y install glusterfs glusterfs-libs glusterfs-server
서버 부팅시 glusterd 데몬이 자동 구동 되도록 하고, 현재 세션에서도 구동시켜줍니다.
# systemctl enable --now glusterd
설치된 버전을 확인합니다.
# glusterd --version
glusterfs 9.6
Repository revision: git://git.gluster.org/glusterfs.git
Copyright (c) 2006-2016 Red Hat, Inc. <https://www.gluster.org/>
GlusterFS comes with ABSOLUTELY NO WARRANTY.
It is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3
or later), or the GNU General Public License, version 2 (GPLv2),
in all cases as published by the Free Software Foundation.
서버간 통신이 이루어져야 하므로 firewalld 또는 iptables 와 같은 방화벽에서 서로의 IP 를 허용해주거나, 데이터가 없는 테스트 서버일 경우 방화벽을 잠시 내려 테스트 합니다.
2. 복제 (Replica) 볼륨 구성
replica 볼륨은 데이터를 여러 브릭에 복제하여 데이터의 안정성과 내구성을 제공합니다.
RAID 시스템의 1 (mirror) 과 유사합니다. 노드 2대로만 구성하는 것이 아니고 여러대로 복제가 가능합니다.
GlusterFS 에서는 기본 3대 이상으로 구성할 것을 권하고 있으며, 2대로 구성을 원할경우 아래 '8. 판사 (Arbiter) 볼륨 구성' 을 참고하세요.
여기에서는 3대의 노드로 구성해 보겠습니다.
패키지 설치와 호스트네임 등록 이후의 설정은 하나의 노드에서만 합니다.
1) Pool 연결
(gnode1 노드에서)
Cluster Pool 을 구성합니다.
# gluster peer probe gnode2
peer probe: success
# gluster peer probe gnode3
peer probe: success
연결된 노드를 확인합니다.
gnode1 에서 명령 실행시 연결된 두개의 노드 (gnode2, gnode3) 가 보입니다.
# gluster peer status
Number of Peers: 2
Hostname: gnode2
Uuid: edea03f3-472b-47b5-a711-ed06763631c4
State: Peer in Cluster (Connected)
Hostname: gnode3
Uuid: 0771cb09-89d3-4a5b-8e7d-3980473ffc0e
State: Peer in Cluster (Connected)
다른 노드에서도 같은 명령을 사용해보면 자신의 노드를 제외한 총 2개의 노드 정보가 확인됩니다.
참고로 peer 노드 제거 명령은 'gluster peer detach <노드명>' 을 사용합니다.
Pool 리스트를 확인합니다.
# gluster pool list
UUID Hostname State
edea03f3-472b-47b5-a711-ed06763631c4 gnode2 Connected
0771cb09-89d3-4a5b-8e7d-3980473ffc0e gnode3 Connected
25d3f6cb-b2ed-4aa1-add7-0a27890ed5ed localhost Connected
이 명령에서는 자신의 노드를 포함한 총 3개의 노드 정보가 확인됩니다.
2) 볼륨 생성
데이터를 저장할 수 있도록 GlusterFS 볼륨을 생성합니다.
(gnode1 노드에서)
3대의 노드를 하나의 볼륨으로 묶습니다. (볼륨명 : gv0, 복제본 : 3)
# gluster volume create gv0 replica 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data
여기에서 volume create: gv0: failed: /data/gv0 is already part of a volume 에러가 출력되는 분은 아래 '5. 볼륨 재구성' 을 참고하세요.
노드 서버 3대로 복제 저장 구성을 한 이유는 2대로만 복제 구성하면 스플릿 브레인에 취약할 수 있기 때문입니다. 스플릿 브레인은 분산 파일 시스템에서 복제된 데이터의 일관성을 유지하기 위해 중요한 개념입니다. 복제된 볼륨이 스플릿 브레인에 취약하다는 것은 데이터의 불일치가 발생할 수 있는 가능성이 있다는 것을 의미합니다. 복제 2 볼륨은 두 개의 복제본을 가지고 있으므로 데이터의 일관성을 유지하기 위해 두 복제본이 동기화되어야 합니다. 그러나 네트워크 문제, 장애 등의 이유로 복제본 간의 통신이 중단되면 각각의 복제본이 독립적으로 운영되는 상황이 발생할 수 있습니다. 이는 데이터의 일관성을 해치는 스플릿 브레인 상태를 초래할 수 있습니다.
gv0 볼륨을 시작합니다.
# gluster volume start gv0
volume start: gv0: success
gv0 볼륨 상태를 확인합니다.
# gluster volume info gv0
Volume Name: gv0
Type: Replicate
Volume ID: 09540703-2a84-4dce-bb6c-af156cf1813d
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
* 중요 : 볼륨 생성 후 옵션을 하나 설정합니다.
볼륨 구성이 어떠한 형태이던 (비록 replica 일지라도) GlusterFS Cluster 를 구성하는 한 개의 peer 가 장애가 났을때 Client 는 42초간 (default) GlusterFS 의 응답을 기다리느라 데이터를 읽거나 쓰지 못하게 됩니다. 서비스 제공시 42초는 긴 시간이기 때문에 장애 서버의 다운을 감지하고 해당 peer 를 빠르게 제거하기 위한 옵션 network.ping-timeout 을 설정해 주어야 합니다.
여기에서는 서버 응답 대기시간을 0초로 적용합니다. 이렇게 하면 peer 다운시 찰나의 지연 (delay) 이 있지만 끊어지지 않으며 데이터 유실또한 발생하지 않습니다.
# gluster volume set gv0 network.ping-timeout 0
volume set: success
# gluster volume info | grep timeout
network.ping-timeout: 0
추후 장애 peer 복구시 파티션 (Brick Directory) 연결 및 glusterd 데몬이 순자적으로 이루어진다면, 다른 peer 에서 생성, 변경된 파일이 자동으로 동기화되어 최신 데이터를 유지하게 됩니다.
사용가능한 옵션 종류는 아래 URL 에서 확인 가능합니다.
https://access.redhat.com/documentation/ko-kr/red_hat_gluster_storage/3.5/html/administration_guide/volume_option_table
* 데이터 저장 형태
데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.
- 파일을 저장하면 replica 3 으로 구성된 gnode1, gnode2, gnode3 노드에 동일한 데이터 저장
3. Quota 설정
Brick 디렉토리에 하위 디렉토리를 생성하여 용량을 제한을 할 수 있습니다.
공식 Document : https://docs.gluster.org/en/v3/Administrator%20Guide/Directory%20Quota/
gv0 볼륨 쿼터 설정을 활성화 합니다.
# gluster volume quota gv0 enable
volume quota : success
참고로 비활성화는 enable 대신 disable 을 입력합니다.
그리고 Client 가 마운트하여 사용하던 중 쿼터 제한을 걸때 사용하는 옵션이 있는데 이에 대한 설명은 아래와 같습니다. (Default : on)
# gluster volume set gv0 quota-deem-statfs on
* 참고
- on: GlusterFS는 디렉토리의 용량 제한을 강제로 적용하고, 해당 디렉토리에서 사용 가능한 실제 용량을 디렉토리의 용량 제한으로 간주합니다. 즉, 사용자가 설정한 용량 제한보다 실제 사용 중인 용량이 크더라도 GlusterFS는 해당 디렉토리의 용량 제한을 적용합니다. 이는 사용자가 실제 사용 중인 용량을 고려하지 않고 일관된 용량 제한을 유지하고자 할 때 유용합니다.
(예 : 2GB 데이터 사용중에 쿼터를 1GB 로 제한하면, 제한값은 1GB 에 머물러 있음)
- off: GlusterFS는 디렉토리의 용량 제한을 강제로 적용하지 않고, 실제 사용 중인 용량을 기준으로 디렉토리의 용량 제한을 판단합니다. 즉, 사용자가 설정한 용량 제한보다 실제 사용 중인 용량이 크다면 GlusterFS는 해당 디렉토리의 용량 제한을 초과로 간주합니다. 이는 실제 사용 중인 용량을 기준으로 용량 제한을 적용하고자 할 때 유용합니다.
(예 : 2GB 데이터 사용중에 쿼터를 1GB 로 제한하면, 제한값은 2GB 에 머물러 있음)
하위 디렉토리를 그냥 만들면 mkdir 명령을 내린 노드에서만 디렉토리가 생성되기때문에 쿼터 적용이 되지 않습니다.
볼륨을 마운트하고 디렉토리를 만들어 놓아야 합니다.
Client 또는 아무 node 에서나 마운트 명령을 내려도 상관없습니다.
# mkdir /imsi
# mount -t glusterfs gnode1:/gv0 /imsi
# mkdir /imsi/{apple,banana,grape}
# umount /imsi
하위 디렉토리에 각 1G 씩 용량 제한을 합니다.
디렉토리를 지정할때는 Brick 디렉토리 (/data/gv0) 를 제외하고 하위 디렉토리만 입력합니다.
# gluster volume quota gv0 limit-usage /apple 1GB
volume quota : success
# gluster volume quota gv0 limit-usage /banana 1GB
volume quota : success
# gluster volume quota gv0 limit-usage /grape 1GB
volume quota : success
gv0 볼륨의 쿼터 설정값을 확인합니다.
# gluster volume quota gv0 list
Path Hard-limit Soft-limit Used Available Soft-limit exceeded? Hard-limit exceeded?
-------------------------------------------------------------------------------------------------------------------------------
/apple 1.0GB 80%(819.2MB) 0Bytes 1.0GB No No
/banana 1.0GB 80%(819.2MB) 0Bytes 1.0GB No No
/grape 1.0GB 80%(819.2MB) 0Bytes 1.0GB No No
Hard-limit 는 1GB 로 원하는 용량이 제한 되었지만, Soft-limit 는 80% 선으로 설정된 것이 보입니다.
- Hard-limit : 사용자 또는 프로세스가 설정된 최대 제한을 초과하지 못하도록 하는 제한하는 값입니다.
- Soft-limit : 사용자 또는 프로세스가 현재 사용 중인 리소스의 제한으로, 사용자가 시스템 리소스를 임시로 초과할 수 있는 한계를 설정합니다. Soft-limit은 Hard-limit 보다 작거나 같아야 합니다. Soft-limit 을 초과하려는 경우에는 경고가 발생하지만 작업을 계속할 수 있습니다. 시스템의 안정성을 고려하기 위해 용량이 거의 채워져간다는 알림을 주기 위한 용도 정도로 보면 됩니다.
Soft-limit 도 100% 까지 사용하기 위해 아래와 같이 변경 설정 해줍니다.
# gluster volume quota gv0 limit-usage /apple 1GB 100
volume quota : success
# gluster volume quota gv0 limit-usage /banana 1GB 100
volume quota : success
# gluster volume quota gv0 limit-usage /grape 1GB 100
volume quota : success
변경 내용을 확인합니다.
# gluster volume quota gv0 list
Path Hard-limit Soft-limit Used Available Soft-limit exceeded? Hard-limit exceeded?
-------------------------------------------------------------------------------------------------------------------------------
/apple 1.0GB 100%(1.0GB) 0Bytes 1.0GB No No
/banana 1.0GB 100%(1.0GB) 0Bytes 1.0GB No No
/grape 1.0GB 100%(1.0GB) 0Bytes 1.0GB No No
4. Client 마운트
GlusterFS 에서는 몇가지 마운트 방법을 제공합니다. GlusterFS (FUSE), NFS, iSCSI, SMB 방식인데 여기에서는 일반적인 FUSE 방식을 설명하겠습니다.
Client 에서 마운트에 필요한 패키지를 설치하고 마운트를 합니다.
GlusterFS 서버를 찾을 수 있도록 도메인을 연결하면 좋겠지만 현재 테스트 환경에서는 hosts 파일을 이용하였으므로 Client 에서도 찾을 수 있도록 /etc/hosts 파일에 아래 내용을 작성해 줍니다.
# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain 192.168.10.10 gnode1 192.168.10.20 gnode2 192.168.10.30 gnode3 |
그리고 마운트 할때는 gnode1 부터 gnode3 까지 아무 서버로 연결해도 상관없습니다.
# yum -y install glusterfs-client
# mkdir /backup
# mount -t glusterfs gnode1:/gv0 /backup
또는 쿼터 적용된 디렉토리로 마운트가 가능합니다.
# mount -t glusterfs gnode1:/gv0/apple /backup
마운트 디렉토리에 파일을 쓰면 모든 노드에 동일하게 복제되어 저장됩니다.
-------------------- 여기부터 다양한 스토리지 구성 테스트 --------------------
5. 볼륨 재구성 (볼륨 완전 삭제, 재생성)
볼륨을 삭제하고 다시 구성할때 에러가 발생하는데 어떻게 해결하는지 알아봅니다.
볼륨을 중지해야 삭제가 가능하기 때문에 먼저 중지 명령을 내립니다.
# gluster volume stop gv0
Stopping volume will make its data inaccessible. Do you want to continue? (y/n) y
volume stop: gv0: success
볼륨을 삭제합니다.
# gluster volume delete gv0
Deleting volume will erase all information about the volume. Do you want to continue? (y/n) y
volume delete: gv0: success
이 상태에서 동일한 디렉토리로 볼륨 설정을 하면 아래와 같이 에러가 발생합니다.
# gluster volume create gv0 replica 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: failed: /data/gv0 is already part of a volume
이는 볼륨을 생성하려는 디렉토리에 메타데이터가 있거나 구성의 흔적 때문인데, 해결책은 아래와 같습니다.
(모든 노드에서 : 볼륨 구성했던 이력이 있는 모든 서버)
# setfattr -x trusted.glusterfs.volume-id /data/gv0
# setfattr -x trusted.gfid /data/gv0
# rm -rf /data/gv0/.glusterfs*
그리고 하나의 노드에서 아래와 같이 명령을 내리면 볼륨이 정상적으로 생성됩니다.
# gluster volume create gv0 replica 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data
6. 장애 노드 (peer) 교체
replica 3 (peer 3개) 으로 구성된 cluster 에서 1개의 노드 (peer) 가 장애나면 2개의 peer 에서 무정지로 서비스가 가능합니다. 이때 장애난 peer 를 새로운 서버로 변경한다고 했을때 cluster 를 재구성 하는 방법 입니다.
gnode1, gnode2, gnode3 중에서 gnode2 가 장애 났다고 가정합니다.
사전작업으로 gnode2 노드에 추가 Disk 를 연결하고 /data 디렉토리로 마운트 했습니다.
그리고 마운트 디렉토리 안에 gv0 이라는 Brick 디렉토리를 생성해 두었습니다..
- /data/gv0
(gnode1 또는 gnode3 에서)
remove-brick 명령을 이용해 장애난 peer 를 replica cluster 에서 제외합니다. (replica 3 -> 2)
# gluster volume remove-brick gv0 replica 2 gnode2:/data/gv0 force
Remove-brick force will not migrate files from the removed bricks, so they will no longer be available on the volume.
Do you want to continue? (y/n) y
volume remove-brick commit force: success
peer 목록에서 제외합니다.
# gluster peer detach gnode2
All clients mounted through the peer which is getting detached need to be remounted using one of the other active peers in the trusted storage pool to ensure client gets notification on any changes done on the gluster configuration and if the same has been done do you want to proceed? (y/n) y
peer detach: success
볼륨 정보를 확인합니다.
# gluster volume info
Volume Name: gv0
Type: Replicate
Volume ID: 8e2fbb51-5f00-43f3-9d09-0655cac39dfb
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode3:/data/gv0
Options Reconfigured:
performance.client-io-threads: off
nfs.disable: on
transport.address-family: inet
storage.fips-mode-rchecksum: on
cluster.granular-entry-heal: on
network.ping-timeout: 0
gnode2 라는 peer 가 cluster 에서 제거된 것이 확인되었습니다.
다시 peer 를 추가 하고 replica 3 으로 재설정하여 데이터를 동기화 합니다.
# gluster peer probe gnode2
peer probe: success
add-brick 명령으로 새로운 노드 하나만 기입하여 replica 3 으로 재구성 합니다.
# gluster volume add-brick gv0 replica 3 gnode2:/data/gv0
volume add-brick: success
이렇게 작업은 마무리 되었습니다.
참고로 success 메세지가 출력되어도 데이터가 동기화 되는 것에는 시간이 걸리므로 상태를 잘 지켜보시기 바랍니다.
7. 복제 (Replica) 볼륨 확장
1) Replica 증설 및 축소
3개의 노드가 replica 3 으로 구성된 상태에서 노드를 한대 더 추가하여 replica 4 로 구성해보겠습니다. (replica 3 -> 4)
먼저 추가되는 노드 (gnode4) 에서 사전 작업을 해주세요.
- 추가디스크 mount (/data) 및 디렉토리 생성 (/data/gv0)
- hostname 및 hosts 설정 (기존 노드 포함)
- glusterfs 패키지 설치 및 가동
기존 노드 서버에서 피어를 추가하고 재구성 명령을 실행합니다.
# gluster peer probe gnode4
peer probe: success
# gluster volume add-brick gv0 replica 4 gnode4:/data/gv0
volume add-brick: success
볼륨 정보를 출력합니다.
# gluster volume info
Volume Name: gv0
Type: Replicate
Volume ID: 63328573-90cc-4272-8094-9fd7b9d74821
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 4 = 4
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Brick4: gnode4:/data/gv0
Options Reconfigured:
features.quota-deem-statfs: on
features.inode-quota: on
features.quota: on
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
추가했던 노드를 제거하는 방법은 다음과 같습니다. (replica 4 -> 3)
# gluster volume remove-brick gv0 replica 3 gnode4:/data/gv0 force
Remove-brick force will not migrate files from the removed bricks, so they will no longer be available on the volume.
Do you want to continue? (y/n) y
volume remove-brick commit force: success
# gluster peer detach gnode4
All clients mounted through the peer which is getting detached need to be remounted using one of the other active peers in the trusted storage pool to ensure client gets notification on any changes done on the gluster configuration and if the same has been done do you want to proceed? (y/n) y
peer detach: success
볼륨 정보를 확인합니다.
# gluster volume info
Volume Name: gv0
Type: Replicate
Volume ID: 63328573-90cc-4272-8094-9fd7b9d74821
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
features.quota-deem-statfs: on
features.inode-quota: on
features.quota: on
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
2) Replica 용량 증설
replica 3 은 복제본이 3개 있다는 뜻이므로 데이터 안정성을 어느정도 확보 했다고 볼 수 있습니다. 하지만 노드의 용량이 줄어들 경우에는 또다른 노드를 마련해서 데이터 저장 공간을 확보해야 하는데요. 추가할 노드 수는 복제본 수의 배수여야 합니다. (예: replica 3 의 볼륨 확장시 3의 배수인 6, 9, 12, ... 의 개수로만 추가 가능)
추가된 노드를 GlusterFS 클러스터에 포함 시키는 방법은 아래와 같습니다.
먼저 추가되는 노드 (gnode4, gnode5, gnode6) 에서 사전 작업을 해주세요.
- 추가디스크 mount (/data) 및 디렉토리 생성 (/data/gv0)
- hostname 및 hosts 설정 (기존 노드 포함)
- glusterfs 패키지 설치 및 가동
그리고 기존 노드에서 peer 를 추가합니다.
# gluster peer probe gnode4
# gluster peer probe gnode5
# gluster peer probe gnode6
볼륨 상태를 출력하여 추가된 노드를 확인합니다.
# gluster volume status
Status of volume: gv0
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick gnode1:/data/gv0 49152 0 Y 11850
Brick gnode2:/data/gv0 49152 0 Y 9917
Brick gnode3:/data/gv0 49152 0 Y 29859
Self-heal Daemon on localhost N/A N/A Y 12991
Quota Daemon on localhost N/A N/A Y 13185
Self-heal Daemon on gnode2 N/A N/A Y 10432
Quota Daemon on gnode2 N/A N/A Y 10537
Self-heal Daemon on gnode5 N/A N/A Y 9175
Quota Daemon on gnode5 N/A N/A Y 9186
Self-heal Daemon on gnode6 N/A N/A Y 9173
Quota Daemon on gnode6 N/A N/A Y 9184
Self-heal Daemon on gnode4 N/A N/A Y 6471
Quota Daemon on gnode4 N/A N/A Y 6483
Self-heal Daemon on gnode3 N/A N/A Y 30817
Quota Daemon on gnode3 N/A N/A Y 30979
Task Status of Volume gv0
------------------------------------------------------------------------------
There are no active volume tasks
위에서 노드가 추가되었지만 아직 Brick 사용 상태는 아닌것으로 확인됩니다.
추가한 노드에도 데이터가 쓰여질 수 있도록 볼륨을 확장해야 합니다.
이를 위해 gluster volume add-brick 명령을 사용합니다.
볼륨명과 replica 구성은 그대로 하고, 추가할 노드만 적어주면 됩니다.
# gluster volume add-brick gv0 replica 3 gnode4:/data/gv0 gnode5:/data/gv0 gnode6:/data/gv0
volume add-brick: success
볼륨 상태를 확인합니다.
# gluster volume info
Volume Name: gv0
Type: Distributed-Replicate
Volume ID: 24463284-fb20-4d4b-9d13-0b891c2f892f
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x 3 = 6
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Brick4: gnode4:/data/gv0
Brick5: gnode5:/data/gv0
Brick6: gnode6:/data/gv0
Options Reconfigured:
features.quota-deem-statfs: on
features.inode-quota: on
features.quota: on
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
'replica 3 구성이 2세트로, 총 6개의 brick 이 구성되어 있다' 라는 뜻인데 아래와 같이 Brick 상태를 보면 추가된 brick 3개는 아직 활성화되지 않은 것으로 출력됩니다.
# gluster volume status |grep Brick
Brick gnode1:/data/gv0 49152 0 Y 30890
Brick gnode2:/data/gv0 49152 0 Y 23376
Brick gnode3:/data/gv0 49152 0 Y 16274
Brick gnode4:/data/gv0 N/A N/A N N/A
Brick gnode5:/data/gv0 N/A N/A N N/A
Brick gnode6:/data/gv0 N/A N/A N N/A
볼륨을 확장 (add-brick) 하거나 축소 (remove-brick) 할 때는 서버 간에 데이터 균형을 재조정해야 하는데, 이때 필요한 패키지가 glusterfs-geo-replication 입니다. 데이터 균형을 맞추기 전에 패키지 설치를 해야합니다.
# yum -y install glusterfs-geo-replication
rebalance 명령으로 데이터 균형 작업을 진행합니다.
# gluster volume rebalance gv0 start
volume rebalance: gv0: success: Rebalance on gv0 has been started successfully. Use rebalance status command to check status of the rebalance process.
ID: df6c2123-04d7-4b45-9311-e05430db6cac
rebalance 상태는 다음 명령으로 확인할 수 있습니다.
status 항목에 모든 작업이 completed 된것과 volume rebalance 작업이 성공되었다는 메세지를 확인할 수 있습니다.
# gluster volume rebalance gv0 status
Node Rebalanced-files size scanned failures skipped status run time in h:m:s
--------- ----------- ----------- ----------- ----------- ----------- ------------ --------------
gnode2 0 0Bytes 2 0 0 completed 0:00:00
gnode3 0 0Bytes 2 0 0 completed 0:00:00
gnode4 0 0Bytes 0 0 0 completed 0:00:00
gnode5 0 0Bytes 1 0 0 completed 0:00:00
gnode6 0 0Bytes 1 0 0 completed 0:00:00
localhost 0 0Bytes 2 0 0 completed 0:00:00
volume rebalance: gv0: success
Client 에서는 마운트 되어 있던 GlusterFS 파티션 가용 공간이 자동으로 두 배 늘어난 것이 확인됩니다.
(용량 확장 전)
# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 889M 0 889M 0% /dev
tmpfs 907M 84K 907M 1% /dev/shm
tmpfs 907M 97M 810M 11% /run
tmpfs 907M 0 907M 0% /sys/fs/cgroup
/dev/vda1 25G 17G 9.0G 65% /
tmpfs 182M 0 182M 0% /run/user/0
gnode1:/gv0 10G 135M 9.9G 2% /backup
(용량 확장 후)
# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 889M 0 889M 0% /dev
tmpfs 907M 84K 907M 1% /dev/shm
tmpfs 907M 97M 810M 11% /run
tmpfs 907M 0 907M 0% /sys/fs/cgroup
/dev/vda1 25G 17G 9.0G 65% /
tmpfs 182M 0 182M 0% /run/user/0
gnode1:/gv0 20G 270M 20G 2% /backup
* 데이터 저장 형태
데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.
- 파일을 저장하면 처음 replica 3 으로 구성된 gnode1, gnode2, gnode3 노드에 데이터 저장
- 추가 파일을 저장하면 나중 replica 3 으로 구성된 gnode4, gnode5, gnode6 노드에 데이터 저장
- 디렉토리는 모든 노드에서 생성
- Client 에서는 모든 노드의 데이터가 합쳐져 보임
즉, gnode1 (또는 gnode2 또는 gnode3) 의 데이터와 gnode4 (또는 gnode5 또는 gnode6) 의 데이터를 합치면 온전한 사용자 데이터가 된다는 것을 확인하였습니다.
3) Replica 구성 및 볼륨 제거
볼륨을 제거하면 구성 방식 (replica, stripe 등) 정보가 같이 삭제 됩니다.
우선 마운트 되어있는 Client 에서 모두 unmount 하여 스토리지를 분리합니다.
# umount /backup
운영중인 볼륨을 중지합니다.
# gluster volume stop gv0
Stopping volume will make its data inaccessible. Do you want to continue? (y/n) y
volume stop: gv0: success
볼륨을 삭제 합니다.
gluster volume delete gv0
Deleting volume will erase all information about the volume. Do you want to continue? (y/n) y
volume delete: gv0: success
아직 테스트하던 peer 는 연결되어진 상태입니다. 볼륨을 재구성 할 예정이므로 peer 연결 해제 및 데이터 삭제 방법만 알아두고 넘어가기로 합니다.
* 노드 분리 방법
# gluster peer detach <노드 이름>
* 데이터 삭제 (각 노드에서 실행)
# setfattr -x trusted.glusterfs.volume-id /data/gv0
# setfattr -x trusted.gfid /data/gv0
# rm -rf /data/gv0/.glusterfs*
8. 분산 (Disperse) 볼륨 구성 - with Parity peer
disperse 볼륨은 데이터와 패리티를 사용하여 데이터를 분산 저장하고, 손상된 브릭의 데이터를 복구할 수 있는 내구성을 제공합니다.
RAID 시스템의 5 구성과 매우 유사한 기능을 제공하고 있어서 파일을 쓸 경우 모든 Brick 에 동시 분산 저장이 되기 때문에 파일 I/O 속도가 빠르며 peer 한 대가 다운되어도 나머지 peer 에서 데이터 조합이 가능하기 때문에 무정지 서비스가 가능합니다. 하지만 peer 두 대 이상이 다운될 경우 Client 에서는 모든 데이터를 읽지 못하게 됩니다.
그럼 disperse 형식으로 볼륨을 생성해 보겠습니다.
먼저 gnode1 노드에서 peer 를 추가 합니다.
# gluster peer probe gnode2
# gluster peer probe gnode3
볼륨을 생성합니다.
# gluster volume create gv0 disperse 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data
disperse 3 옵션은 3개의 노드 (peer) 로 분산 저장 구성한다는 의미입니다. 결국 2개의 데이터 peer 와 1개의 패리티 peer 로 자동 구성됩니다.
생성한 볼륨을 시작합니다.
# gluster volume start gv0
volume start: gv0: success
볼륨에 서버 응답 대기시간을 0초로 적용합니다.
# gluster volume set gv0 network.ping-timeout 0
volume set: success
볼륨 정보를 확인합니다.
# gluster volume info
Volume Name: gv0
Type: Disperse
Volume ID: fb35eca2-9c54-4768-9ea9-eb27c0fd223d
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
network.ping-timeout: 0
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
여기에서 'Number of Bricks: 1 x (2 + 1) = 3' 를 볼 수 있는데, 위에서 설명한대로 (2 + 1) 은 2개의 데이터 Brick 과 1개의 Parity Brick 으로 구성되어 있음을 나타냅니다. 앞에 1 x 는 '이런 세트가 하나있다' 라고 이해하시면 됩니다.
Parity Brick 은 데이터 안정성을 위해 자동 생성되는 Brick 으로, 구성하는 서버 수량에 따라 아래와 같이 자동 할당 됩니다. 그리고 각각의 Brick 이 10GB 의 용량을 가지고 있을때 사용가능한 최종 데이터 저장 용량은 아래와 같습니다.
- 노드가 2개 일때 : 구성 불가. 최소한 3대가 필요합니다.
- 노드가 3개 일때 : 1 x (2 + 1) = 3 # 총 20GB
- 노드가 4개 일때 : 1 x (3 + 1) = 4 # 총 30GB
- 노드가 5개 일때 : 1 x (4 + 1) = 5 # 총 40GB
특이사항으로, 4대로 구성할때만 아래와 같은 메세지가 출력됩니다.
There isn't an optimal redundancy value for this configuration. Do you want to create the volume with redundancy 1 ? (y/n) y
* 데이터 저장 형태
데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.
- 데이터 노드 (peer) 에 나뉘어져 저장
> 데이터 노드가 2대 일때 : 10MB 파일 저장시 gnode1 에 5M, gnode2 에 5M 저장
> 데이터 노드가 3대 일때 : 10MB 파일 저장시 gnode1 에 3.4M, gnode2 에 3.4M, gnode3 에 3.4M 저장
- 1대의 데이터 peer 에 저장되는 용량만큼 Parity Peer 에 저장
- 디렉토리는 모든 노드에서 생성
- 데이터 peer 에 생성되는 용량은 512 byte 단위로 생성됌
> 이용자가 10 byte 텍스트 파일을 생성하더라도 데이터 peer 마다 512 byte 크기의 파일이 생성
> 데이터 peer 가 2대 일때, 이용자가 1000 byte 파일을 생성한다면 각 peer 마다 512 byte 크기의 파일이, 이용자가 1200 byte 파일을 생성하면 각 peer 마다 1024 byte 크기의 파일이 생성 됌.
- peer 1대 장애 : Client 에서 데이터 및 서비스 유지 가능
- peer 2대 장애 : Client 에서 '입력/출력 오류' 상태로 빠짐. 추후 서버가 부팅되어 peer 파티션이 연결되고 glusterd 데몬이 구동되면 자동 연결 됌
참고로 disperse 볼륨에서는 패리티 파편을 명시적으로 지정하지 않습니다. GlusterFS 에서는 disperse 볼륨에 대한 패리티 파편의 위치를 추적하지 않습니다. 대신, disperse 볼륨은 데이터와 패리티를 조합하여 고유한 분산 방식으로 데이터를 보관합니다. 따라서, disperse 볼륨에서는 특정 peer 가 패리티 peer 인지를 명확하게 알 수 없습니다. 데이터와 패리티 파편은 모든 peer 에 균등하게 분산되므로 각 peer 는 동시에 데이터와 패리티를 저장합니다.
9. 판사 (Arbiter) 볼륨 구성
Arbiter 는 GlusterFS 의 Replica 구성에서 사용되는 옵션 중 하나입니다. Replica 구성은 데이터를 여러 Brick 에 복제하여 내구성과 가용성을 제공하는 방식입니다. 일반적으로 Replica 구성은 세 개의 복제 Brick 을 사용하지만, Arbiter 를 사용하면 세 번째 복제 Brick 대신에 판사 (Arbiter) Brick 을 사용합니다.
Arbiter 의 역할은 데이터의 복제를 수행하는 것이 아니라 복제 집합의 일부로서 데이터의 일관성을 유지하는 역할을 합니다. 각 복제 Brick 은 데이터를 가지고 있지만, 판사 Brick 은 실제 데이터를 저장하지 않고, 오로지 복제 그룹 내의 데이터 일관성을 확인하는 역할을 수행합니다. 따라서 Arbiter 를 사용하면 세 번째 Brick 으로 저장할 데이터 용량을 절약할 수 있습니다.
Arbiter 를 사용하는 Replica 구성은 데이터의 내구성과 가용성을 유지하면서 용량 효율성을 개선할 수 있습니다. 예를 들어, 10GB 의 데이터를 저장해야 할 때, 일반적인 Replica 구성은 3개의 10GB Brick 을 필요로 합니다. 그러나 Arbiter 를 사용하는 Replica 구성에서는 2개의 10GB Brick 과 1개의 Arbiter Brick 만으로도 같은 수준의 내구성을 제공할 수 있습니다. (Replica 2 를 구성하는 2개의 Brick 에 데이터 차이가 있어도 Arbiter 때문에 어떤게 최신 peer 인지 구분 가능)
gnode1 노드에서 peer 를 추가 합니다.
# gluster peer probe gnode2
# gluster peer probe gnode3
Arbiter 볼륨을 생성합니다.
# gluster volume create gv0 replica 2 arbiter 1 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data
볼륨을 시작합니다.
# gluster volume start gv0
volume start: gv0: success
볼륨에 서버 응답 대기시간을 0초로 적용합니다.
# gluster volume set gv0 network.ping-timeout 0
volume set: success
볼륨 정보를 확인합니다.
# gluster volume info
Volume Name: gv0
Type: Replicate
Volume ID: 2b88b6dd-c50d-4752-96fd-7acb98ce0d53
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0 (arbiter)
Options Reconfigured:
network.ping-timeout: 0
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
2대의 Replica 서버와 1대의 Arbiter 서버가 구성 되었습니다.
각 peer 가 10GB 일때, Client 에서 사용 가능한 최대 용량은 10G 입니다.
* 데이터 저장 형태
데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.
- 10MB 파일 저장시 gnode1, gnode2 에 각각 10MB 파일 생성되고 gnode3 에는 0 Byte 의 파일 생성
- 디렉토리는 모든 노드에서 생성
- peer 1대 장애 : Client 에서 데이터 및 서비스 유지 가능
- peer 2대 장애 : Client 에서 '전송 종료지점이 연결되어 있지 않습니다' 상태로 빠짐. 추후 다운되었던 Replica 서버 또는 Arbiter 서버가 1대라도 부팅되어 peer 파티션이 연결되고 glusterd 데몬이 구동되면 자동 연결 됌
10. 통합 (Distributed) 볼륨 구성
Distributed 는 GlusterFS 의 기본 볼륨 구성값으로써 모든 peer 의 용량을 합하여 제공되는 방식입니다. disperse 볼륨과 같이 다량의 peer 에 동시에 데이터를 읽고 쓸 수 있는 구성이 아닌, 단순히 용량만 합하여 제공하기 때문에 peer 에 순차적으로 데이터를 저장하는 특징을 보입니다. 모든 peer 에 동시에 데이터를 읽고 쓰지 않으므로 속도가 disperse 보다 빠르지 않으며 parity peer 도 없기 때문에 하나의 peer 가 다운될 경우 데이터를 읽거나 쓰지 못하는 상황이 발생되며, peer 의 서버 대수가 많이 늘어날 수록 장애가 발생할 확률도 높아지게 됩니다.
distributed 볼륨 구성을 위해 gnode1 노드에서 peer 를 추가 합니다.
# gluster peer probe gnode2
중간에 아무런 옵션을 주지 않으면 기본 Distributed 상태로 볼륨이 생성됩니다.
# gluster volume create gv0 gnode1:/data/gv0 gnode2:/data/gv0
volume create: gv0: success: please start the volume to access data
볼륨을 시작합니다.
# gluster volume start gv0
volume start: gv0: success
볼륨에 서버 응답 대기시간을 0초로 적용합니다.
# gluster volume set gv0 network.ping-timeout 0
volume set: success
볼륨 정보를 확인합니다.
# gluster volume info
Volume Name: gv0
Type: Distribute
Volume ID: 77a483c0-479e-4237-91af-aa76058a3f2d
Status: Started
Snapshot Count: 0
Number of Bricks: 2
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Options Reconfigured:
network.ping-timeout: 0
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
2대의 Brick 이 Distribute 로 구성 되었습니다.
각 peer 가 10GB 일때, Client 에서 사용 가능한 최대 용량은 20G 입니다.
* 데이터 저장 형태
데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.
- gnode1 로 마운트하고 파일 저장시 gnode1 노드에 생성되고 계속 저장시 gnode1 노드 용량 (10GB) 까지만 저장 가능
- gnode2 로 마운트하고 파일 저장시 gnode2 노드에 생성되고 계속 저장시 gnode2 노드 용량 (10GB) 까지만 저장 가능
- Client 에서는 20GB 용량으로 보이고 gnode1, gnode2 에 저장된 데이터가 모두 보임
- 디렉토리는 모든 노드에서 생성
- peer 1대 장애 : 장애난 peer 의 데이터는 보이지 않고 남아있는 peer 내의 데이터만 보임. 추후 서버가 부팅되어 peer 파티션이 연결되고 glusterd 데몬이 구동되면 모든 파일들이 잘 보이게 됌
11. NFS 서비스 제공하기 (with NFS-Ganesha) --- 작성중
GlusterFS 를 일반적인 fuse 형식이 아닌 NFS 형식으로 마운트 할 수 있게 기능을 제공합니다.
볼륨 정보를 보면 아래와 같은 nfs 기본 옵션이 출력됩니다.
# gluster volume info
Volume Name: gv0
Type: Replicate
Volume ID: 563a8023-dc1c-4b2d-a86c-af8dcf21c5da
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
여기에서 NFS 를 사용하지 않는 옵션이 켜져 (on) 있습니다. 이것을 off 하고 몇가지 설정을 더 하면, GlusterFS 에서 제공하는 NFS 서버를 사용할 수 있습니다. 하지만 GlusterFS 에서 제공하는 NFS 서버 방식은 NFSv3 이고, 요새는 NFSv4 를 지원하는 NFS-Ganesha 가 별도 배포되고 있습니다. NFS-Ganesha 는 GlusterFS 와의 통합을 용이하게 하기 위해 개발된 것으로 기존의 GlusterFS NFS 서버 대신 NFS-Ganesha 를 사용하면 GlusterFS 와 NFS 간의 상호 운용성이 향상되고 다양한 기능과 유연성을 제공할 수 있습니다.
- 다양한 NFS 버전 지원 : NFSv3, NFSv4, NFSv4.1 및 NFSv4.2 를 지원하므로 다양한 클라이언트와의 상호 운용성이 높아집니다.
- 고급 기능 : 파일 시스템 관리, 보안, 액세스 제어, 성능 튜닝 등의 고급 기능을 제공합니다.
- 확장성 : 다중 프로토콜 지원, 클러스터링, 로드 밸런싱 등의 기능을 통해 GlusterFS 클러스터의 확장성을 향상시킵니다.
- 유연한 구성 : 다양한 구성 옵션과 플러그인 아키텍처를 제공하여 사용자의 요구에 맞게 유연하게 구성할 수 있습니다.
이러한 이유로 NFS-Ganesha 를 이용해 GlusterFS 의 NFS 서비스를 구성해 보겠습니다.
1) 설치
(모든 노드에서)
# yum -y install centos-release-nfs-ganesha30
# sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/CentOS-NFS-Ganesha-30.repo
# yum --enablerepo=centos-nfs-ganesha30 -y install nfs-ganesha-gluster
기본 설정 파일은 별도로 백업해놓고 새로운 설정을 추가 합니다.
# mv /etc/ganesha/ganesha.conf /etc/ganesha/ganesha.conf.ori
# vi /etc/ganesha/ganesha.conf
NFS_CORE_PARAM { mount_path_pseudo = true; # 가상 경로 사용 여부 Protocols = 4; # 제공할 NFS 프로토콜 버전 } EXPORT_DEFAULTS { Squash = "No_root_squash"; # Client 가 root 면 root 권한으로 파일 액세스 가능하도록 FSAL { name = GLUSTER; # 이름 hostname = "gnode1"; # 현재 노드의 호스트명 또는 IP 주소 volume = "gv0"; # GlusterFS 볼륨명 } } EXPORT { Export_Id = 1; # Client 식별자 : uniq ID (No) Path = "/data/gv0"; # GlusterFS 볼륨 마운트 경로 (여기에서는 최상위 디렉토리 제한) Pseudo = "/gv0"; # 가상 경로 (마운트할때 명시되는 이름) Access_Type = None; # 접근 형식 (None : 접근불가, RO : 읽기전용, RW : 읽고쓰기) } EXPORT { Export_Id = 2; Path = "/data/gv0/apple"; Pseudo = "/apple"; Access_Type = RW; } LOG { Default_Log_Level = WARN; # 기본 로그 레벨 } |
데몬 부팅 설정과 함께 데몬을 시작합니다.
# systemctl enable --now nfs-ganesha
서비스 포트 열린것이 확인되었습니다.
# netstat -nltp |grep ganesha
tcp6 0 0 :::875 :::* LISTEN 18997/ganesha.nfsd
tcp6 0 0 :::2049 :::* LISTEN 18997/ganesha.nfsd
2) Client 에서 마운트하기
마운트 하려는 디렉토리를 생성합니다.
# mkdir /backup
볼륨 전체는 마운트가 안되고,
# mount -t nfs gnode1:/gv0 /backup
하위 디렉토리는 마운트 가능합니다.
# mount -t nfs gnode1:/gv0/apple /backup