こんにちは、サーバーワークス 技術1課の三井です。 EC2インスタンスの運用中に、ルートボリュームのEBSを拡張しなければならない場面、意外とあるんじゃないでしょうか。EBSの拡張方法についてGoogle先生に訪ねてみたところ、概ね以下のような手順が一般的なようでした。
- 対象EC2インスタンスにアタッチされているEBSボリュームのスナップショットを作成
- 1で作成したスナップショットを元に、大きいサイズのEBSボリュームを作成
- 対象EC2インスタンスから、既存EBSボリュームをデタッチ
- 2で作成したEBSボリュームを対象EC2インスタンスのルートボリュームとしてにアタッチ
上記の手順自体は問題ないですね。欲を言うとAWS側でEBSをよしなに拡張してくれる機能があったりするとますます我々のゆとり化に拍車が掛かるわけで最高なのですが、なかなかそうも行かないのでしょう。 さて、EBSの拡張には続きがあって、ルートボリュームを拡張したあと、OSからその領域を使うためにはパーティションの拡張・ファイルシステムの拡張が必要になるわけです。これがなかなか曲者です。 Amazon LinuxのAMIを使っているのであれば、上記手順だけで問題ありません。OSの起動時に自動的に新しいEBSのサイズに合わせてパーティションを拡張してくれます。それ以外のAMIから作成しているRHELやCentOSなどのLinuxインスタンスでは、一手間必要になるケースがあります。今回はRHEL6.5を例にして紹介します。
似たような話
少しばかり話は逸れますが、AMIによってはLaunch時にEBSサイズをいくら大きく指定してもパーティションサイズが変わらないものがあります。
aws ec2 run-instances --profile mydev --image-id ami-53641e52 --instance-type t2.micro --key-name hogehoge --subnet-id subnet-1a2b3c4d --security-group-id sg-1a2b3c4d --associate-public-ip-address --block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":12,"DeleteOnTermination":true,"VolumeType": "gp2"}}]'
上記はRHEL6.5 x86_64のAMIを用いて、ルートボリュームを12GBに変更したインスタンスを起動する例です。 上記で起動したインスタンスにログインして確認してみると、ルートパーティションは6GBしか使われていません。
# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 6.0G 2.2G 3.5G 40% / tmpfs 498M 0 498M 0% /dev/shm
ディスクデバイスとしては、指定した12GBをきちんと認識しています。
# fdisk -l /dev/xvda Disk /dev/xvda: 12.9 GB, 12884901888 bytes 97 heads, 17 sectors/track, 15261 cylinders Units = cylinders of 1649 * 512 = 844288 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x0003b587 Device Boot Start End Blocks Id System /dev/xvda1 * 2 7632 6291456 83 Linux
というわけで
話が逸れましたが、「OS側でEBSのサイズを認識し、パーティションを拡張する機能があるかないか」ということで、冒頭のEBSのアタッチ/デタッチの話と繋がってきます。Amazon Linuxにはその仕組みがあるけれど、RHEL6.5のAMIではそういう仕組みがなかった、ということですね。 この件については弊社ブログでも以前、EC2上のLinuxのパーティションを拡張する という記事で紹介しています。 こちらは「OS側でルートボリュームのパーティションサイズを変更できないので、別のインスタンスにEBSをアタッチしてpartedで拡張する」という比較的力技な内容となっています。 が、もう少し楽な方法があるので、ご紹介します。
cloud-init+growpartを使う
cloud-initのモジュールであるgrowpart(cloud-utils-growpart)を導入することで、OS起動時にEBSのサイズに合わせてパーティションサイズを変更できるようになります。 Amazon Linuxには標準でインストール&設定されていて、これのおかげで自動的にルートボリュームのサイズ変更に追従してくれるわけですね。Amazon Linux以外でもAMIによってはデフォルトで構成されているものもあるようです。
インストールと設定
以下はRHEL6.5での手順です。 cloud-utils-growpartはRHELリポジトリには含まれていないので、EPELから拾ってきます。
# rpm --import https://fedoraproject.org/static/0608B895.txt # rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm # yum install --enablerepo=epel cloud-utils-growpart
起動時にパーティションサイズを変更してくれるようにするためには、インストールだけでなくcloud-initの設定ファイルの編集も必要です。 /etc/cloud/cloud.cfgのcloud_init_modulesセクションはデフォルトでは以下のようになっています。
cloud_init_modules: - bootcmd - write-files - resizefs - set_hostname - update_hostname - update_etc_hosts - rsyslog - users-groups - ssh
cloud_init_modulesセクション内に以下一行を追記します。
- growpart
rebootして、どうなったか確認してみます。
# fdisk -l Disk /dev/xvda: 12.9 GB, 12884901888 bytes 97 heads, 17 sectors/track, 15261 cylinders Units = cylinders of 1649 * 512 = 844288 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x0003b587 Device Boot Start End Blocks Id System /dev/xvda1 * 2 15261 12581670+ 83 Linux
パーティションは拡張されましたが、ファイルシステムの拡張は行われていません。
# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 6.0G 2.2G 3.5G 40% / tmpfs 498M 0 498M 0% /dev/shm
どれどれ、と思って試してみたらresize2fsも効きませんでした。おや。
# resize2fs /dev/xvda1 resize2fs 1.41.12 (17-May-2010) The filesystem is already 1572864 blocks long. Nothing to do!
なんだろうなあ、と思いながらここで2回目の再起動を行ったところ、今度はファイルシステムの拡張もきちんと行われていました。
# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 12G 2.3G 9.1G 20% / tmpfs 498M 0 498M 0% /dev/shm
めでたしめでたし。
さいごに
「めでたしめでたし、じゃねーよ!」とセルフツッコミしながらcloud-init.logを追いかけたところ、1回目の再起動でgrowpartによってパーティションの拡張が行われ、2回目の再起動後に今度はファイルシステムの拡張が行われていました。このあたりのロジックがまだ掴めておらず、ちょっとモヤモヤしますが、他のインスタンスにアタッチしてfdiskする手順と比べると2回再起動するほうが格段に楽なので、そういうものなのだと納得することにして、今回の記事を締めたいと思います。 あ、もしこのあたり詳しく知ってて教えてくれる方いたら以下URLから気兼ねなくお声掛けください!!! クラウドを操りSIの世界を変えたいエンジニアをWanted!