ZFS 기반의 NAS/SAN 스토리지 만들기

부제: 최소 금액으로 만들어보는 통합 스토리지 시스템과 활용법

 작성자: 김경민(stone@nuxinfo.net)
1. 부득이 하게 경어는 생략합니다.
2. 마음대로 퍼가셔도 되며 수정해서 작성자 이름을 변경 후 재 배포해도 상관 없습니다. :-)
3. 내용 중 명확히 잘못된 부분이 있으면 언제라도 수정하셔도 됩니다.
4. 내용에 대한 반론이 있다면 메일 또는 공개 게시판에 반론 제기하시면 됩니다.
5. 부족한 부분이나 추가했으면 하는 부분이 있다면 메일로 요청하시면 됩니다만 언제 추가할 지 장담은 못합니다.

ZFS(Zettabyte File System)란?

 

* ZFS 파일 시스템은 기존의 유닉스 파일시스템을 대체하기 위하여 2005년 SOLARIS10에서 처음 소개된 파일시스템으로
파일시스템들 가운데 최초로 128bit파일 시스템을 적용하여 거의 무한대의 용량을 제공하며 파일시스템 자체에서 볼륨 매니저 기능을 포함하여
시스템 내에 있는 하드 디스크들을 구성하거나 스토리지 풀로 통합하여 사용하는 것이 특징이다.[http]wikipedia

2.1 ZFS 기본컨셉과 장점

물론 장단점이 있긴 하지만 필자가 생각했을 때 ZFS가 갖는 좋은 점 몇 가지를 소개하고자 한다.
극강의 파일시스템이라고 불리는 ZFS의 유연성과 편리함을 잘 활용했으면 봤으면 한다.
위의 그림을 다시 풀어보자면 아래와 같은 차이점이 있다는 것을 알 수 있다.
1. 고전적인 Unix,Linux,FreeBSD,etc 에서의 파일 시스템 사용 절차
Device인식(/dev/sda)=> partition => mkfs.ext3 /dev/sda1(format) => mount
또는
format =>partition => newfs /dev/rdsk/c0t0d1s5 => mount /dev/dsk/c0t0d1s1 /mnt
2. LVM 기반의 파일시스템 사용 절차
Device인식(/dev/sda) => PV생성 => VG(volume group)생성 => LV(logical volume)생성 =>mkfs(format) => mount
3. ZFS 사용 절차
zpool생성 => zfs 생성
정말 간단하지 않은가? :-)
ZFS는 고전적인 파일시스템의 개념과 LVM같은 볼륨 매니저가 결합된 형태이며 별도의 파일시스템 생성과 Mount과정이 필요가 없습니다.
물론 대부분의 경우 /storagepool/dataset 형태로 스토리지 풀 하위 디렉토리로 마운트가 되나
필요에 따라 원하는 위치로 마운트 시켜서 사용해도 된다.
  • 간단한 관리 명령어

위의 내용과 다소 중복이 되지만 ZFS의 경우에는 zpool,zfs명령 2가지로 모든 파일시스템에 관한 컨트롤을 다하게 되어 여러 명령어들이 기억하고 배울 필요가 없어진다.
또한 fatab,vfstab 같은 파티션 설정 파일자체도 필요가 없다.

– LVM case –
1. pvcreate /dev/sda /dev/sdb
2. vgcreate VG01 /dev/sda /dev/sdb
3. lvcreate -n lv-home -L 50G VG01(VG01 볼륨 그룹에 50G의 logical volume생성)
4. mkfs.ext3 /dev/VG01/lv-home
5. mount /dev/VG01/lv-home /home 또는 mount /dev/mapper/VG01-lv-home /home

– ZFS case –

1. zpool create STORAGEPOOL /dev/sda /dev/sdb
2. zfs create STORAGEPOOL/home
  • 128bit 파일 시스템으로 거의 무제한 용량의 파일시스템을 활용할 수 있다.

zpool max size: 256zettabytes
참고로 래드햇 리눅스 기준으로 리눅스에서는 약 16T~500T(xfs사용 시)용량을 지원한다.

  • Software Raid system 지원

H/W raid시스템과 비슷하게 mirror(raid1),raid-z(raid5),raid-z2(raid6)등을 구현 가능 하도록 되어있어 값비싼(?) H/W RAID system 을 대체할 수 있다.
혹자는 성능의 문제를 제기할지도 모르겠지만 이 글의 의도는 성능에 촛점을 맞추기보다는 다양한 요구에 대처할수 있는 다기능 스토리지 구성에 목적이 있음을 인지해주기를 바란다.
각각의 장 단점이 있으므로 이 부분은 엔지니어들의 선택에 달려있다.

  • 빠른 snapshot 과 rollback,clone
    zfs 의 유용한 기능중의 하나인 snapshot,clone,rollback을 이용하여 관리자가 원하는 시점의 데이터에 쉽게 엑세스 할 수 있다. 실제 사용하는 예제는 추후 스토리지 활용편에서 좀 더 다루겠지만 간단한게 사용하는 예제를 소개해 보도록 하겠다.
1. zfs snapshot storagepool/data1@sunday (snapshot생성)
2. rm -fr /storagepool/data1/testfile
3. zfs rollback storagepool/data1@sunday (rollback)

위의 과정처럼 snapshot 을 생성해두고 뭔가 문제가 발생했을 때 snapshot을 생성한 시점으로 바로 데이터를 복구할 수 있다.
windows의 VSS(volume shadow copy)와 유사하지만 virtual devices(zvol)를 지원하고
생성된 snapshot을 복제 가능하다는 점에서는 MS VSS보다는 유연하다.

  • 데이터 용량 및 관리의 편의성 제공

zfs의 경우 스토리지풀에 생성된 데이터를 각각의 zfs(or zvol)들이 모두 공유하기 때문에 스토리지풀의 용량만 잘 관리해주면 disk full로 인한 시스템 장애에서 벗어날 수 있다.
참고로 각각의 zvol,dataset(zfs)의 용량을 제한(quota) 및 예약(특정 용량 만큼은 보장하도록) 지정할 수 있다.
아래의 고전적인 파일시스템에서의 용량 증설 과정을 살펴보자.
1. 새 디스크 추가=>파티션 생성 및 파일시스템 생성=>mount=>기존데이터 복제=>fstab or vfstab수정
또는 LVM의 경우
2. 새 디스크 추가 => PV 생성=> VG확장=> LV확장 => 파일시스템 확장(resize2fs,xfs_grow,etc)=>fstab 수정

참고)
ext3의 경우 online resize가 안되므로 반드시 umount하고 resizing을 진행해야 한다.
xfs의 경우 online resize가 가능하므로 동적으로 용량 변경이 필요하고 무정지 시스템이 필요하다면
리눅스의 경우 필자는 XFS를 사용하기를 권장한다.

아래의 예제는 zfs 에서 스토리지풀을 확장하는 과정이다.

zpool add storagepool c2t1d0
  • 파일시스템의 기본 공유 기능

zfs는 기본적으로 nfs,smb(cifs) 등을 제공하여 별도의 설정이 없이도 쉽게 데이터를 공유할 수 있다.
물론 접근 제어(ACLs)의 설정등은 windows시스템보다는 다소 복잡한 면이 있지만
한번 잘 설정해두면 큰 문제없이 사용이 가능할 것이다.

  • 아키텍처와 상관없는 데이터 마이그레이션

스토리지 시스템의 H/W raid 컨트롤러가 고장이 났을 경우 동일 모델의 컨트롤러가 필요한 반면
zfs의 경우 zpool export/import를 이용하면 스토리지풀을 OS와는 상관없이 마이그레이션이 가능하다.
FreeBSD에서 만든 zpool을 Linux,opensolaris,solaris등에서도 별다른 설정 없이
가져와서 사용이 가능하다는 이야기가 된다. 물론 반대의 경우도 당연히 가능하다.

linux LVM

LVM(Logical Volume Manager)
LVM이란 디스크 파티션이나 디스크 자체를 볼륨 그룹으로 만들고 그 위에 Logical 파티션을 생성해서
사용하도록 해주는 프로그램이다.
복잡하게 들릴지 모르겠지만 아래와 같은 상황이 발생했을 경우를 생각해 보도록 하자.
여러분의 리눅스 시스템이 /home 파티션을 10G로 할당을 했다. 그런데 유저들이 늘어나고 디스크 사용량이 많아져서 10G 로는 부족한 상황이 되었다.
이런 경우 여러분은 좀더 여유가 있는 디스크를 추가로 증설을 할 것을 고려할 것이다.
물론 디스크 추가를 위해서 시스템을 셧다운 시켜야 될 것이다.
LVM으로 시스템을 구축하면 이러한 경우 시스템을 셧다운 하지 않고서도 여러분은 /home 파티션을 쉽게 늘려줄 수가 있다.
LVM은 디스크나 파티션을 하나의 가상 디스크로 만들어서 디스크를 관리하는 시스템이다 라고 이해를 하면 된다.

 

앞장에서 배운 RAID과 데이터의 안정성에 기반을 두고 있다면 LVM은 디스크 관리의 효율성에 기반을 두고 있다고 보면 되겠다.
효과적인 디스크 관리를 원한다면 LVM을 사용해 보도록 하자.

 

먼저 아래의 그림을 보도록 하자.

lvm.jpg


용어 설명.

PV Physical Volume 으로 파티션 또는 디스크를 의미한다.
VG Volume Group으로 PV을 그룹화 한것이다.
LV Logical Volume으로 볼륨그룹(VG)에 가상의 파티션을 이야기한다.

LVM 생성

PV 생성하기

PV는 파티션이나 디스크 자체가 될 수 있다. 파티션을 PV로 만들기 위해서는 파티션 타입을 8e(Linux LVM)으로 설정해 주면 되겠다.
아래의 예를 보도록 하자.
/dev/sdb 에 각각 2G,1G 의 LVM 파티션을 설정하는 과정이다.

[root@linuxstudy ~]# fdisk /dev/sdb
Command (m for help): p
Disk /dev/sdb: 6442 MB, 6442450944 bytes
255 heads, 63 sectors/track, 783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
Command (m for help): n 
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-783, default 1): 
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-783, default 783): +2000M
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): p

Disk /dev/sdb: 6442 MB, 6442450944 bytes
255 heads, 63 sectors/track, 783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         244     1959898+  8e  Linux LVM
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
2
Invalid partition number for type `2'
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (245-783, default 245): 
Using default value 245
Last cylinder or +size or +sizeM or +sizeK (245-783, default 783): +1000M

Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 8e
Changed system type of partition 2 to 8e (Linux LVM)

Command (m for help): p
Disk /dev/sdb: 6442 MB, 6442450944 bytes
255 heads, 63 sectors/track, 783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         244     1959898+  8e  Linux LVM
/dev/sdb2             245         367      987997+  8e  Linux LVM

 

준비가 되었다면 이제 PV 을 생성해 보도록 하자.
pvcreate 라는 명령을 이용하면 되겠다.

[root@linuxstudy ~]# pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created
[root@linuxstudy ~]# pvcreate /dev/sdb2
  Physical volume "/dev/sdb2" successfully created
[root@linuxstudy ~]# 

참고로 fdisk 과정을 거치지 않고 디스크를 통째로 사용도 가능하다..^^;

디스크를 통째로 PV로 만들기.

[root@linuxstudy ~]# pvcreate /dev/sdc
  Physical volume "/dev/sdc" successfully created
[root@linuxstudy ~]# 

 

생성된 PV를 보고 싶다면 pvdisplay 명령을 수행하면 된다.

[root@linuxstudy ~]# pvdisplay 
  "/dev/sdb1" is a new physical volume of "1.87 GB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb1
  VG Name               
  PV Size               1.87 GB
  Allocatable           NO
  PE Size (KByte)       0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               LIzfUV-g1dF-17ze-8xxC-DI8H-I96k-eR86wA
   
  "/dev/sdb2" is a new physical volume of "964.84 MB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb2
  VG Name               
  PV Size               964.84 MB
  Allocatable           NO
  PE Size (KByte)       0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               XbYFbH-3bzf-a0EL-Jt0c-B0Sn-32Sy-dh3eSS
   
  "/dev/sdc" is a new physical volume of "8.00 GB"
  --- NEW Physical volume ---
  PV Name               /dev/sdc
  VG Name               
  PV Size               8.00 GB
  Allocatable           NO
  PE Size (KByte)       0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               L7wDn7-Pi5t-RnM3-LX5R-cCJ1-j8H9-xDEjOV
   
[root@linuxstudy ~]# 

 

VG 생성

vgcreate.

vgcreate 볼륨그룹이름 PV PV PV ...

이제 앞에서 만든 PV들을 묶어서 하나의 볼륨그룹(VG)로 생성해 보도록 하겠다.
/dev/sdb1 파티션과 /dev/sdb2 파티션을 VG0 이라는 이름으로 생성하는 예제이다.

[root@linuxstudy ~]# vgcreate VG0 /dev/sdb1 /dev/sdb2
  Volume group "VG0" successfully created
[root@linuxstudy ~]# 

 

생성된 VG를 확인해 보도록 하자.

[root@linuxstudy ~]# vgdisplay 
  --- Volume group ---
  VG Name               VG0
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               2.81 GB
  PE Size               4.00 MB
  Total PE              719
  Alloc PE / Size       0 / 0   
  Free  PE / Size       719 / 2.81 GB
  VG UUID               Xyye0d-VZGJ-gFfX-KLhU-LSe4-KK6r-2HkGP1
   
[root@linuxstudy ~]# 

 

LV 생성

이제 볼륨그룹(VG)에 LV를 생성해 보도록 하자.
LV생성.

lvcreate -L 용량 -n LV이름 VG이름

만들어진 볼륨그룹에 가상의 파티션을 생성하는 과정이라고 이해하면 되겠다.

[root@linuxstudy ~]# lvcreate -L 1.5G -n lvm_home VG0
  Logical volume "lvm_home" created
[root@linuxstudy ~]# 

VG0 볼륨그룹에 lvm_home 이라는 LV를 생성했다.
이제 일반적인 파티션처럼 mkfs 명령으로 포맷을 하고 사용하면 된다.
생성된 장치는 보통 /dev/VG명/LV명 형태로 생성이 된다.

LV 포맷 및 마운트

[root@linuxstudy ~]# mkfs /dev/VG0/lvm_home 
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
[root@linuxstudy ~]# mount /dev/VG0/lvm_home /home

 

제대로 mount가 되었다면 아래와 같이 나올것이다.

/dev/mapper/VG0-lvm_home on /home type ext2 (rw)

 

이렇게 생성된 LV는 차후에 자유롭게 용량을 늘렸다가 줄였다가 할 수 있다.
자세한 사용법은 다음장에서 진행하도록 하겠다.