서버

AWS EBS 확장 및 축소

southouse 2023. 1. 16. 21:01
728x90

인프라를 운영하다 보면, 현재 사용하고 있는 디스크 볼륨의 크기를 늘리거나, 줄여야 할 때가 있다. EBS의 경우에는 기본적으로 확장의 개념은 쉽다. EBS 크기를 확장하고 서버에 접속하여 명령어로 파티션 크기만 늘려주면 된다.

반대로 축소는 굉장히 까다로운 작업이다.

기본적으로 확장만 제공하고 축소 기능은 제공하고 있지 않다.

볼륨크기축소

물론, 서브 볼륨이라면 크기가 작은 새로운 볼륨을 마운트하여 파일 복사만 하면 되지만, 루트 볼륨인 경우에는 단순하게 파일 복사만 해선 안 된다.

새로운 볼륨을 추가하고, 부트 로더를 설치해주고, 기존에 사용하던 루트 볼륨의 UUID를 가져와서 교체할 루트 볼륨에 라벨을 넣어줘야 한다.


Amazon Linux 2 기준으로 작성된 문서입니다. 그 외 CentOS나 RHEL 계열의 리눅스면 동일한 명령어를 사용하지만, Ubuntu의 경우에는 명령어가 조금 다를 수 있습니다.

EBS 확장

EBS의 확장은 간단하다. AWS에서 볼륨 크기를 늘려주고, 서버에 접속하여 파티션 확장 명령어를 입력하면 된다. 그리고 루트 볼륨이나 서브 볼륨이나 확장 방법이 동일하다. 중요한 포인트는 중단 없이 확장이 가능하다는 점이다.

우선, EC2에 할당된 볼륨 수정페이지에 가서 용량을 늘려준다.
ebs_extends

ebs_extends2

10GiB에서 20GiB로 증가시켰고, 이후에 볼륨을 확인해보면 Volume state가 상태에서 In-use - optimizing 상태로 바뀌고 변경이 완료되면 In-use 상태로 바뀐다.

ebs_extends3

이제 EC2에 SSH로 접속하여 확인해보도록 하자.

[ec2-user@ip-192-168-1-11 ~]$ sudo lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  20G  0 disk
|-nvme0n1p1   259:1    0  10G  0 part /
`-nvme0n1p128 259:2    0   1M  0 part

nvme0n1은 디바이스 이름이고, 뒤에 붙은 p1은 해당 디바이스에 할당된 파티션의 번호다. 두번째 파티션을 할당하게 되면 nvme0n1p2로 할당된다. 실제로 디바이스의 위치는 /dev 경로에 위치하게 된다.

/dev/nvme0n1 디바이스 SIZE는 20G로 증가됐고, primary 파티션 1이 '/' 경로에 10G 만큼 마운트 되어 있는걸 확인할 수 있다. 따라서 볼륨은 크기가 증가했지만, 아직 실제로 할당된 크기는 변경 전과 동일하다.

# sudo growpart ${디바이스 경로} ${파티션 번호}
[ec2-user@ip-192-168-1-11 ~]$ sudo growpart /dev/nvme0n1 1
CHANGED: partition=1 start=4096 old: size=20967391 end=20971487 new: size=41938911 end=41943007

[ec2-user@ip-192-168-1-11 ~]$ sudo lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  20G  0 disk
|-nvme0n1p1   259:1    0  20G  0 part /
`-nvme0n1p128 259:2    0   1M  0 part

이걸로 확장은 끝났다. 명령어 두개로 해결할 수 있는 굉장히 간단한 작업이다.


EBS 축소

축소가 안 되는 이유는 생각보다 간단하다. 우리가 외장 하드 100G 짜리를 구매했다가, 그것을 50G로 축소 시킬 방법은 없기 때문이다. 그래서 이번에 작업은 원래대로라면 볼륨 데이터를 이동한다고 설명하는게 맞다.

근데 위에서도 언급했듯이, 서브 볼륨의 크기를 줄이기 위함이라면 단순하게 데이터 이동이 맞지만, 루트 볼륨의 경우라면 볼륨 안에 부팅 시스템, 리눅스 커널, 시스템 파일 등 굉장히 많은 파일을 담고 있기 때문에 좀 더 추가적인 작업이 필요하다.

확장에서 사용한 EBS를 그대로 사용하여, 20G로 할당된 EBS를 다시 10GB로 바꿔보려고 한다.

일단, 새로운 루트 볼륨으로 사용하기 위한 10GB 크기를 가진 EBS를 생성하여 EC2에 연결한다.

EC2에 EBS를 연결하기 위해서는 동일한 가용 영역을 설정해줘야 하고, EBS를 루트 볼륨으로 사용하기 위해서는 해당 리눅스 운영체제의 최소 크기의 조건에 부합해야 한다. 예를 들면, Amazon Linux 2 기준으로 최소 8GB 이상의 크기를 가져야 한다.

EBS 추가요

EBS 연결이요

디바이스 이름은 기본적으로 서브 볼륨의 경우에는 /dev/sd[f-p] 순으로 지정을 해주는 것 같다. 실제로 EC2에 접속하여 확인해보면 /dev/nvme1n1 라는 이름으로 연결되어 있다.

자, EC2에 연결하고 명령어를 통해 제대로 서브 볼륨이 연결됐는지 확인해보도록 하자.

[ec2-user@ip-192-168-1-11 ~]$ sudo lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  20G  0 disk
|-nvme0n1p1   259:1    0  20G  0 part /
`-nvme0n1p128 259:2    0   1M  0 part
nvme1n1       259:3    0  10G  0 disk

nvme1n1 디바이스(볼륨)이 추가됐다.

이제 새로운 볼륨의 파일시스템을 ext4로 포맷해준다.

# 새로운 볼륨의 파일 시스템을 ext4로 포맷
[ec2-user@ip-192-168-1-11 ~]$ sudo mkfs -t ext4 /dev/nvme1n1
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 2621440 blocks
131072 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2151677952
80 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

[ec2-user@ip-192-168-1-11 ~]$ sudo blkid
/dev/nvme1n1: UUID="13baec09-0ca9-4bab-8dfa-7ea77d6153c7" TYPE="ext4"
/dev/nvme0n1: PTUUID="a6da6d83-4bb8-4fdb-855d-26ab58e934ba" PTTYPE="gpt"
/dev/nvme0n1p1: LABEL="/" UUID="47834bf7-764e-42f9-9507-11a3e70b99de" TYPE="xfs" PARTLABEL="Linux" PARTUUID="3f38956d-a18d-4f75-984e-fee6ac8c084d"
/dev/nvme0n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="843c6a80-6801-46e7-96cb-f84eaebc854b"

그 다음에 /mnt/new-vol에 마운트하고, 루트 볼륨에 저장되어 있는 데이터를 rsync라는 명령어를 이용하여 그대로 복사해 가져온다.

# 마운트 디렉토리 생성 및 마운트
[ec2-user@ip-192-168-1-11 ~]$ sudo mkdir /mnt/new-vol
[ec2-user@ip-192-168-1-11 ~]$ sudo mount /dev/nvme1n1 /mnt/new-vol
[ec2-user@ip-192-168-1-11 ~]$ sudo lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  20G  0 disk
|-nvme0n1p1   259:1    0  20G  0 part /
`-nvme0n1p128 259:2    0   1M  0 part
nvme1n1       259:3    0  10G  0 disk /mnt/new-vol

# / 에서 /mnt/new-vol/ 경로로 데이터 복사
[ec2-user@ip-192-168-1-11 ~]$ sudo rsync -axv / /mnt/new-vol/
... 생략
var/spool/postfix/public/flush
var/spool/postfix/public/pickup
var/spool/postfix/public/qmgr
var/spool/postfix/public/showq
var/spool/postfix/saved/
var/spool/postfix/trace/
var/tmp/
var/tmp/systemd-private-c4fce64291b74dc29274c59380caa768-chronyd.service-XmHiCP/
var/tmp/systemd-private-c4fce64291b74dc29274c59380caa768-chronyd.service-XmHiCP/tmp/
var/yp/

sent 1,529,422,377 bytes  received 853,112 bytes  51,873,745.39 bytes/sec
total size is 1,576,059,207  speedup is 1.03

# 확인
[ec2-user@ip-192-168-1-11 ~]$ ll /mnt/new-vol
total 16
lrwxrwxrwx  1 root root    7 Dec 15 21:53 bin -> usr/bin
dr-xr-xr-x  4 root root 4096 Jan 16 07:57 boot
drwxr-xr-x  2 root root    6 Jan 16 10:27 dev
drwxr-xr-x 81 root root 8192 Jan 16 10:35 etc
drwxr-xr-x  3 root root   22 Jan 12 14:25 home
lrwxrwxrwx  1 root root    7 Dec 15 21:53 lib -> usr/lib
lrwxrwxrwx  1 root root    9 Dec 15 21:53 lib64 -> usr/lib64
drwxr-xr-x  2 root root    6 Dec 15 21:52 local
drwxr-xr-x  2 root root    6 Apr  9  2019 media
drwxr-xr-x  3 root root   21 Jan 16 10:40 mnt
drwxr-xr-x  4 root root   27 Dec 15 21:54 opt
dr-xr-xr-x  2 root root    6 Jan 12 14:25 proc
dr-xr-x---  3 root root  119 Jan 16 10:35 root
drwxr-xr-x  2 root root    6 Jan 16 00:52 run
lrwxrwxrwx  1 root root    8 Dec 15 21:53 sbin -> usr/sbin
drwxr-xr-x  2 root root    6 Apr  9  2019 srv
dr-xr-xr-x  2 root root    6 Jan 12 14:25 sys
drwxrwxrwt  8 root root  172 Jan 16 10:04 tmp
drwxr-xr-x 13 root root  155 Dec 15 21:53 usr
drwxr-xr-x 19 root root  269 Jan 12 14:25 var

부트 로더를 설치하고, 기존에 사용하던 루트 볼륨의 UUID를 복사한다.

# 부트 로더 설치
[ec2-user@ip-192-168-1-11 ~]$ sudo grub2-install --root-directory=/mnt/new-vol --force /dev/nvme1n1
Installing for i386-pc platform.
grub2-install: warning: File system `ext2' doesn't support embedding.
grub2-install: warning: Embedding is not possible.  GRUB can only be installed in this setup by using blocklists.  However, blocklists are UNRELIABLE and their use is discouraged..
Installation finished. No error reported.

# /mnt/new-vol 마운트 해제
[root@ip-192-168-1-11 ~]$ sudo umount /mnt/new-vol
[ec2-user@ip-192-168-1-11 ~]$ sudo lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  20G  0 disk
|-nvme0n1p1   259:1    0  20G  0 part /
`-nvme0n1p128 259:2    0   1M  0 part
nvme1n1       259:3    0  10G  0 disk

# 루트 볼륨 UUID 확인
[ec2-user@ip-192-168-1-11 ~]$ sudo blkid
/dev/nvme0n1p1: LABEL="/" UUID="47834bf7-764e-42f9-9507-11a3e70b99de" TYPE="xfs" PARTLABEL="Linux" PARTUUID="3f38956d-a18d-4f75-984e-fee6ac8c084d"
/dev/nvme1n1: UUID="13baec09-0ca9-4bab-8dfa-7ea77d6153c7" TYPE="ext4" PTTYPE="dos"
/dev/nvme0n1: PTUUID="a6da6d83-4bb8-4fdb-855d-26ab58e934ba" PTTYPE="gpt"
/dev/nvme0n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="843c6a80-6801-46e7-96cb-f84eaebc854b"

# 새로운 볼륨에 루트 볼륨 UUID 복사
[ec2-user@ip-192-168-1-11 ~]$ sudo tune2fs -U 47834bf7-764e-42f9-9507-11a3e70b99de /dev/nvme1n1
tune2fs 1.42.9 (28-Dec-2013)

# 새로운 볼륨(/dev/nvme1n1)과 기존 루트 볼륨(/dev/nvme0n1p1)의 UUID가 동일한지 확인
[ec2-user@ip-192-168-1-11 ~]$ sudo blkid
/dev/nvme1n1: UUID="47834bf7-764e-42f9-9507-11a3e70b99de" TYPE="ext4" PTTYPE="dos"
/dev/nvme0n1p1: LABEL="/" UUID="47834bf7-764e-42f9-9507-11a3e70b99de" TYPE="xfs" PARTLABEL="Linux" PARTUUID="3f38956d-a18d-4f75-984e-fee6ac8c084d"
/dev/nvme0n1: PTUUID="a6da6d83-4bb8-4fdb-855d-26ab58e934ba" PTTYPE="gpt"
/dev/nvme0n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="843c6a80-6801-46e7-96cb-f84eaebc854b"

이제, 기존의 루트 EBS 볼륨을 해제하고, 새로운 EBS 볼륨을 루트 EBS 볼륨으로 연결해주면 된다. 인스턴스 상태가 Stopped 됐을 때만 루트 EBS 볼륨 해제가 가능하다.

EC2 인스턴스의 루트 EBS 볼륨 디바이스 이름을 확인하고, 새로운 EBS 볼륨 디바이스 이름을 똑같이 지정하면 된다.

루트 EBS 볼륨 이름

새로운 EBS 볼륨 연결

연결이 됐는지, Volume ID로 확인한다.

EBS 연결 확인

이제 서버에 접속하여 루트 볼륨 연결이 잘 됐는지 확인해보도록 한다!

[ec2-user@ip-192-168-1-11 ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        464M     0  464M   0% /dev
tmpfs           472M     0  472M   0% /dev/shm
tmpfs           472M  392K  472M   1% /run
tmpfs           472M     0  472M   0% /sys/fs/cgroup
/dev/nvme0n1    9.7G  1.7G  7.6G  18% /
tmpfs            95M     0   95M   0% /run/user/1000

[ec2-user@ip-192-168-1-11 ~]$ sudo lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0    0  10G  0 disk /

10G가 할당된 서브 볼륨의 디바이스 이름이 /dev/nvme1n1에서 dev/nvme0n1 으로 바뀌어 있었고, 루트 볼륨으로 할당이 제대로 되었음을 확인한다.

그냥 /etc/fstab에서 UUID만 바꿔주면 되지 않나요?

기존 루트 볼륨의 UUID를 복사하지 말고, 리눅스 부팅 시에 마운트 정보를 불러올 수 있는 /etc/fstab에 루트 볼륨으로 교체할 서브 볼륨의 UUID를 그냥 넣어서 / 에 마운트하면 되지 않을까? 라는 의문이 든다.

[ec2-user@ip-192-168-1-11 ~]$ cat /etc/fstab
UUID=47834bf7-764e-42f9-9507-11a3e70b99de     /           xfs    defaults,noatime  1   1

하지만, 루트 볼륨의 경우 단순하게 데이터를 루트 경로에 마운트가 된다는 의미뿐만 아니라, 위에서 언급한 부트 로더와 연관이 되어 있다. GRUB2 기준으로 리눅스는 부팅 시에 /boot/grub2/grub.cfg 파일에서 커널 및 부팅 정보를 불러와서 부팅한다.

[ec2-user@ip-192-168-1-11 ~]$ sudo cat /boot/grub2/grub.cfg
...
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Amazon Linux (5.10.157-139.675.amzn2.x86_64) 2' --class centos rhel fedora --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.157-139.675.amzn2.x86_64-advanced-47834bf7-764e-42f9-9507-11a3e70b99de' {
    insmod gzio
    insmod part_gpt
    insmod xfs
    search --no-floppy --fs-uuid --set=root 47834bf7-764e-42f9-9507-11a3e70b99de
    linux /boot/vmlinuz-5.10.157-139.675.amzn2.x86_64 root=UUID=47834bf7-764e-42f9-9507-11a3e70b99de ro  console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0
    initrd /boot/initramfs-5.10.157-139.675.amzn2.x86_64.img
}

### END /etc/grub.d/10_linux ###
...

위의 내용을 확인해보면 부팅 시에 /boot/vmlinuz-5.10.157-139.675.amzn2.x86_64 커널을 사용하고, 기본 부팅 디바이스를 UUID가 47834bf7-764e-42f9-9507-11a3e70b99de 인 디바이스로 지정한다는 내용이다.

때문에, UUID를 복사하지 않고 적용하기 위해서는

  1. grub2 설정에서 기본 부팅 디바이스 UUID 업데이트
  2. /etc/fstab 에서 / 마운트 정보를 변경

의 작업이 필요하다.

Reference

300x250