Ubuntu Server: Btrfs Subvolume 사용 설치(NVMe).

** 조금 다른 상황을 가정하고 쓴 다른 글도 있다.


우분투 서버를 설치할 때, 파일시스템을 Btrfs 로 선택할 순 있지만, 서브볼륨을 사용할 순 없다. OpenSuse 는 설치프로그램이 정말 완벽하다할 수 있을 정도인데, 우분투는 이 부분이 많이 아쉽다.

이를 극복하려면, 마치 ArchLinux 를 설치할 때처럼, 약간의 지식이 필요하다.
이 글에서 간단하게 그 방법을 정리해보기로 한다.
다음 글에서 도움을 얻었다.

Ubuntu Server 18.04 btrfs raid1 (optionnal)


우분투 서버 설치 디스크(18.04, HWE 커널)로 부팅한 후 진행하다가, 딱 한가지 신경써야 할 부분이 있다.
디스크 파티션에서, /boot 영역(1GB 정도)을 따로 만드는게 Btrfs 를 사용할 때 여러모로 편리한 면이 있으므로, /boot 파티션을 따로 만들고, 파일시스템은 ext4 로 해준다. (예전에 어떤 책에서는 ext2 를 추천했었는데, 여기선 아예 ext2 를 선택할 수 조차 없다.)

/boot 파티션을 만들면, /boot/efi 는 자동으로 생성된다.

파티션 예.

그리고 끝까지 진행한다.

** 이 글과는 상관이 없지만, 파티션 작업에서 Manual 로 세부 파티션을 정하지 않고, 그냥 Entire Disk 로 진행하면, 중간에 오류가 발생한다. 아마도, 설치 프로그램 어딘가에 버그가 있는 모양이다.
우분투 서버를 설치하면서 그냥 ‘전체 디스크’를 선택할 일은 없으므로.. 이 부분에 큰 신경을 못쓴게 아닐까?
(18.04.2 까지는 이랬는데, 18.04.3 부터는 잘 된다.)

** 또 하나, 파티션 작업이 은근히 불편하다. 꼭 저 화면에서만 파티션 작업을 해야 한다. (미리 나눠놓은 파티션은 인식하지 못한다는 점!)

마지막 12/12, 또는 13/13 이 되었을 때, Reboot Now 를 택하지 말고, Ctrl-Alt-F2(VBox 메뉴 – 입력 – 키보드 – Soft Keyboard) 를 입력한 뒤 두번째 가상 콘솔로 이동한다.

이곳으로 가면, 이제 자유롭게(?) 명령어들을 입력할 수 있다.
좀 더 원활하게 하기 위해 Dvorak 으로 전환한다.

sudo dpkg-reconfigure keyboard-configuration
... 일련의 설정을 끝내고..
sudo setupcon

setupcon 을 해줘야 변경이 즉각 반영된다.

** 모든 명령은 sudo -i 후 관리자 권한으로 진행한다.

이제 여기서 해야할 일은 다음과 같다.

  • Btrfs 압축을 원한다면, defrag 실행.
  • Btrfs Subvolume 생성
  • 생성된 Subvolume 으로, 설치 프로그램이 만든 파일들 복사
  • 서브볼륨을 사용해 새 루트 시스템 mount 후, chroot 작업
  • fstab 수정
  • 부트로더 수정

복잡해보이지만, ArchLinux 는 저런 식으로 설치해야만 한다. 그것에 비하면 훨씬 간단한(?) 작업이다.

작업을 편하게 하기 위해 sudo -i 로 관리자로 전환한다.
원 글에서는 /target/boot/efi 나 /target 을 나중에 umount 하라고 되어 있는데, 그럴 수가 없었다(오류 발생). 따라서 그냥 umount 는 없이 진행한다.

/target 확인

우분투 서버 설치 프로그램은 /target 디렉토리에, 위에서 작업한 일련의 파티션들을 마운트 한 후 시스템을 구성한다. 따라서 먼저 저 디렉토리를 확인해본다.

ll /target # 잘 설치되어 있는지 확인한다.

그 뒤 lsblk 로 현재 디스크 상황도 파악한다.

설정한 대로, ESP, boot, / 모두 잘 만들어져있다.

Btrfs Compression

만약, Btrfs 의 Compression 기능을 원한다면, 이 시점에서 /target 을 압축해줘야 한다. 후에 fstab 에서 btrfs compression 을 줄 경우, 추후에 생성되는 파일들에 대해서만 압축이 이뤄진다. 따라서, 이왕 할거라면 지금 압축 작업을 해주는게 좋다. (물론, 나중에 시스템이 완성된 후에 해도 된다. 아마도.)

btrfs filesystem defragment -r -v -clzo /target

-clzo 가 핵심인데, 현재 Btrfs 는 zlib, lzo, zstd 세가지 압축 방식을 지원하고 있다. 여기서, 압축효율과 속도를 감안하여 가장 추천(?)하는게 lzo 라고 한다. 기본값은 zlib 이다.
압축 시간은 몇분 걸리지 않는다.
압축이 됐는지 여부는, 나중에 compsize(apt install btrfs-compsize)를 통해 알아볼 수 있다.

Sub Volume 생성

이제 /target 으로 이동하여 Btrfs Subvolume 을 생성한다.
우분투는, @ 을 시스템 루트(/)로, @home 을 /home 으로 사용한다.
헌데, OpenSuse 를 보니 보다 다양한 서브볼륨을 사용하고 있었다. 서브볼륨을 사용한다는 의미는 결국, Snapshot 을 활용한다는 뜻이 되므로, 적절히 추가하는게 효과와 효율면에서 더 나은 선택이 될 수 있다고 본다.
물론, ‘관리’가 가능하다는 전제 하에.

하여, @, @home, @var, @opt 총 4개의 서브볼륨을 만들기로 한다. 이 중 @opt 는 큰 효용은 없지만, 일단은 만들어보기로 했다.
또, 저 서브볼륨들을 독립된 파티션에 만들 것인지, 아니면 한 파티션에 서브볼륨으로만 만들 것인지도 고민이 됐는데, 그냥 한 파티션만 사용하기로 했다.
만약 파티션이 다르다면, 아래에 서술할 mount 작업에서 적절히 바꿔주기만 하면 되겠다.

cd /target # /target 은, 우분투 관리자가 작성한 새 시스템 디스크 영역이다.
btrfs subvolume create @
btrfs subvolume create @home
btrfs subvolume create @var
btrfs subvolume create @opt

# 꼭 할 필요는 없으나..
btrfs subvolume set-default @

set-default 에 관한 설명은 나중에.

/target 내부 파일 서브볼륨으로 이동

이제, /target 안에 생성되어 있는 파일들을, 적절히 저 서브볼륨 안으로 적절히 이동시킨다.
그에 앞서, /target/boot 와 /target/boot/efi 는 마운트 해제해줘야 한다. 이건 독립 파티션이므로, 이동(mv)하는 게 무의미하다.
순서는 efi 를 먼저, boot 를 나중에.

/target/home, /target/opt 등은 현 시점에선 비어있으므로, 굳이 옮길 필요는 없다. (디렉토리는 있어야 하나? 마운트 포인트로?)

** cdrom 디렉토리는 /target/run/cdrom 이 아닐 수도 있다. 확인 후 적절히 umount 해줘야 한다.

umount /target/boot/efi
umount /target/boot
umount /target/cdrom 또는 umount /target/run/cdrom

mv -t @ b* d* e* h* i* l* m* o* p* r* s* t* u* v*
mv @/var/* @var

** Btrfs Compress 를 사용하려면?

이 방법은 /target 안에 서브볼륨을 만들고, 그 서브볼륨을 마운트 하기 전에 마치 디렉토리처럼 간주하여 파일을 이동시킨다.
만약, Btrfs Compress 를 사용하고 싶다면, 저렇게 단순히 ‘이동’ 시킨 파일들은 압축되지 않은 상태가 된다.

/target 은 새로 Btrfs 생성한 파티션이 마운트 된 지점이지만, 우분투 설치프로그램은 이곳을 compress 로 마운트하진 않았다.
또, 다른 글에서도 언급했듯이, btrfs 는 한번 마운트 옵션을 주면, 모든 서브볼륨이 같은 마운트 옵션을 갖게 된다. 따라서, compress 를 주지 않았기 때문에, 이번 부트(生..)에서는 compress 를 줄 수가 없다.

따라서, 지금 당장으로는 이미 설치된 파일들을 Btrfs 압축 파티션으로 추가할 수가 없다.

아직 해보지는 않았지만, 만약 Btrfs 압축을 사용하고 싶다면, 다음 사항을 따라야 하지 않을까.. (아주 간략하게만 쓴다. 해보지는 않았기에.)

1. 일단 이 설치를 끝까지 마무리한다.
2. 바로 부팅하지 말고, 다시 라이브 디스크로 부팅한다.
3. 서브볼륨을 원본 이름은 바꾸고, 동일한 이름으로 다시 만든다. 예를 들어, @ 을 @-uncomp 로 바꾸고, 새로 @ 을 만든다.
4. compress 옵션을 주고 마운트 한 뒤, @-old 산하 모든 파일을 @ 로 ‘복사’ 한다. 이동(mv)하면, 아마도 압축되지 않은 상태 그대로 전송될 듯 하다. (확실하지 않다.)

아직 시험 전이라, 꼭 이래야만 하는지는 모르겠다.

run 디렉토리는 mv 가 안될 수도 있다. 굳이 이 디렉토리를 이동해줘야 할 필요는 없는데, 이동해주면, 아래에서 할 chroot 이후에도 네트웍 관련 작업(apt 등)을 그대로 할 수 있게 된다.

따라서, 이 작업이 필요하다면, 그리고 mv 시 run 디렉토리 관련 오류가 난다면, 수동으로 run 디렉토리를 ‘복사’ 해준다.

cp -r /target/run /target/@

만약, run 디렉토리가 mv 로 오류없이 이동한다면 그대로 하면 된다.
내 상식으로는, run 디렉토리는 시스템 첫 부팅 시에 새로 만들어지기 때문에, 굳이 남겨놓을 필요는 없다.

서브볼륨을 사용한 /target 재구성

이제, /target 을 마운트 해제하고, 새롭게 target 을 재구성한다.
그런데, run 디렉토리가 또 문제가 될 수도 있다. Busy 오류가 나오면서 마운트 해제가 되지 않을 경우가 있다.

그럴 때는 굳이 umount 를 하지 말고, /target2 등을 새로 만든 후 그 이하로 아래 작업을 시행하면 된다.

내가 참고한 글을 다시 살펴보면, 여기서 마운트할 때 compress=lzo 등을 선택사항을 줬다. (compress 에 관해선 역시나 ArchLinux 문서를 참고하면 되겠다.) 하지만 여기선 그냥 그 옵션들을 모두 생략했다. compress 에 대해 아직 공부를 하지 못했고, 용량이 충분해서 굳이 모험(?)을 할 필요는 없다고 생각했기 때문이다.

home, opt 는 지금은 mount 해주지 않아도 된다. (현 시점에선 쓸모가 없다.)

또, 원 글에서는 여기에 mount compress 옵션을 줬는데, /target 이 umount 가 되지 않는 상황에선 이 옵션을 줘도 의미가 없다. 게다가 굳이 지금 compress 를 줄 필요도 없다.
나중에 fstab 에서만 옵션을 주면 된다.

# cd /
# umount /target (오류가 나면 하지 말고, mkdir /target2 를 만든 뒤 아래를 모두 target 2 로 바꾼다.)
# mkdir /target2


# mount /dev/nvme0n1p3 /target2 mount -o subvol=@ # set-default 를 해줬기 때문에 subvol 은 필요없다.
# mount /dev/nvme0n1p2 /target2/boot
# mount /dev/nvme0n1p1 /target2/boot/efi
# mount /dev/nvme0n1p3 /target2/var -o subvol=@var

# mount --bind /proc /target2/proc  
# mount --bind /dev /target2/dev  
# mount --bind /sys /target2/sys

만약, set-default 를 해주지 않았다면, 다음과 같이 @ 를 명시해줘야 한다.

# mount /dev/nvme0n1p3 /target -o subvol=@

fstab 수정

이젠, fstab 을 수정해줘야 한다.
chroot 한 뒤 해도 되지만, 지금도 할 수 있다.
lsblk 를 참고하여, fstab 을 아래와 같이 고친다.
맨 먼저 / 를 마운트 해야 하고, 그 후에 home 등을 해주면 된다. (당연하지만, 여기선 반드시 home, opt, var 등 Subvolume 으로 만든 모든 것들을 포함시켜줘야 한다.)

Btrfs 의 현재 제약으로 인해, 마운트 옵션을 서브볼륨별로 달리 줄 수가 없다. 따라서, compress 등 옵션은, 맨 첫 서브볼륨(루트)에만 주고, 나머지엔 써주지 않아도 모두 동일한 옵션이 적용된다.

/boot 를 먼저, /boot/efi 를 나중에 해야 함도 잊지 말 것.

# lsblk -f
NAME         FSTYPE   LABEL UUID                                 MOUNTPOINT
nvme0n1                                                          
├─nvme0n1p1  vfat           zzzz                            /target/boot/efi
├─nvme0n1p2  ext4           yyyy                            /target/boot
└─nvme0n1p3  btrfs          xxxx                            /target


# vim /target2/etc/fstab
UUID=xxxx 	/ 		btrfs 	defaults,compress=lzo,subvol=@ 0 0
UUID=xxxx 	/home 		btrfs 	subvol=@home 0 0
UUID=xxxx 	/var 		btrfs 	subvol=@var 0 0
UUID=xxxx 	/opt 		btrfs 	subvol=@opt 0 0
UUID=yyyy 	/boot 		ext4 	defaults 0 0
UUID=zzzz	/boot/efi 	vfat 	defaults 0 0

밑밥은 끝났다. chroot 로 가상 시스템으로 접근한 뒤, 부트로더 관련 작업들을 해주면, 긴 장정이 끝나게 된다.

chroot 작업

# chroot /target2
# update-initramfs -u -k all  
# grub-install --recheck
# update-grub  

update-initramfs 을 하고 나면, cryptsetup 관련 오류가 발생한다.
이것은, ext4 로 설치했을 땐 생기지 않는데, 아마도 Btrfs 관련한 오작동으로 보인다.
나는 디스크 Encryption 을 전혀 사용하지 않았으므로, 이런 오류가 생길 이유가 없는데, 무슨 이유에선지 사람을 놀라게 했다.
그냥, cryptsetup 꾸러미를 지워버리는게 가장 단순하지만 효과 만점인 해결책이었는데.. 2020년 2월 현재, 이 꾸러미를 지우면, ubuntu-server 꾸러미도 지워진다.
따라서, 그냥 이 문제는 그냥 무시하고 넘길 수 밖에 없다.

이렇게 끝!
나중에 Snapshot 을 사용하는 법을 좀 더 제대로 알게되면, 따로 정리하기로 하자.
또, 이 방법을 응용하면, 나중에 Subvolume 을 추가하더라도 쉽게 사용할 수 있다.

방법은, 일단 다른 디스크(우분투 라이브 디스크)로 부팅한 뒤, 서버로 쓰는 디스크를 마운트하고, 거기서 서브볼륨 생성, 원 파일 이동 등 작업을 한 뒤, fstab 을 수정해주면 된다.

설치가 끝나고 할 일!

위 설치에서 약간 찌꺼기(?)가 남는다. FS_Root(파일시스템 root)에 run, cdrom 디렉토리가 지워지지 않고 그대로 남아있게 된다.

이건 그냥 부팅해서는 볼 수가 없고, 이 디스크를 다시 마운트 해줘야 볼 수 있는데, subvolume set-default 를 했다면, 마운트 시에 subvolid=5 를 추가해줘야만 이 디렉토리들을 볼 수 있게 된다.

이 작업은, 새로 만든 시스템으로 부팅한 후 해야 한다.

sudo mount /dev/xxxx /mnt -o subvolid=5
 % ll /mnt
total 0
drwxr-xr-x 1 root root 238 2020-01-29 00:30 @
drwxr-xr-x 1 root root  30 2020-01-16 17:22 @home
drwxr-xr-x 1 root root   0 2020-01-13 22:37 @opt
drwxr-xr-x 1 root root 128 2020-01-22 15:57 @var
drwxr-xr-x 1 root root   0 2020-01-13 22:37 cdrom
drwxr-xr-x 1 root root 128 2020-01-22 15:57 run

이런 식으로 cdrom 과 run 이 남아있을 가능성이 있다. 불필요하므로 지워준다.

이후, 여러가지 작업이 필요하겠지만, 로캘(locale) 설정, 시간대 설정이 가장 최우선이다.

로캘설정은 몇가지 방법이 있겠지만, dpkg-reconfigure 를 이용하는게 편하다.

sudo dpkg-reconfigure locales

시간대 설정도 같은 명령으로 가능하다.

sudo dpkg-reconfigure tzdata

** 아래 얘기는 내가 쓰긴 했는데, 결론이 뭔질 모르겠네. VBox 로 그래서 성공을 했다는 건가? VBox 가 다 날아가버렸기 때문에 이제 확인도 안되고.

* 실제 기계로는 NVMe 디스크로 위와 같이 해서 성공했지만, Virtual Box 의 NVMe 로는 실패했다. Btrfs 로 하지 않고, ext4 로 해도 NVMe 드라이브로 부팅은 불가능했다.
ㅆㅑㅇ! 이것 땜에 한참을 고생했다. 부팅을 하고 나면 UUID를 찾을 수 없다는 헛소리(?)를 출력하고, initramfs 로 빠져버린다.
실제 기계를 NVMe 로 사용했으므로, VBox 도 그렇게 설정하고, 다시 설치해보며 글을 확실히 정리하려고 했었으나.. VBox 의 오류로 인해 적어도 4시간쯤 헛짓을 했다. (아, 짜증이여..)

안녕하세요. 글 남겨주셔서 고맙습니다.