- 准备工作
因为ovs需要认证(公钥)才能访问其数据,我们为了简化直接在ovs所在节点上运行以下命令:
ovs-appctl -t ovsdb-server ovsdb-server/add-remote ptcp:6632
然后可以直接通过tcp的方式访问ovsdb了
- echo发送存活信息
客户端可以使用tcp方式与服务器保持长连接,所以可能定时需要发送echo信息与服务器确认存活。可编写以下脚本:
import socket
import json
OVSDB_IP = '127.0.0.1'
OVSDB_PORT = 6632
BUFSIZE = 409600
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((OVSDB_IP, OVSDB_PORT))
query = {"method":"echo", "params":[], "id": 0}
s.send(json.dumps(query))
response = s.recv(BUFSIZE)
print response
执行结果为:
{“id”:0,”result”:[],”error”:null}
这是最简单的获取信息方式了,我们接下来要看看OVSDB中到底有些什么数据
- 获得所有数据库名
脚本中其他不变,最后三行换为以下内容,以后步骤也是类似:
query = {"method":"list_dbs", "params":[], "id": 0}
s.send(json.dumps(query))
response = s.recv(BUFSIZE)
print response
执行后结果为
{“id”:0,”result”:[“Open_vSwitch”],”error”:null}
可见现在OVSDB中只有一个数据库Open_vSwitch。接下来我们查询这个数据库有哪些表
- 获得数据库的所有表结构
同样,代码为
query = {"method":"get_schema", "params":["Open_vSwitch"], "id": 0}
s.send(json.dumps(query))
response = s.recv(BUFSIZE)
print response
因为表结构字段较多,所以我们将结果格式化,执行./ovs.py |python -m json.tool
返回的结果将是所有数据库的内容
{
"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。
- 获得所有网桥
我们查看一下网桥信息
query = {"method":"transact", "params":["Open_vSwitch", {"op":"select", "table": "Bridge", "where":[]}], "id": 0}
s.send(json.dumps(query))
response = s.recv(BUFSIZE)
print response
执行./ovs.py |python -m json.tool
返回的结果将是所有数据库的内容
{
"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字段存在,说明该网桥受控制器控制。那我们再看一下其所连控制器的信息。
- 获得所有网桥
我们查看一下网桥信息
query = {"method":"transact", "params":["Open_vSwitch", {"op":"select", "table": "Controller", "where":[]}], "id": 0}
s.send(json.dumps(query))
response = s.recv(BUFSIZE)
print response
执行./ovs.py |python -m json.tool
返回的结果
{
"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信息
代码为
query = {"method":"transact", "params":["Open_vSwitch", {"op":"select", "table": "Flow_Table", "where":[]}], "id": 0}
s.send(json.dumps(query))
response = s.recv(BUFSIZE)
print response
执行./ovs.py |python -m json.tool
返回的结果result为空,而且静态动态流都为空,开始很疑惑,后来了解ovsdb主要是存放静态信息,所以流信息是没有保留的。获取流应该从vswitchd中获取,具体怎么做看下一篇吧:-)
ovsdb和vswitchd的关系如该图所示,还有一些ovs的命令。