share facebook facebook2 twitter menu hatena pocket slack

2016.11.28 MON

EC2 EBS縮小 (というより CentOS ディスク縮小) の流れ

WRITTEN BY大住 孝之

AWS EC2(Linux) のディスクサイズ縮小を行う機会があったので、備忘として整理します。 復旧や作り直しと同意になるので極力行いたくない作業です。
流れは以下のようになります。
各 Volume、Snapshot には判別しやすい名称を付けておくと混乱しないと思います。

01. 縮小対象 EC2 インスタンスの Volume(vol-A) から Snapshot(snap-A) を作成
02. Snapshot から Volume(vol-B) を作成
03. 縮小後のサイズを指定して、空の Volume(vol-C) を作成
04. 作業用 EC2 インスタンスを起動
05. 作業用 EC2 インスタンスに Volume(vol-B、vol-C) をアタッチ
06. データコピー
07. 作業用 EC2 インスタンスから Volume(vol-C) をデタッチ
08. Volume(vol-C) から Snapshot(snap-C) を作成
09. Snapshot(snap-C) から AMI を作成
    - マネジメントコンソールでの操作はデフォルトで Virtualization type  が PV 指定になるようなので、 HVM の場合は注意
10. AMI から縮小後サイズの EC2 インスタンスを起動

肝は 05 のデータコピー部分になるかと思いますので、以下、05部分の手順(一例)です。
ファイルシステムによりコマンドが多少違いますし、環境によっても異なるのであくまで例です。
起動に失敗する場合は大抵 fstab と grub の設定部分誤りなので、その辺りに目星を付けて修正すると起動できると思います。
また、SELINUX は無効にしておいた方がトラブルは少ないと思います。(ssh接続不可等が発生する可能性があります)

$ grep '^SELINUX' /etc/selinux/config
SELINUX=disabled
SELINUXTYPE=targeted

環境

ext4 と xfs で 30GB -> 10GB への縮小を行います。
作業用インスタンスのOSは、コマンド有無があるので対象OSと合わせると良いかと思います。 また、Marketplace のAMIだと stop しないと attach/detach が行えないようなので、 Amazon Linux 等の公式AMIを使用するのが良いのかもしれません。

vol-xxxxxxxx : Unable to detach volume 'vol-xxxxxxxx' with Marketplace codes from instance 'i-xxxxxxxx' as the instance is not in the 'stopped' state.

今回は AWS Marketplace にある CentOS 標準の AMI を対象に実施しました。

  • AMI
  • DiskSize
    • 30GB

縮小元インスタンス情報

Apacheは起動後の確認に使用しただけですが、一応載せてます。

ext4

[root@ip-172-30-0-241 /]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@ip-172-30-0-241 /]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       30G  1.1G   27G   4% /
tmpfs           498M     0  498M   0% /dev/shm
[root@ip-172-30-0-241 /]# httpd -v
Server version: Apache/2.2.15 (Unix)
Server built:   Jul 18 2016 15:24:00

xfs

[root@ip-172-30-0-149 /]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@ip-172-30-0-149 /]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       30G  1.4G   29G   5% /
devtmpfs        478M     0  478M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M   13M  484M   3% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/1000
[root@ip-172-30-0-149 /]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Jul 18 2016 15:30:14

データコピー手順

ほぼ同様の流れなので特記しない限りは ext4 の実行結果を載せます。

1) アタッチ状態確認

Volume(vol-B、vol-C) がアタッチされている事を確認します。 vol-Bを xvdf、vol-C(空ボリューム)を xvdg としています。

[root@ip-172-30-0-241 /]# lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  30G  0 disk
└─xvda1 202:1    0  30G  0 part
xvdf    202:80   0  30G  0 disk
└─xvdf1 202:81   0  30G  0 part /
xvdg    202:96   0  10G  0 disk

2) パーティション設定

縮小前(xvdf)の設定に合わせて縮小後(xvdg)のパーティション設定を行います。

[root@ip-172-30-0-241 /]# fdisk /dev/xvdg
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x714a83d2.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1305, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-1305, default 1305):
Using default value 1305

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/xvdg: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x714a83d2

    Device Boot      Start         End      Blocks   Id  System
/dev/xvdg1   *           1        1305    10482381   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

縮小前後(xvdf/xvdg)で同様の設定になっている事を確認します。

[root@ip-172-30-0-241 /]# fdisk -l

Disk /dev/xvda: 32.2 GB, 32212254720 bytes
255 heads, 63 sectors/track, 3916 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00057cbb

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *           1        3916    31454246   83  Linux

Disk /dev/xvdf: 32.2 GB, 32212254720 bytes
255 heads, 63 sectors/track, 3916 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00057cbb

    Device Boot      Start         End      Blocks   Id  System
/dev/xvdf1   *           1        3916    31454246   83  Linux

Disk /dev/xvdg: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x714a83d2

    Device Boot      Start         End      Blocks   Id  System
/dev/xvdg1   *           1        1305    10482381   83  Linux

3) マウント

ファイルシステムを作成後、マウントします。

  • ext4
[root@ip-172-30-0-241 /]# mkfs.ext4 /dev/xvdg1
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 2620595 blocks
131029 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2684354560
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

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

This filesystem will be automatically checked every 21 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@ip-172-30-0-241 /]# mkdir -p /mnt/old /mnt/new/boot
[root@ip-172-30-0-241 /]# mount -t ext4 /dev/xvdf1 /mnt/old
[root@ip-172-30-0-241 /]# mount -t ext4 /dev/xvdg1 /mnt/new
[root@ip-172-30-0-241 /]# mount -l
/dev/xvdf1 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw,rootcontext="system_u:object_r:tmpfs_t:s0")
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
/dev/xvdf1 on /mnt/old type ext4 (rw)
/dev/xvdg1 on /mnt/new type ext4 (rw)
  • xfs
    xfs を扱うためのパッケージをインストールしておきます。
yum install xfsprogs xfsdump
[root@ip-172-30-0-149 /]# mkfs.xfs /dev/xvdg1
meta-data=/dev/xvdg1             isize=256    agcount=4, agsize=655296 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=2621184, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
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
[root@ip-172-30-0-149 /]# mkdir -p /mnt/old /mnt/new/boot
[root@ip-172-30-0-149 /]# mount -t xfs /dev/xvdf1 /mnt/old
[root@ip-172-30-0-149 /]# mount -t xfs /dev/xvdg1 /mnt/new
[root@ip-172-30-0-149 /]# mount -l
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,seclabel,size=489108k,nr_inodes=122277,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,seclabel)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,seclabel,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,seclabel,mode=755)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
configfs on /sys/kernel/config type configfs (rw,relatime)
/dev/xvdf1 on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=27,pgrp=1,timeout=300,minproto=5,maxproto=5,direct)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,seclabel)
mqueue on /dev/mqueue type mqueue (rw,relatime,seclabel)
nfsd on /proc/fs/nfsd type nfsd (rw,relatime)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,seclabel,size=101536k,mode=700,uid=1000,gid=1000)
/dev/xvdf1 on /mnt/old type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
/dev/xvdg1 on /mnt/new type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

その他にラベル付与やスワップ領域作成等が必要な場合は実施しておきます。

### ext4
# ラベル
e2label /dev/xvdg1 /
blkid
# スワップ
mkswap /dev/xvdg2

### xfs
# ラベル
xfs_admin -L "/boot" /dev/xvdg1
xfs_admin -L "/" /dev/xvdg3
blkid
# スワップ
mkswap /dev/xvdg2

4) ファイルコピー

容量により時間が掛かるのでバックグラウンド実行しておきます。複数パーティションが対象となる場合は、それぞれ実行します。

  • ext4
cd /mnt/old/
( LANG=C date; nohup rsync -avxH \
  --exclude ""proc/*"" \
  --exclude ""sys/*"" \
  --exclude ""dev/*"" \
  /mnt/old/ /mnt/new/; date \
) > /tmp/disk-sync.log 2>&1 < /dev/null &
  • xfs
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 &

5) grubインストール

chroot

OS起動時に作成されるディレクトリ群をマウントした後、 /mnt/new/ に対して chroot します。 (chroot した事を確認するためにログファイルコピーを行っていますが、必須ではありません。)

cp -ip /tmp/disk-sync.log /mnt/new/var/log/
gzip /mnt/new/var/log/disk-sync.log
ls -l /mnt/new/var/log/disk-sync.log*

mount -t proc /proc /mnt/new/proc
mount -t sysfs /sys /mnt/new/sys
mount --bind /dev /mnt/new/dev
chroot /mnt/new/
ls -l /var/log/disk-sync.log.gz

grub

  • ext4
[root@ip-172-30-0-241 /]# grub
Probing devices to guess BIOS drives. This may take a long time.


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]
grub> device (hd0) /dev/xvdg
device (hd0) /dev/xvdg
grub> root (hd0,0)
root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)
setup (hd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  27 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+27 p (hd0,0)/boot/grub/stage2 /boot/grub/grub.conf"... succeeded
Done.
grub> quit
quit
  • xfs
[root@ip-172-30-0-149 /]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-327.36.3.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-327.36.3.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-327.10.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-327.10.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-f32e0af35637b5dfcbedcb0a1de8dca1
Found initrd image: /boot/initramfs-0-rescue-f32e0af35637b5dfcbedcb0a1de8dca1.img
done
[root@ip-172-30-0-149 /]# grub2-install /dev/xvdg
Installing for i386-pc platform.
Installation finished. No error reported.

6) fstab/grub.conf 書き換え

fstab 、grub.conf に UUID 指定がある場合は、書き換えを行います。 (CentOS6 には grub-mkconfig が無いようなので grub.conf は直接書き換えています。)

  • ext4
[root@ip-172-30-0-241 /]# blkid
/dev/xvda1: UUID="cdbab22a-45d6-4cce-95a3-681f42187a46" TYPE="ext4"
/dev/xvdg1: UUID="67a96f57-8e2a-4d6f-b47d-2128b558cc58" TYPE="ext4"
[root@ip-172-30-0-241 /]# cp -ip /etc/fstab /etc/fstab.org
[root@ip-172-30-0-241 /]# vi /etc/fstab
[root@ip-172-30-0-241 /]# diff /etc/fstab.org /etc/fstab
9c9
< UUID=cdbab22a-45d6-4cce-95a3-681f42187a46 /                       xfs     defaults        0 0
---
> UUID=67a96f57-8e2a-4d6f-b47d-2128b558cc58 /                       xfs     defaults        0 0
[root@ip-172-30-0-241 /]# cp -ip /boot/grub/grub.conf /boot/grub/grub.conf.org
[root@ip-172-30-0-241 /]# vi /boot/grub/grub.conf
[root@ip-172-30-0-241 /]# diff /boot/grub/grub.conf.org /boot/grub/grub.conf
17c17
<    kernel /boot/vmlinuz-2.6.32-573.18.1.el6.x86_64 ro root=UUID=cdbab22a-45d6-4cce-95a3-681f42187a46 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD console=ttyS0,115200 crashkernel=auto SYSFONT=latarcyrheb-sun16  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM
---
>    kernel /boot/vmlinuz-2.6.32-573.18.1.el6.x86_64 ro root=UUID=67a96f57-8e2a-4d6f-b47d-2128b558cc58 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD console=ttyS0,115200 crashkernel=auto SYSFONT=latarcyrheb-sun16  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM
  • xfs
    UUID指定部分を書き換えます。 CentOS7 では grub2 が導入済みのようなので /etc/grub/ ではなく、 /etc/grub2/ が使用されます。
[root@ip-172-30-0-149 /]# blkid | grep xvdg
/dev/xvdg1: UUID="5a413a36-b3cd-4902-b18f-3887282d32b7" TYPE="xfs"
[root@ip-172-30-0-149 /]# cp -ip /etc/fstab /etc/fstab.org
[root@ip-172-30-0-149 /]# vi /etc/fstab
[root@ip-172-30-0-149 /]# diff /etc/fstab.org /etc/fstab
9c9
< UUID=ef6ba050-6cdc-416a-9380-c14304d0d206 /                       xfs     defaults        0 0
---
> UUID=5a413a36-b3cd-4902-b18f-3887282d32b7 /                       xfs     defaults        0 0

7) アンマウント

# chrootを終了
[root@ip-172-30-0-241 /]# exit
exit
# アンマウント
[root@ip-172-30-0-241 old]# cd /
[root@ip-172-30-0-241 /]# umount /mnt/old/
[root@ip-172-30-0-241 /]# umount /mnt/new/proc /mnt/new/sys /mnt/new/dev
[root@ip-172-30-0-241 /]# umount /mnt/new/
[root@ip-172-30-0-241 /]# mount -l | grep "old\|new"

ディスク内容の移行が完了したら、 作業用インスタンスから Volume をデタッチして後続作業を行います。

元記事はこちら

EC2 EBS縮小 (というより CentOS ディスク縮小) の流れ

大住 孝之

構築運用担当。 個性的な面々の中で無個性という個性を打ち出していこうと画策中。