Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Docker Sotrage 의 거의 모든 것

거의 모든 것이라고 하니 좀 너무 나간 것 같은 느낌이 든다. 그냥 이것 저것 다뤄 볼려고 한다. 다룰 내용은 다음과 같다.
  • Docker에서 제공하는 스토리지 백앤드(backend)의 종류와 특징들
  • 스토리지 백앤드간의 장점과 단점들
  • 확장성 있는 스토리지 백앤드의 구성을 위한 아이디어들

테스트 환경

테스트 환경은 다음과 같다.
  • 개인 데스크탑 PC
  • 우분투 리눅스 서버 버전 15.10
  • 도커 버전 1.9.1

Docker가 지원하는 스토리지 백앤드 들

Docker는 하나의 이미지로 부터 하나 이상의 컨테이너를 만들 수 있다. 이 과정은 하나의 프로그램 이미지(파일)로 부터, 여러 개의 프로세스를 실행 할 수 있는 리눅스 프로세스 모델과 매우 비슷한 측면이있다. 도커 이미지는 프로그램 이미지에 대응되며, 컨테이너는 프로세스에 대응된다.

 프로세스와 컨테이너

이렇게 하나의 도커 이미지로 부터 여러 개의 컨테이너를 만들려면, 도커 이미지가 "변경"이 되면 안 될 것이다. 프로그램의 파일이 변경되면 안 되듯이 원칙적으로 도커 이미지의 데이터는 변경이 되면 안된다. 실제 도커를 기반으로 SaaS 환경을 구축할 경우 아예, 이미지를 읽기 전용으로 만드는 식으로 구성을 한다. 예를 들어 MySQL을 SaaS 형태로 제공 한다면, Mysql 소프트웨어는 이미지로 만들고, 데이터는 별도의 볼륨에 읽고/쓰는 식으로 구성을 한다.

 읽기/쓰기 데이터를 위한 구성

하지만 도커 이미지의 데이터를 변경해야 하는 경우가 생길 수 있다. 이 경우에도 도커 이미지는 다른 컨테이너들도 공통으로 사용하고 있으므로 수정을 해서는 안된다. 도커는 유니온 파일 시스템(Union File System)을 이용해서 이 문제를 해결 하고 있다. 기본적인 원리는 간단하다. 원본 이미지를 수정 하는 대신 변경된 정보를 따로 저장하고, 원본 데이터와 변경된 정보를 조합해서 복원하는 식으로 데이터를 읽는다. 이렇게 하면, 원본 이미지를 수정 할 필요 없이, 각 컨테이너마다 다른 정보를 저장 할 수 있을 것이다.

도커는 스토리지 백앤드를 위한 다양한 종류의 유니온 파일 시스템을 지원한다. 이들 유니온 파일 시스템데 해서 간단히 살펴보자.

스토리지 드라이버 정보 확인

docker info 명령으로 현재 도커가 사용중인 스토리지 드라이버를 확인 할 수 있다.
# docker info
Containers: 2
Images: 4
Server Version: 1.9.1
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 8
 Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.2.0-16-generic
Operating System: Ubuntu 15.10
CPUs: 1
Total Memory: 992.9 MiB
Name: ubuntu
ID: 3FTQ:B5ER:CNEA:NDDU:4C2U:TO4T:D2UZ:N5E7:Z22X:FQH4:X4OU:4WGY
WARNING: No swap limit support
AUFS 스토리지 드라이버를 사용하고 있는 것을 알 수 있다.

스토리지 드라이버에 따라서 데이터가 저장되는 Root Dir이름이 달라진다. AUFS는 /var/lib/docker/aufs, devicemapper는 /var/lib/docker/devicemapper ... 이런 식이다.

AUFS 스토리지 드라이버

우분투 리눅스의 경우 AUFS를 기본 스토리지 백앤드로 사용한다. AUFS는 커널에 포함된 파일 시스템이 아니기 때문에, 지원하지 않는 배포판들도 있다. 레드햇 계열의 리눅스의 경우 AUFS를 지원하지 않는다.

AUFS는 unification 파일 시스템으로 여러 개의 디렉토리를 일련의 스택으로 묶어서 하나의 단일 뷰로 보여준다.

AUFS 스택은 여러 개의 파일 시스템을 단일 뷰로 만들고 이를 마운트 포인트로 제공한다. 스택을 이루는 디렉토리들은 하나의 마운트 포인터로 묶일 수 있어야 하므로 반드시 같은 리눅스 호스트에 존재해야 한다. AUFS에서는 스택을 이루는 각각의 스택을 브랜치(branch)라고 부른다.

실제 도커 이미지를 이용해서 AUFS 스택이 어떻게 구성되는지 알아보자. 테스트를 위해서 mysql:latest 도커 이미지를 사용했다. mysql 이미지를 pull 해보자.
# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
73e8d4f6bf84: Pull complete 
040bf8e08425: Pull complete 
86e6c3163927: Pull complete 
68f4b3625ea4: Pull complete 
04f7e78a2c8a: Pull complete 
1bade56c3b6b: Pull complete 
dd6387e14c18: Pull complete 
ca30c0626c9b: Pull complete 
0dc5e226a795: Pull complete 
6c164b0f04cb: Pull complete 
......
1924f4186d05: Pull complete 
14961e5db73a: Pull complete 
Digest: sha256:16de02081c408c41361126aaa718f91693688d39a216a74ac8dab841db050228
Status: Downloaded newer image for mysql:latest
이미지 pull을 수행하면, 여러 개의 AUFS 스택을 가져오는 것을 확인 할 수 있다. 이미지를 구성하는 스택의 정보는 /var/lib/docker/aufs/layers 에서 확인 할 수 있다.

mysql 이미지의 이름은 14961e5db73a0dae574... 이며, docker images 명령으로도 확인 할 수 있다.
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              latest              8ed581e3fa7a        7 days ago          188 MB
mysql               latest              14961e5db73a        9 days ago          361.3 MB

aufs/layers 디렉터리로 이동해서 mysql 이미지를 구성하고 있는 스택목록을 확인해 보자.
# cat 14961e5db73a0dae5790a46f9b6ffd4f24a28a3fca106cc9a11d4c496ec9b549 
1924f4186d05daf80e783d294df85f4bc251f59e7021e0a5f00ff094cb95d84b
d17cffff8039b9b33f490104f19f77eb34eb69c3b523c5c34f0bf202113d5693
e8126a9d061e8b0161595a0cd0500958c6d203ac9f40017d0536a8f9b2574aee
0fd3b6e125673affc1f348cdb0c071782bde7d7ab4748bea3e30bc2d1d7ea7ab
5c74d058f7b5e6eacc4274e5c562026f79cc2f53eb680229bf524ef5541ff997
6c164b0f04cb5d66a954104e084d3f591c7ca73ee35c291160a2ac3b414ebc6f
0dc5e226a795507723362cc16046cf16650f8f70dc7bb721b799a5f2a40512ce
ca30c0626c9be0984f257ec2c08f447fa5fc0a2e9408dc25ceae4d89bd5e0773
dd6387e14c188ea22aef03ba85c27edfad31f8418b059e5d47ce6d75b52f5fd7
1bade56c3b6b10fc941e1865de8cb376dbc5a1263b7b70388bba354933bd9030
04f7e78a2c8ac9664503f4ea5a1d94bf27b94620987f241cfb9fd6631f761113
68f4b3625ea4be430a2e97982bb8a470918d0fb933eb65c90e7b99ee5f7d08df
86e6c3163927c5b7baf3b1e3b80855ab9d79d2f14ec9d70df47225c9f603475b
040bf8e0842564e26e62f3e3a30785bd9651c82c52ed99115cd5360ce979e680
73e8d4f6bf84fb8a5fb59ef4851199f94982f6b6f29fed36ddd5d6ead4b30739

각 스택이 저장하고 있는 실제 데이터는 aufs/diff에 저장이 된다. Docker로 mysql 컨테이너를 실행하면, aufs/layers에서 mysql 이미지를 구성하는 스택 파일의 목록을 확인 한 다음 aufs/diff에있는 실제 데이터를 포함한 스택을 읽어서 묶은 다음 컨테이너 레이어를 만든다. 이 컨테이너 레이어를 Union mount 포인트에 마운트 해서 사용한다. 아래는 이 과정을 묘사한 그림이다.

 AUFS의 작동 원리

docker run으로 mysql 컨테이너를 만든다고 가정해 보자. docker는 mysql 이미지의 스택 정보를 읽어서 통합해서 Container Layer를 만든다. 이 컨테이너 Layer의 이름은 db6a84cd7bd...이다. 이 이름은 컨테이너 아이디(container id)로 사용한다. 이렇게 만들어진 컨테이너 레이어는 ausfs/mnt/에 마운트되서 사용된다. Image layer는 읽기 전용으로 데이터가 변경되지 않는다. 변경되는 데이터는 컨테이너 레이어에 쌓인다.

새로 만들어진 db6a84cd7bd에 대한 레이어 정보는 aufs/layers에서 살펴볼 수 있는데, mysql layer의 스택 정보를 사용하고 있음을 알 수 있다. db6a84cd7bd 에서 새로운 이미지를 만들면, 다시 스택이 추가되면서 레이어의 크기가 늘어날 것이다.

다른 스토리지 드라이버와 마찬가지로 CoW(Copy-on-write)기술을 사용한다. 공통되는 데이터들을 그대로 사용하고, 변경되는 정보만 컨테이너 레이어에 저장되기 때문에 디스크 공간을 효율적으로 사용 할 수 있다.

# grep aufs /proc/filesystems 
nodev	aufs
혹은 lsmod로도 확인 할 수 있다.
# lsmod | grep aufs
aufs                  208896  0 

도커 데몬을 실행 할 때는 스토리지 드라이버로 사용할 파일 시스템을 지정해 줘야 한다.
# docker daemon --storage-driver=aufs

혹은 DOCKER_OPTS--storage-driver=aufs를 설정해도 된다.
# cat /etc/default/docker
......
......
DOCKER_OPTS=&#34;--storage-driver=aufs&#34;

데몬이 실행 중인 상태에서는 docker info 명령으로 사용하고 있는 스토리지 드라이버를 확인 할 수 있다.
# docker info
Containers: 3
Images: 20
Server Version: 1.9.1
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 26
 Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.2.0-27-generic
Operating System: Ubuntu 14.04.4 LTS
CPUs: 1
......

스토리지 드라이버로 aufs를 사용하고 있으며, 기본 파일 시스템으로는 extfs(ext2, ext3, ext4...)를 사용하고 있음을 알 수 있다.

OverlayFS

AUFS와 비슷한 유니온 파일시스템이다. AUFS와 비교해서 아래와 같은 차이점을 가지고 있다.
  • AUFS 보다 단순한 디자인을 가지고 있다.
  • 리눅스 커널 3.18부터 정식으로 징원한다.
  • 좀 더 빠르다.
최근 OverlayFS에 대한 인기가 올라가는 중이다. 다만 최근에 만들어진 파일 시스템인 만큼 역사와 전통을 자랑하는 AUFS에 비해서 안정성이 떨어진다는 점이 문제다. 현장에서 사용 할 때는 주의 해야 한다.

OverlayFS의 구조는 다음과 같다.

 overlayfs 구조

lowerdir은 읽기 전용의 이미지 레이어에 대응한다. 컨테이너는 레이어는 이미지 레이어로 부터 만들어지며, 변경되는 정보들이 여기에 저장된다. 최종적으로 컨테이너 마운트를 통해서 이들 정보가 merged된다.

AUFS와 같은 구성이지만 여러 개의 레이어가 스택을 이루는 AUFS와는 달리 단지 두개의 레이어만 가지고 있다. 따라서 AUFS와 같은 멀티레이어 이미지를 구성할 수 없다. 대신 각 이미지 레이어마다 /var/lib/docker/overlay 디렉토리 밑에 자신만의 디렉토리를 가지는 것으로 이 문제를 해결 한다.

OverlayFS 환경 구성
OverlayFS는 2014년 리눅스 3.18부터 mainline에 포함됐다. 현재(2016년 3월)리눅스 커널 버전은 4.2.x로, 2년 이상 된 커널이 아니라면 이미 지원중이다. 테스트에 사용한 우분투 리눅스의 버전을 확인했다.
# uname -r
4.2.0-27-generic

/proc/filesystems에서 지원하는지 확인했다.
# grep overlay /proc/filesystems 
nodev	overlayfs
nodev	overlay

도커를 overlayfs 모드로 실행해보자.
# docker daemon --storage-driver=overlay &amp;
INFO[0000] Firewalld running: false                     
INFO[0000] Default bridge (docker0) is assigned with an IP address 172.17.0.1/16. Daemon option --bip can be used to set a preferred IP address 
....

docker info로 확인했다.
# docker info
Containers: 0
Images: 0
Server Version: 1.9.1
Storage Driver: overlay
 Backing Filesystem: extfs
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.2.0-27-generic
Operating System: Ubuntu 14.04.4 LTS
CPUs: 1
Total Memory: 993.1 MiB
Name: ubuntu
ID: KU6M:JR5Q:K3EL:HCX6:D3O5:LAZX:7HLL:LFYT:3TQN:LGS7:C755:RXN5
WARNING: No swap limit support

overlayfs 분석
우분투리눅스로 부터 컨테이너를 실행했다.
# docker run -it --name test ubuntu /bin/bash
root@10cd3e5e3722:/# 

/var/lib/docker/overlay/10cd... 디렉토리 밑에 merged, upper, work 디렉토리가 만들어진 걸 확인 할 수 있다.
# cd /var/lib/docker/overlay/10cd...
lower-id  merged  upper  work

lower-id에서 이 컨테이너를 실행한 image id를 알 수 있다.

마운트 정보를 확인해 봤다.
# cat /proc/mounts | grep overlay
overlay /var/lib/docker/overlay/10cd3e5e3722d518c3bc90f3698c8f4ed5752c66cdb350158e0eb3c783de3209/merged overlay rw,relatime,lowerdir=/var/lib/docker/overlay/8ed581e3fa7a6290de5d66fd488a38e129a4e8cb749d40b38eb74f9e7fa68844/root,upperdir=/var/lib/docker/overlay/10cd3e5e3722d518c3bc90f3698c8f4ed5752c66cdb350158e0eb3c783de3209/upper,workdir=/var/lib/docker/overlay/10cd3e5e3722d518c3bc90f3698c8f4ed5752c66cdb350158e0eb3c783de3209/work 0 0

  • 레이어가 많지 않아서 전반적으로 깔끔한 느낌이다.
  • AUFS에 비해서 성능이 좋다.
  • 배포판 상관없이 사용할 수 있다.

devicemapper - loop-lvm

devicemapper는 thin 프로비저닝을 위해서 간단히 사용 할 수 있는 디바이스드라이버다. 사용하는 디렉토리는 /var/lib/docker/devicemapper다. AUFS나 overlayfs 경우 파일 시스템기반으로 작동하는데, devicemapper는 블럭디바이스 기반으로 작동한다. devicemapper 모드로 실행하면 데이터를 저장히기 위한 블럭디바이스와 메타데이터(metadata)를 저장하기 위한 블럭디바이스, 단 두개의 블럭디바이스 파일만 만들어진다. 블럭디바이스는 리눅스의 루프(loop) 디바이스를 기반으로 하고 있다.

devicemapper 설정
--storage-driver 옵션으로 devicemapper를 설정할 수 있다.
# docker daemon --storage-driver=devicemapper

docker info 명령으로 확인해 보자.
root@ubuntu:~# docker info
Containers: 0
Images: 0
Server Version: 1.9.1
Storage Driver: devicemapper
 Pool Name: docker-252:0-287636-pool
 Pool Blocksize: 65.54 kB
 Base Device Size: 107.4 GB
 Backing Filesystem: ext4
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data Space Used: 1.821 GB
 Data Space Total: 107.4 GB
 Data Space Available: 3.059 GB
 Metadata Space Used: 1.479 MB
 Metadata Space Total: 2.147 GB
 Metadata Space Available: 2.146 GB
......
데이터파일과 메타데이터 파일을 위한 루프 디바이스를 확인 할 수 있다. devicemapper 디렉토리로 이동해서 파일 정보를 확인해 보자.
root@ubuntu:/var/lib/docker/devicemapper/devicemapper# ls -alh
total 2.0G
drwx------ 2 root root 4.0K Mar 14 23:41 .
drwx------ 5 root root 4.0K Mar 15 00:23 ..
-rw------- 1 root root 100G Mar 15 00:24 data
-rw------- 1 root root 2.0G Mar 15 00:24 metadata

무려 100G짜리 파일이 만들어져 있다. 하지만 이 파일은 sparse파일이다. s 옵션을 이용하면 실제 사용중인 파일의 크기를 알 수 있다.
root@ubuntu:/var/lib/docker/devicemapper/devicemapper# ls -alhs
total 2.0G
4.0K drwx------ 2 root root 4.0K Mar 14 23:41 .
4.0K drwx------ 5 root root 4.0K Mar 15 00:23 ..
2.0G -rw------- 1 root root 100G Mar 15 00:24 data
1.8M -rw------- 1 root root 2.0G Mar 15 00:24 metadata

아래는 lsblk를 실행한 결과다. 루프 디바이스를 확인 할 수 있다.
root@ubuntu:/var/lib/docker/devicemapper/devicemapper# lsblk 
NAME                              MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                                 8:0    0     8G  0 disk 
├─sda1                              8:1    0   243M  0 part /boot
├─sda2                              8:2    0     1K  0 part 
└─sda5                              8:5    0   7.8G  0 part 
  ├─ubuntu--vg-root (dm-0)        252:0    0   6.7G  0 lvm  /
  └─ubuntu--vg-swap_1 (dm-1)      252:1    0  1020M  0 lvm  [SWAP]
sr0                                11:0    1  1024M  0 rom  
loop0                               7:0    0   100G  0 loop 
└─docker-252:0-287636-pool (dm-2) 252:2    0   100G  0 dm   
loop1                               7:1    0     2G  0 loop 
└─docker-252:0-287636-pool (dm-2) 252:2    0   100G  0 dm   

Devicemapper 파일의 기본크기는 100G다. --storage-opt 옵션을 이용해서 루프 데이터와 메타 데이터의 크기를 설정 할 수 있다.
--storage-opt dm.loopdatasize=500GB \
--storage-opt dm.loopmetadatasize=10GB

장점과 단점
배포판에 상관없이 간단하게 사용 할 수 있다는 장점이 있다. 이 것외에는 장점이 없다. 유저별 애플리케이션별로 데이터를 관리하는게 불가능에 가깝우며, 매우 느리다. 그냥 사용하지 않는게 정신건강에 좋다. 이런게 있다는 정도만 알아두자.

Device mapper - direct-lvm

loop-lvm에서 사용하는 루프디바이스는 서비스를 위해서 사용한다. 굳이 파일을 블럭디바이스로 만들어서 사용 할 필요는 없을 것이다. dicrect-lvm은 실제 물리적 디바이스를 블럭디바이스를 스토리지로 사용한다.

물리적 디바이스를 사용하는 만큼, 성능과 관리 측면에서 장점이 있다. 예컨데 블럭디바이스들을 레이드로 묶는 식으로 데이터에 대한 가용성을 높이는 등의 장치를 더 할 수 있다. 하지만 loop-lvm과 마찬가지로 멀티태넌트 환경에서 사용하기 어렵기 때문에, 실제 서비스에서 사용하는 경우는 드물다.

굳이 다루지 않기로 했다.

zfs

ZFS는 COW를 지원하는 파일 시스템이다. AUFS나 OverlayFS도 COW 기반으로 Union file system을 구현하고 있다는 것을 상기하자. 기본적으로 COW를 사용하는 파일 시스템이라면 도커의 백앤드 스토리지 드라이버로 사용할 수 있다.

ZFS의 경우 snapshot을 만들고, 이 snapshot을 기반으로 변경된 정보들만 따로 쓰는 방식으로 파일 시스템을 운용 할 수 있다(도커가 지원하는 다른 COW 파일 시스템인 Btrfs도 동일한 방식으로 작동한다.). 기본 아이디어는 다음과 같다.

 ZFS를 이용한 스토리지 백앤드 구성 개요

ZFS와 AUFS를 비교해서 설명하고 있다. COW 파일시스템은 스냅샷을 만들 수 있다. 스냅샷은 현재 시간의 파일시스템의 상태에 대한 레퍼런스로 이 정보를 이용해서 데이터를 복원 할 수 있다. 보통 스냅샷은 데이터의 복원을 위해서 사용한다.

스냅샷의 또 다른 기능으로 clone이 있다. clone을 이용하면, 스냅샷을 기반으로 하는 새로운 파일 시스템을 만들 수 있다. 변경되는 데이터는 새로 만들어진 파일 시스템에 쌓인다. 원본인 스냅샷에 대한 변경이 없기 때문에 Union file system 처럼 하나의 원본에서 여러 개의 clone 파일 시스템을 만들 수 있다. 즉
  • 스냅샷은 도커 이미지 형태로 사용 할 수 있으며
  • 변경된 내용은 파일 시스템에 (AUFS 의)diff 형태로 쌓이게 된다.
ZFS 구성
리눅스에 ZFS 커널 모듈을 설치해야 한다. . 구성은 Linux native ZFS 설치문서를 참고하자.

나는 3개의 디스크를 raidz1으로 묶었다. 파일 시스템의 이름은 volumes이다.
# zfs list
NAME      USED  AVAIL  REFER  MOUNTPOINT
volumes  67.9K  1.91G  24.0K  /volumes

도커를 위해서 "docker-root" 이름의 파일 시스템을 만들어서 /var/lib/docker로 마운트했다.
# zfs create volumes/docker-root
# zfs list
volumes               122K  1.91G  24.0K  /volumes
volumes/docker-root  24.0K  1.91G  24.0K  /var/lib/docker

도커를 실행했다.
# docker daemon --storage-driver=zfs
# docker info
Containers: 0
Images: 0
Server Version: 1.9.1
Storage Driver: zfs
 Zpool: volumes
 Zpool Health: ONLINE
 Parent Dataset: volumes/docker-root
 Space Used By Parent: 24552
 Space Available: 2045744250
 Parent Quota: no
 Compression: off
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 4.2.0-27-generic
Operating System: Ubuntu 14.04.4 LTS
CPUs: 1
Total Memory: 993.1 MiB
Name: ubuntu
ID: KU6M:JR5Q:K3EL:HCX6:D3O5:LAZX:7HLL:LFYT:3TQN:LGS7:C755:RXN5
WARNING: No swap limit support

컨테이너를 만들면, 컨테이너를 위한 독립적인 zfs 파일 시스템이 만들어진다.
# zfs list
NAME                                                                                        USED  AVAIL  REFER  MOUNTPOINT
volumes                                                                                     223M  1.69G  24.0K  /volumes
volumes/docker-root                                                                         223M  1.69G   946K  /var/lib/docker
volumes/docker-root/001d664e2dd48c995aa08d92bf7423129fcd20fd382cd7b0c8017f05faf61151       38.6K  1.69G   200M  legacy
volumes/docker-root/4976a0f2dc0324fb779f4d2f3e97cf5c9708d08dae8687ea0ce97c9b7376b93e        385K  1.69G   200M  legacy
volumes/docker-root/5c117067c385337de439f29ec469c985aeceefa224a343acfa851820332c1a8d       55.3K  1.69G   200M  legacy
volumes/docker-root/c45e542e5722d52b490f1a44654a881393397a10ea9d6639c08eae3bf63db97c       21.6M  1.69G   199M  legacy
volumes/docker-root/c45e542e5722d52b490f1a44654a881393397a10ea9d6639c08eae3bf63db97c-init  74.6K  1.69G   200M  legacy
volumes/docker-root/ebe73f29e6e12c86af7b8691fa34249926fe105cb808662d7aa26bcac79afe4f        200M  1.69G   200M  legacy

장점과 단점
독립적인 파일 시스템이기 때문에, 파일 시스템 단위로 NFS export, 쿼터 설정, 스냅샷, 마이그레이션 작업들을 할 수 있다. 컨테이너를 서로 격리할 필요가 있는 SaaS, PaaS의 경우 매우 유용한 기능들이다. SaaS 서비스를 한다면, 고려해 보자.

ZFS는 꽤 무거운 파일 시스템이라는 걸 고려할 필요가 있다. 파일 시스템의 갯수에 따라서 메모리가 늘어나는데, 하나의 인스턴스가 수백개 이상의 컨테이너를 유지하지는 않을거라고 보면, 큰 문제는 아닐 것이다.

하지만 인프라를 제대로 구성하기를 원한다면 결국 스토리지를 분리해야 할 거다.

btrfs

GPL기반의 COW 파일 시스템이다. 기능, 구성 측면에서 ZFS와 비슷하다. 이런 이유로 ZFS와 비교대상이 되곤 한다. ZFS 구성과 이름만 다를 뿐, 방식은 동일하기 때문에 굳이 테스트하고 싶지는 않다. 귀찮다.

개인적으로 ZFS와 Btrfs에 대해서는 성능과 안정성, 특히 안정성에 관심이 많다. 가정에서의 NAS 구성 정도가 아닌, IaaS, SaaS, PaaS의 백앤드 스토리지로의 사용이 목적이기 때문이다. 이에 대해서는 A performance comparison of zfs and btrfs on LINUX 문서가 참고할 만하다. 요약 하자면 성능은 Btrfs, 안정성은 ZFS다.