ハマった時は # init 0

試したことを書き綴ってます

AWS API Gateway + lambda で任意のHTTPステータスコードを返却する

API Gateway + lambda で、任意のHTTPステータスコードを返却したい場合、次のことを行えば任意ステータスコードを返却できるようになります。

lambdaが正常終了した場合は、正規表現チェックの対象にならないようなので、lambdaは例外スローする必要があります。

lambda ファンクション作成

まずは、次のようなlambdaファンクションを作成してみます。 名前は、"test_lambda_function"としました

  • パラメータに、key1 または、key2が含まれていないと例外をthrow
  • key2が整数ではない場合、例外throw
# -*- coding: utf-8 -*-
import json
import types

def lambda_handler(event, context):

    print("Received event: " + json.dumps(event, indent=2))
    
    
    if not "key1" in event:
        raise Exception("Parameter error. Missing field 'key1'.")
    if not "key2" in event:
        raise Exception("Parameter error. Missing field 'key2'.")
    if not type(event["key1"]) is types.UnicodeType:
         raise Exception("Parameter error. 'key1' is not a UnicodeType")
         
    try:    
        # key2が整数ではない場合、例外throw
        return 10 + event["key2"]

    except Exception as e:
        raise Exception("Internal error. " + e.message)

API Gateway を作成する。

次のように、先ほど作成したlambdaファンクションを実行するAPI Gateway を作成します。 demoというリソースを作成し、POSTメソッドを作成しています。

f:id:init0:20161127233012p:plain

API Gateway で Method Responseを設定する

Method Responseの設定画面で、HTTPステータスに400(バッドリクエスト)と500(サーバーエラー)を追加します。

f:id:init0:20161127234317p:plain

API Gateway で Integration Responseの設定

Integration Responseの設定画面で、Integration Responseを追加します。 次の2つの設定を追加します。

  • lambdaの例外メッセージに"Parameter error"という文字列が含まれていた場合に、400を返却
  • lambdaの例外メッセージに"Internal error"という文字列が含まれていた場合に、500を返却

f:id:init0:20161127235143p:plain

二つ設定が終わると、以下のようになります。

f:id:init0:20161127235334p:plain

ここまでの設定で、任意ステータスコードが返却できる簡単な設定が完了しました。

テストしてみる

デプロイし動作確認してみます。

f:id:init0:20161128003428p:plain f:id:init0:20161128003410p:plain

正常系

正しいJSONパラメータでHTTPのPOSTリクエストを実行し、200が返却されることを確認してみます。

$ curl -d '{"key1": "aaa", "key2": 100}' \
>     -i -H "Content-type: application/json" -X POST \
>     https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 3
Connection: keep-alive

### (中略) ###

110
パラメータエラー(400)を確認

key2を設定していないリクエストを実行し400が返却されることを確認します。

$ curl -d '{"key1": "aaa"}' \
>     -i -H "Content-type: application/json" -X POST \
>     https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo
HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 219

### (中略) ###

{"stackTrace": [["/var/task/lambda_function.py", 13, "lambda_handler", "raise Exception(\"Parameter error. Missing field 'key2'.\")"]], "errorType": "Exception", "errorMessage": "Parameter error. Missing field 'key1'."}
インターナルサーバーエラー(500)を確認

インターナルサーバーエラーが発生するようにkey2に文字列を入力し、500が返却されることを確認します。

$ curl -d '{"key1": "aaa", "key2": "bbb"}' \
>     -i -H "Content-type: application/json" -X POST \
>     https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo
HTTP/1.1 500 Internal Server Error
Content-Type: application/json

### (中略) ###

{"stackTrace": [["/var/task/lambda_function.py", 21, "lambda_handler", "raise Exception(\"Internal error. \" + e.message)"]], "errorType": "Exception", "errorMessage": "Internal error. unsupported operand type(s) for +: 'int' and 'unicode'"}

レスポンスBodyを修正する。

このままでは、レスポンスのJsonに、スタックトレースがそのまま出力され、かっこ悪いので、レスポンスを編集してみます。

API Gateway の Integration Response で Mapping Template を定義することで修正できます。

デフォルトでは、以下のパラメータがJsonレスポンスに設定されています。 * stackTrace ... スタックトレースがそのまま設定 * errorType ... Exceptionのクラス名(型) * errorMessage ... Exceptionのメッセージ

errorMessageのみ出力するように設定してみます。

f:id:init0:20161128010745p:plain

デプロイし、確認してみます。

lavigne:~ mak$ curl -d '{"key1": "aaa"}' \
>     -i -H "Content-type: application/json" -X POST \
>     https://l43dvdh5bj.execute-api.ap-northeast-1.amazonaws.com/devel/demo
HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 62

### (中略) ###

{
  "errorMessage": "Parameter error. Missing field 'key2'."
}

openstack havana on ubuntu 13.10 (cinder)

openstackとりまとめページ http://init0.hatenablog.com/entry/2013/10/05/232939

LVMの設定

まずは、cinder用に VGを作成します。

nova 用に、ディスクパーティションを用意できる人用

ディスクに空きパーティションがある人は、一般的な方法で、VGを作成する。

  • vgの名称は、cinder-volumes とする。
    • cinderのデフォルト設定では、「cinder-volumes」を使うため。
# pvcreate /dev/sdb1
# vgcreate  cinder-volumes /dev/sdb1
# vgdisplay 
  --- Volume group ---
  VG Name               cinder-volumes
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               50.00 GiB
  PE Size               4.00 MiB
  Total PE              12799
  Alloc PE / Size       0 / 0   
  Free  PE / Size       12799 / 50.00 GiB
  VG UUID               H14HUP-XwkY-EeQt-tqpT-iNGG-abOt-gmBo2x
   

空きパーティションがない人向け

cinder用に使える空きパーティションがない場合は、ddでファイルを作成し、ループバックマウントして無理やりVGを作成する。

  • 再起動するたびに、losetupしないといけないので、/etc/rc.localに、losetupを記載すると便利。
# dd if=/dev/zero of=/home/cinder01.img bs=1024 count=10000000
# losetup -f /home/cinder01.img
# pvcreate /dev/loop0
  Physical volume "/dev/loop0" successfully created
# vgcreate cinder-volumes /dev/loop0
  Volume group "cinder-volumes" successfully created

DB作成

cinder用にDBを作成します。

  • 事前に、stack@localhost、stack@% というユーザは作成済みです。
  • cinderという名称で、DBを作成
  • stackユーザに、cinder DBを操作する全権限を付与する。
# mysql -u root -p
mysql> CREATE DATABASE cinder;
mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'stack'@'localhost';
mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'stack'@'%';

cinderインストール・設定

インストール

# aptitude install cinder-volume cinder-api cinder-scheduler

設定ファイル変更

  • /etc/cinder/cinder.conf
    • DBへの接続設定を追加する。

以下を追加

[database]
sql_connection = mysql://stack:stack@localhost/cinder
  • /etc/cinder/api-paste.ini
    • keystoneへの接続設定を記載する
# 省略
[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = cinder
admin_password = cinder
# 省略

DBにスキーマ登録

# cinder-manage  db sync

keystoneの設定

  • cinderユーザ作成
keystone user-create \
        --name=cinder \
        --pass=cinder \
        --email=cinder@example.com
  • cinderユーザにroleを付与
    • serviceテナントのadminとしてロールを作成。
    • tenant-id, user-id, role-idを事前に調べ、user-role-addの引数で渡す。
# keystone tenant-list | grep service
| 63db5b3fccf04d66b87091d5fbe771b7 | service |   True  |

# keystone user-list | grep cinder
| 300f04f6e9ac442d81ef3ea87fa969c1 |  cinder |   True  |  cinder@example.com |

 # keystone role-list | grep admin
| 58489d413e69439699875718d1407307 |        admin         |

keystone user-role-add \
        --tenant-id 63db5b3fccf04d66b87091d5fbe771b7 \
        --user-id 300f04f6e9ac442d81ef3ea87fa969c1 \
        --role-id 58489d413e69439699875718d1407307
  • REST API バージョン1用のendpointを作成
keystone service-create --name=cinder --type=volume \
  --description="Cinder Volume Service"

# keystone service-list | grep cinder
| 29c2d484d0f64a768423d90c5515b787 |  cinder  |    volume    |      Volume Service      |

keystone endpoint-create \
  --service-id= 29c2d484d0f64a768423d90c5515b787 \
  --publicurl=http://192.168.0.110:8776/v1/%\(tenant_id\)s \
  --internalurl=http://192.168.0.110:8776/v1/%\(tenant_id\)s \
  --adminurl=http://192.168.0.110:8776/v1/%\(tenant_id\)s
  • REST API バージョン2用のendpointを作成
keystone service-create --name=cinderv2 --type=volumev2 \
  --description="Cinder Volume Service V2"

# keystone service-list | grep cinderv2
| a9bbd40f7f9a46debd1f53511fc15d6c | cinderv2 |   volumev2   | Cinder Volume Service V2 |

keystone endpoint-create \
  --service-id=a9bbd40f7f9a46debd1f53511fc15d6c \
  --publicurl=http://192.168.0.110:8776/v2/%\(tenant_id\)s \
  --internalurl=http://192.168.0.110:8776/v2/%\(tenant_id\)s \
  --adminurl=http://192.168.0.110:8776/v2/%\(tenant_id\)s

cinderの再起動

service cinder-api restart
service cinder-volume restart
service cinder-scheduler restart

動作確認

cinderコマンドを使い、volumeを作成・削除する。

# cinder create --display-name vol01 1
# cinder list
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+
|                  ID                  |   Status  | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+
| 521c6a82-0aac-4418-a6b4-b458353c6039 | available |    vol01     |  1   |     None    |  false   |             |
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+

# cinder delete vol01

novaのVMインスタンスにvolumeをアタッチする。

VM起動
nova boot --image ubuntu13.04-qcow2  --flavor 2 --key-name default vm01
volume作成 + アタッチ
nova volume-create --display-name vol01 1

# nova volume-list | grep vol01 | awk '{ print $2 }'
1e3534f0-e3c4-4147-82ec-c2cd9a86bd8f

nova volume-attach vm01 1e3534f0-e3c4-4147-82ec-c2cd9a86bd8f  /dev/vdb
VM上でアタッチされたボリュームを使用する
root@vm01:~# fdisk -l /dev/vdb

Disk /dev/vdb: 1073 MB, 1073741824 bytes
16 heads, 63 sectors/track, 2080 cylinders, total 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/vdb doesn't contain a valid partition table




root@vm01:~# fdisk /dev/vdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xcc49baf5.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 
Using default value 1
First sector (2048-2097151, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-2097151, default 2097151): 
Using default value 2097151

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
root@vm01:~# mkfs.ext4 /dev/vdb1 
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 261888 blocks
13094 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

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
root@vm01:~# mount /dev/vdb1 /mnt/
  • ファイルを作成する。
root@vm01:~# ls /mnt/
lost+found
root@vm01:~# echo "HELLO" > /mnt/hello.txt
  • アンマウントする。
root@vm01:~# umount /mnt 
root@vm01:~# 
volumeデタッチ
nova volume-detach  vm01 1e3534f0-e3c4-4147-82ec-c2cd9a86bd8f
別のVMに作成済みvolumeをアタッチする
# nova boot --image ubuntu13.04-qcow2  --flavor 2 --key-name default vm02
# nova volume-attach vm02 `nova volume-list | grep vol01 | awk '{ print $2 }'` /dev/vdb
VM上でファイルシステムをマウント
  • マウントし、別VMで作成したファイルが存在するか確認
ubuntu@vm02:~$ mount /dev/vdb
vdb   vdb1  
ubuntu@vm02:~$ mount /dev/vdb1 /mnt/
mount: only root can do that
ubuntu@vm02:~$ sudo su - 
root@vm02:~# mount /dev/vdb1 /mnt/
root@vm02:~# ls /mnt/
hello.txt  lost+found
root@vm02:~# cat /mnt/hello.txt 
HELLO

ubuntu13.10でlibguestfs-toolsが動かないので対処

ubuntu13.10 では、12/12現在、libguestfs-toolsが正常に動作しません。(うちの環境だけかも)

libguestfs-test-toolを実行するとこんなエラーが発生します。

** 省略 **
libguestfs: error: external command failed, see earlier error messages
libguestfs-test-tool: failed to launch appliance
libguestfs: closing guestfs handle 0xc14f60 (state 0)

いろいろ調べてみたらproposedリポジトリでは対処済みのパッケージがコミットされているようです。

https://bugs.launchpad.net/ubuntu/+source/libguestfs/+bug/1243190

/etc/apt/sources.list に次の設定を追加して、libguestfs-toolsの再インストールで対処しました。

deb http://jp.archive.ubuntu.com/ubuntu/ saucy-proposed main multiverse universe restricted

早くmainリポジトリにコミットされないかな・・・ これで、guestmount や virt-* などなど便利なコマンドが使えるようになりました。

openstack havana on ubuntu 13.10 (nova)

openstackとりまとめページ http://init0.hatenablog.com/entry/2013/10/05/232939

はじめに

novaの各サービス,nova-compute, keystone, glance, mysqlを1サーバ上にオールインワンで構築した時のメモです。

nova インストール

# aptitude install nova-api nova-cert nova-conductor \
 nova-network nova-scheduler nova-compute-kvm rabbitmq-server \
 python-novaclient python-nova-adminclient

設定のため nova の各サービスは一旦停止する。

# stop nova-network
# stop nova-api
# stop nova-scheduler
# stop nova-cert
# stop nova-conductor
# stop nova-compute

設定ファイル修正

/etc/nova/nova.conf

  • sql_connectionで、mysqlの接続設定をする
    • 事前に、nova用のDB(名称はnova)を作成済み
    • openstackのユーザを、stackという名称で、パスワードをstackで作成済み
    • stackユーザは、novaデータベースの全操作を行えるようロールを付与済み
  • ネットワークは、VlanManagerを使用

補足ですが、nova-apiやnova-network,compute,glance,keystoneなどなど、 それぞれを別サーバ上に設置する場合は、

  • glance_host
  • rabbit_host

などの設定が必要です。

[DEFAULT]
dhcpbridge_flagfile=/etc/nova/nova.conf
dhcpbridge=/usr/bin/nova-dhcpbridge
logdir=/var/log/nova
state_path=/var/lib/nova
lock_path=/var/lock/nova
force_dhcp_release=True
iscsi_helper=tgtadm
libvirt_use_virtio_for_bridges=True
connection_type=libvirt
root_helper=sudo nova-rootwrap /etc/nova/rootwrap.conf
verbose=True
ec2_private_dns_show_ip=True
api_paste_config=/etc/nova/api-paste.ini
volumes_path=/var/lib/nova/volumes
enabled_apis=ec2,osapi_compute,metadata
use_ipv6=false

# MySQL Connection #
sql_connection=mysql://stack:stack@127.0.0.1/nova

## nova-api #
auth_strategy=keystone

## Networking #
network_manager=nova.network.manager.VlanManager
vlan_interface=eth0

/etc/nova/api-paste.ini

  • keystoneとの連携設定をする(tenant,userなどはあらかじめkeystoneに作成済み)
    • tenant名は、service
    • user名とpasswordは、nova,nova
    • keystoneとnovaは同一サーバ上に設置するため、auto_hostは、127.0.0.1
### 省略

[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = nova
admin_password = nova
# signing_dir is configurable, but the default behavior of the authtoken
# middleware should be sufficient.  It will create a temporary directory
# in the home directory for the user the nova process is running as.
#signing_dir = /var/lib/nova/keystone-signing
# Workaround for https://bugs.launchpad.net/nova/+bug/1154809
auth_version = v2.0

### 省略

nova設定

DB初期化と、novaのネットワーク設定を実施する。

DB初期化

# nova-manage db sync

novaの内部ネットワーク作成(fixed ip)

  • あらかじめkeystoneに登録したテナントのIDを確認する。
    • SERVICE_TOKENはkeystoneの設定時に決めたもの
# export SERVICE_TOKEN="ADMIN"
# export SERVICE_ENDPOINT="http://192.168.0.110:35357/v2.0"
#
# keystone tenant-list
WARNING: Bypassing authentication using a token & endpoint (authentication credentials are being ignored).
+----------------------------------+---------+---------+
|                id                |   name  | enabled |
+----------------------------------+---------+---------+
| 291d8659c224497e9183d8be80aa5ef4 |  admin  |   True  |
| b570ab00d8c2492f95082b21618b2359 |   demo  |   True  |
| c53fbee6f45944f5b77e2a1f41ffa9ab | service |   True  |
+----------------------------------+---------+---------+
#
# unset SERVICE_TOKEN
# unset SERVICE_ENDPOINT

demoテナント用のネットワークを作成する。

  • マルチNICとするので、2系統ネットワークを作成する。
  • 1つ目のネットワークは、
    • vlanid=102 (環境に合わせて任意のvlan idで良い)
    • bridge=br102 (環境に合わせて任意の名称で良い)
    • cidrは、10.0.2.0/24 (環境に合わせて任意)
    • projectには、あらかじめ調べたdemoテナントのIDを指定する
  • 2つ目のネットワークは、
    • vlanid=103 (環境に合わせて任意のvlan idで良い)
    • bridge=br103 (環境に合わせて任意の名称で良い)
    • cidrは、10.0.3.0/24 (環境に合わせて任意)
    • projectには、あらかじめ調べたdemoテナントのIDを指定する
# nova-manage network create --vlan=102 --bridge=br102 \
--bridge_interface=eth0 --fixed_range_v4=10.0.2.0/24 \
--num_network=1 --network_size=256 --label=demo1 --gateway=10.0.2.1 \
--fixed_cidr=10.0.2.0/24 --project=b570ab00d8c2492f95082b21618b2359 
#
# nova-manage network create --vlan=103 --bridge=br103 \
--bridge_interface=eth0 --fixed_range_v4=10.0.3.0/24 \
--num_network=1 --network_size=256 --label=demo2 --gateway=10.0.3.1 \
--fixed_cidr=10.0.3.0/24 --project=b570ab00d8c2492f95082b21618b2359 
  • 補足

うちの環境では、network create実行時に、次のエラーが発生する。無視。 多分、環境が汚れまくっているせいだと思う… (/usr/localに入れた記憶はないんだけど…)

2013-11-02 22:02:35.298 4512 INFO nova.network.driver [-] Loading network driver 'nova.network.linux_net'
2013-11-02 22:02:35.346 4512 ERROR stevedore.extension [-] Could not load 'file': (python-glanceclient 0.7.0 (/usr/local/lib/python2.7/dist-packages/python_glanceclient-0.7.0-py2.7.egg), Requirement.parse('python-glanceclient>=0.9.0'))
2013-11-02 22:02:35.346 4512 ERROR stevedore.extension [-] (python-glanceclient 0.7.0 (/usr/local/lib/python2.7/dist-packages/python_glanceclient-0.7.0-py2.7.egg), Requirement.parse('python-glanceclient>=0.9.0'))
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension Traceback (most recent call last):
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension   File "/usr/lib/python2.7/dist-packages/stevedore/extension.py", line 89, in _load_plugins
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension     invoke_kwds,
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension   File "/usr/lib/python2.7/dist-packages/stevedore/extension.py", line 101, in _load_one_plugin
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension     plugin = ep.load()
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension   File "/usr/local/lib/python2.7/dist-packages/pkg_resources.py", line 2059, in load
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension     if require: self.require(env, installer)
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension   File "/usr/local/lib/python2.7/dist-packages/pkg_resources.py", line 2072, in require
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension     working_set.resolve(self.dist.requires(self.extras),env,installer))
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension   File "/usr/local/lib/python2.7/dist-packages/pkg_resources.py", line 598, in resolve
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension     raise VersionConflict(dist,req) # XXX put more info here
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension VersionConflict: (python-glanceclient 0.7.0 (/usr/local/lib/python2.7/dist-packages/python_glanceclient-0.7.0-py2.7.egg), Requirement.parse('python-glanceclient>=0.9.0'))
2013-11-02 22:02:35.346 4512 TRACE stevedore.extension

floating ip の作成

  • 192.168.0.128/28 を、nova の floating ip として作成(予約)する。
# nova-manage floating create --ip_range=192.168.0.128/28

novaの各サービスを起動

# start nova-network
# start nova-api
# start nova-scheduler
# start nova-cert
# start nova-conductor
# start nova-compute

これで、novaの基本的な設定は環境。 後は、ユーザやテナントごとの個別設定。

ユーザ・テナント設定

環境変数設定

novaのクライアントコマンドを実行する場合は、いくつか環境変数を設定する必要がある。

環境変数をexportするための設定ファイル(/root/creds/demo/openrc)を作成し読み込む

  • AUTH_URLには、keystoneのIPを指定
  • USERNAMEには、keystoneで作成したユーザ名を指定
  • PASSWORDには、上記ユーザのパスワードを指定
  • TENANT_NAMEには、demoを指定(本手順の場合)

openrc

export OS_AUTH_URL=http://192.168.0.110:5000/v2.0
export OS_USERNAME=demo
export OS_PASSWORD=demo
export OS_TENANT_NAME=demo
# source /root/creds/demo/openrc

VMへのログイン用SSH鍵ペア設定

SSH鍵ペアを生成し、novaに登録する。

  • 出力場所は、/root/creds/demo/id_rsa
  • パスワードは無しとした
# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /root/creds/demo/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
  • novaに登録する。
    • 最後の引数は任意の名称 (今回は、demokey とした)
nova keypair-add --pub-key /root/creds/demo/id_rsa.pub demokey 

floating ipでの接続時ポート開放

*とりあえず、icmp,sshのポートを開放する。

nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0
nova secgroup-add-rule default tcp 22 22 0.0.0.0/0

VM起動

起動するVMイメージを確認する

  • glanceには、すでにVMイメージは登録済み。
  • 今回は、ubuntu13.04を起動するため、ubuntu13.04のIDを確認する。
# nova image-list
+--------------------------------------+-----------------------------+--------+--------+
| ID                                   | Name                        | Status | Server |
+--------------------------------------+-----------------------------+--------+--------+
| 3696a363-6d14-4c4b-93f6-3430cb734351 | ubuntu12.04                 | ACTIVE |        |
| 4a415489-00ae-46b0-9e6c-c398bff8ef9a | ubuntu13.04-qcow2           | ACTIVE |        |
+--------------------------------------+-----------------------------+--------+--------+

VM起動

  • novaコマンドにてVMを起動する。
# nova boot --image ubuntu13.04-qcow2 --flavor m1.small --key-name demokey  vm01

VM起動確認

  • nova listコマンドにて、起動状況を確認する。
    • Running となったらVM起動完了 (ただしSSHが起動完了しているとは限らない)
# nova list
+--------------------------------------+------+--------+------------+-------------+----------+
| ID                                   | Name | Status | Task State | Power State | Networks |
+--------------------------------------+------+--------+------------+-------------+----------+
| 88e8ef57-ddb0-470d-8ce7-ed22d70f2e12 | vm01 | BUILD  | spawning   | NOSTATE     |          |
+--------------------------------------+------+--------+------------+-------------+----------+
# nova list
+--------------------------------------+------+--------+------------+-------------+--------------------------------+
| ID                                   | Name | Status | Task State | Power State | Networks                       |
+--------------------------------------+------+--------+------------+-------------+--------------------------------+
| 88e8ef57-ddb0-470d-8ce7-ed22d70f2e12 | vm01 | ACTIVE | None       | Running     | demo2=10.0.3.3; demo1=10.0.2.3 |
+--------------------------------------+------+--------+------------+-------------+--------------------------------+
  • SSH秘密鍵を使用してログインする。
  • ついでにマルチNICになっているか確認する
# ssh -i /root/creds/demo/id_rsa 10.0.2.3


ubuntu@vm01:~$ dmesg | grep eth
[    3.379119] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[    3.379125] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready
[    6.128238] IPv6: eth0: IPv6 duplicate address fe80::f816:3eff:fe2d:e66b detected!
ubuntu@vm01:~$
ubuntu@vm01:~$ exit
logout
Connection to 10.0.2.3 closed.

floating ip を割り当てSSHログインする

# nova floating-ip-create
+---------------+-------------+----------+------+
| Ip            | Instance Id | Fixed Ip | Pool |
+---------------+-------------+----------+------+
| 192.168.0.129 | None        | None     | nova |
+---------------+-------------+----------+------+

# nova add-floating-ip vm01 192.168.0.129
#
# ssh -i /root/creds/demo/id_rsa ubuntu@192.168.0.129

VMを停止(破棄)する

# nova delete vm01

openstack havana on ubuntu 13.10 (glance)

openstackとりまとめページ http://init0.hatenablog.com/entry/2013/10/05/232939

インストール

# aptitude install glance
# dpkg -l | grep glance
ii  glance                                            1:2013.2~rc1-0ubuntu1                             all          OpenStack Image Registry and Delivery Service - Daemons
ii  glance-api                                        1:2013.2~rc1-0ubuntu1                             all          OpenStack Image Registry and Delivery Service - API
ii  glance-common                                     1:2013.2~rc1-0ubuntu1                             all          OpenStack Image Registry and Delivery Service - Common
ii  glance-registry                                   1:2013.2~rc1-0ubuntu1                             all          OpenStack Image Registry and Delivery Service - Registry
ii  python-glance                                     1:2013.2~rc1-0ubuntu1                             all          OpenStack Image Registry and Delivery Service - Python library
ii  python-glanceclient                               1:0.11.0-0ubuntu1                                 all          Client library for Openstack glance server.

設定のため、glanceは一旦停止する。

# service glance-api stop
# service glance-registry stop

設定

設定のポイントは、

  • glanceのデータを格納するDBはsqliteに(デフォルト)
  • keystoneとの連携設定をする(tenant,userなどはあらかじめkeystoneに作成済み)
    • tenant名は、service
    • user名とpasswordは、glance,glance
    • keystoneとglanceは同一サーバ上に設置するため、auto_hostは、127.0.0.1

/etc/glance/glance-api.conf

### 省略

[keystone_authtoken]
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = glance
admin_password = glance
#admin_tenant_name = %SERVICE_TENANT_NAME%
#admin_user = %SERVICE_USER%
#admin_password = %SERVICE_PASSWORD%

/etc/glance/glance-registry.conf

### 省略

[keystone_authtoken]
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = glance
admin_password = glance
#admin_tenant_name = %SERVICE_TENANT_NAME%
#admin_user = %SERVICE_USER%
#admin_password = %SERVICE_PASSWORD%

DBへスキーマ登録

# glance-manage db_sync

glance起動

# service glance-api start
# service glance-registry start

イメージ登録

credential設定
  • adminユーザのcredentialを環境変数に設定する
    • .bashrcに書いておくと楽…
# export OS_USERNAME=admin
# export OS_PASSWORD=admin
# export OS_TENANT_NAME=admin
# export OS_AUTH_URL=http://192.168.0.110:5000/v2.0
イメージ登録(qcow2形式の場合)

最近のopenstackは、qcow2形式でさくっとイメージ登録できるようになったみたいです。

# wget http://cloud-images.ubuntu.com/releases/13.04/release/ubuntu-13.04-server-cloudimg-amd64-disk1.img
# glance image-create --disk-format=qcow2 --container-format=bare --is-public=True \
    --name=ubuntu13.04-qcow2 \
    --file=./ubuntu-13.04-server-cloudimg-amd64-disk1.img
イメージ登録(ami形式の場合)

昔ながらのami形式の場合

ダウンロードして、kernelイメージとramdiskの登録

# wget https://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-uec.tar.gz
# tar xvfz  cirros-0.3.0-x86_64-uec.tar.gz
# glance image-create --disk-format=aki --container-format=aki --is-public=True \
    --name=cirros-aki --file=./cirros-0.3.0-x86_64-vmlinuz

# glance image-create --disk-format=ari --container-format=ari --is-public=True \
    --name=cirros-ari --file=./cirros-0.3.0-x86_64-initrd

先ほど登録した、kernelイメージと、ramdiskのIDを確認して、マシンイメージを登録

# glance image-list | grep cirros
| fa6d0a30-f1ff-42f3-959c-7feefb4fda78 | cirros-aki                  | aki         | aki              | 4731440    | active |
| 34565d35-296c-455e-95df-151ca7e2ceb0 | cirros-ari                  | ari         | ari              | 2254249    | active |
# 
# glance image-create --disk-format=ami --container-format=ami --is-public=True \
    --property kernel_id='fa6d0a30-f1ff-42f3-959c-7feefb4fda78' --property ramdisk_id='34565d35-296c-455e-95df-151ca7e2ceb0' \
    --name=cirros-ami --file=./cirros-0.3.0-x86_64-blank.img

openstack havana on ubuntu 13.10

openstack havana(rc1) を ubuntu13.10(beta)上に構築したときのメモです。

1サーバ内に、keystone, glance, nova(compute,network,api ...)のすべてをインストールしています。

openstack havana on ubuntu 13.10 (keystone)

openstackとりまとめページ http://init0.hatenablog.com/entry/2013/10/05/232939

ubuntu13.10 betaに更新したら、いつものごとくopenstackが動かなくなったので、再インストール。 まずは、keystoneから。

事前に、mysqlは次の設定をしてあります。

  • openstack の共通ユーザ stack を作成済み
    • パスワードは、stack
  • keystone 用のデータベース keystone を作成済み
  • ユーザ stack には、keystoneデータベースを操作する全権限を付与
keystone インストール
aptitude install keystone python-keystone keystone-doc
aptitude install python-mysqldb
keystoneの設定ファイル修正

設定変更のポイントは、

  • tokenは'ADMIN'
  • データベースは、sqliteからmysqlに変更
    • ユーザ名とパスワードは、共に、'stack'
    • データベース名は、'keystone'
  • keystoneは、192.168.0.110で動作
    • public_endpoint と admin_endpointを、localhostから192.168.0.110に変更

デフォルト設定との差分を記載しておきます。

< admin_token = ADMIN
---
> # admin_token = ADMIN
6c6
< bind_host = 0.0.0.0
---
> # bind_host = 0.0.0.0
9c9
< public_port = 5000
---
> # public_port = 5000
12c12
< admin_port = 35357
---
> # admin_port = 35357
18,19d17
< public_endpoint = http://192.168.0.110:%(public_port)s/
< admin_endpoint = http://192.168.0.110:%(admin_port)s/
51,52c49
< #debug = False
< debug = True
---
> # debug = False
55,56c52
< #verbose = False
< verbose = True
---
> # verbose = False
91,92c87
< #connection = sqlite:////var/lib/keystone/keystone.db
< connection = mysql://stack:stack@192.168.0.110/keystone
---
> connection = sqlite:////var/lib/keystone/keystone.db
keystoneの再起動 (設定反映)
service keystone restart
エンドポイント、ユーザ、テナントなどなど投入

ちまちまコマンドを入力すると大変なので、大昔に拾ってきたnova.shを改造したスクリプトを走らせます。

スクリプトで実行していることのポイントは、

  • keystone,nova,cinder,glance,ec2,swiftのエンドポイント作成
  • 各テナント作成
    • service用のテナント(service)作成
    • adminテナントと、demoテナント作成
  • ユーザ作成
    • adminユーザと、demoユーザ作成
  • ロール作成
  • テナントとユーザ、ロールのひも付け

keystone.sh

#!/bin/bash

mysql -ustack -pstack -e 'DROP DATABASE IF EXISTS keystone;'
mysql -ustack -pstack -e 'CREATE DATABASE keystone CHARACTER SET utf8;'
keystone-manage db_sync

#
# Initial data for Keystone using python-keystoneclient
#
# Tenant               User      Roles
# ------------------------------------------------------------------
# admin                admin     admin
# service              glance    admin
# service              nova      admin, [ResellerAdmin (swift only)]
# service              quantum   admin        # if enabled
# service              swift     admin        # if enabled
# demo                 admin     admin
# demo                 demo      Member, anotherrole

## invisible_to_admin   demo      Member
## Tempest Only:
## alt_demo             alt_demo  Member
#
# Variables set before calling this script:
# SERVICE_TOKEN - aka admin_token in keystone.conf
# SERVICE_ENDPOINT - local Keystone admin endpoint
# SERVICE_TENANT_NAME - name of tenant containing service accounts
# ENABLED_SERVICES - stack.sh's list of services to start
# DEVSTACK_DIR - Top-level DevStack directory

ADMIN_PASSWORD=admin
SERVICE_PASSWORD=${SERVICE_PASSWORD:-$ADMIN_PASSWORD}
#export SERVICE_TOKEN=$SERVICE_TOKEN
#export SERVICE_ENDPOINT=$SERVICE_ENDPOINT
export SERVICE_TOKEN=ADMIN
export SERVICE_ENDPOINT=http://192.168.0.110:35357/v2.0
SERVICE_TENANT_NAME=service
#ENABLED_SERVICES=quantum

function get_id () {
    echo `$@ | awk '/ id / { print $4 }'`
}

# keystone
keystone service-create --name=keystone --type=identity --description="Identity Service"
service_id=`keystone service-list | grep keystone | awk '{ print $2 }'`
keystone endpoint-create \
    --region RegionOne \
    --publicurl='http://192.168.0.110:$(public_port)s/v2.0' \
    --internalurl='http://192.168.0.110:$(public_port)s/v2.0' \
    --adminurl='http://192.168.0.110:$(admin_port)s/v2.0' \
    --service-id="${service_id}"

# nova
keystone service-create --name=nova --type=compute --description="Compute Service"
service_id=`keystone service-list | grep nova | awk '{ print $2 }'`
keystone endpoint-create \
    --region RegionOne \
    --publicurl='http://192.168.0.110:$(compute_port)s/v1.1/$(tenant_id)s' \
    --internalurl='http://192.168.0.110:$(compute_port)s/v1.1/$(tenant_id)s' \
    --adminurl='http://192.168.0.110:$(compute_port)s/vl.1/$(tenant_id)s' \
    --service-id="${service_id}"


# cinder 
keystone service-create --name=cinder --type=volume --description="Volume Service"
service_id=`keystone service-list | grep cinder | awk '{ print $2 }'`
keystone endpoint-create \
    --region RegionOne \
    --publicurl='http://192.168.0.110:8776/v1/$(tenant_id)s' \
    --internalurl='http://192.168.0.110:8776/v1/$(tenant_id)s' \
    --adminurl='http://192.168.0.110:8776/v1/$(tenant_id)s' \
    --service-id="${service_id}"

# glance 
keystone service-create --name=glance --type=image --description="Image Service"
service_id=`keystone service-list | grep glance | awk '{ print $2 }'`
keystone endpoint-create \
    --region RegionOne \
    --publicurl='http://192.168.0.110:9292/v1' \
    --internalurl='http://192.168.0.110:9292/v1' \
    --adminurl='http://192.168.0.110:9292/v1' \
    --service-id="${service_id}"

# ec2 
keystone service-create --name=ec2 --type=ec2 --description="EC2 Compatibility Layer"
service_id=`keystone service-list | grep ec2 | awk '{ print $2 }'`
keystone endpoint-create \
    --region RegionOne \
    --publicurl='http://192.168.0.110:8773/services/Cloud' \
    --internalurl='http://192.168.0.110:8773/services/Cloud' \
    --adminurl='http://192.168.0.110:8773/services/Admin' \
    --service-id="${service_id}"

# swift
keystone service-create --name=swift --type=object-store --description="Object Storage Service"
service_id=`keystone service-list | grep swift | awk '{ print $2 }'`
keystone endpoint-create \
    --region RegionOne \
    --publicurl 'http://192.168.0.110:8888/v1/AUTH_%(tenant_id)s' \
    --internalurl 'http://192.168.0.110:8888/v1/AUTH_%(tenant_id)s' \
    --adminurl 'http://192.168.0.110:8888/v1' \
    --service-id="${service_id}"

### Tenants
echo "keystone tenant-create --name=admin"
ADMIN_TENANT=$(get_id keystone tenant-create --name=admin)
echo "keystone tenant-create --name=$SERVICE_TENANT_NAME"
SERVICE_TENANT=$(get_id keystone tenant-create --name=$SERVICE_TENANT_NAME)
echo "keystone tenant-create --name=demo"
DEMO_TENANT=$(get_id keystone tenant-create --name=demo)


### Users

echo "keystone user-create --name=admin \\
                     --pass=admin \\
                     --email=admin@example.com"
ADMIN_USER=$(get_id keystone user-create --name=admin \
                                         --pass=admin \
                                         --email=admin@example.com)
echo "keystone user-create --name=demo --pass=demo --email=demo@example.com"
DEMO_USER=$(get_id keystone user-create --name=demo \
                                        --pass=demo \
                                        --email=demo@example.com)



### Roles
echo "keystone role-create --name=admin"
ADMIN_ROLE=$(get_id keystone role-create --name=admin)

echo "keystone role-create --name=KeystoneAdmin"
KEYSTONEADMIN_ROLE=$(get_id keystone role-create --name=KeystoneAdmin)

echo "keystone role-create --name=KeystoneServiceAdmin"
KEYSTONESERVICE_ROLE=$(get_id keystone role-create --name=KeystoneServiceAdmin)

# ANOTHER_ROLE demonstrates that an arbitrary role may be created and used
# TODO(sleepsonthefloor): show how this can be used for rbac in the future!
echo "keystone role-create --name=anotherrole"
ANOTHER_ROLE=$(get_id keystone role-create --name=anotherrole)



# Add Roles to Users in Tenants
echo "keystone user-role-add \\
        --user-id $ADMIN_USER \\
        --role-id $ADMIN_ROLE \\
        --tenant-id $ADMIN_TENANT"
keystone user-role-add --user-id $ADMIN_USER --role-id $ADMIN_ROLE --tenant-id $ADMIN_TENANT
echo "keystone user-role-add \\
        --user-id $ADMIN_USER \\
        --role-id $ADMIN_ROLE \\
        --tenant-id $DEMO_TENANT"
keystone user-role-add --user-id $ADMIN_USER --role-id $ADMIN_ROLE --tenant-id $DEMO_TENANT
echo "keystone user-role-add \\
        --user-id $DEMO_USER \\
        --role-id $ANOTHER_ROLE \\
        --tenant-id $DEMO_TENANT"
keystone user-role-add --user-id $DEMO_USER --role-id $ANOTHER_ROLE --tenant-id $DEMO_TENANT

# TODO(termie): these two might be dubious
echo "keystone user-role-add \\
        --user-id $ADMIN_USER \\
        --role-id $KEYSTONEADMIN_ROLE \\
        --tenant-id $ADMIN_TENANT"
keystone user-role-add --user-id $ADMIN_USER --role-id $KEYSTONEADMIN_ROLE --tenant-id $ADMIN_TENANT
echo "keystone user-role-add \\
        --user-id $ADMIN_USER \\
        --role-id $KEYSTONESERVICE_ROLE \\
        --tenant-id $ADMIN_TENANT"
keystone user-role-add --user-id $ADMIN_USER --role-id $KEYSTONESERVICE_ROLE --tenant-id $ADMIN_TENANT


# The Member role is used by Horizon and Swift so we need to keep it:
echo "keystone role-create --name=Member"
MEMBER_ROLE=$(get_id keystone role-create --name=Member)
echo "keystone user-role-add \\
        --user-id $DEMO_USER \\
        --role-id $MEMBER_ROLE \\
        --tenant-id $DEMO_TENANT"
keystone user-role-add --user-id $DEMO_USER --role-id $MEMBER_ROLE --tenant-id $DEMO_TENANT
#echo "keystone user-role-add --user-id $DEMO_USER --role-id $MEMBER_ROLE --tenant-id $INVIS_TENANT"
#keystone user-role-add --user-id $DEMO_USER --role-id $MEMBER_ROLE --tenant-id $INVIS_TENANT


# Configure service users/roles
### nova

echo "keystone user-create --name=nova --pass=nova --tenant-id=$SERVICE_TENANT --email=nova@example.com"
NOVA_USER=$(get_id keystone user-create --name=nova \
                                        --pass=nova \
                                        --tenant-id=$SERVICE_TENANT \
                                        --email=nova@example.com)
echo "keystone user-role-add \\
        --tenant-id $SERVICE_TENANT \\
        --user-id $NOVA_USER \\
        --role-id $ADMIN_ROLE"
keystone user-role-add --tenant-id $SERVICE_TENANT \
                       --user-id $NOVA_USER \
                       --role-id $ADMIN_ROLE
### glance
echo "keystone user-create \\
        --name=glance \\
        --pass=glance \\
        --tenant-id=$SERVICE_TENANT \\
        --email=glance@example.com"
GLANCE_USER=$(get_id keystone user-create --name=glance \
                                          --pass=glance \
                                          --tenant-id=$SERVICE_TENANT \
                                          --email=glance@example.com)
echo "keystone user-role-add \\
        --tenant-id $SERVICE_TENANT \\
        --user-id $GLANCE_USER \\
        --role-id $ADMIN_ROLE"
keystone user-role-add --tenant-id $SERVICE_TENANT \
                       --user-id $GLANCE_USER \
                       --role-id $ADMIN_ROLE


#-------------------------------------#
### swift
if [[ "$ENABLED_SERVICES" =~ "swift" ]]; then
    SWIFT_USER=$(get_id keystone user-create --name=swift \
                                             --pass="$SERVICE_PASSWORD" \
                                             --tenant-id $SERVICE_TENANT \
                                             --email=swift@example.com)
    keystone user-role-add --tenant-id $SERVICE_TENANT \
                           --user-id $SWIFT_USER \
                           --role-id $ADMIN_ROLE
    # Nova needs ResellerAdmin role to download images when accessing
    # swift through the s3 api. The admin role in swift allows a user
    # to act as an admin for their tenant, but ResellerAdmin is needed
    # for a user to act as any tenant. The name of this role is also
    # configurable in swift-proxy.conf
    RESELLER_ROLE=$(get_id keystone role-create --name=ResellerAdmin)
    keystone user-role-add --tenant-id $SERVICE_TENANT \
                           --user-id $NOVA_USER \
                           --role-id $RESELLER_ROLE
fi
### quantum
#if [[ "$ENABLED_SERVICES" =~ "quantum" ]]; then
    QUANTUM_USER=$(get_id keystone user-create --name=quantum \
                                               --pass=quantum \
                                               --tenant-id $SERVICE_TENANT \
                                               --email=quantum@example.com)
    keystone user-role-add --tenant-id $SERVICE_TENANT \
                           --user-id $QUANTUM_USER \
                           --role-id $ADMIN_ROLE
#fi

### tempest
if [[ "$ENABLED_SERVICES" =~ "tempest" ]]; then
    # Tempest has some tests that validate various authorization checks
    # between two regular users in separate tenants
    ALT_DEMO_TENANT=$(get_id keystone tenant-create --name=alt_demo)
    ALT_DEMO_USER=$(get_id keystone user-create --name=alt_demo \
                                        --pass="$ADMIN_PASSWORD" \
                                        --email=alt_demo@example.com)
    keystone user-role-add --user-id $ALT_DEMO_USER --role-id $MEMBER_ROLE --tenant-id $ALT_DEMO_TENANT
fi

動作確認
# export SERVICE_TOKEN=ADMIN
# export SERVICE_ENDPOINT=http://192.168.0.110:35357/v2.0
# keystone tenant-list
+----------------------------------+---------+---------+
|                id                |   name  | enabled |
+----------------------------------+---------+---------+
| be62de978cb1449bb7f2b07b6d843da1 |  admin  |   True  |
| fd35d9bcbfe24472b64de647c1cfa7ae |   demo  |   True  |
| 5fb7e8b70c5b4ec5a85ac6c805b372d7 | service |   True  |
+----------------------------------+---------+---------+
# keystone user-list
+----------------------------------+---------+---------+---------------------+
|                id                |   name  | enabled |        email        |
+----------------------------------+---------+---------+---------------------+
| 786eddecf5734aa599274efae47bb165 |  admin  |   True  |  admin@example.com  |
| 6aa7c5e45093470ab6b7c34b7398e6d6 |   demo  |   True  |   demo@example.com  |
| 3362dfd307c14f3d8650c8aca5799723 |  glance |   True  |  glance@example.com |
| 8ff413df4d2e4aeabc962f5fd219c28d |   nova  |   True  |   nova@example.com  |
| 24d5d26e796046a1bbefbbcdf5beb6a9 | quantum |   True  | quantum@example.com |
+----------------------------------+---------+---------+---------------------+
# keystone endpoint-list
+----------------------------------+-----------+----------------------------------------------------------+----------------------------------------------------------+----------------------------------------------------------+----------------------------------+
|                id                |   region  |                        publicurl                         |                       internalurl                        |                         adminurl                         |            service_id            |
+----------------------------------+-----------+----------------------------------------------------------+----------------------------------------------------------+----------------------------------------------------------+----------------------------------+
| 17f8987f033b4cb680fe303a5236e40b | RegionOne | http://192.168.0.110:$(compute_port)s/v1.1/$(tenant_id)s | http://192.168.0.110:$(compute_port)s/v1.1/$(tenant_id)s | http://192.168.0.110:$(compute_port)s/vl.1/$(tenant_id)s | 2e5b5b625d7a4a3f978545368549d569 |
| 2b602001fb5d4679961169e082706b2f | RegionOne |     http://192.168.0.110:8888/v1/AUTH_%(tenant_id)s      |     http://192.168.0.110:8888/v1/AUTH_%(tenant_id)s      |               http://192.168.0.110:8888/v1               | 420ef6c5bfab4ffb99b4f3c220a6614e |
| 620cf107eab243dab4e12aa31ce7e50b | RegionOne |        http://192.168.0.110:8776/v1/$(tenant_id)s        |        http://192.168.0.110:8776/v1/$(tenant_id)s        |        http://192.168.0.110:8776/v1/$(tenant_id)s        | 643347a0762a43fd8cffd86ac95d3b96 |
| 96c908693ffc4b8a917e3b3305712306 | RegionOne |               http://192.168.0.110:9292/v1               |               http://192.168.0.110:9292/v1               |               http://192.168.0.110:9292/v1               | a3765d34ffec436ab66a25d2b68889eb |
| ae31ab318bbc458bb8da9efd58b2fe19 | RegionOne |        http://192.168.0.110:$(public_port)s/v2.0         |        http://192.168.0.110:$(public_port)s/v2.0         |         http://192.168.0.110:$(admin_port)s/v2.0         | e54114caf2b1404e965884ae6058ec3a |
| e8ad726861f74259815fcea16408dcf4 | RegionOne |         http://192.168.0.110:8773/services/Cloud         |         http://192.168.0.110:8773/services/Cloud         |         http://192.168.0.110:8773/services/Admin         | 766cc898f98d456dbb00793ca3dd211d |
+----------------------------------+-----------+----------------------------------------------------------+----------------------------------------------------------+----------------------------------------------------------+----------------------------------+
#

次は、glanceです。そのうち投稿。