CentOS7のEBSのボリュームを小さくするのがかなり大変だったので、備忘録として残します。 ほぼEC2 EBS縮小 (というより CentOS ディスク縮小) の流れの通り進めています。 自分の知らなかった部分を補足しました。
EBSは簡単に大きくできるが小さくするのは大変
Elastic Block Store(EBS)はEC2の仮想的な記憶領域で、柔軟に容量を増やしたりスナップショットを取ってバックアップや複製が簡単に出来ます。 ただし、一度大きくしたEBSを小さくすることはできません。 これから新しく作成してAMIに登録する場合は、小さめのボリュームにしておくことをお勧めします。
では、どうやって小さくするかというと、新しく小さいボリュームのEBSを用意してそこにコピーすることでEBSのボリュームを小さくできます。 EC2のルートデバイスとして認識させる必要があるため、パーティションの設定も正しく行います。
標準ファイルシステム ext4とxfs
ボリュームのコピーは標準ファイルシステムによってコマンドが異なるので注意してください。
CentOS7のファイルシステムはxfsで、この記事はそのコピーの方法で進めます。 同じくxfsのOSはAmazon Linux2、Red Hat Enterprise Linux 7など。 対してext4のOSはCentOS6、Amazon Linux、そしてUbuntuです。
ext4のボリューム縮小は参考1: Amazon EC2ルートボリュームのサイズを縮小してみたを参照されると分かり安いと思います。
xfsはほぼ参考2: EC2 EBS縮小 (というより CentOS ディスク縮小) の流れの通り進めました。
CentOS7のEBSのボリュームを小さくする
AMIで利用しやすいように、200GBのボリュームから20GBへ小さくしました。 OS+ミドルウェアで4GB、swap領域で数GB使っていたので最小を20GBとしています。
参考1に倣って言葉の定義をします。
- 新EBSボリューム:新規起動したEC2インスタンスのEBSルートボリューム
- 旧EBSボリューム:縮小対象EC2インスタンスのEBSルートボリューム
手順は次の通り。
- 任意の作業用EC2インスタンスに新EBSボリュームと旧EBSボリュームをアタッチする
- 新EBSボリュームのパーティションを設定する
- 新旧EBSボリュームをマウントする
- 新EBSボリュームを旧EBSボリュームと同期する
- ボリュームを取り外す
- EC2にアタッチして起動する
1. 任意の作業用EC2インスタンスに新EBSボリュームと旧EBSボリュームをアタッチする
EBSをコピーするために新旧EBSボリュームを別の作業用EC2にアタッチします。 作業用EC2はOSがAmazon Linux2です。 インスタンスタイプはt3.microで十分でした。
アタッチ後のブロックデバイス一覧。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
xvdf 202:80 0 200G 0 disk <-旧EBSボリューム
└─xvdf1 202:81 0 200G 0 part
xvdg 202:96 0 20G 0 disk <-新EBSボリューム
xvdf
が旧EBSボリュームでxvdg
が新EBSボリュームです。
2. 新EBSボリュームのパーティションを設定する
新EBSボリュームにパーティションxvdg1
を作ります。
(パーティション内状態でコピーしたら、EC2がルートデバイスとして認識してくれなかった)
# fdisk /dev/xvdg
fdisk (util-linux 2.30.2) へようこそ。
ここで設定した内容は、書き込みコマンドを実行するまでメモリのみに保持されます。
書き込みコマンドを使用する際は、注意して実行してください。
古い xfs 署名は write (書き込み)コマンドを実行すると消えてしまいます。
デバイスには認識可能なパーティション情報が含まれていません。
新しい DOS ディスクラベルを作成しました。識別子は 0x3800409a です。
コマンド (m でヘルプ): n
パーティションタイプ
p 基本パーティション (0 プライマリ, 0 拡張, 4 空き)
e 拡張領域 (論理パーティションが入ります)
選択 (既定値 p): p
パーティション番号 (1-4, 既定値 1): 1
最初のセクタ (2048-41943039, 既定値 2048):
最終セクタ, +セクタ番号 または +サイズ{K,M,G,T,P} (2048-41943039, 既定値 41943039):
新しいパーティション 1 をタイプ Linux、サイズ 20 GiB で作成しました。
コマンド (m でヘルプ): a
パーティション 1 を選択
パーティション 1 の起動フラグを有効にしました。
コマンド (m でヘルプ): p
ディスク /dev/xvdg: 20 GiB, 21474836480 バイト, 41943040 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x3800409a
デバイス 起動 開始位置 最後から セクタ サイズ Id タイプ
/dev/xvdg1 * 2048 41943039 41940992 20G 83 Linux
コマンド (m でヘルプ): w
パーティション情報が変更されました。
設定が日本語になっていた。
n -> p -> 1 -> a -> w
でディスクサイズと同じ大きさのパーティションxvdg1
ができる。
m
でヘルプが見れます。
1度目はパーティション情報の書き込みで失敗している。 下はその時のログ。 再起動してもう一度実行したら成功しました。
コマンド (m でヘルプ): w
パーティション情報が変更されました。
ioctl() を呼び出してパーティション情報を再読み込みします。
パーティション情報の再読み込みに失敗しました。: Device or resource busy
カーネルは古い情報を使用しています。新しい情報を利用するには、システムを再起動するか、もしくは partprobe(8) または kpartx(8) を実行してください。
縮小前後(xvdf/xvdg)で同様の設定になっている事を確認します。
# fdisk -l
ディスク /dev/xvda: 8 GiB, 8589934592 バイト, 16777216 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: gpt
ディスク識別子: 83181C97-6D5E-43C9-9EDE-E2F50EAD5338
デバイス 開始位置 最後から セクタ サイズ タイプ
/dev/xvda1 4096 16777182 16773087 8G Linux ファイルシステム
/dev/xvda128 2048 4095 2048 1M BIOS 起動
パーティション情報の項目がディスクの順序と一致しません。
ディスク /dev/xvdg: 20 GiB, 21474836480 バイト, 41943040 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x3800409a
デバイス 起動 開始位置 最後から セクタ サイズ Id タイプ
/dev/xvdg1 * 2048 41943039 41940992 20G 83 Linux
ディスク /dev/xvdf: 200 GiB, 214748364800 バイト, 419430400 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x000aec37
デバイス 起動 開始位置 最後から セクタ サイズ Id タイプ
/dev/xvdf1 * 2048 419430366 419428319 200G 83 Linux
3. 新旧EBSボリュームをマウントする
# mkdir -p /mnt/old /mnt/new/boot
# mount -t xfs /dev/xvdf1 /mnt/old
# mount -t xfs /dev/xvdg1 /mnt/new
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
xvdf 202:80 0 200G 0 disk
└─xvdf1 202:81 0 200G 0 part /mnt/old <-旧EBSボリューム
xvdg 202:96 0 20G 0 disk
└─xvdg1 202:97 0 20G 0 part /mnt/new <-新EBSボリューム
4. 新EBSボリュームを旧EBSボリュームと同期する
この辺りから自分の言葉で表せない、申し訳ないが参考の手順とその時の出力をのせる。
xfs を扱うためのパッケージをインストールしておきます。
- xfsdump: XFSファイルシステムをバックアップするために、指定した場所にコピーするコマンド
- xfsprogs: xfsdumpのバックアップからファイルを復元するコマンド
インストールコマンド:
yum install xfsprogs xfsdump
容量により時間が掛かるのでバックグラウンド実行しておきます。
# cd /mnt/old/
( LANG=C date; nohup xfsdump -J - /mnt/old \
| xfsrestore -J -p 60 - /mnt/new ; date \
) > /tmp/disk-sync.log 2>&1 < /dev/null &
# ログ
# tail -f /tmp/disk-sync.log
xfsrestore: media label: ""
xfsrestore: file system id: 0f790447-ebef-4ca0-b229-d0aa1985d57f
xfsrestore: session id: 606c299e-31bf-4de9-9bff-36538c642a89
xfsrestore: media id: dafc54f9-af51-4412-88d3-32cfe9298f5d
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsdump: dumping non-directory files
xfsrestore: 21868 directories and 127203 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: status at 10:06:38: 42584/98461 files restored, 47.9% complete, 60 seconds elapsed
xfsdump: ending media file
xfsdump: media file size 4563930720 bytes
xfsdump: dump size (non-dir files) : 4521594712 bytes
xfsdump: dump complete: 111 seconds elapsed
xfsdump: Dump Status: SUCCESS
xfsrestore: restore complete: 112 seconds elapsed
xfsrestore: Restore Status: SUCCESS
2020年 4月 9日 木曜日 10:07:30 UTC
^C[1]+ 終了 ( LANG=C date; nohup xfsdump -J - /mnt/old | xfsrestore -J -p 60 - /mnt/new; date ) > /tmp/disk-sync.log 2>&1 < /dev/null
- grubインストール chroot OS起動時に作成されるディレクトリ群をマウントした後、 /mnt/new/ に対して chroot します。 (chroot した事を確認するためにログファイルコピーを行っていますが、必須ではありません。)
[root@ip-172-31-19-210 old]# cp -ip /tmp/disk-sync.log /mnt/new/var/log/
[root@ip-172-31-19-210 old]# gzip /mnt/new/var/log/disk-sync.log
[root@ip-172-31-19-210 old]# ls -l /mnt/new/var/log/disk-sync.log*
-rw-r--r-- 1 root root 820 4月 9 10:07 /mnt/new/var/log/disk-sync.log.gz
[root@ip-172-31-19-210 old]# mount -t proc /proc /mnt/new/proc
[root@ip-172-31-19-210 old]# mount -t sysfs /sys /mnt/new/sys
[root@ip-172-31-19-210 old]# mount --bind /dev /mnt/new/dev
[root@ip-172-31-19-210 old]# chroot /mnt/new/
[root@ip-172-31-19-210 /]# ls -l /var/log/disk-sync.log.gz
-rw-r--r-- 1 root root 820 4月 9 19:07 /var/log/disk-sync.log.gz
[root@ip-172-31-19-210 /]#
grub xfs
[root@ip-172-31-19-210 /]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1062.9.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-229.14.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-229.14.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-229.4.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-229.4.2.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-123.8.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-123.8.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-f9afeb75a5a382dce8269887a67fbf58
Found initrd image: /boot/initramfs-0-rescue-f9afeb75a5a382dce8269887a67fbf58.img
done
[root@ip-172-31-19-210 /]# grub2-install /dev/xvdg
Installing for i386-pc platform.
Installation finished. No error reported.
- fstab/grub.conf 書き換え fstab 、grub.conf に UUID 指定がある場合は、書き換えを行います。 (CentOS6 には grub-mkconfig が無いようなので grub.conf は直接書き換えています。) xfs UUID指定部分を書き換えます。 CentOS7 では grub2 が導入済みのようなので /etc/grub/ ではなく、 /etc/grub2/ が使用されます。
[root@ip-172-31-19-210 /]# blkid | grep xvdg
/dev/xvdg1: UUID="80ef9b35-2d25-430c-a753-5f6bbc2955e5" TYPE="xfs"
[root@ip-172-31-19-210 /]# cp -ip /etc/fstab /etc/fstab.org
[root@ip-172-31-19-210 /]# vi /etc/fstab
# diff /etc/fstab.org /etc/fstab
9c9
< UUID=0f790447-ebef-4ca0-b229-d0aa1985d57f / xfs defaults 1 1
---
> UUID=80ef9b35-2d25-430c-a753-5f6bbc2955e5 / xfs defaults 1 1
# chrootを抜ける
[root@ip-172-31-19-210 /]# exit
exit
5. ボリュームを取り外す
アンマウント
proc
、sys
、dev
もアンマウントしておく。
[root@ip-172-31-19-210 old]# cd /
[root@ip-172-31-19-210 /]# umount /mnt/old/
[root@ip-172-31-19-210 /]# umount /mnt/new/proc /mnt/new/sys /mnt/new/dev
[root@ip-172-31-19-210 /]# umount /mnt/new/
[root@ip-172-31-19-210 /]# mount -l | grep "old\|new"
ディスク内容の移行が完了したら、 作業用インスタンスから Volume をデタッチして後続作業を行います。
インスタンスを停止して、デタッチ。
6. EC2にアタッチして起動する
EC2の /dev/sda1
にアタッチする。
※ デバイス名が/dev/sda
だとエラーで/dev/sdf
だとルートデバイスとして認識しなかった。
# sshでEC2に接続
$ df -h
df: `/s3': 通信端点が接続されていません
ファイルシス サイズ 使用 残り 使用% マウント位置
devtmpfs 472M 0 472M 0% /dev
tmpfs 495M 0 495M 0% /dev/shm
tmpfs 495M 13M 482M 3% /run
tmpfs 495M 0 495M 0% /sys/fs/cgroup
/dev/xvda1 20G 4.5G 16G 23% /
tmpfs 99M 0 99M 0% /run/user/1001
いえーあー
AMIに登録して失くさないようにする。
参考
- Amazon EC2ルートボリュームのサイズを縮小してみた
- コピーの流れが図で分かり易いです。
- EC2 EBS縮小 (というより CentOS ディスク縮小) の流れ
- CentOS6(ext4)とCentOS7(xfs)のやり方。この記事がなかったら無理だった。ありがとうございます。
- 今から始めるRHEL 7 第2回 標準ファイルシステムとなったXFS
- 問題となったXFSについての解説。
- Linux で Amazon EBS ボリュームを使用できるようにする | docs.aws.amazon.com
- Amazon EBS スナップショット | docs.aws.amazon.com