客户端可以通过ovsdb定义的协议访问openvswitch的数据库,协议在http://tools.ietf.org/html/draft-pfaff-ovsdb-proto-02,看来要成为ietf的标准了?怎么查询这些数据其实有一个样例,但是比较简单,我这里略作扩展,说明如何查询ovs的网桥、所连controller和流信息。
- 准备工作
因为ovs需要认证(公钥)才能访问其数据,我们为了简化直接在ovs所在节点上运行以下命令:
1ovs - appctl - t ovsdb - server ovsdb - server / add - remote ptcp : 6632然后可以直接通过tcp的方式访问ovsdb了
- echo发送存活信息
客户端可以使用tcp方式与服务器保持长连接,所以可能定时需要发送echo信息与服务器确认存活。可编写以下脚本:
Python |copy code |?
01 02 import socket
03 import json
04 05 OVSDB_IP = '127.0.0.1'
06 OVSDB_PORT = 6632
07 BUFSIZE = 409600
08 09 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
10 s.connect((OVSDB_IP, OVSDB_PORT))
11 12 query = {"method":"echo", "params":[], "id": 0}
13 s.send(json.dumps(query))
14 response = s.recv(BUFSIZE)
15 print response
16 执行结果为:
{“id”:0,”result”:[],”error”:null}
这是最简单的获取信息方式了,我们接下来要看看OVSDB中到底有些什么数据- 获得所有数据库名
脚本中其他不变,最后三行换为以下内容,以后步骤也是类似:
Python |copy code |?
1 2 query = {"method":"list_dbs", "params":[], "id": 0}
3 s.send(json.dumps(query))
4 response = s.recv(BUFSIZE)
5 print response
6
执行后结果为
{“id”:0,”result”:[“Open_vSwitch”],”error”:null}
可见现在OVSDB中只有一个数据库Open_vSwitch。接下来我们查询这个数据库有哪些表- 获得数据库的所有表结构
同样,代码为
Python |copy code |?
1 2 query = {"method":"get_schema", "params":["Open_vSwitch"], "id": 0}
3 s.send(json.dumps(query))
4 response = s.recv(BUFSIZE)
5 print response
6
因为表结构字段较多,所以我们将结果格式化,执行./ovs.py |python -m json.tool
返回的结果将是所有数据库的内容123456789101112131415161718192021222324252627282930313233343536373839{"error" : null ,"id" : 0 ,"result" : {"cksum" : "2180939265 17455" ,"name" : "Open_vSwitch" ,"tables" : {"Bridge" : {"columns" : {"controller" : {"type" : {"key" : {"refTable" : "Controller" ,"type" : "uuid"} ,"max" : "unlimited" ,"min" : 0}} ,"datapath_id" : {"ephemeral" : true ,"type" : {"key" : "string" ,"min" : 0}} ,"datapath_type" : {"type" : "string"} ,"external_ids" : {"type" : {"key" : "string" ,"max" : "unlimited" ,"min" : 0 ,"value" : "string"}} ,"fail_mode" : {. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .后面还有很多内容,在这里就不显示了。数据库除了Bridge,还有Controller、Flow Table、Interface、Manager、Mirror、Netflow、Open vswitch、Port、QoS、Queue、SSL、sFlow。看来OVS默认的流Flow表应该是openflow,其他还支持netflow和sflow。
- 获得所有网桥
我们查看一下网桥信息
Python |copy code |?
1 2 query = {"method":"transact", "params":["Open_vSwitch", {"op":"select","table": "Bridge", "where":[]}], "id": 0}
3 s.send(json.dumps(query))
4 response = s.recv(BUFSIZE)
5 print response
6
执行./ovs.py |python -m json.tool
返回的结果将是所有数据库的内容123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163{"error" : null ,"id" : 0 ,"result" : [{"rows" : [{"_uuid" : ["uuid" ,"fd924881-6a15-4a1b-a803-aa49efa38179"] ,"_version" : ["uuid" ,"5306417b-381e-49dd-9ac2-0d95c450919c"] ,"controller" : ["set" ,[ ]] ,"datapath_id" : "0000e0db551f99b4" ,"datapath_type" : "" ,"external_ids" : ["map" ,[ ]] ,"fail_mode" : ["set" ,[ ]] ,"flood_vlans" : ["set" ,[ ]] ,"flow_tables" : ["map" ,[ ]] ,"mirrors" : ["set" ,[ ]] ,"name" : "br-ex" ,"netflow" : ["set" ,[ ]] ,"other_config" : ["map" ,[ ]] ,"ports" : ["set" ,[["uuid" ,"28b44f02-7ecd-4135-9836-f1059ac1ec10"] ,["uuid" ,"596e6d23-ec51-4b56-bddc-5aa0805fe16c"] ,["uuid" ,"82cd970c-ac39-46e6-8aa7-b03529cc8916"] ,["uuid" ,"be77f10f-1a52-4be2-8b9e-c97b26c9acee"] ,["uuid" ,"f8ae4f3c-9d77-4f7e-8707-ee2e36c70e08"]]] ,"protocols" : [ "set" ,[ ]] ,"sflow" : ["set" ,[ ]] ,"status" : ["map" ,[ ]] ,"stp_enable" : false} ,{"_uuid" : ["uuid" ,"e29eac0c-a9ae-4108-a277-21388a24a2f1"] ,"_version" : ["uuid" ,"65e1bd22-6178-4b01-827f-8d64b0840e72"] ,"controller" : ["uuid" ,"15846c69-f014-4a5a-bc8d-3cb67cc3cb03"] ,"datapath_id" : "00000eac9ee20841" ,"datapath_type" : "" ,"external_ids" : ["map" ,[ ]] ,"fail_mode" : ["set" ,[ ]] ,"flood_vlans" : ["set" ,[ ]] ,"flow_tables" : ["map" ,[ ]] ,"mirrors" : ["set" ,[ ]] ,"name" : "br-tun" ,"netflow" : ["set" , [ ]] ,"other_config" : ["map" ,[ ]] ,"ports" : ["set" ,[["uuid" ,"aff50719-bd85-4b72-9283-656844b663aa"] ,["uuid" ,"bcd6e8f9-713f-4177-b730-caed455df9b7"] ,["uuid" ,"d8e93efc-7ebd-4d89-b7d2-b9b4b60c993a"]]] ,"protocols" : ["set" ,[ ]] ,"sflow" : ["set" ,[ ]] ,"status" : ["map" ,[ ]] ,"stp_enable" : false} ,. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .篇幅关系,这里展现了两个网桥br-ex和br-tun,其中port字段可以查询网桥上连接的端口,如果controller字段存在,说明该网桥受控制器控制。那我们再看一下其所连控制器的信息。
- 获得所有网桥
我们查看一下网桥信息
Python |copy code |?
1 2 query = {"method":"transact", "params":["Open_vSwitch", {"op":"select","table": "Controller", "where":[]}], "id": 0}
3 s.send(json.dumps(query))
4 response = s.recv(BUFSIZE)
5 print response
6
执行./ovs.py |python -m json.tool
返回的结果1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192{"error" : null ,"id" : 0 ,"result" : [{"rows" : [{"_uuid" : ["uuid" ,"15846c69-f014-4a5a-bc8d-3cb67cc3cb03"] ,"_version" : ["uuid" ,"3a6bf4ed-035b-4e57-beb3-8bd08997826e"] ,"connection_mode" : ["set" ,[ ]] ,"controller_burst_limit" : ["set" ,[ ]] ,. . . ."role" : "master" ,"status" : ["map" ,[["last_error" ,"Connection refused"] ,["sec_since_connect" ,"423018"] ,["sec_since_disconnect" ,"423089"] ,["state" ,"ACTIVE"]]] ,"target" : "tcp:30.0.0.1"} ,{"_uuid" : ["uuid" ,"77fab68b-c693-4c9e-aea7-ba847809376d"] ,"_version" : ["uuid" ,"5e1f25ec-ae35-43fe-9cf4-835ef5980056"] ,"connection_mode" : ["set" ,[ ]] ,. . . . ."role" : "master" ,"status" : ["map" ,[["last_error" ,"Connection refused"] ,["sec_since_connect" ,"423018"] ,["sec_since_disconnect" ,"423089"] ,["state" ,"ACTIVE"]]] ,"target" : "tcp:30.0.0.1"}]}]}这里列出了两个 controller项,但目标地址都是 30.0.0.1,说明都是同一个 controller,但是这两项的 uuid不同,如 15846c69 - f014 - 4a5a - bc8d - 3cb67cc3cb03是 br - tun设置的 controller,而 77fab68b - c693 - 4c9e - aea7 - ba847809376d是 br - in设置的 controller。- 获得所有openflow信息
代码为
Python |copy code |?
1 2 query = {"method":"transact", "params":["Open_vSwitch", {"op":"select","table": "Flow_Table", "where":[]}], "id": 0}
3 s.send(json.dumps(query))
4 response = s.recv(BUFSIZE)
5 print response
6
执行./ovs.py |python -m json.tool
返回的结果result为空,而且静态动态流都为空,开始很疑惑,后来了解ovsdb主要是存放静态信息,所以流信息是没有保留的。获取流应该从vswitchd中获取,具体怎么做看下一篇吧:-)
ovsdb和vswitchd的关系如该图所示,还有一些ovs的命令。
- 准备工作
最后说明一下,用REST访问ovsdb可以使用程序化的方法获得ovs的信息,为下一步工作打下基础