AWSで仮想化方式 PV(paravirtual) の既存 CentOS AMIを HVMにする

#t2.microが出た！

t1.microに比べて高性能なのにお安い。
さっそく使おうと思ったら、「あなたのAMIはHVMじゃないから無理です」
的なエラー文でt2.microを選択できなかった。

調べてみるとXenの仮想化にはPVとHVMの2通りあり、今まではPVが普通だったのがこれからはHVMで行こう、的な流れらしい。
最近発表されたAWSインスタンスの多くはHVM専用になってる。

PVとHVMについてはこのページがわかりやすかったです。
http://kanny.hateblo.jp/entry/2014/01/19/182759

# PVのCentOS AMIをHVMにする
流れにのってHVMに乗り換えたいんだけど、どうしたらいいんだろう。
といろいろ探すと以下のページに詳しい移行方法が書かれていた。

http://www.agilegroup.co.jp/technote/t1micro-to-t2micro-migration.html
https://forums.aws.amazon.com/thread.jspa?messageID=553638

が、こちらを参考に進めたんですが、そっくりそのまま実行しただけではうまくいかず。
・・・ですので自分の環境でうまくいった方法を記述します。
(* 恐らくmenu.lstへのgrub.confのシンボリックがない為と思います)

今回はCentOS 6.5のPVなAMIをHVMにします。

# 作業用インスタンスを作成
ここからが本題。

適当なHVMなAmazon Linux 64bitを立ち上げます。
このインスタンスはPV-HVMへの変更の作業用インスタンスとなります。

![aws04.png](https://qiita-image-store.s3.amazonaws.com/0/42887/f7c2b4dc-1bd4-a265-12cd-79c0552d3196.png)

インスタンスが立ち上がったらAvailability zoneを控えておきます

# 既存のPVのAMIのスナップショットからVolumeを作成

HVMにしたいPVのAMIのスナップショットからVolume作成します。
SnapShot の一覧からPV AMIのスナップショットを確認し、右クリックでCreate Volumeを選択。

デフォルトのままでいいんですが、Availability zoneは作業用インスタンスのものと合わせます。
これがコピー元Volumeとなります。

![aws01.png](https://qiita-image-store.s3.amazonaws.com/0/42887/72f15676-c169-4717-c426-3e9a81477413.png)

# HVM用新規ボリューム作成

Volumes -> Create Volumeで新規ボリュームも作成します。
ボリュームのサイズは既存のPV AMIのディスク以上であればOKです（同じでいいと思います。）
Availability zoneは作業用インスタンスのものと合わせます。
これはHVM用の新規ボリュームとなります。

![aws02.png](https://qiita-image-store.s3.amazonaws.com/0/42887/98b2fb55-2c0e-ebc9-4c24-dd8826c40a04.png)


# 作業用インスタンスにアタッチ

作成した2個のVolumeを作業用インスタンスにアタッチします。
Volumesの一覧でアタッチするVolumeを右クリックでAttachを選択します。

インスタンスのテキストボックスにカーソルするとアタッチできるインスタンスが一覧されるので選択します。
(ここで、上記で作成したインスタンスがでない場合はAvailability zoneを確認)

Deviceの設定は以下のようにします。

```
コピー元Volume -> Device /dev/sdm
HVM用新規Volume -> Device /dev/sdo
```

Device名はなんでもいいのですが、参考サイトと同じにしました。
変更した場合は適宜読み替えて下さい

# 作業用インスタンスにログインしHVMへの各種設定を行う

作業用インスタンスにログインして各種設定を行います。
ログイン後はrootで作業してください

## パーティションを作成してディスクをコピー

HVM用新規Volumeにパーティション作成

```bash
parted /dev/xvdo --script 'mklabel msdos mkpart primary 1M -1s print quit'
partprobe /dev/xvdo
udevadm settle
```

コピー元Volumeを調整

```bash
e2fsck -f /dev/xvdm
resize2fs -M /dev/xvdm
```

resize2fsを実行すると以下のような記述が出るので控える

```
resize2fs 1.42.8 (20-Jun-2013)
Resizing the filesystem on /dev/xvdm to 210341 (4k) blocks.
The filesystem on /dev/xvdm is now 210341 blocks long.
```

コピー元Volumeの内容をHVM用新規Volumeにコピー。
bsとcountの内容はresize2fsの結果の内容を記述する

```
dd if=/dev/xvdm of=/dev/xvdo1 bs=4K count=210341
```

コピー後、HVM用新規Volumeをリサイズ

```
resize2fs /dev/xvdo1
```

#HVM用新規Volumeをマウントしてchrootする

```
mount /dev/xvdo1 /mnt
cp -a /dev/xvdo /dev/xvdo1 /mnt/dev/
chroot /mnt
```

##ここからの作業はchrootした状態で行う

###grubをインストール

旧AMIにgrubがインストールされてない場合はここでインストール

```
yum install -y grub
```

grub.confがなければシンボリックリンクを作成する。
(たぶんこの作業が参考サイトにはなかったので僕の環境では動かなかった)

```
ln -s /boot/grub/menu.lst /boot/grub/grub.conf
ln -s /boot/grub/grub.conf /etc/grub.conf
```

ファイルがあれば、既存のgrubのstageファイルは削除。

```
rm -f /boot/grub/*stage*
cp /usr/*/grub/*/*stage* /boot/grub/
rm -f /boot/grub/device.map
```

grubをインストール

```
cat <<EOF | grub --batch
device (hd0) /dev/xvdo
root (hd0,0)
setup (hd0)
EOF
```

以下のようになったら成功

```
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/xvdo
grub> root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83
grub> 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.
```

### menu.listを修正

```
vi /boot/grub/menu.lst
```

以下のような感じにします。

-root(hd0) -> root(hd0,0)
-kernel行の root=/dev/xvde1 を root=/　に変更
-kernel行の console=* を console=ttyS0 に変更(なければ追加)
-xen_pv_hvm=enable を追加

以下は僕の設定例です

```
default=0
timeout=0
hiddenmenu
title CentOS6.5
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.32-431.17.1.el6.x86_64 ro root=LABEL=/ console=ttyS0 xen_pv_hvm=enable
        initrd /boot/initramfs-2.6.32-431.17.1.el6.x86_64.img
```

### fstabを修正

```
vi /etc/fstab
```

以下のように修正します。

```
LABEL=/ / ext4 defaults,noatime 1 1
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
```

###ラベルを変更する

```
e2label /dev/xvdo1 /
```

ちゃんと/というラベルになっているか確認

```
tune2fs -l /dev/xvdo1 |grep name
```

`Filesystem volume name:   /`となっていればOKです

#chrootを抜けてアンマウント

```
exit
rm -f /mnt/dev/xvdo /mnt/dev/xvdo1
sync
umount /mnt
```

# HVM用ボリュームからスナップショット作成 -> AMI作成

HVM用Volumeのスナップショットを作成します。
Volumesから該当Volumeで右クリック -> Create Snapshotです。
名前等は適当でOKです。

スナップショットができたら、今度は作成したSnapshotを右クリック -> Create Image
Virtualization type が Hardware-assisted virtualization になっているのを確認します。
(何度かやっていたのですがmenu.listがHVMになっていたら自動で選択されていた)

![aws03.png](https://qiita-image-store.s3.amazonaws.com/0/42887/4912b885-bdf4-14fb-3b96-75b2b825caa5.png)


これでAMIが作成されます。(完成)

# 確認

作成されたAMIからインスタンスを作成し正常起動できるか確認します。
この時、t2.micro等のHVMインスタンスが選択できるかを確認。
これでインスタンスが起動しない場合はやりなおし・・・。