OpenStackの仮想ネットワーク管理機能「Quantum」の基本的な設定

Quantum

OpenStack 2012.2(「Folsom」)で新たに追加された新コンポーネント「Quantum」は、クラウド環境内での仮想ネットワーク作成や管理を行うためのサービスだ。柔軟に仮想ネットワークを作成でき、またネットワーク仮想化に対応したハードウェアとの連携機能も搭載している。今回はこのQuantumの導入方法や、シンプルな仮想ネットワーク環境の構築方法について解説する。

OpenFlowにも対応、物理ネットワーク上に仮想ネットワークを柔軟に構築できる

最近のクラウド環境では、マシンだけでなくネットワークについても仮想化が行われている。たとえば仮想マシンをユーザーごとに独立したネットワークに接続したり、仮想マシンに割り当てられたグローバルIPアドレスを動的に変更する、といった機能などは仮想ネットワークの機能を利用して実現されている。クラウド環境を構築するソフトウェアであるOpenStackでもこのような機能の実装が進んでおり、2012年にリリースされたOpenStack 2012.2(「Folsom」)では仮想ネットワーク機能を提供するための独立したコンポーネント「Quantum」が新たに追加されている。

Quantumは、ソフトウェアで柔軟に構成を変更できるネットワークの構築を目的として開発されたコンポーネントだ。ユーザーからの操作によるプライベートネットワークの作成やネットワークへの仮想マシンの接続、ネットワーク同士の仮想ルーターでの接続、などの機能を提供している。QuantumもOpenStackのほかのコンポーネントと同様にプラグイン構造を取っており、ネットワークを操作する部分はプラグインとしてQuantum本体から切り離されている。Linuxのブリッジ機能(LinuxBridge)を利用して仮想ネットワークを作成するものや仮想スイッチ「Open vSwitch」を利用するもの、OpenFlowを利用するもの、Ciscoのスイッチを利用するものといったプラグインが提供されており、さまざまな構成が実現できる。

Webブラウザ経由でアクセスできるGUI管理コンソール「OpenStack Dashboard(Horizon)」との連携機能もあり、GUIによる仮想ネットワークの管理も可能だ(図1)。

図1 OpenStack Dashboardからのネットワーク管理も可能だ
図1 OpenStack Dashboardからのネットワーク管理も可能だ

Quantumを利用した仮想ネットワーク構成の概念

Quantumでは仮想ネットワークや仮想ルーター、仮想ポートを使い、さまざまなネットワーク構成を仮想的に実現できる。図2はQuantumを使って作成した仮想ネットワーク構成の一例だ。図中の「テナント」は仮想マシンや仮想ネットワークなどの管理単位で、OpenStackのユーザーにはテナントごとにアクセス権限を割り当てることができる。ユーザーは権限のないテナント内の仮想マシンや仮想ネットワークについては操作・閲覧できない。これにより、1つのOpenStack環境内に複数のユーザーを収容できる仕組みになっている。

図2 Quantumを利用して構築した仮想ネットワークの例
図2 Quantumを利用して構築した仮想ネットワークの例

1つのテナント内には複数の仮想ネットワークを作成でき、仮想マシンは複数の仮想ネットワークに接続可能だ。仮想マシンと仮想ネットワークを接続すると仮想ネットワーク側に「ポート」と呼ばれる仮想インターフェイスが作成され、IPアドレスが割り当てられる。このとき、仮想マシンの仮想NICには対応するポートに付与されたIPアドレスを割り当てる必要がある。また、仮想ネットワークから外部ネットワークにアクセスするには、仮想ルータを作成して外部ネットワークと仮想ネットワークを接続する必要がある。

仮想ルータには静的NATを行う機能があり、指定した外部IPアドレス(フローティングIPアドレスと呼ばれる)宛ての通信を、特定の仮想マシンに割り当てられたローカルIPアドレス宛てに変換することができる。この機能を利用することで、外部から仮想マシンに直接アクセスすることが可能になる。

Quantumのコンポーネント

Quantumは4つのコンポーネントから構成されている(表1)。

表1 Quantumのコンポーネント
名称 EPELでのサービス名 説明
Quantum Server quantum-server Quantum全体の管理や統制を行う
L3 Agent quantum-l3-agent L3レベルでのネットワーク設定を実行する
DHCP Agent quantum-dhcp-agent 仮想マシン向けのDHCPサーバーを提供する
Plugin Agent quantum-*-agent(*部分にはプラグイン名称が入る) 仮想ネットワークの作成・管理や仮想マシンと仮想ネットワークを接続するための設定を実行する

まずQuantum Serverは、ユーザーからの操作を受けてネットワーク構成を設定したり、各種設定管理などを行うサーバーだ。ユーザーはこのサーバーが提供するAPIを利用して各種操作を実行する。次のL3 Agentは、L3(TCP/IP)レベルでのネットワーク設定を実行するサービスだ。iptablesによるパケット転送ルールの設定や、ルーター設定などを行う。DHCP Agentは仮想マシンにIPアドレスを割り当てるためのDHCPサーバーを提供する。前述のとおり、仮想マシンのNICには仮想ポートに割り当てられたIPアドレスを割り当てる必要がある。DHCPエージェントは仮想マシンのMACアドレスをチェックし、対応するIPアドレスをDHCPで割り当てる処理を行う。最後のPlugin Agentは、プラグイン固有のネットワーク設定処理を行うサービスだ。

これらのサービスは、必ずしも1つのホスト(ノード)ですべてを実行させる必要はない。たとえば図3は、Quantumの各コンポーネントや関連コンポーネントの一般的な構成例だ。

図3 Quantumの各コンポーネントや関連コンポーネントの一般的な構成例
図3 Quantumの各コンポーネントや関連コンポーネントの一般的な構成例

ここでは制御用のサービスを稼働させる「制御ノード」上でQuantum Serverを稼働させ、外部ネットワークに接続されているインターフェイスを持つ「ネットワークノード」上でL3 AgentおよびDHCP Agent、Plugin Agentを稼働させている。いっぽう、nova-computeサービスを使って仮想マシンを稼働させる「計算ノード」上では、Plugin Agentを稼働させておく必要がある。これらのノード間は制御/管理用のネットワークで接続され、それぞれのサービスはこのネットワーク経由でサービス間の通信を行う。ネットワークノードと計算ノードは制御/管理用ネットワークとは異なるネットワークで接続され、このネットワーク経由で仮想マシンは通信を行う。仮想マシンが外部ネットワークと通信したい場合は、ネットワークノードを経由して行う仕組みだ。

制御ノードとネットワークノードをまとめて1つのノードとして実行させたり、データベースやメッセージサービスを別のホスト上で実行させる、といった構成も可能だ。このあたりは要件に応じて柔軟に変更できるようになっている。なお、この構成ではネットワークノードにNICが3つ必要となる点には注意が必要だ。NICが2つまでのさくらの専用サーバのようなサービスでは、構成を工夫する必要がある。

QuantumのインストールとLinuxBridgeを使った環境構築

それでは、Quantumのインストール手順と各種設定方法について紹介していこう。以下ではOS環境としてRed Hat Enterprise Linux互換のCentOS 6.3を利用し、またFedoraプロジェクトが公開しているパッケージリポジトリ「EPEL(Extra Packages for Enterprise Linux)」を利用してOpenStackのパッケージを入手している。EPELについてはさくらの専用サーバとOpenStackで作るプライベートクラウド記事でその導入方法や使い方を解説しているので、詳しくはそちらを参照してほしい。

利用するプラグインを選択する

Quantumを利用する際、まずはどのプラグインを利用するかを決めなければならない。EPELではQuantum本体とプラグインはそれぞれ別のパッケージとして配布されており、使用するプラグインを含むパッケージをインストールする必要がある。EPELで提供されているプラグインパッケージは表2の7つだ。

表2 EPELで提供されているプラグインパッケージ
パッケージ名 仮想ネットワーク構築に利用するバックエンド
openstack-quantum-cisco シスコ製ルーター
openstack-quantum-linuxbridge Linux標準のブリッジ機能やVLAN
openstack-quantum-metaplugin なし(複数のプラグインを利用する際に使用)
openstack-quantum-nec OpenFlowコントローラ
openstack-quantum-nicira nicira
openstack-quantum-openvswitch Open vSwitch
openstack-quantum-ryu Ryu

このうち、openstack-quantum-ciscoは専用のハードウェアが必要であり、またopenstack-quantum-necやopenstack-quantum-nicira、openstack-quantum-openvswitch、openstack-quantum-ryuは別途対応するソフトウェアやシステムが必要となる。そのため、今回はLinuxのブリッジ機能やVLANを使って仮想ネットワークを構築できるopenstack-quantum-linuxbridgeを使用する例を紹介する。

Quantum関連パッケージのインストール

EPELにおいて、Quantumの本体は「openstack-quantum」というパッケージで提供されている。制御ノードおよびネットワークノードにこれらのパッケージをインストールしておく。

# yum --enablerepo=epel install openstack-quantum

また、ネットワークノードおよび計算ノードにはopenstack-quantum-linuxbridgeパッケージをインストールしておく。

# yum --enablerepo=epel install openstack-quantum-linuxbridge

なお、今回使用したopenstack-quantumパッケージのバージョンは下記のとおりである。

# rpm -q openstack-quantum
openstack-quantum-2012.2.1-1.el6.noarch

サービスの作成

ほかのOpenStackサービスと同様、Quantum関連サービスを稼働させているホストの情報などをKeystoneのデータベースに登録しておく必要がある。今回はKeystoneを稼働させているホストで下記のように実行することで登録を実行した。

QUANTUM_HOST=<Quantum Serverをインストールしたホスト名>
REGION=<登録を行うリージョン名>
export SERVICE_TOKEN=<keystoneで設定したアクセストークン>
export SERVICE_ENDPOINT=http://localhost:35357/v2.0/

keystone service-create --name=quantum --type=network --description="Quantum Network Service"
SERVICE_ID=`keystone service-list | grep quantum | awk '{print $2}'`
keystone endpoint-create --region $REGION --service_id=$SERVICE_ID --publicurl "http://$QUANTUM_HOST:9696/" --adminurl "http://$QUANTUM_HOST:9696/" --internalurl "http://$QUANTUM_HOST:9696/"

ユーザーの作成

次に、QuantumがKeystoneへのアクセスに使用するquantumユーザーを作成する。Keystoneを稼働させているホスト上で下記のコマンドを実行することで作成を行う。

export SERVICE_TOKEN=<keystoneで設定したアクセストークン>
export SERVICE_ENDPOINT=http://localhost:35357/v2.0/
PASSWORD=作成するユーザーのパスワード

TENANT_ID=`keystone tenant-list | grep service | awk '{print $2}'`
ADMIN_ROLE=`keystone role-list | grep admin | awk '{print $2}'`
keystone user-create --tenant-id $TENANT_ID --name quantum --pass $PASSWORD
USER_ID=`keystone user-list | grep quantum | awk '{print $2}'`
keystone user-role-add --user-id $USER_ID --tenant-id $TENANT_ID --role-id $ADMIN_ROLE

制御ノードの設定:データベースの作成と設定ファイルの編集

Quantumの設定は、各ホスト上の/etc/quantumディレクトリ以下に配置された設定ファイルに記述されている。まず制御ノードでは、quantum.confおよびapi-paste.iniファイルの編集が必要だ。また、データベースの設定も必要となる。データベースとしてMySQLを利用している場合、データベースの設定にはquantum-server-setupコマンドが利用できる。

quantum-server-setupコマンドはデータベースおよびQuantumがデータベースへのアクセスに使用するユーザーの作成を行う。デフォルトでは「quantum」というユーザーが作成される。このときパスワードは「-q」オプションで指定できる。

# quantum-server-setup -q <設定するパスワード>
Please select a plugin from: linuxbridge openvswitch
Choice:
linuxbridge ←使用するプラグインを指定する
Quantum plugin: linuxbridge
Plugin: linuxbridge => Database: quantum_linux_bridge
Please enter the password for the 'root' MySQL user: ←MySQLのrootパスワードを入力する
Verified connectivity to MySQL.
Please enter network device for VLAN trunking:
eth0 ←内部ネットワークに接続されているネットワークインターフェイスを指定する
Would you like to update the nova configuration files? (y/n):
n ←自動的にnovaの設定ファイルを更新するかを指定する
Complete!

quantum-server-setupコマンドはデータベースの設定に加えて設定ファイルの変更も行うため、実行後は必ず設定ファイルを確認しておこう。また、quantum-server-setupコマンドはコマンドを実行したホスト上でMySQLサーバーが稼働していることを前提としている。別のホストでMySQLサーバーを実行している場合、そのホスト上でこのコマンドを実行する必要がある。

続いて、Quantumの全体に関連する設定が記述されたquantum.confを編集する。まず必要なのは、使用するプラグインを指定する「core_plugin」項目だ。今回はlinuxbridgeプラグインを使用するので、次のように指定する。

core_plugin = quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2

認証方法を指定する「auth_strategy」項目には「keystone」を指定しておく。

auth_strategy = keystone

また、Quantumでは「Network Namespace」という機能を利用することで仮想ネットワークにおけるIPアドレスの重複を許すことができるが、CentOS 6.3系では現状この機能がサポートされていないため、「allow_overlapping_ips」項目にFalseを指定してこれを無効化しておく。

allow_overlapping_ips = False

使用するメッセージングサービスおよびメッセージングサーバーの稼働ホスト、認証情報なども忘れずに設定しておく。たとえばRabbitMQを利用する場合、次の設定項目を追加しておく。

rpc_backend = quantum.openstack.common.rpc.impl_kombu
rabbit_host = <RabbitMQサーバーを稼働させているホスト名>
rabbit_port = <RabbitMQの稼働ポート>
rabbit_userid = <認証に使用するユーザー名>
rabbit_password = <認証に使用するパスワード>
rabbit_virtual_host = <使用するバーチャルホスト名>

これらを反映させた設定ファイルは以下のようになる。太字の部分が編集および確認が必要な項目だ。

[DEFAULT]
# Show more verbose log output (sets INFO log level output)
verbose = True

# Show debugging output in logs (sets DEBUG log level output)
debug = False

# Address to bind the API server
bind_host = 0.0.0.0

# Port the bind the API server to
bind_port = 9696

# Path to the extensions. Note that this can be a colon-separated list of
# paths. For example:
# api_extensions_path = extensions:/path/to/more/extensions:/even/more/extensions
# The __path__ of quantum.extensions is appended to this, so if your
# extensions are in there you don't need to specify them here
# api_extensions_path =

# Quantum plugin provider module
core_plugin = quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2

# Paste configuration file
api_paste_config = api-paste.ini

# The strategy to be used for auth.
# Supported values are 'keystone'(default), 'noauth'.
auth_strategy = keystone

# Base MAC address. The first 3 octets will remain unchanged. If the
# 4h octet is not 00, it will also used. The others will be
# randomly generated.
# 3 octet
# base_mac = fa:16:3e:00:00:00
# 4 octet
# base_mac = fa:16:3e:4f:00:00

# Maximum amount of retries to generate a unique MAC address
# mac_generation_retries = 16

# DHCP Lease duration (in seconds)
# dhcp_lease_duration = 120

# Enable or disable bulk create/update/delete operations
# allow_bulk = True
# Enable or disable overlapping IPs for subnets
# Attention: the following parameter MUST be set to False if Quantum is
# being used in conjunction with nova security groups and/or metadata service.
allow_overlapping_ips = False

# RPC configuration options. Defined in rpc __init__
# The messaging module to use, defaults to kombu.
rpc_backend = quantum.openstack.common.rpc.impl_kombu
# Size of RPC thread pool
# rpc_thread_pool_size = 64,
# Size of RPC connection pool
# rpc_conn_pool_size = 30
# Seconds to wait for a response from call or multicall
# rpc_response_timeout = 60
# Seconds to wait before a cast expires (TTL). Only supported by impl_zmq.
# rpc_cast_timeout = 30
# Modules of exceptions that are permitted to be recreated
# upon receiving exception data from an rpc call.
# allowed_rpc_exception_modules = quantum.openstack.common.exception, nova.exception
# AMQP exchange to connect to if using RabbitMQ or QPID
control_exchange = quantum

# If passed, use a fake RabbitMQ provider
# fake_rabbit = False

# Configuration options if sending notifications via kombu rpc (these are
# the defaults)
# SSL version to use (valid only if SSL enabled)
# kombu_ssl_version =
# SSL key file (valid only if SSL enabled)
# kombu_ssl_keyfile =
# SSL cert file (valid only if SSL enabled)
# kombu_ssl_certfile =
# SSL certification authority file (valid only if SSL enabled)'
# kombu_ssl_ca_certs =
# IP address of the RabbitMQ installation
rabbit_host = 192.168.100.20
# Password of the RabbitMQ server
rabbit_password = password
# Port where RabbitMQ server is running/listening
rabbit_port = 5672
# User ID used for RabbitMQ connections
rabbit_userid = nova
# Location of a virtual RabbitMQ installation.
rabbit_virtual_host = /nova
# Maximum retries with trying to connect to RabbitMQ
# (the default of 0 implies an infinite retry count)
# rabbit_max_retries = 0
# RabbitMQ connection retry interval
# rabbit_retry_interval = 1

# QPID
# rpc_backend=quantum.openstack.common.rpc.impl_qpid
# Qpid broker hostname
# qpid_hostname = localhost
# Qpid broker port
# qpid_port = 5672
# Username for qpid connection
# qpid_username = ''
# Password for qpid connection
# qpid_password = ''
# Space separated list of SASL mechanisms to use for auth
# qpid_sasl_mechanisms = ''
# Seconds between connection keepalive heartbeats
# qpid_heartbeat = 60
# Transport to use, either 'tcp' or 'ssl'
# qpid_protocol = tcp
# Disable Nagle algorithm
# qpid_tcp_nodelay = True

# ZMQ
# rpc_backend=quantum.openstack.common.rpc.impl_zmq
# ZeroMQ bind address. Should be a wildcard (*), an ethernet interface, or IP.
# The "host" option should point or resolve to this address.
# rpc_zmq_bind_address = *

# ============ Notification System Options =====================

# Notifications can be sent when network/subnet/port are create, updated or deleted.
# There are four methods of sending notifications, logging (via the
# log_file directive), rpc (via a message queue),
# noop (no notifications sent, the default) or list of them

# Defined in notifier api
notification_driver = quantum.openstack.common.notifier.list_notifier
# default_notification_level = INFO
# myhost = myhost.com
# default_publisher_id = $myhost
# Defined in rabbit_notifier for rpc way
# notification_topics = notifications

# Defined in list_notifier
list_notifier_drivers = quantum.openstack.common.notifier.rabbit_notifier

[QUOTAS]
# resource name(s) that are supported in quota features
# quota_items = network,subnet,port

# default number of resource allowed per tenant, minus for unlimited
# default_quota = -1

# number of networks allowed per tenant, and minus means unlimited
# quota_network = 10

# number of subnets allowed per tenant, and minus means unlimited
# quota_subnet = 10

# number of ports allowed per tenant, and minus means unlimited
# quota_port = 50

# default driver to use for quota checks
# quota_driver = quantum.quota.ConfDriver

api-paste.iniファイルにはkeystoneへのアクセスに使用する情報を記述しておく。具体的には、以下の項目について設定が必要だ。

auth_host = <keystoneが稼働しているホスト名>
auth_port = <keystoneが稼働しているポート番号。デフォルトは35357>
auth_protocol = <keystoneへのアクセスに利用するプロトコル。デフォルトはhttp>
admin_tenant_name = <管理用テナント名>
admin_user = <使用するユーザー名>
admin_password = <使用するパスワード>

これらを反映させた設定ファイルの例は以下のようになる。

[composite:quantum]
use = egg:Paste#urlmap
/: quantumversions
/v2.0: quantumapi_v2_0

[composite:quantumapi_v2_0]
use = call:quantum.auth:pipeline_factory
noauth = extensions quantumapiapp_v2_0
keystone = authtoken keystonecontext extensions quantumapiapp_v2_0

[filter:keystonecontext]
paste.filter_factory = quantum.auth:QuantumKeystoneContext.factory

[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
auth_host = 192.168.100.20
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = quantum
admin_password = quantum

[filter:extensions]
paste.filter_factory = quantum.extensions.extensions:plugin_aware_extension_middleware_factory

[app:quantumversions]
paste.app_factory = quantum.api.versions:Versions.factory

[app:quantumapiapp_v2_0]
paste.app_factory = quantum.api.v2.router:APIRouter.factory

以上の設定が完了したら、最後にserviceコマンドでquantum-serverを起動させておく。

# service quantum-server start

なお、quantum-serverはTCPの9696番ポートで待ち受けを行う。ほかのノードからこのポートにアクセスできるようファイアウォールを設定しておこう。

ネットワークノードの設定

ネットワークノードでは、制御ノードで設定したquantum.confおよびapi-paste.iniファイルの編集に加え、以下の設定が必要だ。

  • L3 Agentの設定
  • DHCP Agentの設定
  • プラグインの設定
  • sudoersファイルの設定
  • ブリッジ関連のカーネルパラメータ変更
  • dnsmasqパッケージのバージョン確認とアップデート

なお、L3 AgentやDHCP Agent、プラグインの設定作業はOS_USERNAMEやOS_PASSWORD、OS_AUTH_URL、OS_TENANT_NAMEといった環境変数を定義した状態で実行する必要がある。以下のようにこれらを定義しておこう。

$ export OS_USERNAME=<管理用ユーザー>
$ export OS_TENANT_NAME=<管理用のテナント名>
$ export OS_PASSWORD=<管理用ユーザーのパスワード>
$ export OS_AUTH_URL=http://<keystoneが稼働しているホスト名>:5000/v2.0/

さて、まずはL3 Agentの設定だが、これはquantum-l3-setupコマンドを実行するだけで良い。

# quantum-l3-setup
Please select a plugin from: linuxbridge openvswitch
Choice:
linuxbridge ←使用するプラグインを指定する
Quantum plugin: linuxbridge
Configuration updates complete!

続いてDHCP Agentの設定だが、こちらはquantum-dhcp-setupコマンドで行える。

# quantum-dhcp-setup
Please select a plugin from: linuxbridge openvswitch
Choice:
linuxbridge ←使用するプラグインを指定する
Quantum plugin: linuxbridge
Please enter the Quantum hostname:
192.168.100.20 ←AMQPサーバーが稼働しているホスト名を指定する
Configuration updates complete!

quantum-dhcp-setupコマンドはquantum.confの設定ファイルを書き換えるため、コマンド実行後にquantum.confおよびapi-paste.iniファイルを制御ノードで設定したものと同じになっているか確認しておこう。

Plugin Agentであるlinuxbridge-agentの設定については、/etc/quantum/linuxbridge/linuxbridge_conf.iniというファイルに記述されている。ここで設定が必要なのは「tenant_network_type」および「sql_connection」、「network_vlan_ranges」、「physical_interface_mappings」の4つだ。

まずtenant_network_typeだが、こちらは通常は「vlan」を指定する。

tenant_network_type = vlan

sql_connectionでは以下の形式で使用するデータベースの情報を記述する。

sql_connection = <プロトコル>//<ユーザー名>:<パスワード>@<ホスト名>:<ポート番号>/<データベース名>

たとえばデータベースにMySQLを使用し、ユーザー名およびパスワードが「quantum」、データベースのホスト名が「192.168.100.20」、データベース名が「quantum_linux_bridge」(quantum-server-setupコマンドがデフォルトで作成するデータベース名)、だった場合、下記のようになる。

sql_connection = mysql://quantum:[email protected]:3306/quantum_linux_bridge

「physical_interface_mappings」は、仮想ネットワークの作成に利用するネットワークインターフェイスの指定と、それを参照するための名称の定義を行うものだ。たとえばeth0を使って仮想ネットワークを作成し、そのネットワークを「physnet1」という名称で参照する場合、次のようになる。

physical_interface_mappings = physnet1:eth0

eth0以外のネットワークインターフェイスを仮想ネットワークの作成に使用する場合、eth0の部分を適切なものに置き換えておこう。

「network_vlan_ranges」は、使用するVLANのタグの範囲を指定するものだ。たとえば先に定義したphysnet1でVLANのタグとして1000から2999の間の数を利用する場合、以下のようになる。

network_vlan_ranges = physnet1:1000:2999

通常この値は適当なもので問題ないが、利用できるVLANのタグに制限がある場合は変更が必要だ。

続いて、Quantum関連サービスを実行するquantumユーザーがroot権限でコマンドを実行できるよう、/etc/sudoersファイルに下記を追加しておく。

quantum ALL=(ALL) NOPASSWD:ALL

カーネルパラメータの設定は、ネットワークノードにおいてiptablesによるパケットの転送を正しく行うために必要だ。Linuxカーネルでは、bridge-nf-call-iptablesおよびbridge-nf-call-ip6tables、bridge-nf-call-arptablesといったパラメータで、ブリッジデバイスを通過するTCP/IPパケットについてiptablesによるフィルタリングを適用するかどうかを指定できる。Quantumを利用する場合、これらの値が0になっている(フィルタリングを適用しない)設定となっている必要がある。

これらの値は、次のようにcatコマンドを実行することで確認できる。

# cat /proc/sys/net/bridge/bridge-nf-call-iptables
0
# cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
0
# cat /proc/sys/net/bridge/bridge-nf-call-arptables
0

もし1に設定されている項目があった場合、以下のようにして「0」に変更しておこう。

# echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
# echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
# echo 0 > /proc/sys/net/bridge/bridge-nf-call-arptables

また、念のためIPフォワーディングが有効になっていることも確認しておく。

# cat /proc/sys/net/ipv4/ip_forward
1

なお、これらのデフォルト値は/etc/sysctl.conf内に記述されているのだが、Red Hat Enterprise Linux 6.3(およびその互換環境)ではbridge-nf-call-iptablesおよびbridge-nf-call-ip6tables、bridge-nf-call-arptablesの値が正しく反映されないというバグが確認されている。もし/etc/sysctl.conf内でこれらの値を0に設定しているにも関わらずデフォルト値が1になっている場合は、下記を/etc/rc.localファイルに記述しておくことで対処できるとのことだ。

echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-arptables

これらに加え、DHCP Agentが利用するdnsmasqパッケージのバージョンの確認も必要だ。記事作成時点でCentOS 6.3で提供されているdnsmasqのバージョンは2.48なのだが、DHCP Agentはdnsmasq 2.59以上を必要とする。そのため、より新しいバージョンのdnsmasqを別途インストールする必要がある。今回は、DAGリポジトリで提供されているdnsmasqパッケージをインストールすることにする。DAGリポジトリ(x86_64向け)もしくはDAGリポジトリ(x86向け)からdnsmasqパッケージをダウンロードしてインストールしておこう。たとえばdnsmasq-2.63-1.el6.rfx.x86_64.rpmというパッケージをインストールする場合、以下のようにすれば良い。

rpm -Uvh http://apt.sw.be/redhat/el6/en/x86_64/extras/RPMS/dnsmasq-2.63-1.el6.rfx.x86_64.rpm

以上の設定がすべて完了したら、serviceコマンドでサービスを稼働させておく。

# service quantum-linuxbridge-agent start
# service quantum-l3-agent start
# service quantum-dhcp-agent start

設定ファイルの編集:計算ノード

ネットワークノードでは、制御ノードで設定したquantum.confおよびapi-paste.iniファイルの編集に加え、以下の設定が必要だ。

  • プラグインの設定
  • nova-computeの設定
  • sudoersファイルの設定
  • libvertdの設定

プラグインの設定は、ネットワークノードの設定と同じく/linuxbridge/linuxbridge_conf.iniのみ編集が必要だ。これらは原則としてネットワークノードで設定したものと同じで構わない。

続くnova-computeの設定だが、設定ファイルである/etc/nova.confの修正が必要だ。まず、「network_manager」項目をコメントアウトしておく。

# network_manager = nova.network.quantum.manager.QuantumManager

次に、表3の項目について設定を変更しておく。

表3 nova.confで値を変更/追加すべき個所
設定項目
network_api_class nova.network.quantumv2.api.API
quantum_admin_username <管理用のユーザー名>
quantum_admin_password <管理用ユーザーのパスワード>
quantum_admin_auth_url http://<Keystoneが稼働しているホスト名>:5000/v2.0/
quantum_auth_strategy Keystone
quantum_admin_tenant_name <管理用テナント名>
quantum_url http://<Quantum Serverが稼働しているホスト名>:9696/
libvirt_vif_driver nova.virt.libvirt.vif.QuantumLinuxBridgeVIFDriver

また、quantumユーザーがroot権限でコマンドを実行できるよう、ネットワークノードの場合と同様/etc/sudoersファイルに下記を追加しておく。

quantum ALL=(ALL) NOPASSWD:ALL

仮想化ソフトウェアのフロントエンドにlibvirtを利用している場合、その設定ファイルについても変更が必要だ。変更が必要なのは/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/hpet",」の後に「"/dev/net/tun",」を追加する。この個所は最終的に以下のようになる。

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",
]

さらに、下記の太字の行についてもコメントアウトを外して有効にしておこう。

# The user ID for QEMU processes run by the system instance.
#user = "root"

# The group ID for QEMU processes run by the system instance.
#group = "root"

最後に、「clear_emulator_capabilities」を「0」に設定しておく。

# If clear_emulator_capabilities is enabled, libvirt will drop all
# privileged capabilities of the QEmu/KVM emulator. This is enabled by
# default.
#
# Warning: Disabling this option means that a compromised guest can
# exploit the privileges and possibly do damage to the host.
#
# clear_emulator_capabilities = 1
clear_emulator_capabilities = 0 ←この行を追加する

以上で設定は完了だ。libvirtdサービスおよびopenstack-nova-computeサービスを再起動して設定を反映させるとともに、プラグイン(quantum-linuxbridge-agent)サービスを稼働させておこう。

# service openstack-nova-compute restart
# service libvirtd restart
# service quantum-linuxbridge-agent start

仮想マシンが利用するネットワークの設定を行う

最後に、仮想マシンが利用するネットワークの設定についてその流れを説明しておこう。目的に応じて設定内容は変わるが、今回は図4のように仮想マシンが直接外部ネットワークに接続されたシンプルな構成を作成する例を紹介しよう。

図4 今回作成するネットワーク構成例
図4 今回作成するネットワーク構成例

ここでは、203.0.113.0/24という外部と接続できるネットワーク(外部ネットワーク)があり、ネットワークノードに203.0.113.10、計算ノードに203.0.113.11というIPアドレスが付加されているものとする。ゲートウェイは203.0.113.1で、仮想マシンには203.0.113.100から203.0.113.200の範囲のIPアドレスを割り当てることとする。この場合、各仮想マシンには外部ネットワークのIPアドレスが割り当てられ、ゲートウェイ経由で外部から仮想マシンにアクセスが可能となっている。

ネットワークの作成手順

仮想ネットワークの構築作業は制御ノード上で実行する。このとき、Keystone用の認証情報を環境変数に設定しておく必要がある。以下のようにexportコマンドを実行して設定を行っておこう。

$ export OS_USERNAME=<管理用ユーザー>
$ export OS_TENANT_NAME=<管理用のテナント名>
$ export OS_PASSWORD=<管理用ユーザーのパスワード>
$ export OS_AUTH_URL=http://<keystoneが稼働しているホスト名>:5000/v2.0/

また、以下では対象とするテナントをTENANT_ID変数に設定したうえでコマンドを実行している。たとえばテナント名が「Default」だった場合、以下のようにこの変数を設定しておこう。

TENANT_ID=Default

ネットワークを作成するには、quantum net-createコマンドを使用する。まずはこのコマンドを使用し、「net1」という名前のネットワークを作成する。このネットワークは物理デバイスとしてeth0に対応するphysnet1を使用し、ネットワークタイプにはVLANを使わない「flat」を指定している。また、「--shared」オプションは、ネットワークを共有可能にするオプションだ。

$ quantum net-create --tenant-id $TENANT_ID net1 --shared --provider:network_type flat --provider:physical_network physnet1
Created a new network:
+---------------------------+--------------------------------------+
| Field | Value |
+---------------------------+--------------------------------------+
| admin_state_up | True |
| id | 0a3e1b6f-15a8-46dd-afad-937bdeff2cd9 |
| name | net1 |
| provider:network_type | flat |
| provider:physical_network | physnet1 |
| provider:segmentation_id | |
| router:external | False |
| shared | True |
| status | ACTIVE |
| subnets | |
| tenant_id | Default |
+---------------------------+--------------------------------------+

続いて、作成したネットワーク(net1)に対しquantum subnet-createコマンドでサブネットを割り当てる。以下ではサーバーに対して割り当てられている「203.0.113.0/24」というネットワークを利用するよう設定している。また「--allocation-pool」オプションで203.0.113.100から203.0.113.200の範囲のIPアドレスを仮想ネットワーク/仮想マシンで使用するように指定し、さらに「--gateway」オプションでゲートウェイのIPアドレスを「203.0.113.1」に指定している。

$ quantum subnet-create --tenant-id $TENANT_ID --allocation-pool start=203.0.113.100,end=203.0.113.200 --gateway 203.0.113.1 net1 203.0.113.0/24
Created a new subnet:
+------------------+------------------------------------------------------+
| Field | Value |
+------------------+------------------------------------------------------+
| allocation_pools | {"start": "203.0.113.100", "end": "203.0.113.200"} |
| cidr | 203.0.113./24 |
| dns_nameservers | |
| enable_dhcp | True |
| gateway_ip | 203.0.113.1 |
| host_routes | |
| id | 40b33548-40c6-4ff7-8f42-8c592165f054 |
| ip_version | 4 |
| name | |
| network_id | 0a3e1b6f-15a8-46dd-afad-937bdeff2cd9 |
| tenant_id | Default |
+------------------+------------------------------------------------------+

作成したネットワークは、quantum net-listコマンドで確認できる。

# quantum net-list
+--------------------------------------+------+--------------------------------------+
| id | name | subnets |
+--------------------------------------+------+--------------------------------------+
| 0a3e1b6f-15a8-46dd-afad-937bdeff2cd9 | net1 | 40b33548-40c6-4ff7-8f42-8c592165f054 |
+--------------------------------------+------+--------------------------------------+

仮想ネットワークの設定が完了したら、実際に仮想マシンを立ち上げてみよう。仮想マシンの立ち上げはnova bootコマンドを利用する。このとき、「--nic -net-id=<仮想ネットワークのID>」オプションで接続する仮想ネットワークを指定する。

$ nova boot --flavor 2 --image 08ec2db3-99ba-4da2-b371-19f741c37b2a --key_name mykey --security_group default --nic net-id=0a3e1b6f-15a8-46dd-afad-937bdeff2cd9 test01
+-------------------------------------+--------------------------------------+
| Property | Value |
+-------------------------------------+--------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-SRV-ATTR:host | None |
| OS-EXT-SRV-ATTR:hypervisor_hostname | None |
| OS-EXT-SRV-ATTR:instance_name | instance-00000052 |
| OS-EXT-STS:power_state | 0 |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| accessIPv4 | |
| accessIPv6 | |
| adminPass | 7M93LDfPNrza |
| config_drive | |
| created | 2013-02-21T10:17:37Z |
| flavor | m1.small |
| hostId | |
| id | 3962778c-2841-435d-8766-b6c2013d743d |
| image | cirros-0.3.0-x86_64 |
| key_name | mykey |
| metadata | {} |
| name | test01 |
| progress | 0 |
| security_groups | [{u'name': u'default'}] |
| status | BUILD |
| tenant_id | eb7380b7990d4eb8a27bc9a1b80bf386 |
| updated | 2013-02-21T10:17:37Z |
| user_id | 4537dd6a5b7e4609979a7fe26856c522 |
+-------------------------------------+--------------------------------------+

作成された仮想マシンをnova listコマンドで確認すると、net1という仮想ネットワークに接続され、203.0.113.101というIPアドレスが割り当てられていることが分かる。このIPアドレスを利用し、この仮想マシンに外部ネットワークからアクセスすることが可能だ。

# nova list
+--------------------------------------+--------+--------+---------------------+
| ID | Name | Status | Networks |
+--------------------------------------+--------+--------+---------------------+
| 3962778c-2841-435d-8766-b6c2013d743d | test01 | ACTIVE | net1=203.0.113.101 |
+--------------------------------------+--------+--------+---------------------+

なお、仮想マシンには通常DHCPを使ってIPアドレス割り当てられるのだが、筆者の環境では起動のタイミングによっては正しくIPアドレスが割り当てられない場合があった。その場合、仮想マシンを再起動する、もしくは仮想マシン内で再度DHCPによるIPアドレスの取得を実行させることで正しくIPアドレスを取得できた。

目的に応じて正しいネットワーク構成を

以上の手順で、Quantumを利用してネットワーク設定を行い、外部ネットワークから接続できる仮想マシンを作成することができた。ただ、この構成では仮想ネットワークによって実現できる動的なネットワーク作成や構成変更などの恩恵を受けることができない。また、この構成では仮想マシンが外部ネットワークに直接接続されているため、OpenStackが提供するメタデータサービスに仮想マシンからはそのままではアクセスできない。OpenStackのドキュメントにはより柔軟なネットワーク構成例がいくつか紹介されているので、そちらを参考にして目的に応じた環境を構築すると良いだろう。