第3回 プライベートクラウドを構築してみる~その2~




シダ部長

シダ部長
若い頃は色々な大規模開発プロジェクトで開発者として辣腕を振るい、その後は経験を活かし炎上プロジェクトの火消し人や、先進的技術の R&D などに携わり「受け攻めのシダ」の異名をもつ。

ハブカくん

ハブカくん
シダ部長の指揮する部署に配属されたばかりで、シダ部長のもとで流行りの「クラウド」について七転八倒を繰り広げる。

竹本トミー

竹本トミー
未来の世界のハコ型ロボット

ConoHa Advent Calendar 2015 4日目

シダ部長
ハブカくん、どうだね?順調かね?
ハブカくん
あれ?シダ部長どうしたんですか?今日は仕事サボって勝浦港に釣りに行ったんじゃ…
竹本トミー
それどこの釣りバカ…
シダ部長
(サボって…人聞きが悪いなぁ…)
シダ部長
いやねハブカくんがちゃんと環境構築できているか気になって、有休返上でこうして来てみたわけなんだよ。で、どうだい?調子は?
ハブカくん
(ぶっちゃけ迷惑…)
ハブカくん
いえ、ちょうど今からConoHaでサーバーを起動しようとしてたんですが、スペックの選定でちょっと悩みまして…
シダ部長
どれ、見せてごらん
ハブカくん
っていうか部長、このまま話を進めたら ConoHa Advent Calendar 2015 の 12/4 のエントリって、個人ブログとかに掲載するんじゃなくて会社のコラムになってしまうんですが、いいんですか?
シダ部長
そんな細かいことは気にしなくていい。大人の事情で第3回を ConoHa Advent Calendar 2015 の 12/4 のエントリとするってことに決定したんだから、さっさと困っていることを教えなさい。
ハブカくん
はぁ…(大人って大変だなぁ…)
ハブカくん
openstack-ansible のドキュメントではディスクサイズが最低でも80GB必要って書いてあるので、ConoHaで起動するサーバーのディスク選定では250GBを選択してみたんですが…
ハブカくん
でも、起動したところ以下のように50GBしかないように見えるんですが…
root@133-130-116-204:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        49G  1.6G   45G   4% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            7.9G   12K  7.9G   1% /dev
tmpfs           1.6G  396K  1.6G   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            7.9G   72K  7.9G   1% /run/shm
none            100M     0  100M   0% /run/user
シダ部長
あーなるほどね。では/proc/partitionsを見てごらん?
root@133-130-116-204:~# cat /proc/partitions 
major minor  #blocks  name

 253        0   52428800 vda
 253        1   51380224 vda1
 253        2          1 vda2
 253        5    1045504 vda5
 253       16  209715200 vdb
  11        0    1048575 sr0
  11        1        434 sr1
ハブカくん
あ!vdaは50GBで残りの200GBはvdbなんですね?
シダ部長
そのようだね。だからハブカくんは200GBのほうをopenstack-ansibleで使うようにしないといけないねぇ
ハブカくん
どーやったらそんなことできるんすか?
竹本トミー
ハブカくん、少しは調べる努力しようよ…
シダ部長
いや、いいんだトミーくん、彼にはもうそのような助言をしても無駄なんだよ。諦めて手取り足取り教えてあげようじゃないか。
竹本トミー
部長がそう言うならわかりました。
ハブカくん
部長ってば優すぃー
竹本トミー
ハブカくんにもできる簡単な方法を教えよう。まず以下のコマンドを実行して /dev/vdb にパーティションを1つ作成するんだ。
# echo ',' | sfdisk /dev/vdb
竹本トミー
そして次に以下のコマンドを実行して先程作成したパーティションをフォーマットして…
# mkfs.ext4 /dev/vdb1
竹本トミー
フォーマットしたらパーティションをマウントして、現在の /dev/vda1 の内容をコピー…
# mount /dev/vdb1 /mnt
# rsync -PHSav --exclude '/mnt/' --exclude '/proc/' --exclude '/sys/' / /mnt/
# mkdir -p /mnt/{proc,sys}
竹本トミー
そしてここからちょっとややこしいんだけど、まず /mnt/etc/fstab の / パーティションのマウント定義を /dev/vda1 から /dev/vdb1 に変更するんだ。これは root パーティションを 50GB の /dev/vda1 から 200GB の /dev/vdb1 に変更するために必要なんだ。注意点として、fstab の記述は /dev/vda1 って書いてある場合と UUID でデバイスを指定してある場合があるけど、UUID で指定されていたとしても無理に /dev/vdb1 の UUID で更新する必要はなく、たとえばハブカくんの環境の fstab は以下のように書き換えておいたよ。
root@133-130-116-204:~# diff -u /etc/fstab /mnt/etc/fstab
--- /etc/fstab  2015-05-05 12:44:51.200384000 +0900
+++ /mnt/etc/fstab      2015-11-21 00:05:38.196995183 +0900
@@ -6,6 +6,6 @@
 #
 #                
 # / was on /dev/vda1 during installation
-UUID=24e7865b-dfab-4391-a110-514008616841 /               ext4    errors=remount-ro 0       1
+/dev/vdb1       /               ext4    errors=remount-ro 0       1
 # swap was on /dev/vda5 during installation
 UUID=c2c8ba86-f869-4608-859a-b29e1e28b162 none            swap    sw              0       0
竹本トミー
次に /boot/grub/grub.cfg に記述されている root=UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX という記述を root=/dev/vdb1 に変更するんだ。簡単な方法としては以下のようなコマンドを実行する方法がある。なお、ここで注意してほしいのは、変更するのは /mnt/boot/grub/grub.cfg じゃなく /boot/grub/grub.cfg ということ。
# sed -i -e "s|root=UUID=[0-9a-f-]*|root=/dev/vdb1|g" /boot/grub/grub.cfg
竹本トミー
あとは /mnt をアンマウントして reboot コマンドなどで OS を再起動すれば…ほら、以下のように / パーティションの容量が 50GB から 200GB にサイズアップ!
# df -h
df: ‘/tmp/tmp8t5ABN’: No such file or directory
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb1       197G  1.6G  186G   1% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            7.9G   12K  7.9G   1% /dev
tmpfs           1.6G  400K  1.6G   1% /run
none            5.0M  4.0K  5.0M   1% /run/lock
none            7.9G     0  7.9G   0% /run/shm
none            100M     0  100M   0% /run/user
ハブカくん
うぉぉ!ほんとだ!トミーパイセンすげぇ!
竹本トミー
まぁ、朝飯前だよ、こんなの。
シダ部長
あー、トミーくん、ドヤ顔しているところを誠に申し訳ないんだけど、全部自分でやってしまってるよ?
竹本トミー
はっ!しまった!
ハブカくん
(ちっ、気付かなきゃこのまま楽できたのに、部長め余計なことを…)
ハブカくん
これでもう前回同様に openstack-ansible でセットアップするだけで ConoHa 上に OpenStack 環境が完成するんですね?よーし、ぼく頑張っちゃうぞ!
ハブカくん
ポチポチっとやって、./scripts/bootstrap-aio.sh を実行して…ん?あれ?あれあれれ?何かエラーが出てきた…
+ blk_devices=vdb
+ for blk_dev in '${blk_devices}'
++ awk '/^\/dev\/vdb[0-9]* / {print $2}' /proc/mounts
+ mount_points=/
+ for mount_point in '${mount_points}'
+ umount /
umount: /: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
ハブカくん
なんで / パーティションをアンマウントしようとしているの?わけわかんないよぉ!
シダ部長
「わけわかんないよぉ!」じゃないよ、原因を探ってみようじゃないか。
ハブカくん
でも bootstrap-aio.sh の中じゃ unmount やってる部分が無いんですよぉ…
シダ部長
bootstrap-aio.sh は他のファイルを読み込んでたりしないかい?
ハブカくん
う…ん、あっ!同じ階層にある scripts-library.sh を読み込んでます。
シダ部長
そのファイルの中に今回のエラーに該当する部分があるはずだよ。
ハブカくん
ここですね、きっと
 blk_devices=$(lsblk -nrdo NAME,TYPE,RO | awk '/d[b-z]+ disk [^1]/ {print $1}')
    for blk_dev in ${blk_devices}; do
      # dismount any mount points on the device
      mount_points=$(awk "/^\/dev\/${blk_dev}[0-9]* / {print \$2}" /proc/mounts)
      for mount_point in ${mount_points}; do
        umount ${mount_point}
        sed -i ":${mount_point}:d" /etc/fstab
      done
シダ部長
答えを言ってしまうけど、この抜粋したコードの1行目を見てごらん。awk の引数が「/d[b-z]+」になっているだろう?この記述だと今回みたいに /dev/vdb1 を対象に含めてしまうから、以下のように変更することで小手先の回避が可能になるよ。
# diff -u ./scripts/scripts-library.sh.orig ./scripts/scripts-library.sh
--- ./scripts/scripts-library.sh.orig   2015-11-21 00:29:41.706223880 +0900
+++ ./scripts/scripts-library.sh        2015-11-21 00:29:57.538223880 +0900
@@ -81,7 +81,7 @@
 
   # only do this if the lxc vg doesn't already exist
   if ! vgs lxc > /dev/null 2>&1; then
-    blk_devices=$(lsblk -nrdo NAME,TYPE,RO | awk '/d[b-z]+ disk [^1]/ {print $1}')
+    blk_devices=$(lsblk -nrdo NAME,TYPE,RO | awk '/d[c-z]+ disk [^1]/ {print $1}')
     for blk_dev in ${blk_devices}; do
       # dismount any mount points on the device
       mount_points=$(awk "/^\/dev\/${blk_dev}[0-9]* / {print \$2}" /proc/mounts)
ハブカくん
修正してもう一度 bootstrap-aio.sh を実行…おぉ!今度はうまく通った。
ハブカくん
あとはこの前と同じように bootstrap-ansible.sh と run-playbooks.sh を実行して…と、どうせまだ2時間ぐらいかかるんだからマンガでも読んで待ってよっと。
シダ部長
こらこらこら!
ハブカくん
ハッ!しまった、部長が居たんだった、もう帰ってくんないかなぁ…
シダ部長
……。
竹本トミー
(心の声が漏れてる…)
シダ部長
どうせなら待ち時間の間にトミーから OpenStack 以外の IaaS 基盤ソフトウェアについてレクチャーを受けるといいよ。
ハブカくん
えぇ!?せっかくの待ち時間なのに勉強しなきゃいけないんですかぁ?どんだけ僕を使役するんですか!
シダ部長
いやいやいや、そもそもこれ業務時間中だよね、何か勘違いしてないかい?そもそも業務時間中に勉強できているだけでも感謝してもらいたいねぇ。
ハブカくん
はぁ~い、わかりましたぁ~。
竹本トミー
じゃぁ独断と偏見で説明していくね。
竹本トミー
まずは OpenStack を語るときに欠かせない存在の Eucalyptus(※1)

※1: http://eucalyptus-users.jp/

ハブカくん
ゆ~かりプラス?なんかコアラの餌の強そうなバージョンみたいな名前だね
竹本トミー
(こいつワザとやってないか…?)
竹本トミー
プラスじゃなくプタスね。ユーカリプタス。餌みたいじゃなくて、名前のとおり植物のユーカリのことだよ。
ハブカくん
ふぅ~ん、ググラビリティの低そうな名前だね。困るんだよねソフトウェアの名前に一般名詞を付けられると。
竹本トミー
そーゆーことは Eucalyptus で検索するようになってから言いなよ。

~ 30分後 ~

ハブカくん
へぇ~、なるほど、日本じゃもう Eucalyptus って流行ってないのかぁ
竹本トミー
Hewlett-Packard Enterprise 社に買収されて HP Helion Eucalyptus になって北米ではちゃんとビジネスとして扱われているし、OpenSource としてちゃんとコミュニティが活動を支えているようだけど、日本国内においては流行っていないという印象なんだよね。
ハブカくん
栄枯必衰だね。でもさ、そーなると逆に使ってみたくなるよね。
竹本トミー
じゃー OpenStack の次は Eucalyptus を触ってみる?
ハブカくん
りょーかい。で、その Eucalyptus の構築は簡単なの?
竹本トミー
うーん、Eucalyptus をやってる人は「世界で一番構築が簡単でハマらない」って言ってるけど、どう考えても主観でしかないよねぇ…
ハブカくん
「世界で一番」って形容詞がつくと余計に怪しいね。
竹本トミー
あ、でも、Eucalyptus をやっている人が今 Eucalyptus を簡単に試せる LiveDVD を作っているらしいよ
ハブカくん
LiveDVD! なにそれ!?そんな素敵なものがあるなら是非試してみたい!
竹本トミー
まぁまぁ、慌てないで、まだ作っている最中のようだから、もし本当に完成したら教えるよ。もしかすると完成しない可能性もあるからね。
竹本トミー
さて、次は CloudStack (※2)。これは一時期は OpenStack と双璧を成すほど流行った IaaS 基盤だけど、今は印象としては OpenStack に大きく水をあけられている感じだね。

※2: https://cloudstack.apache.org/

ハブカくん
CloudStack?これは OpenStack の姉妹品か何かなの?あ!わかった!CloudStack のオープンソース版が OpenStack と見た!
竹本トミー
ブッブー、全然違いまーす。CloudStack は OpenStack とは全然違う起源のソフトウェアだよ。
ハブカくん
えぇー!?紛らわしい名前つけるなぁ…、何で OpenStack と連想されるような名前にしたんだろう…?
竹本トミー
ところがどっこい、OpenStack の名前が最初に世に出てくるのは 2010/07/19 なんだけど、CloudStack の名前が最初に出てくるのは 2010/05/17 と、OpenStack より早いんだよね。
ハブカくん
へぇ~、じゃぁ、CloudStack が出てから OpenStack が出てきたっていうこと?
竹本トミー
実際はそれぞれ中の人に聞かなきゃわからないけど、CloudStack は VMOps 社が開発していた VM Instance Manager が CloudStack という名前になったのがその 2010年5月らしいし、OpenStack は NASA と Rackspace 社が報道発表したのがその 2010年7月 なんだけど、OpenStack の最初のコアコンポーネントの Nova の開発自体は僕が中の開発者から「いまこんなの作ってるんだ」って教えてもらったのが 2010年6月だから、実際にはもっと前から開発が始まっていたんだと思うんだよね。
ハブカくん
え?トミーって未来の世界からやってきたんじゃないの?
竹本トミー
やってきたけど!!あぁ、やってきたともさ!!!未来の世界から!それがどうした!!!
ハブカくん
…いえ、何でもないです…
竹本トミー
どうせハブカくんのことだ、CloudStack も触ってみたい!とか言うんだろ?いいよ、教えてやるよ、嫌ってほど触らせてやるよ!
ハブカくん
(トミー怖い…未来の世界からの設定には触れないでおこう…)

~ 30分後 ~

竹本トミー
というわけで、CloudStack は今は Apache Project のソフトウェアとして開発が継続されているんだ。
ハブカくん
なるほど、で、これは LiveDVD とか出てないの?
竹本トミー
そうなんでもかんでも LiveDVD になっていると思わないでほしいなぁ。
ハブカくん
へへへ
竹本トミー
LiveDVD は無いけど、LiveCD は存在するようだね、この動画(※3)を観ると。

※3: https://www.youtube.com/watch?v=Ql8eAO9rvQE

ハブカくん
えー!あるんじゃん!
竹本トミー
でもこの LiveCD がどこで公開されているのか不明なんだよね。
ハブカくん
そうかぁ…。じゃぁ機会があったら地道にインストールしてみるよ。
竹本トミー
うん、いい心掛けだ。さて、次は Wakame-vdc (※4)。これは国産の IaaS 基盤ソフトウェアだ。

※4: http://wakame-vdc.org/

ハブカくん
国産!?
竹本トミー
そう国産。でも国産と言ってもコアデベロッパーが日本に住んでいるっていうだけで、日本人が占める割合は半分ぐらいかな?もしかすると IaaS 基盤ソフトウェアのなかでは一番マルチリンガルな開発環境を持つソフトウェアかもしれない。
ハブカくん
開発に参加する障壁が低そうだ♪
竹本トミー
いいところに気付いたね、実際 Wakame-vdc の開発は OpenStack のような数千人規模の開発とは違うため、メーリングリストやチャットなどで気軽にコンタクトしたりパッチ投げたり、github の issues (※5)にも要望などを日本語で気軽に投稿できるっていう話らしいよ。

※5: https://github.com/axsh/wakame-vdc/issues

ハブカくん
へぇ…気軽に参加できるのってオープンソースの醍醐味のひとつだね。

~ 30分後 ~

竹本トミー
というわけで Wakame-vdc は長らく OpenStack や CloudStack の陰に隠れてて知名度が限定的だったけど、IaaS 基盤ソフトウェアの多様性を考えたときに、Wakame-vdc のアーキテクチャのアプローチは興味深いから、これも機会があれば触ってみるといいよ。
ハブカくん
もう半ばお約束的に聞くけど、まさか LiveDVD とかあったりしないよねぇ?
竹本トミー
あるよ
ハブカくん
やっぱ、そうそう都合よくはないか…ん?え?あるの?
竹本トミー
あるよ
ハブカくん
え?じゃぁ、OpenStack より先にそれを触らせてくれたらよかったのに…。僕ちゃんと第2回で主張したよね?
竹本トミー
そんなこと僕に言われても…ハブカくんに OpenStack をやらせたのはシダ部長だし…
ハブカくん
くそぉ、僕に「ぎゃふん!」って言わせたいがために OpenStack を触らせたに違いない…
竹本トミー
そんな馬鹿な…
ハブカくん
で、その LiveDVD はどこにあるの?
竹本トミー
ここが LiveDVD のプロジェクトサイト(※6)みたいだよ。

※6: https://github.com/axsh/iso-no-wakame

ハブカくん
なんか1台構成だけじゃなく、複数台構成の環境を構築するのにたった1枚のDVDから起動できるとか、すごく便利そうじゃん!
ハブカくん
え~と、プロジェクト名が…いそのワカメ…?磯…
シダ部長
おや?openstack-ansible での構築が完了したんじゃないかな?
ハブカくん
あ、シダ部長!おかえりなさい。
シダ部長
さて、じゃぁ続きをやってみなさい。
ハブカくん
(あれ?何か僕言いかけてたような…)
ハブカくん
えーと、WebUI にアクセスし、まずはイメージファイルを登録(メニューで Admin -> System -> Images とアクセスして [Create Image] をクリック)…っと。
ハブカくん
各項目は以下のように入力して…[Create Image] をクリックと。
Name: ubuntu-14.04
Image Source: Image Location
Image Location: https://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img
Format: QCOW2
Public: checked
ハブカくん
次に外部接続用のネットワークを作成する画面(メニューで Admin -> System -> Networks とアクセスして [Create Network] をクリック)を開き…
ハブカくん
各項目を以下のように入力して…[Create Network] をクリック。
Name: public
Project: admin
Provider Network Type: Flat
Physical Network: flat
External Network: checked
ハブカくん
そして作成したネットワーク「public」にサブネットを作成するために一覧画面で先程作成したネットワーク「public」をクリックして [Create Subnet] をクリック。
ハブカくん
各項目を以下のように入力して…[Next] をクリック
Subnet Name: public-subnet
Network Address: 172.29.248.0/22
Gateway IP: 172.29.248.1
ハブカくん
続いて各項目を以下のように入力して…[Create] をクリック
Enable DHCP: unchecked
Allocation Pools: 172.29.248.200,172.29.248.240
ハブカくん
次に外部接続用ネットワーク「public」に接続するためのルータを作成する画面(メニューで Project -> Network -> Routers とアクセスし [Create Router] をクリック)を開き
ハブカくん
各項目を以下のように入力して…[Create Router] をクリック
Router Name: ext-router
External Network: public
ハブカくん
プロジェクト側の内部ネットワークを作成するためにネットワークを作成する画面(メニューで Project -> Network -> Networks を開き [Create Network] をクリック)
ハブカくん
各項目を以下のように入力して…[Create] をクリック
Network Name: private
Subnet Name: private-subnet
Network Address: 192.0.2.0/24
Gateway IP: 192.0.2.1
ハブカくん
内部ネットワークを先程作成したルータ「ext-router」に接続させるために画面(Project -> Network -> Routers -> 一覧画面で先程作成したルータ「ext-router]をクリック -> Interfaces タブを開き [Add Interface] をクリック)を開き
ハブカくん
項目「Subnet」で「private-subnet」と選択して…[Add Interface]をクリック
ハブカくん
インスタンスに接続するための SSH 鍵を作成するために openstack-ansible 環境に SSH で接続して以下を実行し…
# lxc-attach --name `lxc-ls | grep utility_container`
# source /root/openrc
# nova keypair-add key1 > ~/key1.pem
# chmod 400 ~/key1.pem
ハブカくん
さて、いよいよインスタンスを起動するための画面(Project -> Compute -> Instances を開き [Launch Instance] をクリック)を開き
ハブカくん
各項目に以下を入力し、[Launch]をクリック
Instance Name: vm01
Flavor: m1.small
Instance Boot Source: Boot from image
Image Name: ubuntu-14.04
Security Groups: default
Selected networks: private
ハブカくん
あれ?インスタンスの起動が失敗した…
シダ部長
おやぁ?早速、問題発生のようだね?
ハブカくん
なんか部長の顔がすっごく嬉しそうなんですけどぉ…
シダ部長
オホン!気のせいじゃないかな。さてログを見せてごらん。
ハブカくん
えーと、インスタンスが起動しなかったから…とりあえず nova-compute.log からの抜粋でいいですか?
Traceback (most recent call last):
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/compute/manager.py", line 2155, in _build_resources
    yield resources
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/compute/manager.py", line 2009, in _build_and_run_instance
    block_device_info=block_device_info)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 2441, in spawn
    write_to_disk=True)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 4326, in _get_guest_xml
    context)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 4175, in _get_guest_config
    root_device_name)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 3998, in _configure_guest_by_virt_type
    guest.sysinfo = self._get_guest_config_sysinfo(instance)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 3391, in _get_guest_config_sysinfo
    sysinfo.system_serial = self._sysinfo_serial_func()
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 3380, in _get_host_sysinfo_serial_auto
    return self._get_host_sysinfo_serial_os()
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 3374, in _get_host_sysinfo_serial_os
    raise exception.NovaException(msg)
 NovaException: Unable to get host UUID: /etc/machine-id is empty
シダ部長
いいねぇ。ほら見てごらん、このわかりやすいエラー。
ハブカくん
え?一番最後の machine-id が空っぽって言ってる点ですか?
シダ部長
そうだね、machine-id が空っぽだとエラーになるようだね。ほら、このコード(※7)を見てごらん。

※7: /openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py

def _get_host_sysinfo_serial_os(self):
    """Get a UUID from the host operating system

    Get a UUID for the host operating system. Modern Linux
    distros based on systemd provide a /etc/machine-id
    file containing a UUID. This is also provided inside
    systemd based containers and can be provided by other
    init systems too, since it is just a plain text file.
    """
    if not os.path.exists("/etc/machine-id"):
        msg = _("Unable to get host UUID: /etc/machine-id does not exist")
        raise exception.NovaException(msg)
     with open("/etc/machine-id") as f:
        # We want to have '-' in the right place
        # so we parse & reformat the value
        lines = f.read().split()
        if not lines:
            msg = _("Unable to get host UUID: /etc/machine-id is empty")
            raise exception.NovaException(msg)
シダ部長
ほら、/etc/machine-id ファイルが空っぽだと先程のエラーを出すコードになっているだろう?
ハブカくん
確かにそうですね。じゃぁ machine-id ファイルに UUID か何かを書き込めばいいんでしょうか?
シダ部長
いやいや、待ちなさい。この _get_host_sysinfo_serial_os() を呼んでいる場所を見てごらん
ハブカくん
同じファイルの以下の部分でしょうか?
def _get_host_sysinfo_serial_auto(self):
    if os.path.exists("/etc/machine-id"):
        return self._get_host_sysinfo_serial_os()
    else:
        return self._get_host_sysinfo_serial_hardware()
シダ部長
そうそう。そもそも /etc/machine-id が存在しなければ別の処理に流れるようになっているので、ここは思いきって /etc/machine-id ファイルを消してみようじゃないか。
ハブカくん
はい、わかりました。えいっ。
シダ部長
ではもう一度インスタンスを起動してごらん。
ハブカくん
ぽちぽちぽちっと…あれぇ?またエラーになりました。
シダ部長
今度はどんなエラーだい?
ハブカくん
以下のようです。
Traceback (most recent call last):
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/compute/manager.py", line 2155, in _build_resources
   yield resources
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/compute/manager.py", line 2009, in _build_and_run_instance
   block_device_info=block_device_info)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 2444, in spawn
   block_device_info=block_device_info)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 4511, in _create_domain_and_network
   self.plug_vifs(instance, network_info)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/driver.py", line 666, in plug_vifs
   self.vif_driver.plug(instance, vif)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/vif.py", line 729, in plug
   func(instance, vif)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/virt/libvirt/vif.py", line 485, in plug_bridge
   iface)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/oslo_concurrency/lockutils.py", line 254, in inner
   return f(*args, **kwargs)
 File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/network/linux_net.py", line 1612, in ensure_bridge
   raise exception.NovaException(msg)
NovaException: Failed to add bridge: sudo: unable to resolve host 133-130-116-204
シダ部長
今度もわかりやすいエラーだね
ハブカくん
自身のホスト名 133-130-116-204 が名前解決できないっていう点ですか?
シダ部長
そうだね。対処法はいくつかあるけど、第2回と今回とで違う点を探してみようじゃないか。
竹本トミー
すごい、まるでこうなることが分かってたかのようなよどみのないやりとり…
シダ部長
シッ!
ハブカくん
えーっと、OpenStackの設定的には差がないように見えます。
シダ部長
エラーは「ホスト名が解決できない」だよ? OpenStack の設定よりは OS の設定を疑うほうが筋じゃないかな?
ハブカくん
あぁっ!第2回の環境はホスト名が aio1 で /etc/hosts にも「172.29.236.100 aio1」と定義が入っているのに対し、今回の環境はホスト名が 133-130-116-204 なのに /etc/hosts は aio1 のままです!
シダ部長
気付いたかね
ハブカくん
ってことは、/etc/hosts に「172.29.236.100 133-130-116-204」とすればいいんでしょうか?
シダ部長
うん、その可能性が一番高いような気がするけど、ちょっと考えてみてほしい。なぜ固定的に「172.29.236.100 aio1」という定義なのか…長年の勘が何かを訴えてるんだよね…
ハブカくん
ハッ!それって例の「ティキーン!この感じ…ニュータイプか!」ってやつですか?
シダ部長
うん、違うから。っていうかそのネタはこの業界では地雷原だから避けてね。
ハブカくん
(部長…やっぱり何かに怯えてる…)
ハブカくん
じゃーもう面倒だから…ぽちぽちぽちっと。
シダ部長
え?何したの?
ハブカくん
面倒だったからファイル「/etc/hostname」の中身をaio1に変更して「hostname aio1」を叩いてみました。あ、あと根拠なく nova-compute と nova-scheduler のプロセスを再起動しました。
シダ部長
それはハマリ道の入口…いや、ちょっと nova service-list を叩いてごらん?
ハブカくん
はぁ…、あっ… nova-compute が2台に見えてる…
# nova service-list
+----+------------------+----------------------------------------+----------+---------+-------+----------------------------+-----------------+
| Id | Binary           | Host                                   | Zone     | Status  | State | Updated_at                 | Disabled Reason |
+----+------------------+----------------------------------------+----------+---------+-------+----------------------------+-----------------+
| 3  | nova-cert        | aio1_nova_cert_container-9f91ec5b      | internal | enabled | up    | 2015-11-25T18:44:07.000000 | -               |
| 6  | nova-conductor   | aio1_nova_conductor_container-2a14684e | internal | enabled | up    | 2015-11-25T18:44:08.000000 | -               |
| 9  | nova-scheduler   | aio1_nova_scheduler_container-faa6144f | internal | enabled | up    | 2015-11-25T18:44:11.000000 | -               |
| 12 | nova-consoleauth | aio1_nova_console_container-3a6309f1   | internal | enabled | up    | 2015-11-25T18:44:06.000000 | -               |
| 15 | nova-compute     | 133-130-116-204                        | nova     | enabled | down  | 2015-11-25T18:41:38.000000 | -               |
| 18 | nova-compute     | aio1                                   | nova     | enabled | up    | 2015-11-25T18:44:07.000000 | -               |
+----+------------------+----------------------------------------+----------+---------+-------+----------------------------+-----------------+
シダ部長
ね、変な状態になってしまっただろう?
ハブカくん
むむっ、こうなったら「nova service-delete 15」で古い認識を消して…もう一度インスタンス起動を…
ハブカくん
ぐはぁ…また違うエラーが出た…
Instance failed network setup after 1 attempt(s)
Traceback (most recent call last):
  File "/openstack/venvs/nova-12.0.1/lib/pytho
n2.7/site-packages/nova/compute/manager.py", line 1564, in _allocate_network_async
    dhcp_options=dhcp_options)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/network/neutronv2/api.py", line 727, in allocate_for_instance
    self._delete_ports(neutron, instance, created_port_ids)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/oslo_utils/excutils.py", line 195, in __exit__
    six.reraise(self.type_, self.value, self.tb)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/network/neutronv2/api.py", line 719, in allocate_for_instance
    security_group_ids, available_macs, dhcp_opts)
  File "/openstack/venvs/nova-12.0.1/lib/python2.7/site-packages/nova/network/neutronv2/api.py", line 342, in _create_port
    raise exception.PortBindingFailed(port_id=port_id)
PortBindingFailed: Binding failed for port e0baf507-5aac-489c-bfa4-f2f631b6cab5, please check neutron logs for more information.
シダ部長
もうドハマり状態だよこれは…
ハブカくん
えーっと、エラーの内容は…
シダ部長
いやー、もう一旦諦めようじゃないか
ハブカくん
えぇっ!諦めたらそこで試合終了ですよ?
シダ部長
なに意味のわからないこと言ってるんだね?試合って何だよ。
ハブカくん
あ…すみません、今回は会話に漫才色が少ないせいか、何かネタを入れないと…っていう暗示が…
シダ部長
意味のわからないことを言ってないで、一旦環境を作り直して再挑戦してごらんよ
ハブカくん
えーっ!?また作り直すんですかぁ?
シダ部長
そんなに嫌がるほど面倒な手順じゃないだろう?ほら、さっさとやってごらん。
ハブカくん
はぁ~い。

~ 2時間後 ~

ハブカくん
シダ部長!ホスト名を aio1 にしてから openstack-ansible で環境を作り直してみました。
シダ部長
よし、じゃぁインスタンスを起動してごらん?
ハブカくん
はい、ぽちぽちぽちっと。あ!今度は起動成功しました!
シダ部長
では続きの操作をしてインスタンスに接続してみなさい。
ハブカくん
えっと、セキュリティグループのルール追加画面(Project -> Compute -> Access & Security -> Security Groups tab -> default -> Manage Rules を開き Add Rule をクリック)を開き…
ハブカくん
各項目は以下のように入力して…[Add] をクリックと。
Rule: SSH
Remote: CIDR
CIDR: 0.0.0.0/0
ハブカくん
次に Floating IP の払出し画面(Project -> Compute -> Access & Security -> Floating IPs を開き [Allocate IP to Project] をクリック)を開き
ハブカくん
[Allocate IP] をクリックして、次に払出された Floating IP をインスタンスに割り当てる画面(Project -> Compute -> Access & Security -> Floating IPs を開き、払出された Floating IP の [Associate] をクリック)を開き、「Port to be associated」の項目で vm01 を選択し…インスタンスの一覧でちゃんと割り当てられていることを確認っと。
ハブカくん
じゃーいよいよ SSH で接続を…
# ssh -i ~/key1.pem ubuntu@172.29.248.201
ハブカくん
わーい、やったぁー! SSH でログインできたー!!
シダ部長
ふふふっ、やっと成功したようだね。
ハブカくん
OpenStack って環境構築して使えるようになるまでチョー大変っすね?
シダ部長
いやいや、今回は見事にハマリポイントにハマってくれたから大変だったけど、第2回みたいにハマらない場合は簡単に使えただろう?
ハブカくん
そー言われればそうですね…。でもホスト名を aio1 にしないとハマるとかドキュメントに記載しておいてくれてもいいのに…。
シダ部長
本当にそれが原因だとはまだ断定できないよね?例えば第2回の環境のハードウェア構成でホスト名を aio1 以外にして試したらどうなるかとか…。
ハブカくん
うわぁ…それを試すのって気が遠くなりそうです…。
シダ部長
さすがに毎回それらを手で試すのは辛い作業なので、最近ではインフラのテストも自動化するのがトレンドになっているので、機会があったらインフラのテストについても説明しようじゃないか。
ハブカくん
テストという名前を聞くとじんましんがでる体質なので、できれば遠慮したいです…。
シダ部長
自動化したらじんましんも出なくなると思うんだけどねぇ。
ハブカくん
マジすか?もう手順書なのか表なのか方眼紙なのか理解不能なモノを見なくてもいいんですか?
シダ部長
きっとゼロにはならないかもしれないけど、少なくてもテストにかかる辛い作業は軽減されると言っていいね。
ハブカくん
じゃぁ今度それ教えてください。
シダ部長
では次回はインフラのテストまわりをやろうか。
ハブカくん
いえ、次回は LiveDVD を触りたいです!!!


第3回 プライベートクラウドを構築してみる~その2~