余談
最近,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
結果は,こんな感じ.
手順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 の常連発表者のレベルであれば,たぶん半日のハッカソンで,何らか創り出せるだろう.そんな気がする.