OpenStackで使用されているプラグイン機構Stevedoreの使い方
概要
OpenStackでは、プラグイン機構を採用しており、バックエンドの実装にさまざまなものを選択できるようにしている
たとえば、NeutronではCore pluginに「ml2, openvswitch, nsx」などなど、さまざまなpluginが設定ファイルで設定できる。それをstevedoreというライブラリを用いて実現可能にしている。
今回はそれの使い方について、keystoneclientのauth_plugin
の読み込み部分を見ながら使い方を見ていく
※注意:イマイチ良く分かっていないところがあるので、間違いや詳細が分かる方はコメントください
keystoneclientにauth_pluginについて(stevedoreの使用例)
keystoneclientでは、認証の方法をplugin形式で実装している(Token,Password等)ので、さまざまな認証方法を選択することができる。
実際に、keystoneclientを利用しているkeystonemiddlewareのauth_token( WSGIアプリケーションのFilterでは、設定ファイルで、使用するkeystonclientで読み込むauth_pluginを設定ファイルで下記のように、指定している。
devstackによって生成される、nova.conf
52 53 [keystone_authtoken] 54 signing_dir = /var/cache/nova 55 cafile = /opt/stack/data/ca-bundle.pem 56 auth_uri = http://157.7.84.233:5000 57 project_domain_id = default 58 project_name = service 59 user_domain_id = default 60 password = password 61 username = nova 62 auth_url = http://157.7.84.233:35357 63 auth_plugin = password 64
この設定だとkeystonemiddlewareのauth_tokenでkeystoneclientを作成するときにPassword認証用のプラグインで作成するようになります
/usr/local/lib/python2.7/dist-packages/keystonemiddleware/auth_token.py
176 import logging 177 import os 178 import stat 179 import tempfile 180 181 from keystoneclient import access 182 from keystoneclient import adapter 183 from keystoneclient import auth 184 from keystoneclient.auth.identity import base as base_identity 185 from keystoneclient.auth.identity import v2 186 from keystoneclient.auth import token_endpoint ~~~~~~~~~~~~ ~~~~~~~~~~~~ 825 826 class AuthProtocol(object): ~~~~~~~~~~~~ ~~~~~~~~~~~~ 1494 def _create_identity_server(self): 1495 # NOTE(jamielennox): Loading Session here should be exactly the 1496 # same as calling Session.load_from_conf_options(CONF, GROUP) 1497 # however we can't do that because we have to use _conf_get to 1498 # support the paste.ini options. 1499 sess = session.Session.construct(dict( 1500 cert=self._conf_get('certfile'), 1501 key=self._conf_get('keyfile'), 1502 cacert=self._conf_get('cafile'), 1503 insecure=self._conf_get('insecure'), 1504 timeout=self._conf_get('http_connect_timeout') 1505 )) 1506 1507 # NOTE(jamielennox): The original auth mechanism allowed deployers 1508 # to configure authentication information via paste file. These 1509 # are accessible via _conf_get, however this doesn't work with the 1510 # plugin loading mechanisms. For using auth plugins we only support 1511 # configuring via the CONF file. 1512 auth_plugin = auth.load_from_conf_options(CONF, _AUTHTOKEN_GROUP) 1513 ~~~~~~~~~~~~ ~~~~~~~~~~~~
このAuthProtocolクラスというのが、tokenチェックをするためのWsgiアプリケーションのfilterに当たるのですが、そのなかで_create_identity_server関数定義(keystoneclientを作るような処理をする)のなかでauth_pluginのpluginを読み込んでいます(1512行目)「auth.load_from_conf_options」
の関数の中身を見ていきます
/usr/local/lib/python2.7/dist-packages/keystoneclient/auth/conf.py
79 80 def load_from_conf_options(conf, group, **kwargs): 81 """Load a plugin from an oslo.config CONF object. ~~~~~~ commentのため、割愛 ~~~~~~ 98 """ 99 # NOTE(jamielennox): plugins are allowed to specify a 'section' which is 100 # the group that auth options should be taken from. If not present they 101 # come from the same as the base options were registered in. 102 if conf[group].auth_section: 103 group = conf[group].auth_section 104 105 name = conf[group].auth_plugin 106 if not name: 107 return None 108 109 plugin_class = base.get_plugin_class(name) 110 plugin_class.register_conf_options(conf, group) 111 return plugin_class.load_from_conf_options(conf, group, **kwargs) ~~~~~~ ~~~~~~
ここでは、pluginクラスを生成して、生成したpluginクラスに設定をつっこんでます。実際に、stevedoreを使ってpluginを生成しているのbase.get_plugin_classのところ(109行目)、これも関数の中身を見て行きます
/usr/local/lib/python2.7/dist-packages/keystoneclient/auth/base.py
15 import six 16 import stevedore ~~~~~ ~~~~~ 26 PLUGIN_NAMESPACE = 'keystoneclient.auth.plugin' 27 IDENTITY_AUTH_HEADER_NAME = 'X-Auth-Token' 28 29 30 def get_plugin_class(name): 31 """Retrieve a plugin class by its entrypoint name. 32 33 :param str name: The name of the object to get. 34 35 :returns: An auth plugin class. 36 :rtype: :py:class:`keystoneclient.auth.BaseAuthPlugin` 37 38 :raises keystoneclient.exceptions.NoMatchingPlugin: if a plugin cannot be 39 created. 40 """ 41 try: 42 mgr = stevedore.DriverManager(namespace=PLUGIN_NAMESPACE, 43 name=name, 44 invoke_on_load=False) 45 except RuntimeError: 46 raise exceptions.NoMatchingPlugin(name) 47 48 return mgr.driver ~~~~~~~ ~~~~~~~
やっとここで、stevedoreの登場です(42行目)。 stevedore.DriverManagerが与えられたname(このときはpassword)に対応するクラスを探して、読み込みます。
stevedoreについて
先ほどまで、keytonemiddlewareとkeystoneclientを見て実際にプラグインが読み込まれる過程を見ました。 ここから、stevedoreの使い方を見ていきます。
上記の例を見ても分かるように、stevedoreではpluginクラスをフルクラスネームで書かなくても、読み込まれます(例: password → keystoneclient.auth.identity.generic:Password )
なぜそんなことができるかというと、インストール時にsetup.cfgでそのマッピングについて定義するからです。 その定義がこちら
keystoneclientのsetup.cfg
[entry_points] `console_scripts = keystone = keystoneclient.shell:main keystoneclient.auth.plugin = password = keystoneclient.auth.identity.generic:Password token = keystoneclient.auth.identity.generic:Token v2password = keystoneclient.auth.identity.v2:Password v2token = keystoneclient.auth.identity.v2:Token v3password = keystoneclient.auth.identity.v3:Password v3token = keystoneclient.auth.identity.v3:Token v3unscopedsaml = keystoneclient.contrib.auth.v3.saml2:Saml2UnscopedToken v3scopedsaml = keystoneclient.contrib.auth.v3.saml2:Saml2ScopedToken v3unscopedadfs = keystoneclient.contrib.auth.v3.saml2:ADFSUnscopedToken
ここでは、console_scripts
とkeystoneclient.auth.plugin
はnamespaceといい、インデントが違うpassword
やtoken
がnameといいます。ここまでくれば分かるかと思いますが。
namespaceとnameの組み合わせで、対応クラスがマッピングされます。
例えば、namespace = keystoneclient.auth.plugin , name = passwordとすれば、読み込まれるクラスは、keystoneclient.auth.identity.generic:Passwordになります。
また、rpmやdebパッケージからインストールするとsetup.cfgが見当たらないかと思いますが、その場合は
/usr/local/lib/python2.7/dist-packages/XXXXX.dist-info
の中のentry_points.txt
に同じような定義があります。
例として、keystoneclientのentry_points.txtを下記に記します。
/usr/local/lib/python2.7/dist-packages/python_keystoneclient-1.1.0.dist-info/entry_points.txt
1 [console_scripts] 2 keystone = keystoneclient.shell:main 3 4 [keystoneclient.auth.plugin] 5 password = keystoneclient.auth.identity.generic:Password 6 token = keystoneclient.auth.identity.generic:Token 7 v2password = keystoneclient.auth.identity.v2:Password 8 v2token = keystoneclient.auth.identity.v2:Token 9 v3password = keystoneclient.auth.identity.v3:Password 10 v3scopedsaml = keystoneclient.contrib.auth.v3.saml2:Saml2ScopedToken 11 v3token = keystoneclient.auth.identity.v3:Token 12 v3unscopedadfs = keystoneclient.contrib.auth.v3.saml2:ADFSUnscopedToken 13 v3unscopedsaml = keystoneclient.contrib.auth.v3.saml2:Saml2UnscopedToken
表記は、違いますが雰囲気で分かると思います。 で囲まれている部分がnamespaceに対応し、の下に書かれている部分がnameに相当します
neutronのpluginの読まれ方
ここで疑問に、思う方がいるかもしれませんが(僕は思いました)。password,tokenなどnameを使用して、entry_pointsでそのマッピング先を探すのに、設定ファイルでクラスパスを直接書いている部分があるのはなぜだろう。stevedoreは、nameにクラスパスが指定されていたらそのクラスパスのクラスを読み込むのか?
例えばneutronでは、service_pluginsの指定に、フルクラスネームで書くこともnameで書くこともできます。
neutron.conf
[DEFAULT] service_plugins = router
neutron.conf
[DEFAULT] service_plugins = neutron.services.l3_router.l3_router_plugin.L3RouterPlugin
neutronのpluginの読み込み方を調べてみたところ、こんな風になっていました。
/opt/stack/neutron/neutron/manager.py
130 def _get_plugin_instance(self, namespace, plugin_provider): 131 try: 132 # Try to resolve plugin by name 133 mgr = driver.DriverManager(namespace, plugin_provider) 134 plugin_class = mgr.driver 135 except RuntimeError as e1: 136 # fallback to class name 137 try: 138 plugin_class = importutils.import_class(plugin_provider) 139 except ImportError as e2: 140 LOG.exception(_LE("Error loading plugin by name, %s"), e1) 141 LOG.exception(_LE("Error loading plugin by class, %s"), e2) 142 raise ImportError(_("Plugin not found.")) 143 return plugin_class()
stevedoreは、nameにマッチするentry_pointが見つからない場合は、例外を吐くのでその例外をキャッチし、クラスパスが指定されていることを仮定し、importutilsでimportを試みてるんですね。
なので、設定ファイルのpluginに指定する値は、entry_pointのnameでも、クラスパスでもうまくいくんですね。面白い
pythonパッケージからdebファイルを作成する
諸事情により、Pythonパッケージからdebファイルを作成する必要があったのでその手順をメモ
pythonパッケージからdebファイルを作成するツールをインストール
#apt-get install python-stdeb
debファイル化したい、pythonパッケージのDL
今回は、oslo.db-1.0.2というOpenStackのDB周りの共通コンポーネントをdeb化する
$wget https://pypi.python.org/packages/source/o/oslo.db/oslo.db-1.0.2.tar.gz
py2dscの実行
DLしたファイルを引数に py2dsc を実行
$py2dsc oslo.db-1.0.2.tar.gz
deb_destというフォルダが作成されます
$ls deb_dist oslo.db-1.0.2.tar.gz
deb_dest/oslo.db-1.0.2の下で dpkg-buildpackage を実行
$cd deb_dist/oslo-db-1.0.2 $dpkg-buildpackage -rfakeroot -uc -us $cd .. $ls oslo-db-1.0.2 oslo-db_1.0.2-1_amd64.changes oslo-db_1.0.2-1.debian.tar.gz oslo-db_1.0.2-1.dsc oslo-db-1.0.2.orig oslo-db_1.0.2.orig.tar.gz python-oslo.db_1.0.2-1_all.deb
するとdebファイルが追加されています。
あとは dpkg -i
でインストールしたりいろいろとご自由に
IronicをDevstackでサク?っと試してみた
日本OpenStackユーザ会勉強会で、Ironicのハッカソン日本OpenStackユーザ会 第21回勉強会があるということで、参加しようとIronic環境をDevstackで構築しようとしたが、詰まりどころが満載だったのででデバッグの記録をメモ
とりあえず、Document通りに。。。
git clone https://github.com/openstack-dev/devstack.git devstack
local.conf作成
cat <<END >local.conf [[local|localrc]] # Credentials ADMIN_PASSWORD=password DATABASE_PASSWORD=password RABBIT_PASSWORD=password SERVICE_PASSWORD=password SERVICE_TOKEN=password # Enable Ironic API and Ironic Conductor enable_service ironic enable_service ir-api enable_service ir-cond # Enable Neutron which is required by Ironic and disable nova-network. disable_service n-net enable_service q-svc enable_service q-agt enable_service q-dhcp enable_service q-l3 enable_service q-meta enable_service neutron # Create 3 virtual machines to pose as Ironic's baremetal nodes. IRONIC_VM_COUNT=3 IRONIC_VM_SSH_PORT=22 IRONIC_BAREMETAL_BASIC_OPS=True # The parameters below represent the minimum possible values to create # functional nodes. IRONIC_VM_SPECS_RAM=1024 IRONIC_VM_SPECS_DISK=10 # Size of the ephemeral partition in GB. Use 0 for no ephemeral partition. IRONIC_VM_EPHEMERAL_DISK=0 VIRT_DRIVER=ironic # By default, DevStack creates a 10.0.0.0/24 network for instances. # If this overlaps with the hosts network, you may adjust with the # following. NETWORK_GATEWAY=10.1.0.1 FIXED_RANGE=10.1.0.0/24 FIXED_NETWORK_SIZE=256 # Log all output to files LOGFILE=$HOME/devstack.log SCREEN_LOGDIR=$HOME/logs IRONIC_VM_LOG_DIR=$HOME/ironic-bm-logs END
stack.shで構築
$ ./stack.sh
インストールは、うまく行った、Horizonの画面も確認できた。
さっそく、Ironicノードをプロビジョニングを実行
$nova boot --flavor baremetal --image cirros-0.3.3-uec
$nova list +--------------------------------------+---------+--------+------------+-------------+------------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+---------+--------+------------+-------------+------------------+ | a2c7f812-e386-4a22-b393-fe1802abd56e | testing | ERROR | - | ERROR | private=10.1.0.4 | +--------------------------------------+---------+--------+------------+-------------+------------------+
うまく行き過ぎだとは思ってた、エラーですね。
ログを見てみると、「No valid host was found. There are not enough hosts available」というエラーが。。
早速デバッグ
nova-scheduleのlogより、下記のことが分かった
- nova-schedulerは、フィルタしてホストの選定はすんでいる
- ホストの選定の結果プロビジョニングに失敗するので、またフィルタする
- その結果のホストのぷろびじょにングも失敗するので、retry回数のフィルタにひっかかり
- No valid host was found エラーになっている
プロビジョンでコケているので、
nova-conductorのログを見てみる
- エラーメッセージ「"Failed to add deploy parameters on node"」を確認
- novaのソースをgrep
ironic-apiのログを見てみる
エラーメッセージ「"No conductor service registered which supports driver"」を確認
- なぜか、ironic-conductorが動いていない模様
- ironic-conductorを再起動
- まだ、「No valid host was found」のまま
エラーメッセージ「"Cannot validate PXE bootloader"」を確認
ironic-conductorのログを見てみる
- エラーメッセージ「" Can not validate PXE bootloader. The following paramenters were not passed to ironic:['deploy_kernel', 'deploy_ramdisk']"」
$ironic node-update <node-id> add driver_info/pxe_deploy_kernel=<deploy_kernel> $ironic node-update <node-id> add driver_info/pxe_deploy_ramdisk=<deploy_ramdisk>
まだ、「No valid host was found」のまま
エラーメッセージ「"Cannot execute SSH cmd"」
エラーメッセージ「"connecting to monitor: Cannot set up guest memory"」
- SSHPowerDriverが実行するvirshを実行した時のエラーのようだ。
- エラー内容的には、メモリーが足りないと言われているので、swap領域を作成
- まだ、「No valid host was found」のまま
目立ったエラーメッセージが出なくなったが、プロビジョニングが終わらない現象に遭遇
- よく調べると、ironicのノードstatusが「wait callback」のまま固まっている模様
- Driverからの応答待ちというstatusなので、PXE関連で不具合が起きてる模様
- neutronのdnsmasq(dhcp-agent)がPXEブートのDHCPを担当しているのだが、そもそも疎通が取れていない
Devstackでironicをインストールすると、brbmというベアメタル用のbridgeを作ってくれて、そこにnodeがぶら下がっているのだが、
brbmブリッジとneutronのl2スイッチをつなげる必要がある
(方法はいろいろある、br-tun経由、br-intに直接指す等)とりあえずは、br-intブリッジとbrbmブリッジを接続
それでも、ノードstatusが「wait callback」のまま固まっている・・・・
- tftpサーバのアドレスが、ironic-conductorが動いているホストのIPであることに気づく、ironicノードがironic-conductorが動いているホストと通信できないといけないことに気づく。下記手順で通信可能にする
- (1) 仮想L2NWをテナントの仮想ルータに接続
- (2) ホスト側のルーティングテーブルに、仮想L2NWの経路を、仮想ルータの外部アドレスIF経由で追加
ここまできて、やっと動きました。 そもそも、なぜこんなにデバッグに時間がかかったかというと、ironicのプロビジョニングプロセスをまったく調べずに実行したことが原因ですね。
ただ、今回調べたところ、いろいろと制約があるなと感じました。
nodeからtftpサーバにアクセスできる必要がある。
nodeからIronic APIを叩ける必要がある
Ironic conductorからnodeにアクセスできる必要がある
- tftpと同様で、ironic conductorから見て、nodeが所属するサブネットが被ってはいけない(routingできないから)
ネットワーク周りが、結構難しいなぁという印象。
Publicクラウドとして、仮想ネットワーク作り放題で、vmとベアを意識せずにポコポコプロビジョニングというのは、まだ難しいのかぁ。
Ironicは少し面白そうなので、もう少し追いかけてみる。
Rack、WSGIサーバのThread処理の実装について(1)
はじめに
本記事では、あえてRack,WSGIサーバと言っているが、いわゆるWEBアプリケーションサーバ以外のサーバソフトウェアの実装でも共通の話題である「クライアントからの接続ー通信処理」の実装方式として、NativeThreadのパターンとGreenThreadのパターンの2つの違いを自分用に2回にわたってメモ
事前知識
ソケットプログラミング等で、チャットプログラム等を作ったりしたことがある人は、ご存知かもしれないが。サーバの通信処理がどのようなフローで行われるかを少しここでおさらいする。
- サーバソケット(通信要求を受け付けるためのソケット)を作成する
- サーバソケットを指定のIP(通常、0.0.0.0でどのIFのIPでも受けれるようにする)、指定のportで通信要求を待つ
- クライアントからの通信要求をacceptする
- クライアントと通信路が確立される
見て分かると思うが、1プロセス1スレッドでサーバを実装してしまうと、同時に1つのクライアントしかさばけないため、3と4の間で各クライアントごとにスレッド、プロセスを生成して4以降のクライアントごとの処理はスレッドやプロセスに任せるのが一般的である。
NativeThreadで実装されている例(WEBrick)
どんなNativeThreadがいるのか
ここでは、WEBrick(Rackサーバ)を題材にする
下記のような、テスト用のRackアプリケーションを用意する
#!/usr/bin/env ruby require 'rubygems' require 'rack' include Rack class TestApp def call(env) sleep(1000) [200, {"Content-Type" => "text/plain"}, ["test"]] end end Handler::WEBrick.run TestApp.new, :Port => 3000
上記を実行し、psでスレッドの数を見る(当方Macなので、-Mオプションを使用しています)
$ruby test.rb [2015-01-03 14:46:16] INFO WEBrick 1.3.1 [2015-01-03 14:46:16] INFO ruby 1.9.3 (2013-02-22) [x86_64-darwin10.8.0] [2015-01-03 14:46:16] INFO WEBrick::HTTPServer#start: pid=76852 port=3000 $ps -M ukinau 76852 s002 0.0 S 31T 0:00.04 0:00.16 ruby test.rb 76852 0.0 S 31T 0:00.00 0:00.00
なんで最初から、ネイティブスレッドが1つ作られているんだ?と思ったけど、後述するnetstatの結果より、ipv4,v6で1つずつ接続待ちのスレッドを作っていると思われる
curlでwebappにアクセスしてみる。
$curl http://localhost:3000
test.rbの中でsleepして、コネクション確立状態をキープしているのでその間にいろいろ確認
$netstat -an | grep 3000 tcp4 0 0 127.0.0.1.3000 127.0.0.1.52542 ESTABLISHED tcp4 0 0 127.0.0.1.52542 127.0.0.1.3000 ESTABLISHED tcp46 0 0 *.3000 *.* LISTEN tcp4 0 0 *.3000 *.* LISTEN $ps -M ukinau 76852 s002 0.0 S 31T 0:00.05 0:00.18 ruby test.rb 76852 0.0 S 31T 0:00.00 0:00.00 76852 0.0 S 31T 0:00.00 0:00.00 76852 0.0 S 31T 0:00.02 0:00.03
Threadが2個増えた!1つが先ほどのcurlからのリクエストを担当し、もう1つは次のクライアントのためにあらかじめスレッドを作成しているものだと思われる。
curlのリクエストが終了したら、1つ減った。
$ps -M ukinau 76852 s002 0.0 S 31T 0:00.07 0:00.20 ruby test.rb 76852 0.0 S 31T 0:00.00 0:00.00 76852 0.0 S 31T 0:00.07 0:00.11
もう一度、curlを送ると
$ps -M ukinau 76852 s002 0.0 S 31T 0:00.08 0:00.21 ruby test.rb 76852 0.0 S 31T 0:00.00 0:00.00 76852 0.0 S 31T 0:00.08 0:00.13 76852 0.0 S 31T 0:00.00 0:00.00
スレッドが一つ増えた! う〜ん、もしかしたら、1つ多いスレッドは次のクライアントのためのものではないかもしれない。。。CPU使用時間が増えるのが上から3番目のスレッドだけなので、なんかユーティリティ用のスレッドなのかもしれない・・・・
現状分かる範囲でまとめると、
- ipv6listen用スレッド = 1
- ipv4listen用スレッド = 1
- クライアント処理用スレッド × クライアント数
- 謎のスレッド = 1
の4種類のネイティブスレッドでWEBrickは実現しているようです。
クライアントの処理がNativeThreadだと何がいいのか
NativeThreadのスケジューリングは、OSのプロセススケージューラによってスケジューリングされるため各スレッドは、コアの分だけ同時に動くことができる。もう少し端的に言うと各ThreadがOSに認識される。そのため、先ほどのsampleプログラムであるTestAppのcallメソッドの中に、sleep(1000)などのブロック関数があっても別のクライアントに影響を与えないのだ。
題材である、WEBアプリだとあまりないシチュエーションかもしれないが、各スレッドが独立して動くのでスレッド同士影響を与えないよう、スレッドセーフであることをきちんと確認する必要がある。
Backlogってなんぞや
はじめに
サーバソフトウェアの設定ファイル等でよく見かける項目であるBacklogってどういう意味なんだろうと、少し調べたのでメモを残します。
Backlog
apacheやnginx、memchachedなどのサーバ系ソフトウェアの設定ファイルの中で設定することが多い、このBacklogとは何なのかをここでは言及する。
サーバアプリケーションがlistenしているソケットがacceptしていない、確立済TCPセッションを何個までOS側で保持するかを定義したもの。
例えば、下記のようなサーバーアプリケーションがあるとする。
server.py
import evenlet server_sock = eventlet.listen(('0.0.0.0', 6001),backlog = 1) new_sock, address = server_sock.accept() new_sock1, address = server_sock.accept() while True: a = 1 print("ここは到達しないコード")
上記のサーバアプリケーションに、5個の接続要求(telnetとかを使って)を出すと。3個目までTCPコネクションが確立され、4,5個目の接続要求は無視される。
netstatで確認してみると、下記のようになる。
$netstat -an | grep 6001 tcp4 0 0 127.0.0.1.52608 127.0.0.1.6001 SYN_SENT tcp4 0 0 127.0.0.1.52607 127.0.0.1.6001 SYN_SENT tcp4 0 0 127.0.0.1.6001 127.0.0.1.52601 ESTABLISHED tcp4 0 0 127.0.0.1.52601 127.0.0.1.6001 ESTABLISHED tcp4 0 0 127.0.0.1.6001 127.0.0.1.52600 ESTABLISHED tcp4 0 0 127.0.0.1.52600 127.0.0.1.6001 ESTABLISHED tcp4 0 0 127.0.0.1.6001 127.0.0.1.52599 ESTABLISHED tcp4 0 0 127.0.0.1.52599 127.0.0.1.6001 ESTABLISHED tcp4 0 0 *.6001 *.* LISTEN
コードを見てもらうと分かる通り、サーバ(server.py)では2回しかacceptされていないが、netstatでは下記の3つセッションが確立できていることが分かる(ESTABLISHED)
これは、server.pyからは2つのコネクションしか見えていないが、残りの1つのセッションはOS側で保持してくれていることが分かる、この何個のセッションをOS側で面倒見るかを定義したものがbacklogである。
今回は、backlog=1でサーバソケットをlistenしているため3個目のリクエストはセッションが確立されたが4、5個目のリクエストはクライアントからSYNパケットを送っているが、サーバに無視されている。
これらの挙動を図にまとめるとこんな感じになる。注目していただきたいのは下記の点
- ソケットキューの大きさがbacklog数
- ソケットキューは、サーバソケットごと(=port)ごとに作成される
- accept()システムコールが呼ばれると、確立済のTCPセッションはソケットキューから削除され、ファイルディスクリタに登録される(関連づけられる)
maxconn
ソケットキューの長さの最大値を定義するカーネルパラメーター、128がデフォルトで定義されている。backlogでmaxconnより大きな数字を定義しても、maxconnの値が優先されます。
まとめ
(付録)Devstackはどんなことをしているのか
この記事は、Devstackはどんなことをしているのかの付録記事になっており、下記の2部構成になっております。
- devstackのソースを読むときに非常にお世話になったコマンド
- devstackを読みながら、インストールしたときの手順書
付録1.devstackのソースを読むときに非常にお世話になったコマンド
devstackは、シェルスクリプトであり。他のファイルで定義されている関数をsourceコマンドで動的に読み込みます。そのため、簡単に関数の定義や変数の定義がある場所を調べることができないのですが、そのような場合はgrepコマンドを下記のように使うと便利です。
$grep -n "" * */* */*/* | grep <検索したい文字列>
使用例(AGENT_BINARYという変数がどこで使われているか調べたいとき)
$grep -n "" * */* */*/* | grep AGENT_BINARY lib/neutron:489: run_process q-agt "python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE" lib/neutron:507: run_process q-domua "python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE.domU" lib/neutron_plugins/bigswitch_floodlight:44: AGENT_BINARY="$NEUTRON_DIR/neutron/plugins/bigswitch/agent/restproxy_agent.py" lib/neutron_plugins/brocade:41: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-linuxbridge-agent" lib/neutron_plugins/ibm:102: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-ibm-agent" lib/neutron_plugins/linuxbridge_agent:49: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-linuxbridge-agent" lib/neutron_plugins/nec:78: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-nec-agent" lib/neutron_plugins/ofagent_agent:72: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-ofagent-agent" lib/neutron_plugins/oneconvergence:63: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-nvsd-agent" lib/neutron_plugins/openvswitch_agent:66: AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-openvswitch-agent" lib/neutron_plugins/ryu:53: AGENT_BINARY="$NEUTRON_DIR/neutron/plugins/ryu/agent/ryu_neutron_agent.py"
付録2.ソースからインストールする際の、手順のメモ(殴り書きなので、適宜微修正をしないといけないかもしれません)
注意していただきたいこと
<****>は適宜自分の環境に置き換えて入力してください。
構築した環境について
- Openstackバージョン:stable/junoを想定
- 環境:ubuntu14.04
- 構成:ALL in One
- インストールコンポーネント:keystone,nova,cinder,glance,neutron
- 設定:基本的に、標準の設定を想定
- Novaのハイパーバイザー: kvm + qemu
- Neutron:ml2プラグイン + ovsエージェント
(1)$ mkdir /opt/stack #インストール先のディレクトリを作成
(2)rabbitmqで名前解決が必要になるため、hostnameファイルに下記を追加
127.0.0.1 localhost
(3)依存パッケージのインストール(適宜Devstackの files/<component-name> を確認する方が確実)
dist指定があるものは、ディストリビューションのバージョンがdistに指定されているバージョンの場合だけインストール。NOPRIMEはインストールしない
general
* bridge-utils * pylint * python-setuptools * screen * unzip * wget * psmisc * git * lsof # useful when debugging * openssh-server * openssl * python-virtualenv * python-unittest2 * iputils-ping * wget * curl * tcpdump * euca2ools # only for testing client * tar * python-cmd2 # dist:precise * python-dev * python2.7 * bc
keystone
* python-lxml * python-pastescript * python-pastedeploy * python-paste * sqlite3 * python-pysqlite2 * python-sqlalchemy * python-mysqldb * python-webob * python-greenlet * python-routes * libldap2-dev * libsasl2-dev
nova
* bridge-utils * pylint * python-setuptools * screen * unzip * wget * psmisc * git * lsof # useful when debugging * openssh-server * openssl * python-virtualenv * python-unittest2 * iputils-ping * wget * curl * tcpdump * euca2ools # only for testing client * tar * python-cmd2 # dist:precise(12.04LTS) * python-dev * python2.7 * bc
n-cpu
* lvm2 * open-iscsi * open-iscsi-utils # Deprecated since quantal dist:precise * genisoimage * sysfsutils * sg3-utils * python-guestfs # NOPRIME
n-api
* python-dateutil * msgpack-python * fping
n-novnc
* python-numpy
glance
* gcc * libffi-dev * libmysqlclient-dev # testonly * libpq-dev # testonly * libssl-dev # testonly * libxml2-dev * libxslt1-dev # testonly * python-eventlet * python-routes * python-greenlet * python-sqlalchemy * python-wsgiref * python-pastedeploy * python-xattr * python-iso8601 * zlib1g-dev # testonly
cinder
* tgt * lvm2 * qemu-utils * libpq-dev * open-iscsi * open-iscsi-utils # Deprecated since quantal dist:precise
neutron
* ebtables * iptables * iputils-ping * iputils-arping * mysql-server #NOPRIME * sudo * python-boto * python-iso8601 * python-paste * python-routes * python-suds * python-pastedeploy * python-greenlet * python-kombu * python-eventlet * python-sqlalchemy * python-mysqldb * python-pyudev * python-qpid # dist:precise * dnsmasq-base * dnsmasq-utils # for dhcp_release only available in dist:precise * rabbitmq-server # NOPRIME * qpidd # NOPRIME * sqlite3 * vlan
(4)pipのインストール
(4−1)https://bootstrap.pypa.io/get-pip.pyをダウンロード
$curl -o get-pip.py https://bootstrap.pypa.io/get-pip.py
$sudo -E python <get-pip.py>
(5)特定のライブラリだけバージョンを指定して、あらかじめインストールし、アップデートされないようにReadOnlyにする
Openstackを使うにあたって、下記のバージョン依存がある
(5−1)sudo pip install "prettytable=0.7.2"
$sudo pip install "prettytable=0.7.2"
(5−2)sudo pip install "httplib2=0.8"
$sudo pip install "httplib2=0.8"
(5−3)アップデートされないように、644のパーミッションを設定する
$sudo chmod 644 /usr/lib/python2.7/dist-package/prettytable-0.7.2* $sudo chmod 644 /usr/lib/python2.7/dist-package/httplib2*
→Devstackだと上記コマンドだけど、sudo chmod 555のじゃないと意味ないんじゃないか?
(6)RPCバックエンド(amqpサーバ) のインストール
$ sudo apt-get install rabbitmq-server
(7)DBサーバのインストール、簡単な初期設定
(7−1)$ sudo apt-get install mysql-server #インストール
$sudo apt-get install mysql-server
(7−2)~/.my.cnf の作成(mysqlコマンドを引数無しで実行すると、これの値が参照される)
~/.my.cnf
[client] user=<user名> password=<password> host=<host名>
(8)neutronのエージェントが依存するパッケージ(agentが操作する対象の仮想スイッチ等)をインストール(ml2_plugin/openvswitchの場合)
(8−1)カーネルが3.13よりバージョンが低ければ、「openvswitch-datapath-dkms」もaptでインストール
$sudo apt-get install openvswitch-datapath-dkms
(8−2)openvswitchとかインストール
$sudo apt-get install make fakeroot dkms openvswitch-switch linux-headers-<kernel_version>
→kernel_versionは:「cat /proc/version | cut -d " " -f3」で取得できる
Openstackコンポーネントのインストール
(9)openstack/requirementsコンポーネント
→ 各コンポーネントの依存関係が定義されるファイル(requirements.txt,test-requirements.txt)のバージョンをOpenstack内で統一してくれる、requirementsファイルに定義されていないライブラリは使用されないことを約束する
→使い方は、$python update.py <コンポーネントのソースディレクトリのパス>
→2つのコンポーネントがtestというライブラリを使用するとするときに、1つ目のコンポーネントがバージョン0.8を使っていて、もう片方がバージョン1.2を使っている場合。1つ目のコンポーネントが最初にインストールされると、2つ目のコンポーネントでバージョン0.8のライブラリを使うことになるのでエラーが起きることがある。その解決策として作られた。
(9−1)cd /opt/stack
$cd /opt/stack
(9−2)git clone git://git.openstack.org/openstack/requirements.git stable/juno
$git clone git://git.openstack.org/openstack/requirements.git stable/juno
(10)openstack-dev/pbrコンポーネント
→インストールオプションをsetup.cfgに書いて、setuptoolsでインストールするときにsetupメソッドをフックしてその、オプションを適用してくれるらしい。
(10−1)cd /opt/stack
$cd /opt/stack
(10−2)git clone git://git.openstack.org/openstack-dev/pbr.git
$git clone git://git.openstack.org/openstack-dev/pbr.git
(10−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(10−4)./update.py /opt/stack/pbr
$./update.py /opt/stack/pbr
→pbrのrequirements.txt,test-requirements.txtで定義されているライブラリがglobal-requirementsに定義されているか、バージョンは古くないかを検査してくれる
(10−5)sudo pip install /opt/stack/pbr
$sudo pip install /opt/stack/pbr
(11)openstack/cliffコンポーネント
→CLIフレームワーク、各コンポーネントのCLIソフトウェアを作成するときに使われている模様
(11−1)cd /opt/stack
$cd /opt/stack
(11−2)git clone git://git.openstack.org/openstack/cliff.git
$git clone git://git.openstack.org/openstack/cliff.git
(11−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(11−4)./update.py /opt/stack/cliff
$./update.py /opt/stack/cliff
(11−5)sudo pip install /opt/stack/cliff
$sudo pip install /opt/stack/cliff
(12)openstack/oslo.configコンポーネント
→Openstack共通のコンフィグとかが入っている
(12−1)cd /opt/stack
$cd /opt/stack
(12−2)git clone git://git.openstack.org/openstack/oslo.config.git
$git clone git://git.openstack.org/openstack/oslo.config.git
(12−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(12−4)./update.py /opt/stack/oslo.config
$./update.py /opt/stack/oslo.config
(12−5)sudo pip install /opt/stack/oslo.config
$sudo pip install /opt/stack/oslo.config
(13)openstack/oslo.messagingコンポーネント
→コンポーネント間の通信処理(amqp)を行うライブラリ
(13−1)cd /opt/stack
$cd /opt/stack
(13−2)git clone git://git.openstack.org/openstack/oslo.messaging.git
$git clone git://git.openstack.org/openstack/oslo.messaging.git
(13−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(13−4)./update.py /opt/stack/oslo.messaging
$./update.py /opt/stack/oslo.messaging
(13−5)sudo pip install /opt/stack/oslo.messaging
$sudo pip install /opt/stack/oslo.messaging
(14)openstack/oslo.rootwrapコンポーネント
→各コンポーネントは、SU権限が必要な処理をすることがある、Cinderだったらmountとかneutronだったらrouteの追加とか
(14−1)cd /opt/stack
$cd /opt/stack
(14−2)git clone git://git.openstack.org/openstack/oslo.rootwrap.git
$git clone git://git.openstack.org/openstack/oslo.rootwrap.git
(14−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(14−4)./update.py /opt/stack/oslo.rootwrap
$./update.py /opt/stack/oslo.rootwrap
(14−5)sudo pip install /opt/stack/oslo.rootwrap
$sudo pip install /opt/stack/oslo.rootwrap
(15)openstack/pycadfコンポーネント
→よくわからないhttp://docs.openstack.org/developer/pycadf/
(15−1)cd /opt/stack
$cd /opt/stack
(15−2)git clone git://git.openstack.org/openstack/pycadf.git
$git clone git://git.openstack.org/openstack/pycadf.git
(15−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(15−4)./update.py /opt/stack/pycadf
$./update.py /opt/stack/pycadf
(15−5)sudo pip install /opt/stack/pycadf
$sudo pip install /opt/stack/pycadf
(16)openstack/stevedoreコンポーネント
(16−1)cd /opt/stack
$cd /opt/stack
(16−2)git clone git://git.openstack.org/openstack/stevedore.git
$git clone git://git.openstack.org/openstack/stevedore.git
(16−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(16−4)./update /opt/stack/stevedore
$./update /opt/stack/stevedore
(16−5)sudo pip install /opt/stack/stevedore
$sudo pip install /opt/stack/stevedore
(17)openstack/taskflowコンポーネント
(17−1)cd /opt/stack
$cd /opt/stack
(17−2)git clone git://git.openstack.org/openstack/taskflow.git
$git clone git://git.openstack.org/openstack/taskflow.git
(17−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(17−4)./update /opt/stack/taskflow
$./update /opt/stack/taskflow
(17−5)sudo pip install /opt/stack/taskflow
$sudo pip install /opt/stack/taskflow
(18)python-keystoneclientコンポーネントのインストール
(18−1)cd /opt/stack
$cd /opt/stack
(18−2)git clone git://git.openstack.org/openstack/python-keystoneclient.git
$git clone git://git.openstack.org/openstack/python-keystoneclient.git
(18−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(18−4)./update /opt/stack/python-keystoneclient
$./update /opt/stack/python-keystoneclient
(18−5)sudo pip install /opt/stack/python-keystoneclinet
$sudo pip install /opt/stack/python-keystoneclinet
(18−6)mode -644 owner <実行ユーザ>でpython-keystoneclient/etc/bash_completion.d/keystone.bash_completionを/etc/bash_completion.d配下にコピー
$sudo install -D -m 0644 -o <実行ユーザ> {/opt/stack/python-keystoneclient/etc/bash_completion.d/,/etc/bash_completion.d/}keystone.bash_completion
(19)python-glanceclientコンポーネントのインストール
(19−1)cd /opt/stack
$cd /opt/stack
(19−2)git clone git://git.openstack.org/openstack/python-glanceclient.git
$git clone git://git.openstack.org/openstack/python-glanceclient.git
(19−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(19−4)./update.py /opt/stack/python-glanceclient
$./update.py /opt/stack/python-glanceclien
(19−5)sudo pip install /opt/stack/python-glanceclient
$sudo pip install /opt/stack/python-glanceclient
(19−6)mode -644 owner <実行ユーザ>でpython-glanceclient/etc/bash_completion.d/glance.bash_completionを/etc/bash_completion.d配下にコピー
$sudo install -D -m 0644 -o <実行ユーザ> {/opt/stack/python-glanceclient/etc/bash_completion.d/,/etc/bash_completion.d/}glance.bash_completion
(20)python-neutronclientコンポーネントのインストール
(20−1)cd /opt/stack
$cd /opt/stack
(20−2)git clone git://git.openstack.org/openstack/python-neutronclient.git
$git clone git://git.openstack.org/openstack/python-neutronclient.git
(20−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(20−4)./update.py /opt/stack/python-neutronclient
$./update.py /opt/stack/python-neutronclient
(20−5)sudo pip install /opt/stack/python-neutronclient
$sudo pip install /opt/stack/python-neutronclient
(20−6)mode 644 owner <実行ユーザ>でpython-neutronclient/etc/bash_completion.d/neutron.bash_completionを/etc/bash_completion.d配下にコピー
$sudo install -D -m 0644 -o <実行ユーザ> {/opt/stack/python-neutronclient/etc/bash_completion.d/,/etc/bash_completion.d/}neutron.bash_completion
(21)python-novaclientコンポーネントのインストール
(21−1)cd /opt/stack
$cd /opt/stack
(21−2)git clone git://git.openstack.org/openstack/python-novaclient.git
$git clone git://git.openstack.org/openstack/python-novaclient.git
(21−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(21−4)./update.py /opt/stack/python-novaclient
$./update.py /opt/stack/python-novaclient
(21−5)sudo pip install /opt/stack/python-novaclient
$sudo pip install /opt/stack/python-novaclient
(21−6)mode 644 owner <実行ユーザ>でpython-novaclient/etc/bash_completion.d/nova.bash_completionを/etc/bash_completion.d配下にコピー
$sudo install -D -m 0644 -o <実行ユーザ> {/opt/stack/python-novaclient/etc/bash_completion.d/,/etc/bash_completion.d/}nova.bash_completion
(22)openstackclientコンポーネントのインストール ( 696line in stack.sh )
(22−1)cd /opt/stack
$cd /opt/stack
(22−2)git clone git://git.openstack.org/openstack/python-openstackclient.git
$git clone git://git.openstack.org/openstack/python-openstackclient.git
(22−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(22−4)./update.py /opt/stack/python-openstackclient
$./update.py /opt/stack/python-openstackclient
(22−5)sudo pip install /opt/stack/python-openstackclient
$sudo pip install /opt/stack/python-openstackclient
(23)Keystoneのインストール
(23−1)cd /opt/stack
$cd /opt/stack
(23−2)git clone git://git.openstack.org/openstack/keystone.git stable/juno
$git clone git://git.openstack.org/openstack/keystone.git stable/juno
(23−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(23−4)./update.py /opt/stack/keystone
$./update.py /opt/stack/keystone
(23−5)sudo pip install /opt/stack/keystone
$sudo pip install /opt/stack/keystone
(24)Keystoneの設定
(24−1)cd /opt/stack/keystone
$cd /opt/stack/keystone
(24−2)sudo mkdir /etc/keystone ; sudo chown <実行ユーザ> /etc/keystone
$sudo mkdir /etc/keystone
$sudo chown <実行ユーザ> /etc/keystone
(24−3)Keystoneのソースディレクトリから下記の設定ファイルを/etc/keystone配下にコピー ・keystone.conf.sample → keystone.conf ・keystone-paste.ini ・policy.json
$cp /opt/stack/keystone/etc/keystone.conf.sample /etc/keystone
$cd /opt/stack/keystone/etc/keystone-pate.ini /etc/keystone
$cd /opt/stack/keystone/etc/policy.json /etc/keystone
(24−4)keystone.confを以下のように編集
keystone.conf
[DEFAULT] public_endpoint=http://<keystoneが動くIP>:%(public_port)s/ admin_endpoint=http://<keystoneが動くIP>:%(admin_port)s/ admin_token=<admin portのtoken> use_syslog=True public_bind_host=0.0.0.0 admin_bind_host=0.0.0.0 [assignment] driver=keystone.assignment.backends.sql.Assignment [auth] [cache] [catalog] driver=keystone.catalog.backends.sql.Catalog [credential] [database] connection=mysql://user:password@127.0.0.1/keystone?charset=utf8 [ec2] driver=keystone.contrib.ec2.backends.sql.Ec2 [endpoint_filter] [endpoint_policy] [federation] [identity] driver=keystone.identity.backends.sql.Identity [identity_mapping] [kvs] [ldap] [matchmaker_redis] [matchmaker_ring] [memcache] [oauth1] [os_inherit] [paste_deploy] config_file=/etc/keystone/keystone-paste.ini [policy] [revoke] [saml] [signing] [ssl] [stats] [token] driver=keystone.token.backends.sql.Token [trust]
(25)Glanceのインストール
(25−1)cd /opt/stack
$cd /opt/stack
(25−2)git clone git://git.openstack.org/openstack/glance.git stable/juno
$git clone git://git.openstack.org/openstack/glance.git stable/juno
(25−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(25−4)./update.py /opt/stack/glance
$./update.py /opt/stack/glance
(25−5)sudo pip install /opt/stack/glance
$sudo pip install /opt/stack/glance
(26)Glanceの設定
(26−1)sudo mkdir /etc/glance ; sudo chown <実行ユーザ> /etc/glance
$sudo mkdir /etc/glance
$sudo chown <実行ユーザ> /etc/glance
(26−2)cp /opt/stack/glance/etc/glance-registory.conf /etc/glance
$cd /opt/stack/glance/etc/glance-registory.conf /etc/glance
(26−3)glance-registory.conf の設定を以下のように編集
glance-registry.conf
[DEFAULT] debug=True sql_connection=mysql://<user名>:<password>@127.0.0.1/glance?charset=utf8 use_syslog=True bind_host = 0.0.0.0 bind_port = 9191 backlog = 4096 api_limit_max = 1000 limit_param_default = 25 rabbit_host = localhost rabbit_port = 5672 rabbit_use_ssl = false rabbit_userid = guest rabbit_password = guest rabbit_virtual_host = / rabbit_notification_exchange = glance rabbit_notification_topic = notifications rabbit_durable_queues = False qpid_notification_exchange = glance qpid_notification_topic = notifications qpid_hostname = localhost qpid_port = 5672 qpid_username = qpid_password = qpid_sasl_mechanisms = qpid_reconnect_timeout = 0 qpid_reconnect_limit = 0 qpid_reconnect_interval_min = 0 qpid_reconnect_interval_max = 0 qpid_reconnect_interval = 0 qpid_heartbeat = 5 qpid_protocol = tcp qpid_tcp_nodelay = True [database] [keystone_authtoken] auth_host=<keystoneのIP> auth_port=35357 auth_protocol=http cafile= auth_uri=http://<keystoneのIP>:35357/v2 signing_dir=/var/cache/glance/registry identity_uri = http://127.0.0.1:35357 admin_tenant_name = service admin_user = glance admin_password = stack [paste_deploy] flavor=keystone [profiler]
(26−4)cp /opt/stack/glance/etc/glance-api.conf /etc/glance
$cp /opt/stack/glance/etc/glance-api.conf /etc/glance
(26−5)glance-api.confを下記のように編集
glance-api.conf
[DEFAULT] debug=True sql_connection=mysql://<user名>:<password>@127.0.0.1/glance?charset=utf8 use_syslog=True bind_host = 0.0.0.0 bind_port = 9191 backlog = 4096 api_limit_max = 1000 limit_param_default = 25 rabbit_host = localhost rabbit_port = 5672 rabbit_use_ssl = false rabbit_userid = guest rabbit_password = guest rabbit_virtual_host = / rabbit_notification_exchange = glance rabbit_notification_topic = notifications rabbit_durable_queues = False qpid_notification_exchange = glance qpid_notification_topic = notifications qpid_hostname = localhost qpid_port = 5672 qpid_username = qpid_password = qpid_sasl_mechanisms = qpid_reconnect_timeout = 0 qpid_reconnect_limit = 0 qpid_reconnect_interval_min = 0 qpid_reconnect_interval_max = 0 qpid_reconnect_interval = 0 qpid_heartbeat = 5 qpid_protocol = tcp qpid_tcp_nodelay = True [database] [keystone_authtoken] auth_host=<keystoneのIP> auth_port=35357 auth_protocol=http cafile= auth_uri=http://<keystonのIP>:35357/v2 signing_dir=/var/cache/glance/registry identity_uri = http://127.0.0.1:35357 admin_tenant_name = service admin_user = glance admin_password = stack [paste_deploy] flavor=keystone [profiler]
(26−6)下記のファイルを/opt/stack/glance/etc から /etc/glanceにコピー ・glance-cache.conf ・glance-registry-paste.ini ・glance-api-paste.ini ・policy.json ・schema-image.json
$cp /opt/stack/glance/etc/glance-cache.conf /etc/glance
$cp /opt/stack/glance/etc/glance-registry-paste.ini /etc/glance
$cp /opt/stack/glance/etc/glance-api-paste.ini /etc/glance
$cp /opt/stack/glance/etc/policy.json /etc/glance
$cp /opt/stack/glance/etc/shcema-image.json /etc/glance
(27)Cinderのインストール (27−1)cd /opt/stack
$cd /opt/stack
(27−2)git clone git://git.openstack.org/openstack/cinder.git stable/juno
$git clone git://git.openstack.org/openstack/cinder.git stable/juno
(27−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(27−4)./update.py /opt/stack/cinder
$./update.py /opt/stack/cinder
(27−5)sudo pip install /opt/stack/cinder
$sudo pip install /opt/stack/cinder
(28)Cinderの設定
(28−1)sudo mkdir /etc/cinder ; sudo chown <実行ユーザ> /etc/cinder
$sudo mkdir /etc/cinder
$sudo chown <実行ユーザ> /etc/cinder
(28−2)cp /opt/stack/cinder/etc/policy.json /etc/cinder
$cp /opt/stack/cinder/etc/policy.json /etc/cinder
(28−3)rootwrapの設定
(28−3−1)mkdir -m 755 /etc/cinder/rootwrap.d
$mkdir -m 755 /etc/cinder/rootwrap.d
(28−3−2)cp /opt/stack/cinder/etc/rootwrap.d/* /etc/cinder/rootwrap.d/
$cp /opt/stack/cinder/etc/rootwrap.d/* /etc/cinder/rootwrap.d/
(28−3−3)sudo chown -R root:root /etc/cinder/rootwrap.d
$sudo chown -R root:root /etc/cinder/rootwrap.d
(28−3−4)sudo chmod 644 /etc/cinder/rootwrap.d/*
$sudo chmod 644 /etc/cinder/rootwrap.d/*
(28−7)cp /opt/stack/cinder/etc/rootwrap.conf /etc/cinder/
$cp /opt/stack/cinder/etc/rootwrap.conf /etc/cinder/
(28−8)/etc/cinder/rootwrap.confを下記のように追加
rootwrap.conf
filters_path = /etc/cinder/rootwrap.conf
(28−9)sudo chown root:root /etc/cinder/rootwrap.conf
$sudo chown root:root /etc/cinder/rootwrap.conf
(28−10)sudo chmod 0644 /etc/cinder/rootwrap.conf
$sudo chmod 0644 /etc/cinder/rootwrap.conf
(28−11)/etc/sudoers.d/cinder-rootwrapを下記の内容で作成
cinder-rootwrap
<実行ユーザ> ALL=(root) NOPASSWD : /usr/bin/cinder-rootwrap /etc/cinder/rootwrap.conf *
(28−12)cp /opt/stack/cinder/etc/api-paste.ini /etc/cinder
$cp /opt/stack/cinder/etc/api-paste.ini /etc/cinder
(28−13)cp /opt/stack/cinder/etc/cinder.conf.sample /etc/cinder/cinder.conf
$cp /opt/stack/cinder/etc/cinder.conf.sample /etc/cinder/cinder.conf
(28−14)cinder.confを下記のように変更
cinder.conf
[DEFAULT] auth_strategy=keystone debug=True verbose=True volume_group=stack-volumes volume_name_template=volume-%s my_ip=<cinderのipアドレス> iscsi_helper = tgtadm sql_connection=mysql://<user名>:<password>@127.0.0.1/cinder?charset=utf8 api_paste_config=/etc/cinder/api-paste.ini rootwrap_config=/etc/cinder/rootwrap.conf osapi_volume_extension=cinder.api.contrib.standard_extensions state_path=/opt/stack/data/cinder lock_path=/opt/stack/data/cinder periodic_interval=60 use_syslog=True rpc_backend=cinder.openstack.common.rpc.impl_kombu rabbit_hosts=<rabbitmqのIP> rabbit_password=stack [BRCD_FABRIC_EXAMPLE] [CISCO_FABRIC_EXAMPLE] [database] [fc-zone-manager] [keymgr] [keystone_authtoken] auth_host=<keystoneのIP> auth_port=35357 auth_protocol=http admin_tenant_name=service admin_user=cinder admin_password=stack signing_dir=/var/cache/cinder cafile= auth_uri=http://<keystoneのIP>:35357/v2.0 [matchmaker_redis] [matchmaker_ring] [profiler] [ssl]
※CINDER_DRIVER(local.conf[localrc]に指定する環境変数)に何も指定しないと、defaultという値が入るが、devstack/lib/cinder_plugins/配下にdefaultというファイルはないため、driverの設定は行われない。
(29)Neutronのインストール
(29−1)cd /opt/stack
$cd /opt/stack
(29−2)git clone git://git.openstack.org/openstack/neutron.git stable/juno
$git clone git://git.openstack.org/openstack/neutron.git stable/juno
(29−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(29−4)./update,py /opt/stack/neutron
$./update,py /opt/stack/neutron
(29−5)sudo pip install /opt/stack/neutron
$sudo pip install /opt/stack/neutron
※Devstackでは、ENABLE_SERVICESにryuとかmidonetとか指定すると、third_partyのインストール処理もここで実行される(Devstackでは対応遅れてる)
(30)Novaのインストール
(30−1)ハイパーバイザーのインストール
(30−1−1)libvirtとqemu-kvmのインストール
$sudo apt-get install qemu-kvm,libvirt-bin,python-libvirt,python-guestfs
(30−2)novncをclone
$git clone https://github.com/kanaka/noVNC.git
(30−3)novaのソースを取得
$git clone git://git.openstack.org/openstack/nova.git stable/juno
(30−4)cd /opt/stack/requirements
$cd /opt/stack/requirements
(30−5)./update.py /opt/stack/nova
$./update.py /opt/stack/nova
(30−6)sudo pip install /opt/stack/nova
$sudo pip install /opt/stack/nova
(30−7)sudo install -D -m 0644 -o <実行ユーザ> /opt/stack/nova/tools/nova-manage.bash_completion /etc/bash_completion.d/nova-manage.bash_completion
$sudo install -D -m 0644 -o <実行ユーザ> /opt/stack/nova/tools/nova-manage.bash_completion /etc/bash_completion.d/nova-manage.bash_completion
(31)Novaの以前の設定等があれば削除
(31−1)iptablesの内容を削除
# Delete rules sudo iptables -S -v | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-A" | sed "s/-A/-D/g" | awk '{print "sudo iptables",$0}' | bash # Delete nat rules sudo iptables -S -v -t nat | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-A" | sed "s/-A/-D/g" | awk '{print "sudo iptables -t nat",$0}' | bash # Delete chains sudo iptables -S -v | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-N" | sed "s/-N/-X/g" | awk '{print "sudo iptables",$0}' | bash # Delete nat chains sudo iptables -S -v -t nat | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-N" | sed "s/-N/-X/g" | awk '{print "sudo iptables -t nat",$0}' | bash
(31−2)sudo virsh list --allをして、novaのprefixが付くvmを削除
$sudo virsh destroy
$sudo virsh undefine --managed-save
(31−3)ISCIセッションの削除
tgts=$(sudo iscsiadm --mode node | grep volume- | cut -d ' ' -f2) for target in $tgts; do sudo iscsiadm --mode node -T $target --logout || true done sudo iscsiadm --mode node --op delete || true
(31−4)過去のnovaで作ったvmのデータの削除
$sudo rm -fr /opt/stack/data/nova/instances/*
(31−5)過去のnovaに関するデータのディレクトリやキャッシュの削除
$sudo rm -fr /opt/stack/data/nova
$sudo rm -fr /var/cache/nova
(32)Novaの設定
(32−1)sudo mkdir /etc/nova ; sudo chown <実行ユーザ> /etc/nova
$sudo mkdir /etc/nova
$sudo chown <実行ユーザ> /etc/nova
(32−2)policy.json を本番環境にコピー
$cp /opt/stack/nova/etc/policy.json /etc/nova
(32−3)nova-api用の設定
(32−3−1)api-paste.iniファイルを本番環境にコピー
$cp /opt/stack/nova/etc/api-paste.ini /etc/nova
(32−4)nova-compute用の設定
(32−4−1)ipフォワーディングを有効
$sudo sysctl -w net.ipv4.ip_forward=1
(32−4−2)SELinuxが動いていたら、virt_use_execmem(ゲストOSの executable memory and executable_stack を有効にする) 組み込みルールをONにする
$sudo setsebool virt_use_execmem on
(32−4−3)vmのデータを格納するディレクトリを作成、所有ユーザの変更
$mkdir -p /opt/stack/nova/instances
$sudo chown <実行ユーザ> /opt/stack/nova/instances
→novaでvmを作成すると、vmごとにフォルダが作られ、instances/<vmごとに付けられる乱数>のディレクトリの中は下記のようになる
$ ls /opt/stack/nova/instances/kflksalfdjafdj -rw-rw---- 1 libvirt-qemu kvm 18549 Nov 27 21:40 console.log -rw-r--r-- 1 libvirt-qemu kvm 11010048 Nov 27 21:41 disk -rw-rw-r-- 1 libvirt-qemu kvm 419840 Nov 27 19:25 disk.config -rw-r--r-- 1 stack libvirtd 176 Nov 27 19:25 disk.info -rw-rw-r-- 1 stack libvirtd 2697 Nov 27 19:25 libvirt.xml
(32−5)nova.confの作成と編集
nova.conf
[DEFAULT] verbose=True debug=True auth_strategy=keystone use_syslog=True # allow_resize_to_same_host=True api_paste_config=/etc/nova/api-paste.ini rootwrap_config=/etc/nova/rootwrap.conf scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler dhcpbridge_flagfile=/etc/nova/nova.conf force_dhcp_release=True fixed_range= default_floating_pool=public #s3_host= #s3_port=8080 osapi_compute_extension=nova.api.openstack.compute.contrib.standard_extensions my_ip=<実行するホストIP> osapi_compute_workers=4 ec2_workers=4 metadata_workers=4 #neutron # network_api_class=nova.network.neutronv2.api.API neutron_admin_username=neutron neutron_admin_password=stack neutron_admin_auth_url=http://<neutronの認証サーバのIP(普通はkeystone)>/v2.0 neutron_auth_strategy=keystone neutron_admin_tenant_name=service neutron_region_name=RegionOne neutron_url=http://<neutron-ip>:9696 service_neutron_metadata_proxy=True libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver linuxnet_interface_driver= vif_plugging_is_fatal=True vif_plugging_timeout=300 sql_connection=mysql://<user名>:<パスワード>@127.0.0.1/nova?charset=utf8 instance_name_template=instance-%08x volume_api_class=nova.volume.cinder.API state_path=/opt/stack/data/nova lock_path=/opt/stack/data/nova instances_path=/opt/stack/data/nova/instances force_config_drive=always logging_context_format_string="%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s" novncproxy_base_url=http://<novncproxyを動かしてるip>:6080/vnc_auto.html xvpvncproxy_base_url=http://<xvpnvncproxyを動かしてるip>:6081/console vnc_enabled=true vncserver_listen=127.0.0.1 vncserver_proxyclien_address=127.0.0.1 ec2_dmz_host=<nova-api or nova-api-ec2を動かしてるサーバのIP> rpc_backend=nova.openstack.common.rpc.impl_kombu rabbit_hosts=<rabbitmqのIP> rabbit_password=stack glance_api_servers=<glanceのIP>:9292 use_usb_tablet=False default_ephemeral_format=ext4 compute_driver=libvirt.LibvirtDriver #firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver firewall_driver=nova.virt.firewall.NoopFirewallDriver security_group_api=neutron [conductor] workers=4 [osapi_v3] enabled=True [keystone_authtoken] auth_host=<keystoneのIP> auth_port=35357 auth_protocol=http admin_tenant_name=service admin_user=nova admin_password=stack signing_dir=/var/cache/nova cafile= [libvirt] virt_type=qemu cpu_mode=none injection_partition=-2 [keymgr] fixed_key = 962A3A8992C79BB4A2968AB28417F75D2D286FB16F2C537B26B8AE39CB1F6C92
(32−6)nova-compute かつ hypervisorにlibvirt(libvirtのインターフェースを使ってHypervisorを操作する)を使用する場合の設定
(32−6−1)Neutronのml2プラグイン or openvswitchプラグインでopenvswitch agentを使う場合、/etc/libvirt/qemu.confに下記の設定を追加または、編集
cgroup_device_acl = [ "/dev/null", "/dev/full", "/dev/zero", "/dev/random", "/dev/urandom", "/dev/ptmx", "/dev/kvm", "/dev/kqemu", "/dev/rtc", "/dev/hpet","/dev/net/tun", ]
(32−6−2)実行ユーザを libvirtdグループに追加
$sudo usermod -G libvirtd <実行ユーザ>
(32−6−3)libvirtdを再起動
$sudo service libvirtd restart
(33)Horizonのインストール
(33−0)djangoのuser認証モジュール(contrib.auth framework)のkeystoneを使うモジュールのインストール (33−1)cd /opt/stack
$cd /opt/stack
(33−2)git clone git://git.openstack.org/openstack/django_openstack_auth.git
$git clone git://git.openstack.org/openstack/django_openstack_auth.git
(33−3)cd /opt/stack/requirements
$cd /opt/stack/requirements
(33−4)./update.py /opt/stack/django_openstack_auth
$./update.py /opt/stack/django_openstack_auth
(33−5)sudo pip install /opt/stack/django_openstack_auth
$sudo pip install /opt/stack/django_openstack_auth
(33−6)Apache と WSGIモジュールのインストール (33−7)apache2 , libapache2-mod-wsgiをパッケージ管理ツールからインストール
$sudo apt-get install apache2 libapache2-mod-wsgi
(33−8)wsgiモジュールを有効化
$a2enmod wsgi
→実際は、/etc/apache2/mod-availablesの設定ファイルを、mod-enablesにシンボリックリンクを張る (33−9)Horizonのソースを取得、インストール (33−10)cd /opt/stack
$cd /opt/stack
(33−11)git clone git://git.openstack.org/openstack/horizon.git stable/juno
$git clone git://git.openstack.org/openstack/horizon.git stable/juno
(33−12)cd /opt/stack/requirements
$cd /opt/stack/requirements
(33−13)./update.py /opt/stack/horizon
$./update.py /opt/stack/horizon
(33−14)sudo pip install /opt/stack/horizon
$sudo pip install /opt/stack/horizon
(34)rsyslogの設定
(34−1)openstack用の設定ファイルの作成
$sudo touch /etc/rsyslog.d/90-stack-m.conf
(34−2)90-stack-m.confを下記のように編集
90-stack-m.conf
$ModLoad imrelp $InputRELPServerRun 516
(34−3)rsyslogdを再起動
$sudo service rsyslog restart
(35)RabbitMQの設定
(35−1)パスワードの変更
$rabbitmqctl change_password guest <password>
(36)Mysqlの設定
(36−1)rootユーザのパスワード設定
$sudo mysqladmin -u root password <password>
(36−2)すべてのホストからアクセスしてくるrootユーザにグローバルレベル('.')のすべて操作権限を与える
$sudo mysql -uroot -p<password> -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$DATABASE_USER'@'%' identified by '$DATABASE_PASSWORD';"
(36−3)/etc/mysql/my.cnfを作成、以下のように変更
[mysqld]セクションに
・bind-address=0.0.0.0
・default-storage-engine=InnoDB
を追記
(36−4)sudo service mysql restart
$sudo service mysql restart
*devstackだとこのあたりで、screenの起動や設定を行う *devstackだとこのあたりで、起動した各プロセスが正常に動いているかどうかを管理するためのディレクトリ/opt/stack/statusを作成する *devstackだとこのあたりで、dstatの起動や設定を行う
Openstakコンポーネントの起動〜初期化処理〜
「ここから先は、tmuxなりscreenで各プロセスごとにwindow
を用意することをおすすめします」
Keystone
(37)Keystoneの初期設定
(37−1)DBの作成
$mysql
>DROP DATABASE IF EXISTS keystone
>CREATE DATABASE keystone CHARACTER SET utf8
(37−2)DBのマイグレーション
$keystone-manage db_sync
(37−3)PKIのセットアップ
$sudo rm -fr /etc/keystone/ssl
$keystone-manage pki_setup
(37−4)authキャッシュ用のディレクトリ作成
$sudo mkdir -p /var/cache/keystone/auth
$sudo chown <実行ユーザ> /var/cache/keystone/auth
(38)Keystoneの起動
(38−1)apache経由か単体で起動する場合かで、条件分岐
(38−1[apache])apache経由で起動する場合は、apache用のコンフィグファイルをsite-enablesに設定し、apacheを再起動
(38−1[単体])単体で受ける場合、keystone-allコマンドを実行
$keystone-all --config-file /etc/keystone/keystone.conf --debug
(38−2)keystoneが動いてるか確認、curlでレスポンスが帰ってくるかどうか
$curl --noproxy '*' -k http://<ip>:35375/v2.0/
(38−3)openstack client (python-openstack-client) を使うための環境変数を設定
→servicetoken(設定ファイルで設定している)を用いて認証する。
$export OS_TOKEN=<keystone設定ファイルに記入した、service_token>
$export OS_URL=http://<ip>:5000/v2.0
(38−4)openstack client を使い下記のような、テナント(プロジェクト)、ユーザ、ロールを作成
# Tenant User Roles
# ------------------------------------------------------------------
# -- -- servic
# -- -- ResellerAdmin
# -- -- Member
# admin admin admin
# demo admin admin
# demo demo Member, anotherrole
# invisible_to_admin demo Member
# service -- --
(38−4−1) adminテナントの作成
$openstack project create admin
(38−4−2) adminテナントを主要テナントとするadminユーザを作成する
$openstack user create admin --project <project-id(admin)> --email admin@example.com --password admin-password
(38−4−3) adminロールを作成
$openstack role create admin
(38−4−4) adminユーザにadminテナントのadmin権限を与える
$openstack role add <role-id(admin)> --project <project-id(admin)> --user <user-id(admin)>
(38−4−5) serviceテナントの作成、serviceロールを作成
→各コンポーネントは、このserviceテナントのユーザ(role:admin)にならないといけない
$openstack project create service
$openstack role create service
(38−4−6) ResellerAdminロールを作成
→ swiftの中のadminロールは、自分のテナントの管理しかできないが
→ ResellerAdminロールは、すべてのテナントの管理ができるため、Nova , Ceilometer等はこちらを使う
→ ResellerAdminロールの名前は、swiftのswift-proxy.confで設定できる
$openstack role create ResellerAdmin
(38−4−7)Memberロールを作成
→ SwiftとHorizonで使われるロール
$openstack role create Member
(38−4−8)anotherroleロールを作成
→ 一般的な権限として使われるロールを作成
$openstack role create antherrole
(38−4−9)invisible_to_adminテナントの作成
→ adminユーザが見ることのできないテナント
$openstack project create invisible_to_admin
(38−4−10)demoテナントとdemoユーザを作成
$openstack project create demo
$openstack user create demo --project <project-id(demo)> --email demo@example.com --password <demo-pass>
(38−4−11)demoユーザとadminユーザの権限の設定
$openstack role add --project <project-id(demo)> --user <user-id(demo)> <role-id(member)>
$openstack role add --project <project-id(demo)> --user <user-id(admin)> <role-id(admin)>
$openstack role add --project <project-id(demo)> --user <user-id(demo)> <role-id(another role)>
$openstack role add --project <project-id(invisible_to_admin)> --user <user-id(demo)> <role-id(Member)>
(38−5)Keystoneコンポーネントのサービスカタログの登録、エンドポイントの登録 (38−5−1)サービスの登録
$openstack service create keystone --type identity ---description "Keystone Identity Service"
(38−5−2)エンドポイントの登録
$openstack endpoint create <service-id(keystone)> --region RegionOne
--publicurl http://<ip>:5000/v2.0
--adminurl http://<ip>:35375/v2.0
--internalurl http://<ip>:5000/v2.0
→public_url:インターネット経由のアクセス(エンドユーザを想定)
→admin_url:管理操作用のアクセス
→internal_url:他のOpenStackコンポーネント用のLAN経由のアクセス
(38−6)Novaコンポーネントのユーザ作成、サービスカタログの登録、エンドポイントの登録
(38−6−1)novaユーザの作成、serviceテナントのadmin権限の付与
$openstack user create nova --password <password> --project <project-id(service)> --email nova@example.com
$openstack add role <role-id(admin)> --project <project-id(service)> --user <user-id(nova)>
(38−6−2)novaのサービスカタログの登録
$openstack service create nova --type=compute --description="Nova Compute Service"
(38−6−3)novaのエンドポイントの登録
$openstack endpoint create <service-id(nova)> --region RegionOne
--publicurl "http://<ip>:8774/v2/$(tenant_id)s"
--adminurl "http://<ip>:8774/v2/$(tenant_id)s"
--internalurl "http://<ip>:8774/v2/$(tenant_id)s"
(38−6−4)nova v3 API用のサービスの登録
$openstack service create novav3 --type=computev3 --description="Nova Compute Service V3"
(38−6−5)nova v3 API用のエンドポイントの登録
$openstack endpoint create $NOVA_V3_SERVICE --region RegionOne
--publicurl "http://<ip>:8774/v3"
--adminurl "http://<ip>:8774/v3"
--internalurl "http://<ip>:8774/v3"
(38−6−6)EC2互換API用のサービスの登録
$openstack service create ec2 --type ec2 --description "EC2 Compatibility Layer"
(38−6−7)EC2互換API用のエンドポイントの登録
$openstack endpoint create ec2 --region RegionOne
--publicurl "http://<ip>:8773/services/Cloud"
--adminurl "http://<ip>:8773/services/Admin"
--internalurl "http://<ip>:8773/services/Cloud"
(38−6−8)novaがswift経由でイメージをダウンロードする可能性がある場合(swiftが有効になっている場合)ResellerAdmin ロールを付与する必要がある
$openstack add role <role-id(ResellerAdmin)> --project <project-id(service)> --user <user-id(nova)>
(38−7)Glanceコンポーネントのユーザ作成、サービスカタログの登録、エンドポイントの登録
(38−7−1)glanceユーザの作成、serviceテナントのadmin権限の付与
$openstack user create glance --password <password> --project <project-id(service) --email glance@example.com
$openstack add role <role-id(admin)> --project <project-id(service)> --user <user-id(glance) >
(38−7−2)glanceのサービスカタログの登録
$openstack service create --type image --description "Glance Image Service" glance
(38−7−3)glanceのエンドポイントの登録
$openstack endpoint create glance --region RegionOne
--publicurl "http://<ip>:9292"
--adminurl "http://<ip>:9292"
--internalurl "http://<ip>:9292"
(38−8)Cinderコンポーネントのユーザ作成、サービスカタログの登録、エンドポイントの登録
(38−8−1)Cinderユーザの作成、serviceテナントのadmin権限の付与
$openstack user create cinder --password <password> --project <project-id(service)> --email cinder@example.com
$openstack role add <role-id(admin)> --project <project-id(service)> --user <user-id(cinder)>
(38−8−2)Cinder v1API用のサービスカタログを登録する
$openstack service create cinder --type volume --description="Cinder Volume Service"
(38−8−3)Cinder v1API用のエンドポイントを登録する
$openstack endpoint create <service-id(cinder)> --region RegionOne
--publicurl http://<ip>:8776/v1/$(tenant_id)s
--adminurl http://<ip>:8776/v1/$(tenant_id)s
--internalurl http://<ip>:8776/v1/$(tenant_id)s
(38−8−4)Cinder v2API用のサービスカタログを登録する
$openstack service create cinderv2 --type=volumev2 --description="Cinder Volume Serbvice V2"
(38−8−5)Cinder v2API用のエンドポイントを登録する
$openstack endpoint create cinderv2 --region RegionOne
--publicurl http://<ip>:8776/v2/$(tenant_id)s
--adminurl http://<ip>:8776/v2/$(tenant_id)s
--internalurl http://<ip>:8776/v2/$(tenant_id)s
(38−9)Neutronコンポーネントのユーザ作成、サービスカタログの登録、エンドポイントの登録
(38−9−1)Neutronユーザの作成、serviceテナントのadmin権限の付与
$openstack user create neutron --password <pass> --project <project-id(service)> --email neutron@example.com
$openstack role add <role-id(admin)> --project <project-id(service)> --user <user-id(neutron)>
(38−9−2)Neutron API用のサービスカタログを登録
$openstack service create neutron --type=network --description="Network Service"
(38−9−3)Neutron API用のエンドポイントを登録する
$openstack endpoint create <service-id(neutron)> --region RegionOne
--publicurl "http://<ip>:9696/"
--adminurl "http://<ip>:9696/"
--internalurl "http://<ip>:9696/"
(39)Token-flow authの終了
→各々のコンポーネントのユーザを作成したので、token認証をやめる。
$unset OS_TOKEN
$unset OS_URL
(40)password認証のための環境変数を設定
$export OS_AUTH_URL=http://<ip>:5000/v2.0
$export OS_TENANT_NAME=admin
$export OS_USERNAME=admin
$export OS_PASSWORD=<pass>
Horizon
(41)Horizonの初期設定
(41−1)/opt/stack/horizon/openstack_dashboard/local/localsettings.py.exampleをlocalsettings.pyにリネーム
→horizon GUIで有効にするタブ、設定などを定義する(ex, ロードバランサー、ファイヤーウォール)
(41−2)localsettings.pyを自分の環境に合わせて、変更
(41−3)apacheがドキュメントルートとして使うディレクトリを作成する
$sudo mkdir -p /opt/stack/horizon/.blackhole
(41−4) 000-defaultのサイトを無効にする
$sudo a2dissite 000-default
(41−5)/etc/apache2/sites-available配下に、horizon.confを下記のように作成する
horizon.conf
<VirtualHost *:80> WSGIScriptAlias / /opt/stack/horizon/openstack_dashboard/wsgi/django.wsgi WSGIDaemonProcess horizon user=<実行ユーザ> group=<実行ユーザ> processes=3 threads=10 home=/opt/stack/horizon WSGIApplicationGroup %{GLOBAL} SetEnv APACHE_RUN_USER <実行ユーザ> SetEnv APACHE_RUN_GROUP <実行ユーザ> WSGIProcessGroup horizon DocumentRoot /opt/stack/horizon/.blackhole/ Alias /media /opt/stack/horizon/openstack_dashboard/static <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /opt/stack/horizon/> Options Indexes FollowSymLinks MultiViews Require all granted AllowOverride None Order allow,deny allow from all </Directory> ErrorLog /var/log/apache2/horizon_error.log LogLevel warn CustomLog /var/log/apache2/horizon_access.log combined </VirtualHost> WSGISocketPrefix /var/run/apache2
(42)apacheを再起動して、horizonを有効にする
$sudo service apache start
Glance
(43)Glanceの初期設定
(43−1)Glance イメージを格納するディレクトリを作成
$mkdir -p /opt/stack/data/glance/images
(43−2)Glance イメージのローカルキャッシュディレクトリを作成
$mkdir -p /opt/stack/data/glance/cache
(43−3)Glance用のDBを作成
$mysql
>DROP DATABASE IF EXISTS glance
>CREATE DATABASE glance CHARACTER SET utf8
(43−4)DBのマイグレーション
$glance-manage db_sync
(43−5)cache用のディレクトリの作成
$sudo mkdir -p /var/cache/glance/api
$sudo chown <実行ユーザ> /var/cache/glance/api
$sudo mkdir -p /var/cache/glance/registry
$sudo chown <実行ユーザ> /var/cache/glance/registry
Neutron
(44)Neutronの初期設定
(44−1)設定ファイル格納ディレクトリの作成、ownerの変更
$sudo mkdir /etc/neutron
$sudo chown <実行ユーザ> /etc/neutron
(44−2)設定ファイルのひな形のコピー
$cp /opt/stack/neutron/etc/neutron.conf /etc/neutron
(44−3)設定ファイルを下記のように編集
neutron.conf
[DEFAULT] verbose = True debug = True policy_file = /etc/neutron/policy.json allow_overlapping_ips = True auth_strategy = keystone notify_nova_on_port_status_change = True norify_nova_on_port_data_change = True nova_url = http://<nova-api>:8774/v2 nova_admin_username = nova nova_admin_password = <nova-password> nova_admin_tenant_id = <nova-admin-tenant-id> nova_admin_auth_url = http://<nova-amin-api>:35357/v2.0 state_path = /opt/stack/data/neutron rpc_backend = neutron.openstack.common.rpc.impl_kombu rabbit_hosts = <rabbit-ip> rabbit_password = <rabbit-password> lock_path = $state_path/lock core_plugin = ml2 service_plugins = neutron.services.l3_router.l3_router_plugin.L3RouterPlugin [matchmaker_redis] [matchmaker_ring] [quotas] [agent] root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf [keystone_authtoken] auth_host = <keystone-ip> auth_port = 35357 auth_protocol = http admin_tenant_name = service admin_user = neutron admin_password = <neutron-pass> signing_dir = /var/cache/neutron [database] [service_providers] service_provider=LOADBALANCER:Haproxy:neutron.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default service_provider=VPN:openswan:neutron.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default
(44−4)ml2プラグイン用の設定ファイルのひな形をコピー
$mkdir -p /etc/neutron/plugins/
$cp /opt/stack/neutron/etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugins/
(44−5)ml2_conf.iniを下記のように編集
ml2_conf.ini
[ml2] mechanism_drivers=openvswitch,linuxbridge type_drivers=local,flat,vlan,gre,vxlan [ovs] local_ip = <ip> [database] connection=mysql://<user>:<pass>@<ip>/neutron_ml2?charset=utf8 [ml2_type_flat] [ml2_type_vlan] [ml2_type_gre] [ml2_type_vxlan] [securitygroup] firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver [agent] root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf
(44−6)rootwrap設定
(44−6−1)mkdir -p -m 755 /etc/neutron/rootwrap.d
$mkdir -p -m 755 /etc/neutron/rootwrap.d
(44−6−2)cp -pr /opt/stack/neutron/etc/neutron/rootwrap.d/* /etc/neutron/rootwrap.d/
$cp -pr /opt/stack/neutron/etc/neutron/rootwrap.d/* /etc/neutron/rootwrap.d/
(44−6−3)sudo chown -R root:root /etc/neutron/rootwrap.d
$sudo chown -R root:root /etc/neutron/rootwrap.d
(44−6−4)sudo chmod 644 /etc/neutron/rootwrap.d/*
$sudo chmod 644 /etc/neutron/rootwrp.d/*
(44−6−5)rootwrap.confのコピー
$cp -p /opt/stack/neutron/etc/neutron/rootwrap.conf /etc/neutron
(44−6−6)rootwrap.confを下記のように追記
rootwrap.conf
filters_path = /etc/cinder/rootwrap.conf
(44−6−7)sudo chown root:root /etc/neutron/rootwrap.conf
$sudo chown root:root /etc/neutron/rootwrap.conf
(44−6−8)sudo chmod 0644 /etc/neutron/rootwrap.conf
$sudo chmod 0644 /etc/neutron/rootwrap.conf
(44−6−9)/etc/sudoers.d/neutron-rootwrapを下記内容で作成
neutron-rootwrap
<実行ユーザ> ALL=(root) NOPASSWD: /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf *
(44−7)neutron-l2agentとneutron-serverの共通初期化処理
(44−7−1)api-paste.ini , policy.jsonをコピー
$cp /opt/stack/neutron/etc/api-paste.ini /etc/neutron/api-paste.ini $cp /opt/stack/neutron/etc/policy.json /etc/neutron/policy.json
(44−8)neutron-l2agentの初期化処理
(44−8−1)neutron-ovs-cleanupを実行
$neutron-ovs-cleanup
(44−8−2)br-intブリッジの作成
$sudo ovs-vsctl --no-wait -- --may-exist add-br br-int #→--no-wait:vswitchd からの応答を待たない(switchedが起動していないときに使わないとエラーで落ちる) #→ --may-exist :同じ名前のbridgeがいても、新しく作る(初期化される) $sudo ovs-vsctl --no-wait br-set-external-id br-int bridge-id br-int
(44−9)neutron-dhcpagentの初期化処理
(44−9−1)設定ファイルのコピー
$cp /opt/stack/neutron/etc/dhcp_agent.ini /etc/neutron/dhcp_agent.ini
(44−9−2)dhcp_agent.iniを下記のように編集
[DEFAULT] verbose = True debug = True use_namespaces = True root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf ovs_use_veth = False interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver dhcp_agent_manager = neutron.agent.dhcp_agent.DhcpAgentWithStateReport
(44−10)neutronl3-agentの初期化処理
(44−10−1)設定ファイルのコピー
$cp /opt/stack/neutron/etc/l3_agent.ini /etc/l3_agent.ini
(44−10−2)l3_agent.iniを下記のように編集
[DEFAULT] verbose = True debug = True use_namespaces = True root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf ovs_use_veth = False interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver external_network_bridge = br-ex l3_agent_manager = neutron.agent.l3_agent.L3NATAgentWithStateReport
(44−10−3)$neutron-ovs-cleanupを実行
(44−10−4)br-exブリッジを作成
$sudo ovs-vsctl --no-wait --may-exist add-br br-ex
$sudo ovs-vsctl br-set-external-id br-ex bridge-id br-ex
(44−10−5)br-exに割り当てられたIPを削除
$sudo ip addr flush dev br-ex
(44−11)neutron-metaagentの初期化処理
(44−11−1)設定ファイルコピー
$cp /opt/stack/neutron/etc/metadata_agent.ini /etc/neutron/metadata_agent.ini
(44−11−2)metadata_agent.iniの設定を下記のように変更する
[DEFAULT] verbose = True debug = True nova_metadata_ip = <nova-ip> root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf auth_host = <keystone-ip> auth_port = 35375 auth_protocol = http admin_tenant_name = service admin_user = neutron admin_password = <password>
(44−11−3)cache用のディレクトリの作成
$sudo mkdir -p /var/cache/neutron
(44−12)neutron-debug-command用の初期化処理
(44−12−1)設定ファイルをコピー
$cp /opt/stack/neutron/etc/l3_agent.ini /etc/neutron/debug.ini
(44−12−2) 下記のように、設定ファイルを変更
debug.ini
[DEFAULT] verbose = False debug = False use_namespaces = True ovs_use_veth = False interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver external_network_bridge = br-ex [agent] root_helper = sudo /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf
(44−13)neutron用のDBの作成
$mysql
>DROP DATABASE IF EXISTS neutron
>CREATE DATABASE neutron CHARACTER SET utf8
(44−14)DBのマイグレーション
$neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2_plugin.ini upgrade head
(45)neutron-dhcpagent用の初期化
(45−1)NetworkManagerから実行されたdnsmasq以外のdnsmasqプロセスをkill
pidof NetworkManagerの出力がなにもなければ、「$sudo killall dnsmasq」
(45−2)iptablesのエントリを削除(clean_iptables in lib/nova)
# Delete rules
$sudo iptables -S -v | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-A" | sed "s/-A/-D/g" | awk '{print "sudo iptables",$0}' | bash
# Delete nat rules
$sudo iptables -S -v -t nat | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-A" | sed "s/-A/-D/g" | awk '{print "sudo iptables -t nat",$0}' | bash
# Delete chains
$sudo iptables -S -v | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-N" | sed "s/-N/-X/g" | awk '{print "sudo iptables",$0}' | bash
# Delete nat chains
$sudo iptables -S -v -t nat | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-N" | sed "s/-N/-X/g" | awk '{print "sudo iptables -t nat",$0}' | bash
(45−3)ホストOSのIPフォワーディングを有効にする
$sudo sysctl -w net.ipv4.ip_forward=1
Volume Service
(46)Cinderの初期設定
(46−1)Cinder用のDBの作成
$mysql
>DROP DATABASE IF EXISTS cinder
>CREATE DATABASE cinder CHARACTER SET utf8
(46−2)DBのマイグレーション
$cinder-manage db_sync
(46−3)Cinder用ボリュームグループの作成
(46−3−1)ボリュームグループのフィジカルボリュームにするための、イメージを作成
$truncate -s 20000 /opt/stack/data/cinder/stack-image-backing-file
(46−3−2)ループバックでバイスとimageファイルの結びつけ
$sudo losetup -f --show /opt/stack/data/cinder/stack-image-backing-file
(46−3−3)ボリュームグループの作成
$sudo vgcreate stack-volume <ループバックデバイス(例:/dev/loop0)>
(46−3−4)tgtで後で使用するディレクトリの作成
$sudo mkdir -p /opt/stack/data/cinder/volumes
(46−4)iscsiターゲットを削除
$sudo tgtadm --op show --mode target #→iscsiターゲットの確認
$sudo tgt-admin --delete <tgt-id> #→iscsiターゲットを削除
(46−5)もし、論理ボリュームが残っていたら削除
(46−6)キャッシュ用ディレクトリを作成
$sudo mkdir /var/cache/cinder/
$sudo chown <実行ユーザ> /var/cache/cinder
Nova
(47)Novaの初期設定
(47−1)Nova用のDBの作成
$mysql
>DROP DATABASE IF EXISTS nova
>CREATE DATABASE CHARACTER SET latin1 #=>なぜlatin1?
(47−2)DBのマイグレーション
$nova-manage db_sync
(47−3)キャッシュ用のディレクトリの作成
$sudo mkdir -p /var/cache/nova
$sudo chown <実行ユーザ> /var/cache/nova
(47−4)キーペアを保存するディレクトリの作成
$sudo mkdir -p /opt/stack/data/nova/keys
$sudo chown -R <実行ユーザ> /opt/stack/data/nova
※Devstackだとこのあたりで、neutronを使うためにnovaの設定ファイルを編集する(novaのセキュリティグループの無効化とか)
Openstakコンポーネントの起動〜起動〜
Glance
(48)glance-registryの起動
$glance-registry --config-file /etc/glance/glance-registry.conf
(49)glance-apiの起動
$glance-api --config-file /etc/glance/glance-api.conf
(50)glanceにイメージの登録(ここは、なんでもいいのでイメージを登録)
(50−1) tokenの取得
$keystone token-get
(50−2)イメージの登録(イメージは適当にさがしてください)
$glance --os-auth-token <token> --os-image-url http://<ip>:9292 image-create --name "test" --is-public True --disk-format=qcow2 --copy-from "<imageのurl>"
Nova
(51)nova-apiの起動
$nova-api
Neuron
(52)neutron-serverの起動
$neutron-server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2_plugin.ini
(53)neutron-l2-agentの起動(neutron-openvswitch-agent)
$neutron-openvswitch-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2_plugin.ini
(54)neutron-dhcp-agentの起動
$neutron-dhcp-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/dhcp_agent.ini
(55)neutron-l3-agentの起動
$neutron-l3-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/l3_plugin.ini
(56)neutron-metadata-agentの起動
$neutron-metadata-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/metadata_agent.ini
(57)初期ネットワークの作成(demoテナントのネットワークとか)
(57−1)デモテナントのプライベートネットワーク作成
$openstack project list #→demoテナントのidをメモ
$neutron net-create --tenant-id <tenant-id(demo)> "private"
(57−2)デモテナントのプライベートサブネットの作成
$neutron subnet-create --tenant-id <tenant-id(demo)> --ip_version 4 --gateway 192.168.0.1 --name "private-subnet" <net-id(57-1で作ったやつ)> "192.168.0.0/24"
(57−3)デモテナントのルータの作成
$neutron router-create --tenant-id <tenant-id(demo)>
(57−4)デモテナントのルータを"private-subnet"サブネットに接続
$neutron router-interface-add <router-id(57-3で作ったやつ)> <subnet-id(57-2で作ったやつ)>
(57−5)外部ネットワークの作成
$neutron net-create "public" --router:external=True
(57−6)外部ネットワークのサブネットの作成
$neutron subnet-create --ip_version 4 --gateway 172.16.0.1 --name "public-subnet" <net-id(57-5で作ったやつ)> "172.16.0.0/24" --enable_dhcp=False
(57−7)デモテナントのルータを外部ネットワークにつなぐ
$neutron router-gateway-set <router-id(57-3で作ったやつ)> <net-id(57-7で作ったやつ)>
(57−8)ホストのbr-exインターフェースに57-6のgatewayに指定したipアドレスを設定
$sudo ip addr add 172.16.0.1/24 dev br-ex
(57−9)br-exインターフェースをアップ
$sudo ip link set br-ex up
(57−10)デモテナントのprivateネットワークへのrouteをホストに追加
$sudo route add -net 192.168.0.0/24 gw 172.16.0.1
Nova
(58)nova-computeの起動
$sg libvirtd nova-compute --config-file /etc/nova/nova.conf
(59)nova-conductorの起動
$nova-conductor --config-file /etc/nova/nova.conf
(60)nova-schedulerの起動
$nova-scheduler --config-file /etc/nova/nova.conf
(61)nova-novncproxyの起動
$nova-novncproxy --config-file /etc/nova/nova.conf --web /opt/stack/noVNC
(62)nova-xvpvncproxyの起動
$nova-xvpvncproxy --config-file /etc/nova/nova.conf
(63)nova-consoleauthの起動
$nova-consoleauth --config-file /etc/nova/nova.conf
Cinder
(64)/opt/stack/data/cinder/volumesのシンボリックリンクを/etc/tgt/stack.dに置く
$sudo ln -sf /opt/stack/data/cinder/volumes /etc/tgt/stack.d
(65)tgt用の設定ファイルを作成
$echo "include /etc/tgt/stack.d/*" | sudo tee -a /etc/tgt/targets.conf
(66)tgtサービスの再起動
$sudo service tgt restart
(67)tgtの設定
$sudo tgtadm --mode system --op update --name debug --value on
(68)cinder-apiの起動
$cinder-api --config-file /etc/cinder/cinder.conf
(69)cinder-schedulerの起動
$cinder-scheduler --config-file /etc/cinder/cinder.conf
(70)cinder-backupの起動
$cinder-backup --config-file /etc/cinder/cinder.conf
(71)cinder-volumeの起動
$cinder-volume --config-file /etc/cinder/cinder.conf
おめでとうございます。ここまで無事たどりついたらOpenstackが動いているはずです。
Devstackはどんなことをしているのか
はじめに
OpenStack (2枚目) Advent Calendar 2014/12/15です。
あまり書慣れていないのですが、がんばります。
この前、DevStackのソースを読んで、Devstackがやっていることを手作業で再現してみるということをやってみたので、Devstackが大体どんなことをやっているのか?を5つのポイントにしてまとめてみました。
また、付録としてdevstackに沿って手作業でインストールしたときの手順書を掲載します。興味ある方はご覧ください
Devstackのソースを読むことのすすめ
devstackを普段使っている方、使いたいと思ってる方はざっとでいいので、一度devstackのスクリプトを読むことをオススメします(特に初級〜中級技術者の人)理由としては、下記の点があげられます。
- openstackがどういう過程を踏んで、構築されるかが分かる
- 手作業でOpenstackをインストールできるようになる
- ./stack.shで失敗したときに、その原因の推測が容易にできるようになる
- シェルスクリプトに大分なれることができる
本題、Devstackが大体どんなことをしているのか
1. Openstackに必要なパッケージのインストール
devstack/files/apts 配下に、各コンポーネントの名前(一部プロセス名)のファイルがあり、その中に、必要なパッケージファイルが羅列されています。 Devstackは、ENABLED_SERVICES で指定されているコンポーネントに必要なパッケージファイルを devstack/files/apts 配下のファイルより読み取り、apt-get等でインストールします
2. pipのインストールと、特定のライブラリをあらかじめインストール
pipは、pythonのパッケージ関連システムです。Openstackはソースコードを取得して、pipでローカルインストールします。
pipのインストール
$curl -o get-pip.py https://bootstrap.pypa.io/get-pip.py
$sudo -E python get-pip.py
prettytableとhttplib2というライブラリは、バージョンの指定があるようなので、先にインストール
$sudo pip install "prettytable=0.7.2"
$sudo pip install "httplib2=0.8"
3. ここからが、肝心のOpenstackコンポーネントのインストール
keystoneとかをインストールする前に共通コンポーネントをインストールする必要がある。
その中でも、「requirements」「pbr」2つの共通コンポーネントは一番最初にインストールする。
3-1. openstack/requirementsコンポーネントのインストール
requirementsコンポーネントは、
各コンポーネントのrequirements.txt
をチェックしrequirementsコンポーネントのglobal-requirements.txt
に定義されていないライブラリはないか?
各コンポーネントのrequirements.txt
で定義されているライブラリのバージョンはglobal-requirements.txt
より古くないか?
をチェックしてくれるもの。All in One構成を想定して各コンポーネントのライブラリ同士が悪さをしないようにするものらしい。(バージョンの違いとか)
特にインストールとかはせず、checkoutするだけ
$ git clone git://git.openstack.org/openstack/requirements.git stable/juno
3-2. openstack-dev/pbrコンポーネントのインストール
pbrコンポーネントは、
インストールオプションをsetup.cfgに書いて、setuptoolsでインストールするときにsetupメソッドをフックしてその、オプションを適用してくれるらしい。
インストールは下記の手順
$git clone git://git.openstack.org/openstack-dev/pbr.git
$cd /opt/stack/requirements
$./update.py /opt/stack/pbr #=>requirements.txtのチェックをしてくれる
$sudo pip install /opt/stack/pbr
3-3. その他のコンポーネントのインストール
その他の共通コンポーネント(openstack/oslo.config , openstack/oslo.messaging など)やkeystone,novaなどのコンポーネントのインストール
どのコンポーネントも手順は、3-2と同じ
gitでcheckout
update.py で requirements.txtをチェック(openstack/requirements)
pip install
4. 設定ファイルの編集、起動
最後に、各コンポーネントに関する設定ファイルの編集。
多分devstackのスクリプトを読むのが一番めんどくさいのがここ。というのも、devstackでは結構いろんな設定をすることができてそれを柔軟に対応するために、
~~~~が設定されてたら、AとBとCという設定ファイルに*******を追加して、Dという設定ファイルを追加で作成する
みたいなことがたくさん書かれているためである
5. 各クライアントツールを使って初期データの投入
5-1. keystone
- 各テナントの作成「admin,demo,service,invisible_to_admin」
- 各ユーザの作成「admin,demo」「nova,glance,neutron,cinder」
- 各ロールの作成「admin,Member,anotherrole,ResellerAdmin,service」
- 各ユーザとテナントに対してロールを設定する(下記に表を示す)
- サービスカタログとエンドポイントの登録
ユーザとロールの対応表(参考)
ユーザ | テナント | ロール |
---|---|---|
admin | admin | admin |
admin | demo | admin |
demo | demo | Member,anotherrole |
demo | invisible_to_admin | Member |
nova | service | admin |
glance | service | service |
neutron | service | admin |
cinder | service | admin |
→各コンポーネントのユーザは、serviceテナントに所属させる必要がある
5-2. glance
- cirrosイメージの登録
5-3. neutron
- デモテナント用のプライベートネットワーク、サブネットの作成(dhcp有効)
- 外部ネットワーク、サブネットの作成(dhcp無効)
- デモテナント用のルータの作成
- デモテナント用のルータのインターフェスの作成(プライベートネットワーク)
- デモテナント用のルータにgatewayの設定(外部ネットワーク)
→外部ネットワークでは、dhcpが無効になっていることに注意。つまりadminテナントでインスタンスを作って外部ネットワークに直接接続しても、ipが降ってこないのでssh等でアクセスすることができない。
→あと、devstackではデモテナントのプライベートネットワークにホスト(OpenstackをインストールしたPC)上からアクセスできるように、 下記の二つを実施している
- br-exインターフェースにIPアドレスを振って(ip addr add
dev br-ex) - routeを追加してる(ip route add -net
gw <デモテナントのgw側のIFのアドレス>)
6.インストールは終了、あとは遊ぶだけ!
まとめ
今回、devstackがどんなことをしているのか5つのポイントにしてまとめてみましたが、ここでは、設定ファイルの編集については具体的には触れていません。
というのもopenstackの使う機能によって、作る設定ファイル、内容がまったく違うからです。devstackでは、それらに対応するためコードが複雑化しているように見えます。私はこれらの背景より、devstackでどのように設定ファイルを編集しているかを知ることはあまり意味がないと考えています。なのでここでは4ステップ目に「設定ファイルの編集、起動」とだけ記しています。
この後に、Devstackが行っていることを手作業で再現したときの手順メモを付録(別日記)として載せますので、もう少しdevstackがどんなことをしているかを知りたい方、手作業でインストールしてみたい方は参考にしてみてください。