Floating IP で Nova と Quantum の違いをみる

全然使っていなかった、このページですが、OpenStack ユーザ会で http://openstack.jp/adventcalendar-2012.html:アドベントカレンダー をやろうということになったので、新しく作るのも何なので、このページを使って書いてみます。

Folsom リリースから Quantum が正式リリースになりました。開発者の一人としてうれしく思います。

Nova には floating IP と security group というネットワーク系の機能があり、当然ながら、これらも Quantum の一部になって行きます。Folsom リリースでは開発する機能が盛り沢山だったせいか、
floating IP を含む L3 機能の実装は遅れに遅れて、Folsom RC1 (release candidate) の期間中にようやく実装できました。 security group にいたっては時間切れで Grizzly に見送りになってしまいました。

前置きが長くなってしまいましたが、Nova と Quantum で Floating IP と Security Gruop がどう違うかみたいと思います。

あんまりおもしろいことは書けないので、複数 NIC で floating IP を使う場合には、Nova の Floating IP は使えないので、Quantum の Floating IP を直接使いましょう、ということを実験してみたいと思います。

Nova の Floating IP

通常 VM を起動すると Private IP アドレス (fixed_ip) が割り当てられるので、外からアクセスできません。そこで、Public IP アドレスを割り当てて、外部からのアクセスがあった場合は DNAT を行って、VM まで辿りつきます。この Public IP アドレスが floating IP です。Private 側のアドレスは
VM を起動したら変わらないので fixed (固定) IP、外側のアドレスはどの VM に割り当てるかを決めたり、後で割り当て先の VM を変更できるので、floating (浮いた) IP ですね。 AWS では Elastic IP ですね。

Quantum になって、複数の VNIC を持った VM が起動しやすくなりました。複数 NIC を持った環境で Floating IP を使うとどうなるかを見てみます。

ネットワークを3つ作っておいて、とりあえず VM を3個起動しています。こんな感じの構成です。

環境は Folsom Update1 (2012.2.1) の Nova + Quantum です。Folsom Update1 (2012.2.1) で Nova から Quantum の floating IP を使う機能が入りました。

$ nova list
+--------------------------------------+------+--------+----------------------------------------------------+
| ID                                   | Name | Status | Networks                                           |
+--------------------------------------+------+--------+----------------------------------------------------+
| 859bbff7-6ba7-4421-9e1f-588379fa2038 | s1   | ACTIVE | net1=10.0.0.3                                      |
| 37cf07fe-5b24-4304-bb56-80b70347580e | s2   | ACTIVE | net2=172.16.1.3; net1=10.0.0.4                     |
| 140d872b-2f78-4c62-a528-85898284e446 | s3   | ACTIVE | net3=192.168.123.3; net2=172.16.1.4; net1=10.0.0.5 |
+--------------------------------------+------+--------+----------------------------------------------------+

Nova から操作してみましょう。

$ nova floating-ip-pool-list
+---------+
| name    |
+---------+
| ext_net |
+---------+
$ nova floating-ip-list
+--------------+-------------+----------+---------+
| Ip           | Instance Id | Fixed Ip | Pool    |
+--------------+-------------+----------+---------+
| 172.24.4.227 | None        | None     | ext_net |
| 172.24.4.228 | None        | None     | ext_net |
| 172.24.4.229 | None        | None     | ext_net |
+--------------+-------------+----------+---------+

nova コマンドを見ると、インスタンス名と floating IP しか指定できません。複数 NIC がある場合にはどうなってしまうのでしょうか。

$ nova help add-floating-ip
usage: nova add-floating-ip <server> <address>

Add a floating IP address to a server.

Positional arguments:
  <server>   Name or ID of server.
  <address>  IP Address.

やってみると 3つ目で失敗したようです。たしかに割り当てられていません。

$ nova add-floating-ip s1 172.24.4.227
$ nova add-floating-ip s2 172.24.4.228
$ nova add-floating-ip s3 172.24.4.229
ERROR: Error. Unable to associate floating ip (HTTP 400) (Request-ID: req-0a915c79-2fc4-4801-bfc9-1f30a9431707)
$ nova floating-ip-list
+--------------+--------------------------------------+----------+---------+
| Ip           | Instance Id                          | Fixed Ip | Pool    |
+--------------+--------------------------------------+----------+---------+
| 172.24.4.227 | 859bbff7-6ba7-4421-9e1f-588379fa2038 | 10.0.0.3 | ext_net |
| 172.24.4.228 | 37cf07fe-5b24-4304-bb56-80b70347580e | 10.0.0.4 | ext_net |
| 172.24.4.229 | None                                 | None     | ext_net |
+--------------+--------------------------------------+----------+---------+
$ quantum floatingip-list
+--------------------------------------+------------------+---------------------+--------------------------------------+
| id                                   | fixed_ip_address | floating_ip_address | port_id                              |
+--------------------------------------+------------------+---------------------+--------------------------------------+
| 114c1e52-e4b6-4622-b186-965781f430b0 |                  | 172.24.4.229        |                                      |
| 433c4582-e452-4abc-bc5d-359fc977f313 | 10.0.0.3         | 172.24.4.227        | e0d51e99-612d-4e35-a9a6-4e19443c44e0 |
| 46d910a4-a519-4785-b2f7-d02203a1f0bb | 10.0.0.4         | 172.24.4.228        | 559a1cae-7999-4274-85dc-ea77b13bac60 |
+--------------------------------------+------------------+---------------------+--------------------------------------+

Quantum のログを見るとこうなっています。

2012-12-11 21:25:08 5712 TRACE quantum.api.v2.resource ExternalGatewayForFloatingIPNotFound: 
External network d360185c-db6e-430c-bd38-e52554765bb7 is not reachable from subnet 
8da47637-6538-45f5-a753-0ee3d168fc3f.  Therefore, cannot associate Port 
616b1ca4-2353-472f-9351-b1a58bb9f2cb with a Floating IP.

External network d360185c-db6e-430c-bd38-e52554765bb7 から subnet 8da47637-6538-45f5-a753-0ee3d168fc3f には到達できないと叫んでいます。

subnet 8da47637-6538-45f5-a753-0ee3d168fc3f は net3 上の subnet なので、上の図を見ると、確かに外部ネットワークとはつながっていません。

$ quantum net-list
+--------------------------------------+---------+--------------------------------------+
| id                                   | name    | subnets                              |
+--------------------------------------+---------+--------------------------------------+
| 72fd56c6-24b5-4ed9-bb38-be547f8e507a | net3    | 8da47637-6538-45f5-a753-0ee3d168fc3f |
| 7619360b-d1ff-495e-8377-3b0742ee9329 | net1    | f9e5880e-1155-48a0-8f32-677a6c902eff |
| d360185c-db6e-430c-bd38-e52554765bb7 | ext_net | 736a4bb6-64db-410d-8332-2673b5514270 |
| e26c9324-d303-4355-a0ae-62e192733f5f | net2    | 751fe2bc-7796-436f-bf34-a37d445065ff |
+--------------------------------------+---------+--------------------------------------+

Floating IP を割り当てる NIC はどうも適当な順番で呼ばれているようです。 nova/api/openstack/compute/contrib/floating_ips.py を見ると、こうなっていて、明らかに適当です。
これまで Multi NIC をみんなどうやって使ってきたのでしょうか????

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _('No fixed ips associated to instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # TODO(tr3buchet): this will associate the floating IP with the
        # first fixed_ip an instance has. This should be
        # changed to support specifying a particular fixed_ip if
        # multiple exist.
        if len(fixed_ips) > 1:
            msg = _('multiple fixed_ips exist, using the first: %s')
            LOG.warning(msg, fixed_ips[0]['address'])

        try:
            self.network_api.associate_floating_ip(context, instance,
                                  floating_address=address,
                                  fixed_address=fixed_ips[0]['address'])


という訳で、複数の NIC を持つ VM の場合、nova の add-floating-ip では使いものにならないことが分かりました。特に、Quantum で外部と接続するつもりのないネットワークに接続した VM を作る場合は危険すぎます。

後始末をしてから今度は Quantum で試してみましょう。さっきの後始末。きれいになくなりました。

$ nova floating-ip-list
+--------------+--------------------------------------+----------+---------+
| Ip           | Instance Id                          | Fixed Ip | Pool    |
+--------------+--------------------------------------+----------+---------+
| 172.24.4.227 | 859bbff7-6ba7-4421-9e1f-588379fa2038 | 10.0.0.3 | ext_net |
| 172.24.4.228 | 37cf07fe-5b24-4304-bb56-80b70347580e | 10.0.0.4 | ext_net |
| 172.24.4.229 | None                                 | None     | ext_net |
+--------------+--------------------------------------+----------+---------+
$ nova remove-floating-ip 37cf07fe-5b24-4304-bb56-80b70347580e 172.24.4.228
$ nova remove-floating-ip 859bbff7-6ba7-4421-9e1f-588379fa2038 172.24.4.227
$ nova floating-ip-delete 172.24.4.227
$ nova floating-ip-delete 172.24.4.228
$ nova floating-ip-delete 172.24.4.229
$ nova floating-ip-list

$ quantum floatingip-list

$  

Quantum でやってみる

floating IP の操作はこんな感じ。

まず、Floating IP pool を調べます。 --router:external というフラグがあるネットワークを調べるのですが、net-external-list コマンドを使うのが楽です。

$ quantum net-external-list -c id -c name
+--------------------------------------+---------+
| id                                   | name    |
+--------------------------------------+---------+
| d360185c-db6e-430c-bd38-e52554765bb7 | ext_net |
+--------------------------------------+---------+

floating IP の確保はこんな感じ

$ quantum floatingip-create
usage: quantum floatingip-create [-h] [-f {shell,table}] [-c COLUMN]
                                 [--variable VARIABLE] [--prefix PREFIX]
                                 [--request-format {json,xml}]
                                 [--tenant-id tenant-id] [--port-id PORT_ID]
                                 [--fixed-ip-address FIXED_IP_ADDRESS]
                                 floating_network_id ...
quantum floatingip-create: error: too few arguments
$ quantum floatingip-create ext_net
Created a new floatingip:
+---------------------+--------------------------------------+
| Field               | Value                                |
+---------------------+--------------------------------------+
| fixed_ip_address    |                                      |
| floating_ip_address | 172.24.4.227                         |
| floating_network_id | d360185c-db6e-430c-bd38-e52554765bb7 |
| id                  | bb96193e-6a10-4207-93fe-2a47efbcaaf1 |
| port_id             |                                      |
| router_id           |                                      |
| tenant_id           | 87b32cbf8f7041e69ab7f315059a30da     |
+---------------------+--------------------------------------+
$ quantum floatingip-list
+--------------------------------------+------------------+---------------------+---------+
| id                                   | fixed_ip_address | floating_ip_address | port_id |
+--------------------------------------+------------------+---------------------+---------+
| bb96193e-6a10-4207-93fe-2a47efbcaaf1 |                  | 172.24.4.227        |         |
+--------------------------------------+------------------+---------------------+---------+

とりあえず NIC が 3つある、さっき失敗した VM s3 でやってみます。まず VMインスタンス ID を調べて、NIC に対応する Quantum の port を調べます。

テクニックとしては port-list の後ろに -c オプションを付けると表示する項目が限定できます。また、'--' で区切った後に絞り込みを行う条件を指定できます。ここでは VM の instance ID は device_id に入っていますので、それで絞り込みます。

$ nova list
+--------------------------------------+------+--------+----------------------------------------------------+
| ID                                   | Name | Status | Networks                                           |
+--------------------------------------+------+--------+----------------------------------------------------+
| 859bbff7-6ba7-4421-9e1f-588379fa2038 | s1   | ACTIVE | net1=10.0.0.3                                      |
| 37cf07fe-5b24-4304-bb56-80b70347580e | s2   | ACTIVE | net2=172.16.1.3; net1=10.0.0.4                     |
| 140d872b-2f78-4c62-a528-85898284e446 | s3   | ACTIVE | net3=192.168.123.3; net2=172.16.1.4; net1=10.0.0.5 |
+--------------------------------------+------+--------+----------------------------------------------------+
$ quantum port-list -c id -c fixed_ips -- --device_id 140d872b-2f78-4c62-a528-85898284e446
+--------------------------------------+--------------------------------------------------------------------------------------+
| id                                   | fixed_ips                                                                            |
+--------------------------------------+--------------------------------------------------------------------------------------+
| 616b1ca4-2353-472f-9351-b1a58bb9f2cb | {"subnet_id": "8da47637-6538-45f5-a753-0ee3d168fc3f", "ip_address": "192.168.123.3"} |
| 65a6a9e3-59d9-4285-bd33-9dd2eb9caa5a | {"subnet_id": "751fe2bc-7796-436f-bf34-a37d445065ff", "ip_address": "172.16.1.4"}    |
| ee682e9f-11c4-4b02-b19b-9858b44f20a4 | {"subnet_id": "f9e5880e-1155-48a0-8f32-677a6c902eff", "ip_address": "10.0.0.5"}      |
+--------------------------------------+--------------------------------------------------------------------------------------+

どうやら、外向きのネットワークに接続された net1 に対応する 10.0.0.5 に対応する NIC は ee682e9f-11c4-4b02-b19b-9858b44f20a4 だと分かりました。

$ quantum floatingip-associate
usage: quantum floatingip-associate [-h] [--request-format {json,xml}]
                                    [--fixed-ip-address FIXED_IP_ADDRESS]
                                    floatingip-id port_id
quantum floatingip-associate: error: too few arguments
$ quantum floatingip-associate bb96193e-6a10-4207-93fe-2a47efbcaaf1 ee682e9f-11c4-4b02-b19b-9858b44f20a4
Associated floatingip bb96193e-6a10-4207-93fe-2a47efbcaaf1
$ quantum floatingip-list
+--------------------------------------+------------------+---------------------+--------------------------------------+
| id                                   | fixed_ip_address | floating_ip_address | port_id                              |
+--------------------------------------+------------------+---------------------+--------------------------------------+
| bb96193e-6a10-4207-93fe-2a47efbcaaf1 | 10.0.0.5         | 172.24.4.227        | ee682e9f-11c4-4b02-b19b-9858b44f20a4 |
+--------------------------------------+------------------+---------------------+--------------------------------------+

やっと割り当てができました。

では、ping を打ってみましょう。

$ ping 172.24.4.227
PING 172.24.4.227 (172.24.4.227) 56(84) bytes of data.
^C
--- 172.24.4.227 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4002ms

すこし焦りました。
Nova の security group の設定を忘れていました。今度は大丈夫でした。

$ nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0
+-------------+-----------+---------+-----------+--------------+
| IP Protocol | From Port | To Port | IP Range  | Source Group |
+-------------+-----------+---------+-----------+--------------+
| icmp        | -1        | -1      | 0.0.0.0/0 |              |
+-------------+-----------+---------+-----------+--------------+
$ ping 172.24.4.227
PING 172.24.4.227 (172.24.4.227) 56(84) bytes of data.
64 bytes from 172.24.4.227: icmp_req=1 ttl=63 time=1.61 ms
64 bytes from 172.24.4.227: icmp_req=2 ttl=63 time=1.39 ms
64 bytes from 172.24.4.227: icmp_req=3 ttl=63 time=1.43 ms
64 bytes from 172.24.4.227: icmp_req=4 ttl=63 time=1.19 ms
64 bytes from 172.24.4.227: icmp_req=5 ttl=63 time=1.35 ms
^C
--- 172.24.4.227 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 1.195/1.396/1.611/0.136 ms

という訳で長くなりましたが、Quantum の Floating IP の使い方を見てみました。

結論としては、複数 NIC で floating IP を使う場合には、Quantum の Floating IP を
直接使いましょう、ということです。

でも、UUID だらけで面倒ですね。

Horizon で Quantum floating IP を直接操作できるように実装中なので、ご期待下さい。

Security Group は時間切れなので、またの機会に。基本的には Amazon VPC Security Group 相当です。