VMwarePlayer+Ubuntu/KVM/OVSでOpenFlowテスト環境をつくる(5)

はじめに

第1回第4回 までで1つの OVS で KVM 仮想マシンを束ねる形の環境を作りました。その環境上で OpenFlow で仮想マシン間通信をコントロールするというテストをいくつかやってきたのですが、単一のスイッチでやれる範囲って、基本的にはフローの操作だけで、環境的には広がらないんだよね。フロー操作そのものについては、もうある程度見れた(気がする)ので、もうちょっと環境を広げることを考えます。

今回は

  • Ubuntu12.10 を使った KVM ホストの構築: brcompat mode を使わない OVS/KVM 環境の構築
  • OVS複数ブリッジの設定

についてです。

[2013-03-04] veth 仮想リンクじゃなくて OVS Patch Port を使ってブリッジ間接続をする方法について追記しました。

Ubuntu12.10 & non-brcompat OVS

これまでは Ubuntu 12.04 なマシンを使っていたのですが、libvirt/0.9.11 以降は Open vSwitch をサポートしているので brcompat 使わなくてイイ、という話があったので、まずそれを試してみようと言うことに。

  • oftest01/Ubuntu12.01
stereocat@oftest01:~$ virsh version
Compiled against library: libvir 0.9.8
Using library: libvir 0.9.8
Using API: QEMU 0.9.8
Running hypervisor: QEMU 1.0.0

stereocat@oftest01:~$ ovs-vsctl --version
ovs-vsctl (Open vSwitch) 1.4.0+build0
Compiled Sep 26 2012 03:17:30
stereocat@oftest01:~$
  • oftest03/Ubuntu12.10
stereocat@oftest03:~$ virsh version
Compiled against library: libvir 0.9.13
Using library: libvir 0.9.13
Using API: QEMU 0.9.13
Running hypervisor: QEMU 1.2.0

stereocat@oftest03:~$ ovs-vsctl --version
ovs-vsctl (Open vSwitch) 1.4.3
Compiled Feb 18 2013 12:58:42
stereocat@oftest03:~$

ref.

基礎設定

基本的には第1回 同様ですが、brcompat の設定は行いません。そのため、brcompat_mod は組み込まれません。また、ovs-brcompatd も起動しません。

stereocat@oftest03:~$ sudo service openvswitch-switch status
[sudo] password for stereocat:
ovsdb-server is running with pid 1361
ovs-vswitchd is running with pid 1371
stereocat@oftest03:~$ lsmod | grep brcompat
stereocat@oftest03:~$ lsmod | grep openvsw
openvswitch            43049  2
stereocat@oftest03:~$


NICの設定だけちょっと変えて、OpenFlowテスト用のネットワーク(eth1:192.168.11.0/24)に KVM ホストがつなぐためのインタフェースを ovsbr0p1 というのにしておきます。

  • /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
        address 192.168.144.126
        netmask 255.255.255.0
        gateway 192.168.144.2
        dns-nameservers 192.168.144.2 192.168.2.16 8.8.8.8

auto eth1
iface eth1 inet manual
        up /sbin/ifconfig $IFACE up
        down /sbin/ifconfig $IFACE down

auto ovsbr0p1
iface ovsbr0p1 inet static
        address 192.168.11.101
        netmask 255.255.255.0

OVS設定するまでは ovsbr0p1 は有効になりません。

stereocat@oftest03:~$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN mode DEFAULT
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:ea:f4:c0 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
stereocat@oftest03:~$ 
OVS設定

OVSの設定を行います。

stereocat@oftest03:~$ sudo ovs-vsctl add-br ovsbr0
stereocat@oftest03:~$ sudo ovs-vsctl add-port ovsbr0 eth1
stereocat@oftest03:~$ sudo ovs-vsctl add-port ovsbr0 ovsbr0p1 -- set interface ovsbr0p1 type=internal
stereocat@oftest03:~$
stereocat@oftest03:~$ sudo ovs-vsctl show
e7f05e4d-46fb-4182-a6ee-d48ec9c232c5
    Bridge "ovsbr0"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "ovsbr0p1"
            Interface "ovsbr0p1"
                type: internal
        Port "eth1"
            Interface "eth1"
    ovs_version: "1.4.3"
stereocat@oftest03:~$
stereocat@oftest03:~$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN mode DEFAULT
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:ea:f4:c0 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
5: ovsbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
6: ovsbr0p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT
    link/ether ce:46:96:1c:53:98 brd ff:ff:ff:ff:ff:ff
stereocat@oftest03:~$
stereocat@oftest03:~$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ea:f4:c0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.144.126/24 brd 192.168.144.255 scope global eth0
    inet6 fe80::20c:29ff:feea:f4c0/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
    inet6 fe80::20c:29ff:feea:f4ca/64 scope link
       valid_lft forever preferred_lft forever
5: ovsbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
6: ovsbr0p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether ce:46:96:1c:53:98 brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.101/24 brd 192.168.11.255 scope global ovsbr0p1
    inet6 fe80::cc46:96ff:fe1c:5398/64 scope link
       valid_lft forever preferred_lft forever
stereocat@oftest03:~$

ovsbr0, ovsbr0p1 が見えるようになります。

VMのインポート

既に VM があるので、イメージをコピーしてインポートします。第3回でやったように virt-install --import していくだけ。ただし、brcompat を使わないので、NIC周りの設定は変えてやる必要があります。

#!/bin/sh

VINST=/usr/bin/virt-install

# (略)

sudo $VINST \
        --import \
        --force \
        --name=$NAME \
        --ram=$MEM \
        --vcpus=1 \
        --disk path=$DISK,format=qcow2 \
        --os-variant=ubuntuprecise \
        --accelerate \
        --network user,mac=$MAC \
        --graphics vnc,port=$VNCPORT,listen=0.0.0.0,keymap=ja

と、こんな感じにします。brcompat が有効になっている場合、--network bridge=br0 とか使えたのですが、いまは brcompat を有効にしていないので、これだとインポートできません。どうも VMXML ファイルを直接書き換える必要があるようなので、今のところはとりあえず --network user で読み込んで後から XML ファイルを編集します。

いったん --network user でインポートすると、インタフェースの定義はこうなっています。

    <interface type='user'>
      <mac address='52:54:00:00:00:01'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

これを、こんな感じに書き換えます。

    <interface type='bridge'>
      <mac address='52:54:00:00:00:01'/>
      <source bridge='ovsbr0'/>
      <virtualport type='openvswitch' />
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

あとは、VM を起動してやって、OVS に "vnetX" で接続されていれば大丈夫。

stereocat@oftest03:~$ sudo virsh list --all
Id    Name                           State
----------------------------------------------------
11    ofvm01                         running

stereocat@oftest03:~$
stereocat@oftest03:~$ sudo ovs-vsctl show
e7f05e4d-46fb-4182-a6ee-d48ec9c232c5
    Bridge "ovsbr0"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "ovsbr0p1"
            Interface "ovsbr0p1"
                type: internal
        Port "vnet0"
            Interface "vnet0"
        Port "eth1"
            Interface "eth1"
    ovs_version: "1.4.3"
stereocat@oftest03:~$

Multi Bridge OVS

最終的に、こういう三角形のトポロジを作ってみます。

ブリッジの追加とブリッジ間接続

まずはブリッジ間接続に使う仮想的なリンクとインタフェースを作っておきます。

stereocat@oftest03:~$ sudo ip link add name veth0-0 type veth peer name veth0-1
stereocat@oftest03:~$ sudo ip link set veth0-0 up
stereocat@oftest03:~$ sudo ip link set veth0-1 up

あとは OVS に新しいブリッジ(ovsbr1)を追加して、各ブリッジにポートを追加していくだけ。

stereocat@oftest03:~$ sudo ovs-vsctl add-br ovsbr1
stereocat@oftest03:~$ sudo ovs-vsctl add-port ovsbr0 veth0-0
stereocat@oftest03:~$ sudo ovs-vsctl add-port ovsbr1 veth0-1

確認してみるとこんな感じ。

stereocat@oftest03:~$ ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN mode DEFAULT
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:ea:f4:c0 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
5: ovsbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT
    link/ether 00:0c:29:ea:f4:ca brd ff:ff:ff:ff:ff:ff
6: ovsbr0p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT
    link/ether f2:dc:b3:27:50:af brd ff:ff:ff:ff:ff:ff
10: veth0-1: <NO-CARRIER,BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT qlen 1000
    link/ether ba:eb:e5:e7:ae:a2 brd ff:ff:ff:ff:ff:ff
11: veth0-0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 06:42:29:9e:10:20 brd ff:ff:ff:ff:ff:ff
12: ovsbr1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT
    link/ether 4a:e1:d9:33:0c:46 brd ff:ff:ff:ff:ff:ff
stereocat@oftest03:~$
stereocat@oftest03:~$ sudo ovs-vsctl show
e7f05e4d-46fb-4182-a6ee-d48ec9c232c5
    Bridge "ovsbr0"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "ovsbr0p1"
            Interface "ovsbr0p1"
                type: internal
        Port "veth0-0"
            Interface "veth0-0"
        Port "eth1"
            Interface "eth1"
    Bridge "ovsbr1"
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
        Port "veth0-1"
            Interface "veth0-1"
    ovs_version: "1.4.3"
stereocat@oftest03:~$
VMとブリッジの接続

VMXMLファイルを編集して接続先ブリッジを指定してやります。()

  • virsh edit ofvm04
    <interface type='bridge'>
      <mac address='52:54:00:00:00:04'/>
      <source bridge='ovsbr1'/>
      <target dev='tap1'/>
      <virtualport type='openvswitch'>
        <parameters interfaceid='dcd62ab2-de58-41c5-9d75-1b001f1b8452'/>
      </virtualport>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

ついでに、OVSに接続するインタフェースの名前も設定しておきます。() 何も指定しない場合、vnetX というのが使われますが、これは VM の起動順に振られるので、必ずしも名前とVMが1対1に連動しません。(今までは起動スクリプト書いてVMの変動がない環境で作業していたのでほぼ固定だったのですが、テストとかでVM起動したり落としたりしているだけでずれてくるので、固定した方が便利。)

なお、VM のインタフェース名を固定する場合、"vnet" または "vif" で始まる名前は libvirt が予約しているので使用できません。

This name can be manually specifed, however the name must not start with either 'vnet' or 'vif', which are prefixes reserved by libvirt and certain hypervisors.

http://libvirt.org/formatdomain.html#elementsNICSTargetOverride

ofvm01, ofvm04 を起動した状態だとこうなります。

stereocat@oftest03:~$ sudo ovs-vsctl show
e7f05e4d-46fb-4182-a6ee-d48ec9c232c5
    Bridge "ovsbr0"
        Controller "tcp:192.168.144.119"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "ovsbr0p1"
            Interface "ovsbr0p1"
                type: internal
        Port "veth0-0"
            Interface "veth0-0"
        Port "tap1"
            Interface "tap1"
        Port "eth1"
            Interface "eth1"
    Bridge "ovsbr1"
        Controller "tcp:192.168.144.119"
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
        Port "tap4"
            Interface "tap4"
        Port "veth0-1"
            Interface "veth0-1"
    ovs_version: "1.4.3"
stereocat@oftest03:~$
トポロジの確認

せっかくなので、

をつかってトポロジを確認してみます。

といってもまだ OVS にコントローラとの設定入れてないので追加。ついでに Datapath ID もわかりやすいのに変更。

stereocat@oftest03:~$ sudo ovs-vsctl set-controller ovsbr0 tcp:192.168.144.119
stereocat@oftest03:~$ sudo ovs-vsctl set-controller ovsbr1 tcp:192.168.144.119
stereocat@oftest03:~$ sudo ovs-vsctl set bridge ovsbr0 other-config:datapath-id=0000000000000001
stereocat@oftest03:~$ sudo ovs-vsctl set bridge ovsbr1 other-config:datapath-id=0000000000000002

topology-controller.rb を実行してみる。

stereocat@oftest02:~/trema-orig/ruby_topology$ sudo trema run topology-controller.rb
0x1 (port 3) <-> 0x2 (port 1)
topology updated
0x1 (port 3) <-> 0x2 (port 1)
0x2 (port 1) <-> 0x1 (port 3)
topology updated

ということで、見たままですが、2つのブリッジが相互につながっているというのが確認できます。

三角形にする

あとは流れ同じ流れで、veth の作成とブリッジの作成/ポート追加をやっていくだけです。

  • OVS設定
stereocat@oftest03:~$ sudo ovs-vsctl show
e7f05e4d-46fb-4182-a6ee-d48ec9c232c5
    Bridge "ovsbr0"
        Controller "tcp:192.168.144.119"
            is_connected: true
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "ovsbr0p1"
            Interface "ovsbr0p1"
                type: internal
        Port "veth0-0"
            Interface "veth0-0"
        Port "tap1"
            Interface "tap1"
        Port "eth1"
            Interface "eth1"
        Port "veth2-1"
            Interface "veth2-1"
    Bridge "ovsbr1"
        Controller "tcp:192.168.144.119"
            is_connected: true
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
        Port "tap4"
            Interface "tap4"
        Port "veth0-1"
            Interface "veth0-1"
        Port "veth1-0"
            Interface "veth1-0"
    Bridge "ovsbr2"
        Controller "tcp:192.168.144.119"
            is_connected: true
        Port "tap6"
            Interface "tap6"
        Port "veth1-1"
            Interface "veth1-1"
        Port "ovsbr2"
            Interface "ovsbr2"
                type: internal
        Port "veth2-0"
            Interface "veth2-0"
    ovs_version: "1.4.3"
stereocat@oftest03:~$
  • トポロジ情報
stereocat@oftest02:~/trema-orig/ruby_topology$ sudo trema run topology-controller.rb
[sudo] password for stereocat:
0x3 (port 2) <-> 0x1 (port 5)
topology updated
0x2 (port 2) <-> 0x3 (port 1)
0x3 (port 2) <-> 0x1 (port 5)
topology updated
0x1 (port 5) <-> 0x3 (port 2)
0x2 (port 2) <-> 0x3 (port 1)
0x3 (port 2) <-> 0x1 (port 5)
topology updated
0x1 (port 3) <-> 0x2 (port 1)
0x1 (port 5) <-> 0x3 (port 2)
0x2 (port 2) <-> 0x3 (port 1)
0x3 (port 2) <-> 0x1 (port 5)
topology updated
0x1 (port 3) <-> 0x2 (port 1)
0x1 (port 5) <-> 0x3 (port 2)
0x2 (port 2) <-> 0x3 (port 1)
0x3 (port 1) <-> 0x2 (port 2)
0x3 (port 2) <-> 0x1 (port 5)
topology updated
0x1 (port 3) <-> 0x2 (port 1)
0x1 (port 5) <-> 0x3 (port 2)
0x2 (port 1) <-> 0x1 (port 3)
0x2 (port 2) <-> 0x3 (port 1)
0x3 (port 1) <-> 0x2 (port 2)
0x3 (port 2) <-> 0x1 (port 5)
topology updated

おわりに

複数ブリッジ構成で何をすべきなのか、という話は、実は trema -v run したときに出力される、裏で何をやっているのか、という操作を見るとわかりやすい。というのは Trema本にかいてありますね。

今回、OVSに複数のブリッジを作るというのをやっていますが、同一ホストで複数の OVS を動かすというのもできるんじゃないのかなあと思って試してはみました。が、プロセス等は起動するものの、ブリッジ周りの動作でぶつかるらしく上手くいかなかった。

ともかく、複数台のスイッチがある(ように見える)環境がなんとかできたっぽいので、あとはこの上でのテストをやっていければいいかなあ……今週はとりあえず環境整備までか。