【AWS EBS】EC2 Linux のルートボリュームを縮小する方法

Blog-Thumbnail_KUDs-01 AWS

はじめに

背景と目的

EBS (Elastic Block Store)ボリュームは、その使用量に応じて課金されます。
そのため、必要以上の大きさを持つボリュームを維持していると、無駄なコストが発生してしまいます。
また、スナップショットも課金されるので、認識しておきましょう。

この記事は、EBS のサイズを縮小したいという方向けです。

そもそも、既存 EBS ボリュームのサイズ縮小はできない

EBS ボリュームのサイズを小さく変更することはできません。ただし、より小さなボリュームを作成し、そのボリュームに対して rsync や などのアプリケーションレベルのツールを使用して、データを移行することができます。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/modify-volume-requirements.html

Amazon EBS ボリュームのサイズは、大きくすることしかできません。ボリュームサイズを小さくすることはできません。ボリュームサイズを小さくしたい場合は、まず小さなボリュームを作成してください。次に、アプリケーションレベルのツールを使用してデータを移行します。

https://repost.aws/ja/knowledge-center/ebs-increase-decrease-volume-size

ブロックデバイスの性質上、サイズ縮小をサポートすることは難しいでしょう。
そのため、「新規にサイズの小さな EBS ボリュームを作成して、アプリケーションレベルのツールを使って移行してね」とのこと。

そのやり方を教えてほしいのに…!

と、思うかもしれません。
しかし、残念ながらそのような公式の手順書はありません。
アプリケーションはユーザ側で管理すべきものなので、AWS が手順化するようなものではありませんし、環境に依るので網羅的な記載は困難でしょう。
EC2 内部のアプリケーションはもちろん、OS や、ブートローダなんかにも依存しますしね。

なお、今回は以下の構成で行います。

  • OS: Amazon Linux 2
  • インスタンスタイプ: t2.micro
  • EBS: gp3 / 30GB → gp3 / 8GB
  • FS: xfs

構成が異なる方は、適宜手順やコマンドを修正しつつお試しください。

前提知識

AWS EC2 と EBS に関する基本的な知識

まず、Amazon EC2 は、ユーザーが仮想マシンをフレキシブルに利用できるAWSのクラウドサービスです。
※EC2: Elastic Compute Cloud

EBS はEC2インスタンスで使用する永続的なブロックレベルストレージを提供します。
※EBS: Elastic Block Store

今回の議題的に、読者層はこの辺りの基本知識は理解している前提で進みます。

Linux システム管理の基礎

この記事は、AWS EC2 インスタンス上の Linux システムのストレージを管理する方法について説明します。
したがって、Linuxのファイルシステム、パーティショニング、マウントポイント、および基本的なコマンドライン操作についての基本的な理解が必要です。

使用するコマンド

fdisk, mkfs.xfs, rsync, mount, chroot, grub2-mkconfig, grub2-install, vi 等を使用します。
これらのコマンドの基本的な使い方については、この記事では詳しく説明しません。
手順のみの確認では必要ないかと思いますが、必要に応じて man 等確認してください。

ルートボリュームの縮小に向けた準備

データのバックアップ

まず、本手順を実施する前に、 AMI を取得する等、バックアップすることを強く推奨します。

移行先となる EBS ボリュームを新規作成

次に、移行先となる EBS ボリュームを新規作成しておきましょう。
このボリュームは、最終的には縮小版のルートボリュームとして使用されます。
そこで、現状どのくらいの容量が使われているのかは事前に確認しておきましょう。

# cat /etc/fstab
#
UUID=a9962bc2-1c87-41b5-ba10-7be5ba7cd663     /           xfs    defaults,noatime  1   1
# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs    /     a9962bc2-1c87-41b5-ba10-7be5ba7cd663 /
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  468M     0  468M   0% /dev
tmpfs          tmpfs     477M     0  477M   0% /dev/shm
tmpfs          tmpfs     477M  412K  476M   1% /run
tmpfs          tmpfs     477M     0  477M   0% /sys/fs/cgroup
/dev/xvda1     xfs        30G  2.5G   28G   9% /
tmpfs          tmpfs      96M     0   96M   0% /run/user/1000

現状では、2.5 GB 使用中でした。
一方、ボリュームサイズは 30 GB です。
明らかに過剰なキャパシティなので、新規に 8 GB の EBS を作成し、データを移行していきましょう。

なお、EBS 作成時は、対象の EC2 インスタンスと同一の AZ に EBS を作成する必要がありますので留意ください。

また、EBS 作成が完了すれば、対象の EC2 の /dev/xvdf 等にアタッチしておきましょう。
[EC2] > [Volumes] > [vol-xxxxxxxxxx] > [Actions] > [Attach volume] を選択してアタッチできます。

データの移行

では、いよいよ本題です。

移行先ボリュームがアタッチできているか確認

# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs    /     a9962bc2-1c87-41b5-ba10-7be5ba7cd663 /
xvdf
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  468M     0  468M   0% /dev
tmpfs          tmpfs     477M     0  477M   0% /dev/shm
tmpfs          tmpfs     477M  416K  476M   1% /run
tmpfs          tmpfs     477M     0  477M   0% /sys/fs/cgroup
/dev/xvda1     xfs        30G  2.5G   28G   9% /
tmpfs          tmpfs      96M     0   96M   0% /run/user/1000

まず、AWS マネジメントコンソールで移行先の EBS をアタッチ後、ブロックデバイスが認識されていることを確認します。
ここでは、/dev/xvdf にアタッチしていることが確認できます。

移行先ボリュームをフォーマットする

# mkfs.xfs /dev/xvdf
meta-data=/dev/xvdf              isize=512    agcount=4, agsize=524288 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1    bigtime=0 inobtcount=0
data     =                       bsize=4096   blocks=2097152, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

問題なければ次行きましょう。

移行先ボリュームにパーティションを作成

# fdisk /dev/xvdf

Welcome to fdisk (util-linux 2.30.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

The old xfs signature will be removed by a write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x37f06bd3.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-16777215, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-16777215, default 16777215):

Created a new partition 1 of type 'Linux' and of size 8 GiB.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

ガンガン行きましょう。

新規パーティション(/dev/xvdf1)にXFSファイルシステムを作成

# mkfs.xfs /dev/xvdf1
meta-data=/dev/xvdf1             isize=512    agcount=4, agsize=524224 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1    bigtime=0 inobtcount=0
data     =                       bsize=4096   blocks=2096896, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs    /     a9962bc2-1c87-41b5-ba10-7be5ba7cd663 /
xvdf
└─xvdf1 xfs          24f02088-d3a4-4ff6-9418-8ed4d3447cc1
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  468M     0  468M   0% /dev
tmpfs          tmpfs     477M     0  477M   0% /dev/shm
tmpfs          tmpfs     477M  420K  476M   1% /run
tmpfs          tmpfs     477M     0  477M   0% /sys/fs/cgroup
/dev/xvda1     xfs        30G  2.5G   28G   9% /
tmpfs          tmpfs      96M     0   96M   0% /run/user/1000

ここでは、/dev/xvdf1 パーティションが作成されていることを確認できます。

移行先ボリュームをマウント

# mkdir /mnt/new
# mount /dev/xvdf1 /mnt/new
# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs    /     a9962bc2-1c87-41b5-ba10-7be5ba7cd663 /
xvdf
└─xvdf1 xfs          24f02088-d3a4-4ff6-9418-8ed4d3447cc1 /mnt/new
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  468M     0  468M   0% /dev
tmpfs          tmpfs     477M     0  477M   0% /dev/shm
tmpfs          tmpfs     477M  420K  476M   1% /run
tmpfs          tmpfs     477M     0  477M   0% /sys/fs/cgroup
/dev/xvda1     xfs        30G  2.5G   28G   9% /
tmpfs          tmpfs      96M     0   96M   0% /run/user/1000
/dev/xvdf1     xfs       8.0G   90M  8.0G   2% /mnt/new

ここでは、/mnt/new にマウントできていることを確認できます。

rsync でデータをコピー

# rsync -aAXv --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found} / /mnt/new/
...
sent 2,428,052,201 bytes  received 1,123,469 bytes  37,086,651.45 bytes/sec
total size is 2,423,471,200  speedup is 1.00
# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs    /     a9962bc2-1c87-41b5-ba10-7be5ba7cd663 /
xvdf
└─xvdf1 xfs          24f02088-d3a4-4ff6-9418-8ed4d3447cc1 /mnt/new
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  468M     0  468M   0% /dev
tmpfs          tmpfs     477M     0  477M   0% /dev/shm
tmpfs          tmpfs     477M  420K  476M   1% /run
tmpfs          tmpfs     477M     0  477M   0% /sys/fs/cgroup
/dev/xvda1     xfs        30G  2.5G   28G   9% /
tmpfs          tmpfs      96M     0   96M   0% /run/user/1000
/dev/xvdf1     xfs       8.0G  2.6G  5.5G  32% /mnt/new

ここでは、/mnt/new にデータが入ってることを確認できます。

移行先ボリューム GRUB の設定とインストール

# mount -t proc /proc /mnt/new/proc
# mount -t sysfs /sys /mnt/new/sys
# mount --bind /dev /mnt/new/dev
# mount --bind /run /mnt/new/run
# chroot /mnt/new
# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.10.184-175.731.amzn2.x86_64
Found initrd image: /boot/initramfs-5.10.184-175.731.amzn2.x86_64.img
done
# grub2-install /dev/xvdf
Installing for i386-pc platform.
Installation finished. No error reported.

fstab の更新

# cat /etc/fstab
#
UUID=a9962bc2-1c87-41b5-ba10-7be5ba7cd663     /           xfs    defaults,noatime  1   1
# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs    /     a9962bc2-1c87-41b5-ba10-7be5ba7cd663
xvdf
└─xvdf1 xfs          24f02088-d3a4-4ff6-9418-8ed4d3447cc1 /
# vi /etc/fstab
# cat /etc/fstab
#
UUID=24f02088-d3a4-4ff6-9418-8ed4d3447cc1     /           xfs    defaults,noatime  1   1

ここでは、UUID を移行先のものに書き換えておきましょう。

※執筆していて気が付いたのですが、LABEL の設定を忘れてますね。
※必要に応じて以下のコマンドを実施して、LABEL も設定しておきましょう。

# xfs_admin -L "/" /dev/xvdf1

結果の検証

新しいルートボリュームでの再起動

最後に、新しいルートボリュームへのデータ移行と設定が完了したら、新しいボリュームでシステムを再起動することで、移行が正常に行われたか確認します。

マネジメントコンソール or CLI から、移行元の EBS をデタッチし、移行先の EBS は /dev/xvda 等にアタッチしてから EC2 を起動しましょう。

起動後、SSH 等でインスタンスに正常ログインできることを確認します。

ボリュームサイズの確認

念のため、システムが新しいルートボリュームを使用していることと、そのボリュームサイズが想定したサイズになっていることを確認します。

# lsblk -f
NAME    FSTYPE LABEL UUID                                 MOUNTPOINT
xvda
└─xvda1 xfs          24f02088-d3a4-4ff6-9418-8ed4d3447cc1 /
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  468M     0  468M   0% /dev
tmpfs          tmpfs     477M     0  477M   0% /dev/shm
tmpfs          tmpfs     477M  412K  476M   1% /run
tmpfs          tmpfs     477M     0  477M   0% /sys/fs/cgroup
/dev/xvda1     xfs       8.0G  2.6G  5.5G  32% /
tmpfs          tmpfs      96M     0   96M   0% /run/user/1000
# cat /etc/fstab
#
UUID=24f02088-d3a4-4ff6-9418-8ed4d3447cc1     /           xfs    defaults,noatime  1   1

以上でルートボリュームの縮小とその結果の検証が完了しました。
ここまでの手順に問題が無ければ、正常にルートボリュームの縮小が行われ、システムも新しいルートボリュームから起動しているはずです。

まとめ

EBS ボリュームの縮小によって、ストレージの費用を抑えることができます。

しかし、データロスのリスクが伴います。
実施する際にはバックアップを取得したうえで実施することを推奨します。

また、本移行ではインスタンスの再起動が必要となるため、システムダウンタイムが発生するという点もご留意ください。

コメント