안녕하세요 오픈소스컨설팅에서 리눅스 기술지원을 하고 있는 이동원입니다.
오픈소스컨설팅에서 일하면서, 리눅스 환경의 다양한 오픈소스를 하나하나 알아가는 재미로, 눈코 뜰새 없이 바쁘게 시간을 보내고 있습니다.
리눅스 시스템을 지원하다 보면, 파일 시스템 용량이 부족한 경우가 생겨서 파일 시스템 확장이 필요한 경우가 있습니다. 그럴 때 유용하게 사용했던 growpart
라는 명령 도구가 있어서 소개해 보겠습니다.
예전에는 fdisk 나 parted 명령어를 사용해서, 파티션 작업을 했었습니다. fdisk 및 parted 도구는 Text User Interface 릍 통해서, 수행할 작업을 메뉴 방식으로 선택할 수 있습니다. 익숙해지면 사용하는데 크게 어려움은 없지만, 기반 지식등이 좀 있어야 잘못 작업할 일이 없습니다.
이에 비해, growpart 는 쉽게 디스크 파티션 확장을 할 수 있습니다.
간단히 장점을 나열해 보면 다음과 같습니다.
- 명령이 매우 단순합니다.
- 적용 전에 작업 전/후 변경 사항을 확인할 수 있습니다.
- 파티션 확장시 섹터 정보를 알지 못 하더라도, 도구에서 자동으로 처리해 줍니다.
그리고 제한 사항으로는,
- 파티션의 마지막 섹터 주소 이후에 연속된 빈 공간이 있어야 합니다.
- 디스크 확장을 한 경우, 확장할 파티션이 디스크 레이아웃 상 마지막 파티션이어야 합니다. (위 제한사항처럼, 마지막 섹터 주소 이후에 빈 공간이 있어야 합니다.)
이제 growpart 라는 명령 도구를 사용해서 루트 파일시스템을 확장하는 방법을 알아보고, 어떤 식으로 파티션을 확장하는지 알아보겠습니다.
growpart 와 growpart 를 이용한 루트 파일 시스템 확장
1. growpart 란
growpart 는 유명한 Linux 배포판인 ubuntu 를 제공하는 canonical 에서 작성하고 공개한 오픈소스 도구로, 디스크의 파티션 테이블을 수정하여 파티션을 확장하는데 사용합니다.
간단히 growpart 에 대하여 살펴보고, 파일시스템을 확장해 보겠습니다.
제가 테스트할 환경은 아래와 같습니다.
[ec2-user@ip-172-31-32-193 ~]$ cat /etc/os-release |grep PRETT
PRETTY_NAME="Amazon Linux 2"
[ec2-user@ip-172-31-32-193 ~]$ uname -ri
5.10.135-122.509.amzn2.x86_64 x86_64
- AWS 환경에서 테스트를 하고 있고, Amazon Linux 2 를 OS 이미지로 선택했습니다.
growpart 명령과 관련 패키지 정보, 그리고 help 출력과 man page 출력를 확인해 보겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ which growpart
/usr/bin/growpart
[ec2-user@ip-172-31-32-193 ~]$ rpm -qf /usr/bin/growpart
cloud-utils-growpart-0.31-3.amzn2.noarch
[ec2-user@ip-172-31-32-193 ~]$ rpm -qi cloud-utils-growpart-0.31-3.amzn2.noarch
Name : cloud-utils-growpart
Version : 0.31
Release : 3.amzn2
Architecture: noarch
Install Date: Wed 14 Sep 2022 09:02:23 PM UTC
Group : System Environment/Base
Size : 64795
License : GPLv3
Signature : RSA/SHA256, Wed 12 Jan 2022 07:31:03 AM UTC, Key ID 11cf1f95c87f5b1a
Source RPM : cloud-utils-growpart-0.31-3.amzn2.src.rpm
Build Date : Thu 23 Dec 2021 05:47:21 AM UTC
Build Host : build.amazon.com
Relocations : (not relocatable)
Packager : Amazon Linux
Vendor : Amazon Linux
URL : https://launchpad.net/cloud-utils
Summary : Script for growing a partition
Description :
This package provides the growpart script for growing a partition. It is
primarily used in cloud images in conjunction with the dracut-modules-growroot
package to grow the root partition on first boot.
[ec2-user@ip-172-31-32-193 ~]$ file /usr/bin/growpart
/usr/bin/growpart: POSIX shell script, ASCII text executable
[ec2-user@ip-172-31-32-193 ~]$ growpart --help
growpart disk partition
rewrite partition table so that partition takes up all the space it can
options:
-h | --help print Usage and exit
--fudge F if part could be resized, but change would be
less than 'F' bytes, do not resize (default: 1048576)
-N | --dry-run only report what would be done, show new 'sfdisk -d'
-v | --verbose increase verbosity / debug
-u | --update R update the the kernel partition table info after growing
this requires kernel support and 'partx --update'
R is one of:
- 'auto' : [default] update partition if possible
- 'force' : try despite sanity checks (fail on failure)
- 'off' : do not attempt
- 'on' : fail if sanity checks indicate no support
Example:
- growpart /dev/sda 1
Resize partition 1 on /dev/sda
[ec2-user@ip-172-31-32-193 ~]$ man growpart |tail -n +9|head -n2
SYNOPSIS
growpart [OPTIONS] DISK PARTITION-NUMBER
/usr/bin/growpart
가 명령어 경로입니다.- 패키지는
cloud-utils-growpart
입니다. 패키지의 버전은 0.31 입니다. - 패키지 정보 중에 Description 부분을 보니, cloud image 에서 인스턴스를 생성하고 첫 부팅시에, root 볼륨의 크기를 늘리기 위해 사용된다는 설명입니다.
growpart
명령은 binary 가 아닌 shell script 입니다. 나중에 스크립트 내용을 확인해 보겠습니다.growpart --help
명령으로 보니, 사용할 수 있는 option 과, Example 로 명령어 예시를 보여줍니다.- growpart man page 를 통해, 명령어 형식도 확인할 수 있습니다.
- Example 에 “
growpart /dev/sda 1
“ 와 man page 에서 확인한 “growpart [OPTIONS] DISK PARTITION-NUMBER
” 과 비교해 보니, 사용법이 좀 더 이해가 가는 것 같습니다.. - 제가 테스트하는 환경에 적용해 보면, 아래 명령처럼 사용하면 되겠습니다.
growpart /dev/xvda 1
아래는 제가 사용하는 환경의 디스크 및 파티션 정보입니다.
[ec2-user@ip-172-31-32-193 ~]$ df -hT /
Filesystem Type Size Used Avail Use% Mounted on
/dev/xvda1 xfs 20G 2.1G 18G 11% /
[ec2-user@ip-172-31-32-193 ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 20G 0 disk
└─xvda1 202:1 0 20G 0 part /
[ec2-user@ip-172-31-32-193 ~]$ sudo parted /dev/xvda print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
128 1049kB 2097kB 1049kB BIOS Boot Partition bios_grub
1 2097kB 21.5GB 21.5GB xfs Linux
- 인스턴스 생성시에 볼륨 크기는 20GB 로 설정했고, 설정된대로 /dev/xvda 디바이스가 20G 로 보입니다.
- /dev/xvda 에 볼륨에 파티션이 1개 있습니다. 파티션 1번입니다.
- 아 그리고 gpt 파티션 테이블입니다.
파티션 테이블은 mbr 과 gpt 를 주로 쓰는데, 가장 큰 차이는 mbr 은 파티션 크기가 2TB 까지이고, gpt 는 이론상 8ZB(K->M->G->T->P->E->Z) 입니다.
2. growpart 명령으로 루트 파티션을 확장
이제 디스크를 확장시킨 후에 growpart 로 파티션을 확장시켜서 루트 파일시스템의 크기를 늘려보도록 하겠습니다.
순서는 아래처럼 진행하는데, 디스크 확장하는 첫번째 부분에 대한 설명은 생략하겠습니다.
- 루트 디스크 볼륨 확장 – 각 Cloud platform 에서 볼륨 크기를 확장합니다. 현재 20G 인데 50G 로 늘리겠습니다.
- 루트 파티션 확장 – 여기서의 주제인
growpart
명령어를 사용하겠습니다. - 파일시스템 확장 – 현재 xfs 파일시스템이니,
xfs_growfs
명령어로 확장합니다.
주의: 어떠한 환경이든, 볼륨 작업을 하기 전에는 백업을 준비하여 장애 상황에 대한 대비를 하는게 좋겠습니다.
1) 루트 디스크 볼륨 확장
위에 적은대로 디스크 볼륨을 확장하는 설명은 생략하고, 결과만 보도록 하겠습니다.
아래는 gnome-disks
라는 도구로 확장 전과 확장 후의 화면을 캡쳐해 봤습니다.
- 확장 후 파티션 1 번 옆에
"Free Space"
가 생긴게 보입니다. 디스크 볼륨이 확장되었습니다.
command line 에서도 확인해 보겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 50G 0 disk
└─xvda1 202:1 0 20G 0 part /
[ec2-user@ip-172-31-32-193 ~]$ sudo parted /dev/xvda print
Error: The backup GPT table is not at the end of the disk, as it should be. This might mean that another operating system believes the disk is smaller. Fix, by moving
the backup to the end (and removing the old backup)?
Fix/Ignore/Cancel? ^C
Warning: Not all of the space available to /dev/xvda appears to be used, you can fix the GPT to use all of the space (an extra 62914560 blocks) or continue with the
current setting?
Fix/Ignore? ^C
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvda: 53.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
128 1049kB 2097kB 1049kB BIOS Boot Partition bios_grub
1 2097kB 21.5GB 21.5GB xfs Linux
lsblk
에서 xvda 의 SIZE 가 50G 로 표시됩니다.parted
명령을 치니, Error 와 Warning 을 뿌리면서 선택을 강요합니다. “Ctrl + C” 키를 눌러 무시하도록 합니다. 아래 부분에Disk /dev/xvda: 53.7GB
를 확인할 수 있습니다.
명령어나 툴에 따라서, 디스크 볼륨의 크기가 약간씩 다르게 나오는 것을 볼 수 있습니다.
용량을 계산할 때, 10의 멱승으로 계산하느냐 2의 멱승으로 계산하느냐에 따라 다릅니다.
AWS 콘솔에서는 2의 멱승으로 계산하는 것 같습니다. 표준 표기법으로 20 GiB 인거죠.
lsblk 명령 결과에서도 2의 멱승으로 계산해서 20GiB 가 됩니다.
위에 이미지(gnome-disks 유틸)나 parted 명령 결과에서 보여주는 크기는 10의 멱승으로 계산되다 보니, 20GiB 를 21GB 로, 50GiB 를 54GB 로 표시되고 있습니다.
- 테스트하는 환경의 디스크 디바이스는
/dev/xvda
이고, 파티션 번호는1
입니다.lsblk
명령과parted
명령에서 확인했었습니다. 아래 명령을 사용하면 되겠습니다.growpart /dev/xvda 1
바로 사용해 보겠습니다만… 그 전에 혹시나 싶으니 확인 한번 해 보고 가겠습니다.
growpart
의 option 으로 –dry-run 이 있었습니다. 확인해 보겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ growpart --help | grep dry
-N | --dry-run only report what would be done, show new 'sfdisk -d''
--dry-run
옵션을 사용하면, 어떻게 수행될지 리포팅만 한다고 설명하고 있습니다.
–dry-run 옵션을 사용해 보겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ sudo growpart --dry-run /dev/xvda 1
CHANGE: partition=1 start=4096 old: size=41938911 end=41943007 new: size=104853471 end=104857567
# === old sfdisk -d ===
label: gpt
label-id: 7F24463C-2CA8-4011-B531-E8704FF21B48
device: /dev/xvda
unit: sectors
first-lba: 34
/dev/xvda1 : start= 4096, size= 41938911, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=9076114B-E4B7-482F-BBA6-6BDC653099B7, name="Linux"
/dev/xvda128 : start= 2048, size= 2048, type=21686148-6449-6E6F-744E-656564454649, uuid=90A9EC5E-30EB-4E82-B78D-E26BE1019820, name="BIOS Boot Partition"
# === new sfdisk -d ===
label: gpt
label-id: 7F24463C-2CA8-4011-B531-E8704FF21B48
device: /dev/xvda
unit: sectors
first-lba: 34
/dev/xvda1 : start= 4096, size= 104853471, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=9076114B-E4B7-482F-BBA6-6BDC653099B7, name="Linux"
/dev/xvda128 : start= 2048, size= 2048, type=21686148-6449-6E6F-744E-656564454649, uuid=90A9EC5E-30EB-4E82-B78D-E26BE1019820, name="BIOS Boot Partition"
- old 와 new 가 있는 걸로 보니, 현재 정보가 어떻게 바뀔지의 정보를 보여줍니다.
- xvda1 파티션의 시작 sector 는 4096 이고, size 가 41,938,911 에서, 1,048,53,471 로 확장되는 것을 보여줍니다. 512Byte 를 곱한다고 보면, 용량이 맞는 것 같습니다.
parted
명령에서도 sector 단위로 다시 확인해 보겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ sudo parted /dev/xvda unit s print
Error: The backup GPT table is not at the end of the disk, as it should be. This might mean that another operating system believes the disk is smaller. Fix, by moving the backup to the end (and
removing the old backup)?
Fix/Ignore/Cancel? ^C
Warning: Not all of the space available to /dev/xvda appears to be used, you can fix the GPT to use all of the space (an extra 62914560 blocks) or continue with the current setting?
Fix/Ignore? ^C
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvda: 104857600s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
128 2048s 4095s 2048s BIOS Boot Partition bios_grub
1 4096s 41943006s 41938911s xfs Linux
- Error 와 Warning 은 일단 아까처럼, Ctrl+C 키로 무시하겠습니다.
- 파티션 1번의 시작 sector 번호가 4096s 로 나오고 Size 도 위의
growpart --dry-run
명령의 정보와 같습니다.
이제 growpart
를 --dry-run
옵션 없이 실행하겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ sudo growpart /dev/xvda 1
CHANGED: partition=1 start=4096 old: size=41938911 end=41943007 new: size=104853471 end=104857567
- prompt 가 순식간에 떨어집니다.
잘 됐을까요?gnome-disks
에서, 그리고 command line 으로 확인해 보겠습니다.
[ec2-user@ip-172-31-32-193 ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 50G 0 disk
└─xvda1 202:1 0 50G 0 part /
[ec2-user@ip-172-31-32-193 ~]$ sudo parted /dev/xvda print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvda: 53.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
128 1049kB 2097kB 1049kB BIOS Boot Partition bios_grub
1 2097kB 53.7GB 53.7GB xfs Linux
lsblk
명령에서, xvda1 의 크기가 늘어난 것을 확인할 수 있습니다.- parted 명령에서 이전에 출력되던 Error 와 Warning 도 사라졌습니다. (디스크 볼륨 확장으로 인해 생긴 현상이고,
growpart
를 수행하면서 정리가 되었습니다.) - 그런데
gnome-disks
에서 파란색으로 보이는 파티션 영역 중 중간에 그 전에 없던 선이 생겼습니다.
아직 루트 파일시스템의 확장이 안 되어, 파일시스템 사용량을 제대로 표시해 주지 못 하고 있습니다.
3) 루트 파일시스템 확장
마지막 단계입니다.
테스트하는 환경에서 사용하는 파일시스템은 xfs 입니다.
xfs_growfs
명령을 사용합니다.
[ec2-user@ip-172-31-32-193 ~]$ xfs_growfs |& head -n 1
Usage: xfs_growfs [options] mountpoint
xfs_growfs
는 디바이스가 마운트된 상태에서 실행하며, 명령어의 인자로 디바이스가 마운트된 디렉토리(마운트 포인트)를 주면 됩니다.
[ec2-user@ip-172-31-32-193 ~]$ df -hT /
Filesystem Type Size Used Avail Use% Mounted on
/dev/xvda1 xfs 20G 2.1G 18G 11% /
[ec2-user@ip-172-31-32-193 ~]$ sudo xfs_growfs /
meta-data=/dev/xvda1 isize=512 agcount=11, agsize=524159 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1 spinodes=0
data = bsize=4096 blocks=5242363, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 5242363 to 13106683
[ec2-user@ip-172-31-32-193 ~]$ df -hT /
Filesystem Type Size Used Avail Use% Mounted on
/dev/xvda1 xfs 50G 2.2G 48G 5% /
xfs_growfs
를 실행하기 전에,df
결과에서 /dev/xvda1 은 크기는 20G 입니다.xfs_growfs
를 실행 후, 50G 로 확장된 것을 확인할 수 있습니다.
- 파란색으로 표시되는 파티션 영역의 중간쯤에 있던 선도 아래로 내려갔습니다. 파일시스템이 확장되어 파일시스템 사용량을 제대로 표시하게 되었습니다.
3. 정리
이렇게 growpart 를 이용해서 루트 파일시스템을 확장하는 방법을 확인해 봤습니다.
(물론, Data 용도로 사용하는 추가 디스크 볼륨에서도 사용할 수 있습니다.)
정리를 해 보면, 아래와 같은 절차로 파일시스템을 확장합니다.
디스크 확장
루트 파티션 확장
루트 파일시스템 확징
2번째 절차에서만 사용하는 growpart 를 설명하다 보니, 전/후에 진행되는 작업들도 설명하게 되었습니다.
여기서 언급은 하지 않았지만,
예전에 파티션을 확장하는 방법은 약간 파괴(?)적인 방법이었습니다.
간단히 설명하면,
fdisk 를 이용해서 기존 파티션을 지우고, 늘어난 디스크 크기에 맞게 파티션을 다시 만드는 겁니다.
정말 그렇게 진행해도 될까 하며, 손을 떨면서 명령어를 치던 때가 생각납니다.
그에 비하면, 정말 간편하게 파티션을 확장할 수 있게 해주는 도구라고 생각됩니다.
다음 글에서는 growpart 스크립트 파일 내용을 보면서, growpart 스크립트가 어떻게 실행되는지를 확인해 보겠습니다.
잡설)
리눅스 시스템을 초기 구축할 때, 파티션 구성을 어떻게 해야 할까요?
운영 환경은 물리/가상화/클라우드 등으로 다양하며, 파티션 구성도 일반적인 파티션에 파일 시스템을 구성할 수도 있고, LVM 의 LV 위에 파일 시스템을 구성할 수도 있습니다.
OS 를 설치하면서 루트 파일 시스템을 생성하는 경우, LVM 으로 생성할지 일반 파티션에 생성할지 잘 판단이 안 될 수 있습니다. 정해진 답은 없습니다. 환경과 목적에 맞게 적절히 구성해야 합니다.
그러나, 초기 설치시부터 앞으로의 운영 상황을 고려하여 구성하기에는 정보가 부족하고, 알아서 구성하더라도 예상은 빗나갈 수 있습니다.
이렇다 보니, 파일 시스템이 가득 차는(full) 상황이 올 수 있으며, 루트 파일 시스템에 대해서도 확장이 필요한 상황이 올 수 있습니다.
어떤 운영 환경이라도 파일 시스템이 확장될 수 있는 유연성이 필요합니다.
클라우드나 가상화 환경은 기본적으로 유연성이 높습니다. 쉽게 디스크를 확장할 수 있고, 추가할 수 있습니다. 할당된 볼륨이 작다면 디스크를 늘리면 그만입니다.
그러나 물리 환경은 디스크의 조달이 클라우드나 가상화만큼 쉽지 않으며, 조달하였다 하더라도 현재 구성에 따라 파일 시스템 확장이 불가할 수도 있습니다. 여러 제약을 생각하면, 물리환경에서는 LVM 으로 구성하는게 확장성을 고려할 때 좀 더 유연한 구성이 됩니다.