AWS
EC2
ebs

EBSのボリュームサイズを縮小する

More than 1 year has passed since last update.

EBSのディスクサイズを縮小するやり方はググると色々出てくるものの、なぜか現在のEBS Backedなインスタンスだと日本語の情報の手順ではできなかったのでメモ。

普通にゆっくりインスタンスを止められる状況でのやり方です。(スナップショット取って新しいVMでやることなどで停止時間は短くすることは可能)


1. 新規のEBSを作成

まず目的のサイズのEBSを持ったEC2インスタンスを作り、そのEBSボリュームをデタッチすることで作成する。

というのもこうしないと Partition に BIOS Boot Partition が無くて立ち上がらないため。

そしてこのボリュームのVolumeIDをメモっておく。VMはこの時点で用済みということで削除。


2. 作業用EC2を作成

t2.smallインスタンスで十分ぽい。

以下作業は全て root にて。

数百ギガだと rsync でのコピーが長く tmux にて作業したいのでtmuxをインストール。

AWSコマンドのjson操作でjqは必須なのでこれも入れる。

あと aws configure で cli 操作もできるようにしておく。権限はEC2周りはフルアクセスで。

# yum install tmux jq

# aws configure
AWS Access Key ID []: xxx
AWS Secret Access Key []: xxx
Default region name []: ap-northeast-1
Default output format [None]: json

(この後のコマンドでよく使うので)
# export INSTANCE_ID=`/opt/aws/bin/ec2-metadata | grep instance-id | cut -d " " -f2`
# export NEW_VOLUME_ID=メモっておいたVolumeID


3. 新EBSをAttach

aws ec2 attach-volume --volume-id ${NEW_VOLUME_ID} --instance-id ${INSTANCE_ID} --device /dev/sdf 

lsblk #確認


4. フォーマットして余計なデータをなくす

mkfs.ext4 /dev/xvdf1 


5. 元となるEBSをEC2からデタッチし、作業用AWSにアタッチ

export TARGET_NAME=hoge

export TARGET_ID=`aws ec2 describe-instances --filters "Name=tag:Name,Values=${TARGET_NAME}" | jq -r '.Reservations[].Instances[].InstanceId'`

aws ec2 describe-instances --instance-ids ${TARGET_ID} | jq -r '.Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId' | xargs aws ec2 detach-volume --volume-id
aws ec2 attach-volume --volume-id {戻り値のボリューム名} --instance-id=${INSTANCE_ID} --device /dev/sdg


6. パーティションにラベルを付ける

xvdgと同じラベルをつける。(/etc/fstab や /boot/grub/grub.conf で指定されている値にしない場合に起動時にボリュームがマウントされないため。)

e2label /dev/xvdg1

e2label /dev/xvdf1
e2label /dev/xvdf1 /
e2label /dev/xvdf1


7. デバイスをマウント

mkdir -p /mnt/small /mnt/large

mount -t ext4 -r /dev/xvdg1 /mnt/large
mount -t ext4 /dev/xvdf1 /mnt/small
df -hT


8. Rsyncでコピー

tmux

rsync -ax /mnt/large/ /mnt/small


9. アンマウント

umount /mnt/large/ /mnt/small/


10. EBSをデタッチ

/opt/aws/bin/ec2-describe-instances --region ap-northeast-1 `/opt/aws/bin/ec2-metadata  | grep instance-id | cut -d " " -f2` | grep /dev/sd | cut -f 3 | xargs -n 1 aws ec2 detach-volume --volume-id

※適当なワンライナーなのでちょっと動作が変わると動かないかも


11. 元のEC2に新しい方のEBSをアタッチして起動後に動作確認

aws ec2 attach-volume --volume-id ${NEW_VOLUME_ID} --device /dev/xvda --instance-id $TARGET_ID

aws ec2 start-instances --instance-ids $TARGET_ID


12. スナップショットを取ってAMI作成

aws ec2 create-image --instance-id $TARGET_ID --name ${TARGET_NAME}_`date "+%Y%m%d"`


13. イメージからインスタンスを作り直す

CloudFormation使ってればImageIdを変更するだけだったり。

インスタンスが問題なく立ち上がったら不要なEBSボリュームやスナップショットを削除して完了。


参考

http://superuser.com/questions/332252/creating-and-formating-a-partition-using-a-bash-script

http://atodorov.org/blog/2014/02/07/aws-tip-shrinking-ebs-root-volume-size/