Amazon LinuxをVirtualBoxで動かす

# はじめに
AWSのEC2でサービスの運用しているんだけど、手元のPCでも環境を再現したいなーと思うことって無いですか？ここではAWSのEC2インスタンスのイメージを取得し、VirtualBoxで利用する方法を記述します。

![743079001408413771.gif](https://qiita-image-store.s3.amazonaws.com/0/32789/dd0c441c-957b-e6b2-646f-41014f3f2eb0.gif)

# 全体の流れ
- EC2インスタンスをRAWイメージで取得
- 新しいRAWイメージファイルを用意
- 最初に取得したRAWイメージを新しいイメージファイルにコピー
- 新しいイメージファイルにGRUBをインストール
- 新しいイメージファイルをVMwareのvdiフォーマットに変換
- VirtualBoxで起動


# 手順
## 0.事前準備
- コピーしたいEC2インスタンスにGRUBをインストールしておきます

```
# yum install grub
```

- コピーしたいEC2インスタンスにsudoできるサーバアカウントを作成しておきます

> EC2だとrootアカウントのパスワードがわからないため、VirtualBoxで起動した後にコンソールからログインしてroot権限になれるアカウントを事前に作っておきます

- コピーしたいEC2インスタンスに作業領域のEBSボリュームをmountします

```
# lsblk
NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvdf  202:80   0  60G  0 disk 
xvda1 202:1    0  30G  0 disk /
# mkfs -t ext4 /dev/xvdf
# mkidr /export
# mount /dev/xvdf /export
# df
Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/xvda1            30963708   4716624  26142300  16% /
tmpfs                   304236         0    304236   0% /dev/shm
/dev/xvdf             61927420    184136  58597556   1% /export
```
> 作業領域の大きさはコピーするEC2インスタンスのディスクサイズの二倍以上は確保しておいてください。EC2のRAWイメージファイルを作成する際にEC2のディスク容量と同じサイズを消費します。

## 1. EC2インスタンスをRAWイメージで取得
```
# cd /export
# dd if=/dev/xvda1 of=ec2.raw
62914560+0 records in
62914560+0 records out
32212254720 bytes (32 GB) copied, 3854.56 s, 8.4 MB/s
```

## 2. 新しいイメージファイルを用意

**空の領域を作成します（8GBの例）**

```
# dd if=/dev/zero of=new.raw bs=1M count=8192
8192+0 records in
8192+0 records out
8589934592 bytes (8.6 GB) copied, 233.631 s, 36.8 MB/s
```

> この時のサイズはEC2インスタンスでのディスク使用量よりは大きめのサイズにしてください。1024×8＝8192です。

**ループバックデバイスの設置**

```
# losetup -fv new.raw
Loopデバイス は /dev/loop0 です
```


**新しいRAWイメージにパーティションを作成します**

```
# cfdisk /dev/loop0
```

> パーティションは全体で1つ作ります
> 作成したパーティションは「ブート可」にします
> 必ず「書き込み」をしてから終了してください

![cfdisk.png](https://qiita-image-store.s3.amazonaws.com/0/32789/94b0a02c-fa4e-1e55-7372-cbb4a99f0365.png)


**作成したパーティションの物理情報を表示します**

```
# fdisk -l -u /dev/loop0
ディスク /dev/loop0: 8589 MB, 8589934592 バイト
ヘッド 255, セクタ 63, シリンダ 1044, 合計 16777216 セクタ
Units = セクタ数 of 1 * 512 = 512 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00000000

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/loop0p1   *          63    16777215     8388576+  83  Linux
```

**データ領域のパーティションの開始位置を指定してループバックデバイスを作成します**

```
# losetup -fv -o 32256 new.raw
Loopデバイス は /dev/loop1 です
```

> 32256はセクタサイズ×始点ブロック＝512×63＝32256から計算します。ディスクの先頭のMBRのある領域を上書きしないためです。

**ファイルシステムを作成します**

```
# mkfs.ext4 -b 4096 /dev/loop1 2097144
mke2fs 1.42.3 (14-May-2012)
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
524288 inodes, 2097144 blocks
104857 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2147483648
64 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

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

> 2097144は((終点ブロック-始点ブロック)×セクタサイズ)/ブロックサイズ＝((16777215-63)*512/4096)＝2097144と計算します

## 3. 最初に取得したEC2のRAWイメージを新しいイメージファイルにコピー

**最初に取得したRAWイメージにループバックデバイスを設置**

```
# losetup -fv ec2.raw
Loopデバイス は /dev/loop2 です
```

**それぞれのイメージファイルをマウントします**

```
# mkdir /mnt/ec2
# mount -t ext4 /dev/loop2 /mnt/ec2
# mkdir /mnt/new
# mount -t ext4 /dev/loop1 /mnt/new
```

**イメージの中身をコピーします**

```
# cp -a /mnt/ec2/* /mnt/new/
```

## 4. 新しいイメージファイルにGRUBをインストール

**grubをインタラクティブモードで起動して設定を行います**

```
# grub --device-map=/dev/null
grub> device (hd0) new.raw
grub> root (hd0,0)
grub> setup (hd0)
grub> quit
```

**/mnt/new/boot/grub/menu.lstを編集します**

```menu.lst
# created by imagebuilder
default=0
timeout=10
#hiddenmenu

title Amazon Linux 2013.03 (3.4.48-45.46.amzn1.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-3.4.48-45.46.amzn1.x86_64 root=/dev/sda1 LANG=en_US.UTF-8 KEYTABLE=us
initrd /boot/initramfs-3.4.48-45.46.amzn1.x86_64.img
（省略）
```

> root行が`(hd0)`だった場合は`(hd0,0)`に変更
> kernel行の`root=LABEL=/`は`root=/dev/sda1`に変更
> kernel行に`console=hvc0`とあったら削除します


**fstabを修正**


> tune2fsでかっこ良くラベルをつけられれば、この作業は必要ないんでしょうけど。。

**片付けをします**

```
# umount /mnt/new
# umount /mnt/ec2
# losetup -d /dev/loop0
# losetup -d /dev/loop1
# losetup -d /dev/loop2
```


## 5. RAWイメージをvdiファイルに変換します


DOSプロンプトよりVBoxManage.exeを実行


```
> VBoxManage convertdd new.raw new.vdi
```

> EC2にVirtualBoxをインストールするのはまた手間なので、ローカルのPCなどにnew.rawをダウンロードしてローカル上で実行することをオススメします。VBoxManage.exeまでのPATHを通しておきましょう。

## 6. VirtualBox起動

変換したvdiファイルをストレージとして接続して起動します

![grub.png](https://qiita-image-store.s3.amazonaws.com/0/32789/b1e48c20-f52b-064c-b641-2a9efd43266f.png)

![login.png](https://qiita-image-store.s3.amazonaws.com/0/32789/e1b28a4b-f771-70fe-8928-fe7ee053f524.png)



# まとめ
これでAmazon EC2のインスタンスをVirtualBoxにインポートすることができました。しかし、このサーバを実用的に使うにはネットワーク設定やAWSならではの設定を調整していかないといけないので、とても面倒です。


# 参考
http://smashingboxes.com/ideas/how-to-convert-ec2-ami-to-vmdk-for-vagrant
https://church.cs.virginia.edu/genprog/index.php/Converting_an_EC2_AMI_to_a_VirtualBox_.vdi

# 仲間募集
[株式会社スピカ](http://spika.co.jp)では一緒に切磋琢磨できるエンジニアの方を募集しています！ぜひ、[こちら](https://www.wantedly.com/companies/spika/projects)をご覧ください！！