EC2でXenのmini-osを動かす手順

余談

最近,mruby を動作させる超軽量クラウドOSなんてのを,なんちゃってで作っている. ざっくりとした経過は,先週末くらいからtwitterで呟いている.

一応,会社を持っているので,そちらで展開することは不可能ではなさげではある. でも開発資金もないし市場も立ち上がっている風でもない.ネタ系で済ましておいたほうが,傷を負わなくて済むような気もする. 資金力が十分にあるならば,大学に持ちかけて共同研究でも始めちゃうようなネタという気もするのだが. 思案の最中. うだつが上がらんと,ほんと,なんにもできないねぇ. やだやだ.

閑話休題.

まくら

そのOSは,Xen の mini-os (厳密にいうと stubdom)をベースにしているので,Amazon EC2 でも動作する. Amazon が提供していないカーネルを独自に EC2 で動作させるためには,どうやら EBS ボリュームを作らねばならないらしい. 私は,AWS の単なるユーザで,細かいところはあまり詳しくない. よって,EBS ボリューム以外での起動方法もあるのかもしれないが….

手順は本家ヘルプページに割と細かく説明されている. 解説ブログも,ググれば山盛り. さすがは,みんな大好きAWS.

だがしかし,最近になって,AWS は,管理ツールを AWS-CLI というものに統合しようとしている一方,本家ヘルプページは,AWS-CLI への対応が十分にできていない.

そこで,本稿では,AWS-CLI で mini-os をブートさせるための手順を記す.

作業

概要

独自のカーネルをEC2上で動作させるためのイメージ(以下,オレオレイメージ)は,EBS のスナップショットから作るようになっている. Xen ではおなじみの PV-GRUB が,オレオレイメージ中にある boot/grub/menu.lst を読み, kernel (本稿の場合は mini-os)をロードしブートする. 手元環境でEBSを作ってアップロードすることもできるのかもしれないが(知らない),ここでは EC2 上で t1.micro を立ち上げて作業する. 一連の作業時間は,1時間もかからない.t1.micro なら10円にも満たないような額だろう.

本稿では,ビルドは手元で行うことを想定している.ビルド環境さえもEC2上に立てるということも,もちろんできる. その際の作業の読み替え箇所は,いちいち言及するまでも無いだろう.

手順0: ~/.aws/config

こんな感じ.

1
2
3
4
5
[default]
aws_access_key_id=ないしょ
aws_secret_access_key=ないしょ
region=ap-northeast-1
output=text

region が違うと,下記例示の image-id やらなにやら変更が要るかもしれない.

手順1: EBSボリュームへのアクセスを行う EC2 インスタンスの生成

EC2のインスタンスを立ち上げる.

1
$ aws ec2 run-instances --image-id ami-dcfa4edd --instance-type t1.micro --security-group-ids quick-start-1 --key-name monaka

—security-groups-ids や —key-name は,ご自分の環境に合わせて. —image-id も,好みの環境があるなら,それで. でも,本稿の例だと複雑なことはしないので,amiの選択に凝るのは時間の無駄かも.

結果はこんな感じ.

1
2
3
4
5
6
7
8
578606849602 r-351e1831
GROUPS    sg-e242dbe3 quick-start-1
INSTANCES 0   i386    None    False   xen ami-dcfa4edd    i-a3bec9a4  t1.micro    aki-ec5df7ed    monaka  2014-02-01T11:04:33.000Z    None    None    /dev/sda1   ebs None    paravirtual
MONITORING    disabled
PLACEMENT ap-northeast-1b None    default
SECURITYGROUPS    sg-e242dbe3 quick-start-1
STATE 0   pending
STATEREASON   pending pending

手順2: 諸々のファイルを入れるEBSボリュームの生成

1
$ aws ec2 create-volume --size 1 --availability-zone ap-northeast-1b

mini-os のサイズは1MB以下なのだが,EBSボリュームの最低サイズは1GB.無駄だがやむなし.

結果はこんな感じ.

1
ap-northeast-1b  2014-02-01T10:46:19.012Z    1   None    creating    vol-1cbb4b16    standard

手順3: EBSボリュームのEC2インスタンスへのアタッチ

1
Monacintosh:~ monaka$ aws ec2 attach-volume --volume-id vol-1cbb4b16 --instance-id i-a3bec9a4 --device /dev/sdh1

vol-1cbb4b16 は,手順2の結果で得られたもの.i-a3bec9a4 は,手順1の結果で得られたもの.

結果はこんな感じ.

1
2014-02-01T11:05:25.613Z /dev/sdh1   i-a3bec9a4  attaching   vol-1cbb4b16

手順4: 作業用 EC2 インスタンスへの ssh ログイン

手順1で,インスタンスを立ち上げた直後は,サーバのFQDNが判らない. そろそろインスタンスのプロビジョニングも終わっているはずなので,確認.

1
$ aws ec2 describe-instances --instance-ids i-a3bec9a4

結果はこんな感じ

1
2
3
4
5
6
7
8
9
RESERVATIONS 578606849602    r-351e1831
GROUPS    sg-e242dbe3 quick-start-1
INSTANCES 0   i386    None    False   xen ami-dcfa4edd    i-a3bec9a4  t1.micro    aki-ec5df7ed    monaka  2014-02-01T11:04:33.000Z    ip-10-132-154-11.ap-northeast-1.compute.internal    10.132.154.11   ec2-54-199-18-76.ap-northeast-1.compute.amazonaws.com   54.199.18.76    /dev/sda1   ebs None    paravirtual
BLOCKDEVICEMAPPINGS   /dev/sda1
EBS   2014-02-01T11:04:36.000Z    True    attached    vol-69bc4c63
MONITORING    disabled
PLACEMENT ap-northeast-1b None    default
SECURITYGROUPS    sg-e242dbe3 quick-start-1
STATE 16  running

compute.amazonaws.com で終わっているのが,外向きのFQDN. 今回の場合は,ec2-54-199-18-76.ap-northeast-1.compute.amazonaws.com なので,おもむろに ssh.

Amazon Linux の場合は,ログインユーザは ec2-user となる.

サーバの公開鍵を受け入れるかどうかなど聞かれる. 結果は,こんな感じ.

1
2
3
4
5
6
7
8
9
10
11
12
13
The authenticity of host 'ec2-54-199-18-76.ap-northeast-1.compute.amazonaws.com (54.199.18.76)' can't be established.
RSA key fingerprint is e8:10:70:59:ce:4b:7b:59:97:92:35:d8:35:a7:3a:92.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ec2-54-199-18-76.ap-northeast-1.compute.amazonaws.com,54.199.18.76' (RSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

See /usr/share/doc/system-release/ for latest release notes.
No packages needed for security; 170 packages available
Amazon Linux version 2013.09 is available.
[ec2-user@ip-10-132-154-11 ~]$ 

手順5: EBSボリュームのマウント

手順3では,EBSボリュームはアタッチしかしていない. ここでファイルシステムを作成して,マウントする.

ファイルシステムの生成は,こんな感じ.

1
[ec2-user@ip-10-132-154-11 ~]$ sudo mkfs.ext2 /dev/sdh1

結果は,こんな感じ.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
  32768, 98304, 163840, 229376

Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

ファイルシステムはできたので,早速マウント.

1
[ec2-user@ip-10-132-154-11 ~]$ sudo mount /dev/sdh1 /mnt

特にメッセージの出力など無く,コマンドプロンプトに戻ってくる.

手順6: menu.lst の生成

PV-GRUB が読む menu.lst を,EBSボリューム(の中にあるファイルシステム)に置く. エディタ使ってもいいけれど,この程度なら猫で十分.

1
2
3
4
5
6
7
8
[root@ip-10-132-154-11 ec2-user]# sudo -s
[root@ip-10-132-154-11 ec2-user]# cat > /mnt/boot/grub/menu.lst
default 0

title MiniOS test
        root (hd0)
        kernel /mini-os
[root@ip-10-132-154-11 ec2-user]# exit

sudo -s を使ったので,最後には exit で,ec2-user に戻しておいた.

手順7: mini-os のコピー

何らかの方法で行う. ふつうは scp を使うと思う. そして,EC2 インスタンス上の /mnt/mini-os に配置する. ここでmenu.lst の記述に引っ張られて,うっかり,/mini-os に置いたりとかしないように.

手順8: スナップショットの生成

手順7までで,EC2インスタンスは用済みとなる. だから,stop-insrance なり terminate-instance なりで落としてもよい. けれども,最初の動作確認ができるまでは,立ち上げっぱなしのほうがよいかもしれない. EC2の課金は1時間単位だけれども,1時間以内にn回立ち上げ直すと,n時間分の料金になる.

EC2のインスタンスにアタッチしたままでも,スナップショットは取れる. そうでないと,スナップショットの意味が無い.

操作は,こんな感じ.

1
$ aws ec2 create-snapshot --volume-id vol-1cbb4b16
1
2
結果は,こんな感じ.
None  578606849602    None    snap-940d6c7a   2014-02-01T11:24:16.000Z    pending vol-1cbb4b16    1

手順9: スナップショットからオレオレイメージの生成

いよいよ佳境.スナップショットからオレオレイメージを生成する. 正直言うと,よく調べがついていないのだけれど,イメージの概要を示すjsonファイルが必要らしい. 短いものなので,これもテキストエディタを持ち出すまでもないはず.

1
2
3
4
$ cat > blockdevice.json
[
        {"DeviceName":"/dev/xvda","Ebs":{"VolumeType":"standard","DeleteOnTermination":true,"VolumeSize":1,"SnapshotId":"snap-940d6c7a"}}
]

VolumeSize は,最初に 1GB で作ったから.SnapshotId は,手順8の出力と合わせる.

そして,イメージの登録を行う.

1
$ aws ec2 register-image --root-device-name /dev/xvda --name "Mini-os test" --block-device-mappings file://blockdevice.json --architecture x86_64

結果は,こんな感じ.

1
ami-ef650eee

手順10: オレオレイメージの起動

そして感動のフィナーレ.オレオレイメージの起動.

1
$ aws ec2 run-instances --image-id ami-ef650eee --instance-type t1.micro --security-group-ids quick-start-1 --key-name monaka

結果は,こんな感じ

1
2
3
4
5
6
7
8
578606849602 r-f17d65f5
GROUPS    sg-e242dbe3 quick-start-1
INSTANCES 0   x86_64  None    False   xen ami-ef650eee    i-b38630b4  t1.micro    monaka  2014-02-01T11:46:28.000Z    None    None    /dev/xvda   ebs None    paravirtual
MONITORING    disabled
PLACEMENT ap-northeast-1b None    default
SECURITYGROUPS    sg-e242dbe3 quick-start-1
STATE 0   pending
STATEREASON   pending pending

これだけだと,本当に立ち上がったのか判らない.

ログの取得は,こんな感じで行う.

1
$ aws ec2 get-console-output --instance-id i-b38630b4

i-b38630b4 は,オレオレイメージの run-instance の結果から引っ張ってくる.

mini-os 自身は小さいものの,mini-os の実行環境のプロビジョニングには,そこそこの時間がかかる. 遅い時は5分以上かかるので,気長に待つ. どうせ1時間までは同じ時間だから.

雑感

EC2 == クラウド == インフラ屋さんやWeb屋さん

という第一印象を持つかもしれないが,stubdom は,newlibだのlwIPだの使っていて,技術要素としては,むしろ組込み屋の定番ライブラリで成り立っている.

2000年ごろには,IOKit を用いてオレオレOSを作るのが流行ったが,同様に,オレオレクラウドOSを作るのが地味に流行るかもしれない. 情報量が少なくて,とっかかりは辛いが,#kernelvm の常連発表者のレベルであれば,たぶん半日のハッカソンで,何らか創り出せるだろう.そんな気がする.