IT이야기2010. 9. 14. 12:30
ZFS 파일시스템은 snapshot(스냅샷) 기능을 제공하여, 원하면 언제든지 snapshot시점으로 복원할 수 있다. 명령어 한줄로 snapshot을 만들고, 명령어 한줄로 복원한다. snapshot 생성을 매일 1회 이상 자동으로 실행되도록 해주면, 데이터 복원에 유용할 것이다.

ZFS 파일시스템

참고로 FreeBSD 8.0은 ZFS v13을, 8.1은 v14를 지원한다. FreeBSD 8.2 또는 9.0에서는 v15를 지원할 예정이다. ZFS v15는 Solaris 10 update 8과 FreeBSD간의 호환성이 좋아졌으며, ZFS파일시스템에 php 코드가 있을 경우에 기존보다 15~20%정도 RPS가 향상되었다.

이 글은 FreeBSD에서 ZFS파일시스템을 운영한 것을 토대로 작성했지만 OS와 상관없이 ZFS파일시스템이라면 동일하게 적용된다.

1. snapshot 만들기

이론적으로 snapshot은 최대 2의 64제곱개까지 만들 수 있다. snapshot은 같은 스토리지 풀(파일시스템, 볼륨)의 공간을 사용한다.

snapshot을 만들어보자. snapshot시에 형식은 '파일시스템@snapshot명' 또는 '볼륨@snapshot명'이다. snapshot 이름은 기존 이름과 중복되지 않으면 임의로 만들면 된다.

# zfs snapshot data/log@2010_0621_1740_Mon

snapshot이름은 개인적으로 '년월일' 형식을 선호한다. snapshot 목록을 볼 때, 별도 속성 옵션(-o creation)을 줘야 생성일자를 볼 수 있는 불편함 때문이다. 좀 더 직관적으로 표기하기위해 요일까지 붙여줘도 좋다.

2. snapshot 확인하기

생성된 snapshot 목록을 살펴보자. 생성일시를 알고 싶다면 -o creation의 추가 옵션이 필요하다.

# zfs list -t snapshot
NAME                          USED  AVAIL  REFER  MOUNTPOINT
... 생략 ...
 data/log@2010_0619_0701_Sat   26K      -  20.9M  -
 data/log@2010_0620_0701_Sun   30K      -  21.5M  -
 data/log@2010_0621_0701_Mon   31K      -  21.5M  -
 data/log@2010_0621_1740_Mon     0      -  28.5M  -

3. snapshot rollback하기

rollback은 snapshot 방법과 동일하다. 특정 시점으로 되돌리고 싶으면 해당 'snapshot명'을 지정하기만 하면 된다.

# zfs rollback data/log@2010_0621_1740_Mon
cannot rollback to 'data/log@2010_0621_1740_Mon': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
data/log@2010_0621_1750_Mon
data/log@2010_0621_1813_Mon

위의 경우는 data/log@2010_0621_1740_Mon 스냅샷 이후(즉, 보다 최근)에 2개의 스냅샷이 존재하기 때문에 나오는 메시지이다. 이를 무시하고 롤백하려면 -r 옵션(Recursively)을 주면 된다.

# zfs rollback -r data/log@2010_0621_1740_Mon

※ 여기서는 snapshot 생성, 확인, 복원에 대해 간단하게 적었으며, 자세한 글은 '커피닉스(coffeenix.net)'에 올려뒀다.

* 관련글
2009/02/26 - [시스템이야기] - FreeBSD 7에서 ZFS 사용 (유연성은 좋으나, 성능은 불만족)

Posted by 좋은진호
IT이야기2009. 8. 31. 19:07
지난 금요일(8.28일)에 Apache Software Foundation의 웹사이트가 해킹을 당해 서비스를 일시 중지한 적이 있다. F-Secure의 'Apache.org hack'을 읽은 금요일 밤에 접속했을 때는 웹서비스는 정상적으로 복구된 상태였다.

apache


다행인 것은 공격자는 Apache 웹서버 자체의 S/W적인 취약점이나 SSH의 취약점이 아닌 SSH key 인증을 이용해서 접근했다. minotaur.apache.org(people.apache.org로 알려진 서버) 서버에 파일을 업로드 한 것이다. 이 minotaur 서버는 Apache 커미터들에게 쉘 계정을 제공하는 서버이다.

ASF측에서는 예방차원에서 서버를 모두 shutdown했다. 그리고 초기 조사 이후에 apache.org 서비스를 eris.apache.org(이 서버는 공격 당하지 않은 안전한 서버)로 DNS를 변경했고, 이 서버를 통해 공지페이지를 제공했다. 그 이후 유럽의 장애 대처 및 백업 서버인 aurora.apache.org 서버(이 서버 또한 안전한 서버)로 서비스를 변경했다. 현재 aurora.apache.org IP와 www.apache.org IP가 같은 것을 보면 아직 유럽의 임시 서버를 통해서 서비스가 되고 있는 것으로 보인다.

공격자는 www.apache.org 내의 CGI 스크립트를 포함하여 몇몇 파일을 생성까지 했다. 그런데, ASF의 서버들은 rsync의 자동화처리(cron에 등록되어 있을 것 같음)를 통해서 파일을 각 서버로 자동 배포하는 구조로 되어 있다. 공격자가 생성한 몇몇 파일들이 자동적으로 sync가 되었는데, 복구는 ZFS 스냅샷으로 이전 상태로 복원했다고 한다. ZFS 파일시스템의 우수성을 다시 한번 느끼게 한다.

참고로 ZFS파일시스템은 주기적으로 snapshot을 실행(zfs snapshot -r ... 형식) 한다면, 적은 공간으로 파일시스템을 원하는 시점으로 되돌릴 수 있다(zfs rollback). ZFS에 대해서는 'FreeBSD 7에서 ZFS 사용 (유연성은 좋으나, 성능은 불만족)' (2009.2월)을 읽어보기 바란다.

apache.org 얘기로 돌아가서, 공격자가 서버 접속해서 상위 권한을 획득하지는 않았다. 하지만 다운로드 받는 분들은 디지털 signature 체크(MD5 등)를 하길 바란다. 자세한 글은 아파치 인프라팀의 'apache.org downtime - initial report' 글에 있다.

서버 운영자들 중 PW없이 접속하도록 SSH 인증키를 만들어 놓곤 한다. 그러나 이 키들이 노출됐을 때 얼마나 위험한 것인지 잘 아셔야 한다. 그리고, 왜 이런 오픈소스 진영의 서버들을 해킹하려고 시도하는지, 안타깝다. 그런 노력(?)을 하려거든, 오픈소스 진영에 기부나 할 것이지...

Posted by 좋은진호
시스템이야기2009. 2. 26. 09:30

FreeBSD 7.0부터는 오픈솔라리스의 ZFS(Zettabyte File System)을 사용할 수 있다. ZFS는 파일시스템과 볼륨관리자가 통합되어 있는 장점을 최대한 살려 한두개의 과정만으로 파일시스템을 바로 사용할 수 있다. 또한 마치 찰흙을 붙였다 떼었다 하는 듯한 느낌으로 볼륨 관리의 유연성을 맛 볼 수 있다. 그러나 FreeBSD에서는 아직 실험적으로 동작중이며, IO 성능 또한 만족스럽지 못하다. 결국 FreeBSD에서 만큼은 미래를 위해 맛보기용 파일시스템로 즐기면 될 듯 싶다.

간단한 ZFS의 특징을 정리하면.

- 파일시스템 + 볼륨관리자가 통합되었다.
- 128비트 파일시스템이며, 디렉토리와 파일의 갯수에 제한이 없다.
- 미러링, 그리고 RAID기능에 해당하는 raidz를 지원한다.
- 물리적 disk를 쉽게 스토리지 풀에 추가할 수 있다.
- 상태 모니터링이 효과적이다. (iostat, status, history, get 등)
- 스냅샷 기능을 지원한다.

1. ZFS 풀과 파일시스템 생성 (zpool create, zfs create, zpool list, zfs list)

# zpool create data mfid0s1h
# zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
data                   31.8G    110K   31.7G     0%  ONLINE     -
# df -t zfs
Filesystem    1K-blocks    Used    Avail Capacity  Mounted on
data           32771968       0 32771968     0%    /data

zpool create 명령만으로 쉽게 '스토리지 풀'을 생성했다. 이 명령 하나만으로 바로 파일시스템을 이용할 수가 있다. 매우 간단하지 않는가?
리눅스의 LVM과 비교해보자. LVM은 PV 생성 -> VG 생성 -> LV 생성의 3과정을 거쳐야 한다. 1) 디스크나 파티션을 LVM으로 사용하겠다고 선언하는 PV(Physical Volume) 생성(pvcreate) 과정. 2) 이후 PV를 하나의 큰 덩어리로 묶는 VG(Volume Group) 생성(vgcreate) 과정. 3) 필요한 만큼만 떼어 내어 실제 사용가능한 파일시스템으로 만드는 LV(Logical Volume) 생성 과정. 이와 비교하면 zfs는 정말 간단하다.

이제 하나의 풀에 여러 파일시스템을 만들어보자.

# zfs create data/backup
# zfs create data/log
# zfs create data/photo
# zfs list
NAME          USED  AVAIL  REFER  MOUNTPOINT
data          182K  31.3G    22K  /data
data/backup    18K  31.3G    18K  /data/backup
data/log       18K  31.3G    18K  /data/log
data/photo     18K  31.3G    18K  /data/photo

data 풀에 data/backup, data/log, data/photo 파일시스템을 생성했다. 그런데 마운트포인트가 모두 /data 아래로 생성되었는데, 다른 곳으로 할 수는 없을까? zfs set 명령 하나면 바로 변경 가능하다. 또는 생성할 때 -o mountmpoint=/backup 옵션으로 지정할 수 있다.
(※ zfs get all 또는 zfs get mountpoint로 속성 정보를 얻을 수 있다.)

# zfs set mountpoint=/backup data/backup
# zfs list /backup
NAME          USED  AVAIL  REFER  MOUNTPOINT
data/backup    18K  31.3G    18K  /backup
# df -h -t zfs
Filesystem    1K-blocks    Used    Avail Capacity  Mounted on
data              31G      0B     31G     0%    /data
data/log          31G      0B     31G     0%    /data/log
data/photo        31G      0B     31G     0%    /data/photo
data/backup       31G      0B     31G     0%    /backup

위의 파티션을 보면 용량이 모두 31GB로 표시되었다. zfs의 각 파티션이 '스토리지 풀'의 최대 용량까지 함께 사용하기 때문이다. data/photo 파티션은 5G만 사용하라고 쿼터를 할당해보자. 이 쿼터는 허용치만큼 늘릴 수도 줄일 수도 있다. 리눅스의 LVM이 확장하는 것만 가능(lvextend)한 것과 비교하면 상당히 유연한 자세를 취하고 있다.

# zfs set quota=5g data/photo
# zfs list data/photo
NAME         USED  AVAIL  REFER  MOUNTPOINT
data/photo    18K  5.00G    18K  /data/photo
#
# zfs set quota=3g data/photo
# zfs list data/photo
NAME         USED  AVAIL  REFER  MOUNTPOINT
data/photo    18K  3.00G    18K  /data/photo
#
# df -h data/photo
Filesystem    Size    Used   Avail Capacity  Mounted on
data/photo    3.0G    128K    3.0G     0%    /data/photo

만약 다른 파티션에서 용량을 사용하게 되면 그 양만큼 다른 파티션은 사용할 공간이 줄게 된다. 아래를 보면 /data/log가 11G를 사용중이다. 그래서 다른 파티션은 31GB-11GB 뺀 용량이 전체 사이즈로 표현된다.

# df -h -t zfs
Filesystem     Size    Used   Avail Capacity  Mounted on
data            20G      0B     20G     0%    /data
data/log        31G     11G     20G    35%    /data/log
data/photo     3.0G    128K    3.0G     0%    /data/photo
data/backup     20G      0B     20G     0%    /backup

ZFS는 자체에 데이터 안정성을 높을 높이는 mirror와 RAID-Z 기능을 제공한다. mirror기능으로 풀을 만들어 보자.

# zpool create backup mirror mfid1 mfid3
# df -h -t zfs
Filesystem    Size    Used   Avail Capacity  Mounted on
backup         66G      0B     66G     0%    /backup

디스크는 SAS 73GB짜리이다. ufs 또는 zfs로 1개의 파일시스템을 만들면 66GB가 나온다. 2개 디스크인데, 132GB가 아닌 66GB로 표시되는 것은 mirror로 생성되었음을 보여준다. mirror로 설정되어 있는지 확인하는 방법은 뒤에서 다시 얘기하겠다.

2. zfs는 당신이 한 일을 모두 알고 있다. (zfs history)

# zpool history
History for 'data':
2009-02-16.18:32:06 zpool create data mfid0s1h
2009-02-16.18:33:23 zfs create data/backup
2009-02-16.18:33:31 zfs create data/log
2009-02-16.18:33:50 zfs create data/photo
2009-02-16.18:35:19 zfs set mountpoint=/backup data/backup
2009-02-16.18:41:17 zfs create -o mountpoint=/work data/work
2009-02-16.18:51:07 zfs set quota=5g data/photo
2009-02-16.19:00:09 zfs set quota=3g data/photo
2009-02-16.19:16:41 zfs set quota=5g data/photo
2009-02-16.19:21:36 zfs set quota=3g data/photo
2009-02-16.19:28:49 zfs destroy data/work

'data' 풀에 적용된 작업이 모두 나왔다.

3. 상태 살펴보기 (zpool iostat, zpool status)

# zpool iostat 2
               capacity     operations    bandwidth
pool         used  avail   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
data        11.4G  20.4G      8     63   881K  1.58M
data        11.6G  20.1G      0  1.75K  32.0K   128M
data        11.9G  19.9G      0  1.88K  64.0K   133M
data        12.1G  19.7G      0  2.09K  32.0K   128M
data        12.3G  19.4G      0  2.17K  64.0K   131M
data        12.6G  19.2G      0  2.20K  32.0K   137M
data        12.8G  18.9G      0  2.33K  32.0K   139M
data        12.9G  18.9G    610  1.49K  75.8M  77.8M
data        12.9G  18.9G    521  1.61K  65.0M  89.7M
data        12.9G  18.9G    615  1.35K  76.5M  71.2M

IO 상태를 2초간격으로 살펴본 것이다. 리눅스나 FreeBSD에서 iostat를 해봤을 것이다. iostat는 디스크별로 IO를 보는 것이며, zpool iostat는 '스토리지 풀'별로 살펴보는 것이다. 'data' 풀의 ONLINE상태를 확인할 수 있다.

# zpool status
  pool: data
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        data        ONLINE       0     0     0
          mfid0s1h  ONLINE       0     0     0

다음은 'backup'풀이 mfid1, mfid3 2개 disk를 사용하여 mirror되어 있는 것을 볼 수 있다.

# zpool status
  pool: backup
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        backup      ONLINE       0     0     0
          mirror    ONLINE       0     0     0
            mfid1   ONLINE       0     0     0
            mfid3   ONLINE       0     0     0

errors: No known data errors

4. ZFS 풀과 파일시스템 unmount & 지우기 (zpool destroy, zfs umount, zfs destroy)

파일시스템를 umount하기 위해서는 'zfs umount 파일시스템' 형태로 하며, 완전 제거는 'zfs destroy'로 한다. 파일시스템이 사용중이지 않으면 바로 unmount와 제거가 가능하다.

# cd /data/log
# zfs umount  data/log
cannot unmount '/data/log': Device busy
# cd /
# zfs umount  data/log
# zfs mount   data/log
# zfs destroy data/log

스토리지 풀 전체를 제거할 때도 마찬가지로 zpool destroy로 하면 된다.

# zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
data                   31.8G   10.9G   20.9G    34%  ONLINE     -
# zpool destroy data
cannot unmount '/backup': Device busy
could not destroy 'data': could not unmount datasets
# cd /
# zpool destroy data
# zpool list
no pools available

5. FreeBSD에서는 ZFS를 서비스에 적용할 수 있을까? (성능 및 기타 사항)

ZFS는 최소 1GB이상의 메모리를 권장한다. 그러나 ZFS는 실제 많은 메모리를 사용하는 경우가 있다. 파일시스템 성능 체크를 하는 동안 panic: kmem_malloc(16305): kmem_map too small: 332353536 total allocated 같은 메시지를 뿌리면서 몇 번 다운되었다. i386 환경에서는 kmem address space(vm.kmem_size_max)의 최대값이 320M으로 되어 있다. 그러나 이 수치는 ZFS을 사용하기에는 낮은 수치이므로 기본값을 그대로 사용할 경우에는 커널 패닉이 발생할 수 있다고 한다. 그래서 나도 다운이 된 것이었다. vm.kmem_size는 read only값이므로 /boot/loader.conf 에 다음 2줄을 추가한다. 그리고 부팅을 하고, 필요시 이 수치는 더 늘리면 된다.

vm.kmem_size="512M"
vm.kmem_size_max="512M"

[ 부팅 전 ]
# sysctl -a|grep kmem
vm.kmem_size_scale: 3
vm.kmem_size_max: 335544320
vm.kmem_size_min: 0
vm.kmem_size: 335544320

[ 부팅 후 ]
# sysctl -a|grep kmem
vm.kmem_size_scale: 3
vm.kmem_size_max: 536870912
vm.kmem_size_min: 0
vm.kmem_size: 536870912

bonnie++로 Sequential Output/Input/Create, Random, Random Create의 성능 비교를 했다. ufs 파일시스템과 비교했을 때 각 항목별로 대략 2~5배 이하의 만족스럽지 못한 성능이 나왔다. zfs 기본 생성외에 mirror로 이뤄진 풀, raidz 로 이뤄진 풀도 낮은 수치인 것은 마찬가지였다.

그리고, 부팅 후 ZFS를 처음 create할 때는 다음과 같은 메시지가 나온다.

This module (opensolaris) contains code covered by the
Common Development and Distribution License (CDDL)
see http://opensolaris.org/os/licensing/opensolaris_license/
WARNING: ZFS is considered to be an experimental feature in FreeBSD.
ZFS filesystem version 6
ZFS storage pool version 6

'WARNING' 부분이 보이는가? FreeBSD에서는 실험적인 상태이고, 성능 또한 상당히 낮으니, 편리함과 유연함을 높이 산다고 하더라고 서비스에 적용하기는 무리가 있다. 아직 FreeBSD에서는 재밌게 즐기면 된다. 즐기다 보면 미래에 적용해도 괜찮을 때가 오겠지...

6. 참고 자료

* ZFS 시작하기
* ZFS Tuning Guide
* FreeBSD 7.1 달라진 것 몇가지 (2009.1.20, 글 좋은진호)
* FreeBSD 7.0 사용기 (2008.3.7, 글 좋은진호, ZFS 사용기 일부 포함)



Posted by 좋은진호
시스템이야기2008. 3. 7. 22:57
FreeBSD 7.0의 사용기 몇가지를 적어보겠다.

1. make buildworld 시간 : 1시간 2분 (FreeBSD 6.x대와 별반 차이 없음)

2. 차세대 전송 프로토콜인 SCTP를 사용하기 위해서는 커널에서 INET, INET6 모두 define되어 있어야 한다. INET6을 define하지 않고 커널 컴파일을 하면 에러가 발생한다. ( /usr/src/sys/conf/NOTES )

    Note YOU MUST have both INET and INET6 defined.
    you don't have to enable V6, but SCTP is
    dual stacked and so far we have not teased apart
    the V6 and V4.. since an association can span
    both a V6 and V4 address at the SAME time :-)
'INET, INET6가 모두 정의되어 있어야 한다. V6를 enable할 필요는 없다. 그러나 SCTP가 dual stack으로 되어 있어서 지금까지 우리는 V6과 V4를 별도로 분리하지(teased apart) 않았다. (dual-stacked라 분리할 필요가 없었다는 의미) 왜냐하면 SCTP 커넥션(association)은 V6과 V4주소가 동시에 펼쳐지기(span) 때문이다.'
SCTP 에서는 커넥션을 association라고 부르므로, 위의 문장중 'association'은 커넥션으로 이해하면 된다.

3.  TCP 디버깅 로그가 이전 보다 자세하다.

1) 6.x 버전
kernel: Connection attempt to TCP ???.???.???.???:??? from ???.???.???.???:??? flags:0x12
2) 7 버전
kernel: TCP: [???.???.???.???]:80 to [???.???.???.???]:64938 tcpflags 0x12<SYN,ACK>; tcp_input: Connection attempt to closed port
    그리고, Connection attempt 외에 또다른 로그.
kernel: TCP: [???.???.???.???]:21 to [???.???.???.???]:40255 tcpflags 0x18<PUSH,ACK>; tcp_do_segment: FIN_WAIT_2: Received 10 bytes of data after socket was closed, sending RST and removing tcpcb

4. ZFS 파일시스템

/boot/loader.conf 에 다음과 같이 설정하고 리부팅하면, XFS와 ZFS 파일시스템을 사용할 수 있다.
xfs_load="YES"                   # XFS
zfs_load="YES"                   # ZFS

kldstat로 동적링크된 커널모듈(.ko) 목록을 확인해보자.
# kldstat
Id Refs Address    Size     Name
 1    5 0xc0400000 8fb638   kernel
 2    1 0xc0cfc000 81404    xfs.ko
 3    1 0xc0d7e000 b8344    zfs.ko
 4    1 0xc0e37000 6a22c    acpi.ko
#
# kldstat -v
... 생략 ...
 2    1 0xc0cfc000 81404    xfs.ko
        Contains modules:
                Id Name
                 1 xfs
 3    1 0xc0d7e000 b8344    zfs.ko
        Contains modules:
                Id Name
                 2 zfsctrl
                 3 zfs
                 4 zfs_zvol
                 5 zfs_vdev
... 생략 ...

ZFS 사용을 위한 준비는 완료됐다. zfs, zpool 등의 명령으로 ZFS 파일시스템을 만들고 확인해본다.
# zpool create data /dev/da0s1h
# mount
... 생략 ...
data on /data (zfs, local)
# zfs list
NAME   USED  AVAIL  REFER  MOUNTPOINT
data   105K  17.1G    18K  /data

ZFS와 UFS간의 성능테스트와 그 이외의 응용프로그램 등의 성능은 추후 테스트를 해볼 것이다.
덧붙여서 FreeBSD 7 리뷰글과 Live CD로 설치하는 화면을 'Review of FreeBSD 7'에서 볼 수 있다.

※ 시스템 환경 : Dell 1950, CPU 5310 X 2개, 2G 메모리, SAS, No RAID
Posted by 좋은진호