VMwarePlayer+Ubuntu/KVM/OVSでOpenFlowテスト環境をつくる(6)
はじめに
第5回 に書いた OVS ブリッジ間接続について、
というコメントをいただいたので、veth 仮想リンクでつないでいた物を、OVS patch port で置き換えてどうなる物かやってみました。
OVS Patch Port?
ovs-vswitchd.conf.db(5) を見てみます。
Interface TABLE An interface within a Port. Summary: (略) Patch Options: options : peer optional string (略) Details: (略) Patch Options: Only patch interfaces support these options. options : peer: optional string The name of the Interface for the other side of the patch. The named Interface's own peer option must specify this Interface's name. That is, the two patch interfaces must have reversed name and peer values. (略) System-Specific Details: type: string The interface type, one of: system An ordinary network device, e.g. eth0 on Linux. Some- times referred to as ``external interfaces'' since they are generally connected to hardware external to that on which the Open vSwitch is running. The empty string is a synonym for system. internal A simulated network device that sends and receives traf- fic. An internal interface whose name is the same as its bridge's name is called the ``local interface.'' It does not make sense to bond an internal interface, so the terms ``port'' and ``interface'' are often used impre- cisely for internal interfaces. tap A TUN/TAP device managed by Open vSwitch. (略) patch A pair of virtual devices that act as a patch cable. (略)
…と思ったらわかりやすい解説があった
事前確認
veth はいったん全部消します。Patch Port の名前はこんな感じにしてみます。
patch0-1 patch1-0 +--------+ +--------+ | ovsbr0 +--------------+ ovsbr1 | +---+----+ +----+---+ | patch0-2 | patch1-2 | +--------+ | +-------+ ovsbr2 +-------+ +--------+ patch2-0 patch2-1
veth 全部消した状態でチェック(VMは起動してある)。
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 4: ovsbr2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT link/ether 2e:32:b6:35:09:45 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: 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 7: ovsbr0p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT link/ether 4a:99:17:4e:8b:27 brd ff:ff:ff:ff:ff:ff 9: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500 link/ether fe:54:00:00:00:01 brd ff:ff:ff:ff:ff:ff 10: tap4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500 link/ether fe:54:00:00:00:04 brd ff:ff:ff:ff:ff:ff 11: tap6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500 link/ether fe:54:00:00:00:06 brd ff:ff:ff:ff:ff:ff stereocat@oftest03:~$ 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 "eth1" Interface "eth1" Port "tap1" Interface "tap1" Bridge "ovsbr1" Controller "tcp:192.168.144.119" Port "ovsbr1" Interface "ovsbr1" type: internal Port "tap4" Interface "tap4" Bridge "ovsbr2" Controller "tcp:192.168.144.119" Port "ovsbr2" Interface "ovsbr2" type: internal Port "tap6" Interface "tap6" ovs_version: "1.4.3" stereocat@oftest03:~$
OVS Patch Port 設定
Patch Portの追加(各ポートで、対向側のポートを peer で指定する必要がある)。
sudo ovs-vsctl add-port ovsbr0 patch0-1 -- set interface patch0-1 type=patch options:peer=patch1-0 sudo ovs-vsctl add-port ovsbr1 patch1-0 -- set interface patch1-0 type=patch options:peer=patch0-1 sudo ovs-vsctl add-port ovsbr0 patch0-2 -- set interface patch0-2 type=patch options:peer=patch2-0 sudo ovs-vsctl add-port ovsbr2 patch2-0 -- set interface patch2-0 type=patch options:peer=patch0-2 sudo ovs-vsctl add-port ovsbr1 patch1-2 -- set interface patch1-2 type=patch options:peer=patch2-1 sudo ovs-vsctl add-port ovsbr2 patch2-1 -- set interface patch2-1 type=patch options:peer=patch1-2
再度確認。OVS内部の話なので、OS上には特に変化なし。
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 4: ovsbr2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT link/ether 2e:32:b6:35:09:45 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: 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 7: ovsbr0p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT link/ether 4a:99:17:4e:8b:27 brd ff:ff:ff:ff:ff:ff 9: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500 link/ether fe:54:00:00:00:01 brd ff:ff:ff:ff:ff:ff 10: tap4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500 link/ether fe:54:00:00:00:04 brd ff:ff:ff:ff:ff:ff 11: tap6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500 link/ether fe:54:00:00:00:06 brd ff:ff:ff:ff:ff:ff stereocat@oftest03:~$
OVS コンフィグはこうなる。
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 "patch0-1" Interface "patch0-1" type: patch options: {peer="patch1-0"} Port "patch0-2" Interface "patch0-2" type: patch options: {peer="patch2-0"} Port del-controller Interface del-controller Port "eth1" Interface "eth1" Port "tap1" Interface "tap1" Bridge "ovsbr1" Port "ovsbr1" Interface "ovsbr1" type: internal Port "tap4" Interface "tap4" Port "patch1-0" Interface "patch1-0" type: patch options: {peer="patch0-1"} Port "patch1-2" Interface "patch1-2" type: patch options: {peer="patch2-1"} Bridge "ovsbr2" Port "patch2-0" Interface "patch2-0" type: patch options: {peer="patch0-2"} Port "ovsbr2" Interface "ovsbr2" type: internal Port "tap6" Interface "tap6" Port "patch2-1" Interface "patch2-1" type: patch options: {peer="patch1-2"} ovs_version: "1.4.3" stereocat@oftest03:~$
さてこれで動くか…と思いきや、動かない。topology-controller 動かしてみるが何も出てこない。いったん、各ブリッジからコントローラの設定を消して、"actions=NORMAL" で動かすようにしてみて、VM 間の通信が通るかどうかを確認してみるが通らない。
/var/log/openvswitch/ovs-vswitchd.log
Mar 04 22:59:11|00256|dpif|WARN|system@ovsbr1: failed to add patch1-2 as port: Address family not supported by protocol Mar 04 22:59:11|00257|bridge|WARN|patch1-2 port has no interfaces, dropping Mar 04 22:59:11|00258|bridge|INFO|destroyed port patch1-2 on bridge ovsbr1
DBを見てみる。
stereocat@oftest03:~$ sudo ovs-vsctl list Interface (略) _uuid : 5465cc19-768a-422a-b538-f8f54d45d6f8 admin_state : [] cfm_fault : [] cfm_mpid : [] cfm_remote_mpids : [] duplex : [] external_ids : {} ingress_policing_burst: 0 ingress_policing_rate: 0 lacp_current : [] link_resets : [] link_speed : [] link_state : [] mac : [] mtu : [] name : "patch1-0" ofport : -1 options : {peer="patch0-1"} other_config : {} statistics : {} status : {} type : patch (略)
admin_state が "up" になってないし、ofportが -1 になっている? もう一度 ovs-vswitchd.conf.db(5) をチェック…すると、"OVS が ofport を -1 にセットしている場合、このインタフェースは追加されない" とある。うーむ。
ofport: optional integer OpenFlow port number for this interface. Unlike most columns, this column's value should be set only by Open vSwitch itself. Other clients should set this column to an empty set (the default) when creating an Interface. Open vSwitch populates this column when the port number becomes known. If the interface is successfully added, ofport will be set to a number between 1 and 65535 (generally either in the range 1 to 65279, inclusive, or 65534, the port number for the OpenFlow ``local port''). If the interface cannot be added then Open vSwitch sets this column to -1.
Patch Port の ofport=-1 になる問題の調査
OVS が patch port をサポートしてない?
OpenStack Quantum で Patch Port 使っているというので (OVS Quantum Plugin Documentation | Open vSwitch) ソースを見てみる。
def setup_tunnel_br(self, tun_br): '''Setup the tunnel bridge. Creates tunnel bridge, and links it to the integration bridge using a patch port. :param tun_br: the name of the tunnel bridge.''' self.tun_br = ovs_lib.OVSBridge(tun_br, self.root_helper) self.tun_br.reset_bridge() self.patch_tun_ofport = self.int_br.add_patch_port( cfg.CONF.OVS.int_peer_patch_port, cfg.CONF.OVS.tun_peer_patch_port) self.patch_int_ofport = self.tun_br.add_patch_port( cfg.CONF.OVS.tun_peer_patch_port, cfg.CONF.OVS.int_peer_patch_port) if int(self.patch_tun_ofport) < 0 or int(self.patch_int_ofport) < 0: LOG.error(_("Failed to create OVS patch port. Cannot have " "tunneling enabled on this agent, since this version " "of OVS does not support tunnels or patch ports. " "Agent terminated!")) exit(1) self.tun_br.remove_all_flows() self.tun_br.add_flow(priority=1, actions="drop")
ofport が 0 より小さい場合はエラー処理になってる。
- Q
- What features are not available in the Open vSwitch kernel datapath that ships as part of the upstream Linux kernel?
Frequently Asked Questions
- A
- The kernel module in upstream Linux 3.3 and later does not include tunnel virtual ports, that is, interfaces with type "gre", "ipsec_gre", "gre64", "ipsec_gre64", "vxlan", or "lisp". It is possible to create tunnels in Linux and attach them to Open vSwitch as system devices. However, they cannot be dynamically created through the OVSDB protocol or set the tunnel ids as a flow action.
Work is in progress in adding tunnel virtual ports to the upstream Linux version of the Open vSwitch kernel module. For now, if you need these features, use the kernel module from the Open vSwitch distribution instead of the upstream Linux kernel module.
The upstream kernel module does not include patch ports, but this only matters for Open vSwitch 1.9 and earlier, because Open vSwitch 1.10 and later implement patch ports without using this kernel feature.
いろいろ回ってたらそれっぽいのを発見。
openvswitch dkms package についての fix が入っているという。この時点ではインストールされていない。
stereocat@oftest03:~$ aptitude search openvswitch i openvswitch-brcompat - Open vSwitch bridge compatibility support p openvswitch-brcompat:i386 - Open vSwitch bridge compatibility support i A openvswitch-common - Open vSwitch common components p openvswitch-common:i386 - Open vSwitch common components i openvswitch-controller - Open vSwitch controller implementation p openvswitch-controller:i386 - Open vSwitch controller implementation p openvswitch-datapath-dkms - Open vSwitch datapath module source - DKMS version i openvswitch-datapath-source - Open vSwitch datapath module source - module-assistant version p openvswitch-dbg - Debug symbols for Open vSwitch packages p openvswitch-dbg:i386 - Debug symbols for Open vSwitch packages p openvswitch-ipsec - Open vSwitch GRE-over-IPsec support p openvswitch-ipsec:i386 - Open vSwitch GRE-over-IPsec support i A openvswitch-pki - Open vSwitch public key infrastructure dependency package i openvswitch-switch - Open vSwitch switch implementations p openvswitch-switch:i386 - Open vSwitch switch implementations p openvswitch-test - Open vSwitch test package p python-openvswitch - Python bindings for Open vSwitch p quantum-plugin-openvswitch - Quantum is a virtual network service for Openstack. (openvswitch plugin) p quantum-plugin-openvswitch-agent - Quantum is a virtual network service for Openstack. (openvswitch plugin agent) stereocat@oftest03:~$
インストールする。
stereocat@oftest03:~$ sudo aptitude install openvswitch-datapath-dkms [sudo] password for stereocat: The following NEW packages will be installed: dkms{a} openvswitch-datapath-dkms 0 packages upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 2,027 kB of archives. After unpacking 12.8 MB will be used. Do you want to continue? [Y/n/?] Get: 1 http://jp.archive.ubuntu.com/ubuntu/ quantal-updates/main dkms all 2.2.0.3-1.1ubuntu1.1 [71.4 kB] Get: 2 http://jp.archive.ubuntu.com/ubuntu/ quantal-updates/universe openvswitch-datapath-dkms all 1.4.3-0ubuntu2.1 [1,955 kB] Fetched 2,027 kB in 23s (85.7 kB/s) Selecting previously unselected package dkms. (Reading database ... 63865 files and directories currently installed.) Unpacking dkms (from .../dkms_2.2.0.3-1.1ubuntu1.1_all.deb) ... Selecting previously unselected package openvswitch-datapath-dkms. Unpacking openvswitch-datapath-dkms (from .../openvswitch-datapath-dkms_1.4.3-0ubuntu2.1_all.deb) ... Processing triggers for man-db ... Setting up dkms (2.2.0.3-1.1ubuntu1.1) ... Setting up openvswitch-datapath-dkms (1.4.3-0ubuntu2.1) ... Creating symlink /var/lib/dkms/openvswitch/1.4.3/source -> /usr/src/openvswitch-1.4.3 DKMS: add completed. Kernel preparation unnecessary for this kernel. Skipping... Building module: cleaning build area....(bad exit status: 2) ./configure --with-linux='/lib/modules/3.5.0-25-generic/build' && make -C datapath/linux........... cleaning build area....(bad exit status: 2) DKMS: build completed. openvswitch: Running module version sanity check. - Original module - Installation - Installing to /lib/modules/3.5.0-25-generic/updates/dkms/ brcompat.ko: Running module version sanity check. - Original module - Installation - Installing to /lib/modules/3.5.0-25-generic/updates/dkms/ depmod......... DKMS: install completed. stereocat@oftest03:~$ stereocat@oftest03:~$ ls /lib/modules/3.5.0-25-generic/updates/dkms/ brcompat.ko openvswitch.ko stereocat@oftest03:~$ sudo find / -name openvswitch.ko -type f /var/lib/dkms/openvswitch/1.4.3/3.5.0-25-generic/x86_64/module/openvswitch.ko /var/lib/dkms/openvswitch/1.4.3/build/datapath/linux/openvswitch.ko /lib/modules/3.5.0-25-generic/kernel/net/openvswitch/openvswitch.ko /lib/modules/3.5.0-25-generic/updates/dkms/openvswitch.ko /lib/modules/3.5.0-17-generic/kernel/net/openvswitch/openvswitch.ko stereocat@oftest03:~$
カーネルモジュールの入れ替えなので再起動する。
再度 DB を確認。
stereocat@oftest03:~$ sudo ovs-vsctl list interface (略) _uuid : 166d972b-fb9d-4a60-8d36-de6b5cac7d37 admin_state : up cfm_fault : [] cfm_mpid : [] cfm_remote_mpids : [] duplex : [] external_ids : {} ingress_policing_burst: 0 ingress_policing_rate: 0 lacp_current : [] link_resets : 0 link_speed : [] link_state : up mac : [] mtu : [] name : "patch0-1" ofport : 2 options : {peer="patch1-0"} other_config : {} statistics : {collisions=0, rx_bytes=7936, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=124, tx_bytes=7936, tx_dropped=0, tx_errors=0, tx_packets=124} status : {} type : patch (略)
Patch Port が有効になっているのがわかる。
再度動作確認
OVS Config を表示してみる。
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 del-controller Interface del-controller Port "patch0-1" Interface "patch0-1" type: patch options: {peer="patch1-0"} Port "eth1" Interface "eth1" Port "tap1" Interface "tap1" Port "patch0-2" Interface "patch0-2" type: patch options: {peer="patch2-0"} Bridge "ovsbr1" Controller "tcp:192.168.144.119" is_connected: true Port "ovsbr1" Interface "ovsbr1" type: internal Port "patch1-0" Interface "patch1-0" type: patch options: {peer="patch0-1"} Port "patch1-2" Interface "patch1-2" type: patch options: {peer="patch2-1"} Port "tap4" Interface "tap4" Bridge "ovsbr2" Controller "tcp:192.168.144.119" is_connected: true Port "patch2-0" Interface "patch2-0" type: patch options: {peer="patch0-2"} Port "patch2-1" Interface "patch2-1" type: patch options: {peer="patch1-2"} Port "ovsbr2" Interface "ovsbr2" type: internal Port "tap6" Interface "tap6" ovs_version: "1.4.3" stereocat@oftest03:~$
topology-controller でトポロジ確認
stereocat@oftest02:~/trema-orig/ruby_topology$ sudo trema run topology-controller.rb 0x3 (port 1) <-> 0x1 (port 5) topology updated 0x1 (port 2) <-> 0x2 (port 1) 0x3 (port 1) <-> 0x1 (port 5) topology updated 0x1 (port 2) <-> 0x2 (port 1) 0x3 (port 1) <-> 0x1 (port 5) 0x3 (port 2) <-> 0x2 (port 2) topology updated 0x1 (port 2) <-> 0x2 (port 1) 0x1 (port 5) <-> 0x3 (port 1) 0x3 (port 1) <-> 0x1 (port 5) 0x3 (port 2) <-> 0x2 (port 2) topology updated 0x1 (port 2) <-> 0x2 (port 1) 0x1 (port 5) <-> 0x3 (port 1) 0x2 (port 2) <-> 0x3 (port 2) 0x3 (port 1) <-> 0x1 (port 5) 0x3 (port 2) <-> 0x2 (port 2) topology updated 0x1 (port 2) <-> 0x2 (port 1) 0x1 (port 5) <-> 0x3 (port 1) 0x2 (port 1) <-> 0x1 (port 2) 0x2 (port 2) <-> 0x3 (port 2) 0x3 (port 1) <-> 0x1 (port 5) 0x3 (port 2) <-> 0x2 (port 2) topology updated
おわりに
あっさり終わるかなと思いきや結構面倒だった…。OVS Patch Port でもブリッジ間接続ができるというのはわかりました。とりあえず Patch Port 設定して動いた、というところなので、veth 仮想リンク使うのと何か違いがあるのかな? というのは今のところは正直よくわかりません。あ、使う上では、全部 OVS DB に閉じた使い方ができる Patch Port の使い勝手が良さそうだ、というのはあります。(veth 作ってから OVS 設定やるという二度手間が省ける。) openvswitch-datapath-dkms とかカーネル側の対応が必要なようなので、OS側の都合がつけば、ですが。