리눅스에 새 디스크를 붙이는 순서는 정해져 있다. lsblk로 인식 확인 → (선택)파티션 → mkfs 포맷 → 마운트포인트 생성 → mount 임시 마운트 → blkid로 UUID 확인 → /etc/fstab 등록 → mount -a 검증이다. fstab은 반드시 UUID로 등록하고 옵션에 nofail을 넣는다. 디바이스 이름(/dev/nvme1n1 등)은 부팅마다 바뀔 수 있어 fstab에 직접 쓰면 부팅이 깨질 수 있다.
1. 새 디스크 인식 확인 (lsblk)
클라우드 콘솔에서 볼륨을 붙였거나 물리 디스크를 장착했으면 먼저 OS가 보는지 확인한다. AWS Nitro 계열 인스턴스는 /dev/nvme1n1, 구형 Xen 기반은 /dev/xvdf로 잡힌다.
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS nvme0n1 259:0 0 20G 0 disk ├─nvme0n1p1 259:1 0 19G 0 part / └─nvme0n1p128 259:2 0 1M 0 part nvme1n1 259:3 0 100G 0 disk
nvme1n1이 100G로 보이고 MOUNTPOINTS가 비어 있다. 아직 포맷도 마운트도 안 된 빈 디스크다. 여기서 디바이스 이름을 정확히 확인하고 넘어간다. 잘못된 디스크를 포맷하면 운영 데이터가 날아간다.
막상 해보면 디바이스 이름을 착각하는 데서 사고가 가장 많이 난다. SIZE와 기존 마운트 여부를 같이 보고 새 디스크가 맞는지 두 번 확인한다.
2. 파티션은 만들어야 하나 (선택)
결론부터 말하면, 단일 용도로 디스크 전체를 한 덩어리로 쓸 거라면 파티션을 만들 필요가 없다. 디스크 전체(/dev/nvme1n1)에 바로 파일시스템을 만들어도 된다. 파티션 테이블을 굳이 두는 경우는 한 디스크를 여러 영역으로 쪼개거나, 나중에 파티션 단위 관리가 필요할 때다.
파티션을 만든다면 2TiB를 넘는 디스크는 MBR이 아니라 GPT를 써야 한다. parted로 GPT 파티션 하나를 만드는 방법은 다음과 같다.
$ sudo parted /dev/nvme1n1 mklabel gpt $ sudo parted -a opt /dev/nvme1n1 mkpart primary 0% 100% $ lsblk /dev/nvme1n1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS nvme1n1 259:3 0 100G 0 disk └─nvme1n1p1 259:4 0 100G 0 part
이제 대상 디바이스는 파티션 /dev/nvme1n1p1이 된다. 파티션을 안 만들기로 했다면 아래부터는 /dev/nvme1n1을 그대로 쓰면 된다. 이 글에서는 파티션 없이 디스크 전체를 쓰는 쪽으로 진행한다.
3. 파일시스템 포맷 (ext4 또는 xfs)
리눅스 서버에서 가장 흔한 선택은 ext4와 xfs다. RHEL 계열의 기본 파일시스템은 xfs, Debian/Ubuntu 계열은 ext4가 기본이다. 큰 파일과 병렬 I/O가 많은 워크로드면 xfs, 작은 파일이 많고 온라인 축소(shrink)가 필요할 수 있으면 ext4를 권한다. xfs는 확장은 되지만 축소가 안 된다.
ext4로 포맷
$ sudo mkfs -t ext4 /dev/nvme1n1 mke2fs 1.46.5 (30-Dec-2021) Creating filesystem with 26214400 4k blocks and 6553600 inodes Filesystem UUID: 9b2e7c1a-3f4d-4a8b-9c2e-1d5f6a7b8c9d Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (131072 blocks): done Writing superblocks and filesystem accounting information: done
xfs로 포맷
$ sudo mkfs -t xfs /dev/nvme1n1
meta-data=/dev/nvme1n1 isize=512 agcount=4, agsize=6553600 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1 bigtime=1 inobtcount=1 nrext64=0
data = bsize=4096 blocks=26214400, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=12800, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
mkfs -t xfs는 mkfs.xfs를 호출한다. 기본 옵션이 운영용으로 적절하므로 별도 튜닝 없이 그대로 쓴다. 한 가지 함정이 있다. 디스크에 이미 파일시스템 흔적이 남아 있으면 mkfs.xfs는 덮어쓰기를 거부하고 멈춘다.
mkfs.xfs: /dev/nvme1n1 appears to contain an existing filesystem (ext4). mkfs.xfs: Use the -f option to force overwrite.
정말 그 디스크가 맞다면 sudo mkfs -t xfs -f /dev/nvme1n1로 강제한다. 이 안전장치 덕분에 디스크를 잘못 지정해도 한 번 걸러진다. ext4의 mkfs.ext4는 마운트되지 않은 디스크면 경고 정도만 내고 진행하므로 디바이스 이름 확인이 더 중요하다.
4. 마운트포인트 생성과 임시 마운트 (mount -t)
마운트할 디렉터리를 먼저 만든다. 데이터용이면 /data나 /mnt/data처럼 용도를 알 수 있는 경로가 좋다.
$ sudo mkdir -p /data $ sudo mount -t xfs /dev/nvme1n1 /data
-t 뒤에는 포맷할 때 쓴 파일시스템 타입을 넣는다. ext4면 -t ext4다. 사실 mount는 타입을 자동 판별하므로 -t를 생략해도 마운트되지만, 의도한 타입이 맞는지 명시하는 습관이 사고를 줄인다. 마운트가 됐는지 확인한다.
$ df -h /data Filesystem Size Used Avail Use% Mounted on /dev/nvme1n1 100G 747M 100G 1% /data
이 마운트는 임시다. 지금 재부팅하면 마운트가 풀린다. 영구로 만들려면 다음 단계인 fstab 등록이 필요하다.
5. UUID 확인 (blkid)
fstab에는 디바이스 이름 대신 UUID를 쓴다. 디바이스 이름(/dev/nvme1n1, /dev/xvdf)은 디스크를 추가하거나 떼면 부팅 때 순서가 바뀔 수 있다. UUID는 파일시스템에 고정으로 박혀 있어 바뀌지 않는다.
$ sudo blkid /dev/nvme1n1 /dev/nvme1n1: UUID="3f8a1b2c-4d5e-6f70-8a9b-0c1d2e3f4a5b" TYPE="xfs"
여기 나온 UUID 값을 복사한다. lsblk -f로도 같은 값을 볼 수 있다.
$ lsblk -f /dev/nvme1n1 NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS nvme1n1 xfs 3f8a1b2c-4d5e-6f70-8a9b-0c1d2e3f4a5b 99.3G 1% /data
6. /etc/fstab 영구 등록
/etc/fstab은 부팅 때 자동 마운트할 파일시스템을 정의한다. 한 줄이 한 마운트이고 여섯 개 필드로 구성된다.
- fs_spec: 디바이스.
UUID=...형식으로 쓴다. - fs_file: 마운트포인트 디렉터리.
- fs_vfstype: 파일시스템 타입(ext4, xfs 등).
- fs_mntops: 마운트 옵션. 쉼표로 구분.
- fs_freq: dump 백업 대상 여부. 보통 0.
- fs_passno: 부팅 시 fsck 검사 순서. 루트는 1, 나머지는 2, 검사 안 하면 0.
편집기로 /etc/fstab 끝에 한 줄 추가한다.
$ sudo vi /etc/fstab
추가할 내용(xfs 기준):
UUID=3f8a1b2c-4d5e-6f70-8a9b-0c1d2e3f4a5b /data xfs defaults,nofail 0 0
ext4면 세 번째 필드를 ext4로 바꾸고, fsck를 쓰려면 여섯 번째 필드를 2로 둔다. xfs는 부팅 fsck를 쓰지 않으므로 0이 맞다.
UUID=9b2e7c1a-3f4d-4a8b-9c2e-1d5f6a7b8c9d /data ext4 defaults,nofail 0 2
nofail을 꼭 넣는다. 이 옵션은 해당 디바이스가 부팅 시점에 없거나 마운트에 실패해도 오류로 보고하지 않고 부팅을 계속하게 한다. 클라우드에서 볼륨이 분리됐거나 디스크 교체 중일 때, nofail이 없으면 시스템이 emergency mode로 떨어져 콘솔 접속 없이는 복구가 안 된다. 데이터 디스크에는 거의 항상 nofail을 권한다.
7. mount -a로 부팅 전 검증
fstab을 잘못 쓰면 다음 재부팅에서 부팅이 멈춘다. 재부팅하기 전에 반드시 mount -a로 문법을 검증한다. 먼저 임시 마운트를 풀고 fstab만으로 마운트되는지 본다.
$ sudo umount /data $ sudo mount -a $ df -h /data Filesystem Size Used Avail Use% Mounted on /dev/nvme1n1 100G 747M 100G 1% /data
mount -a는 fstab에서 noauto가 아닌 항목을 전부 마운트한다. 에러 없이 끝나고 df -h에 다시 보이면 fstab이 정상이다. 만약 UUID 오타가 있으면 다음처럼 나온다.
mount: /data: can't find UUID=3f8a1b2c-....
dmesg(1) may have more information after failed umount(1) system call.
이 에러가 보이면 부팅하지 말고 fstab의 UUID를 blkid 출력과 다시 대조한다. nofail을 넣어 뒀더라도 검증은 해야 한다. nofail은 부팅을 막지 않을 뿐, 마운트 자체가 잘못된 걸 고쳐 주지는 않는다.
systemd를 쓰는 배포판이라면 fstab 변경 후 sudo systemctl daemon-reload를 한 번 실행해 mount 유닛을 갱신해 두면 깔끔하다.
8. 최종 확인
전체 결과를 df -h와 lsblk로 한 번에 본다.
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/nvme0n1p1 19G 4.2G 15G 22% / /dev/nvme1n1 100G 747M 100G 1% /data $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS nvme0n1 259:0 0 20G 0 disk ├─nvme0n1p1 259:1 0 19G 0 part / └─nvme0n1p128 259:2 0 1M 0 part nvme1n1 259:3 0 100G 0 disk /data
이제 /data가 nvme1n1에 영구 마운트됐다. 마지막으로 소유권을 애플리케이션 계정에 맞춰 둔다. root만 쓰면 마운트 직후 일반 사용자 쓰기가 막힌다.
$ sudo chown -R www-data:www-data /data
참고로 출력의 버전 번호(mke2fs 1.46.5 등)와 UUID 값은 배포판과 디스크 상태에 따라 다르다. 명령 순서와 옵션이 핵심이다.