用REST获得openvswitch ovsdb的信息

客户端可以通过ovsdb定义的协议访问openvswitch的数据库,协议在http://tools.ietf.org/html/draft-pfaff-ovsdb-proto-02,看来要成为ietf的标准了?怎么查询这些数据其实有一个样例,但是比较简单,我这里略作扩展,说明如何查询ovs的网桥、所连controller和流信息。

    1. 准备工作
    2. 因为ovs需要认证(公钥)才能访问其数据,我们为了简化直接在ovs所在节点上运行以下命令:

      ovs-appctl -t ovsdb-server ovsdb-server/add-remote ptcp:6632

      然后可以直接通过tcp的方式访问ovsdb了

    3. echo发送存活信息
    4. 客户端可以使用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中到底有些什么数据

    5. 获得所有数据库名
    6. 脚本中其他不变,最后三行换为以下内容,以后步骤也是类似:

      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。接下来我们查询这个数据库有哪些表

    7. 获得数据库的所有表结构
    8. 同样,代码为

      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。

    9. 获得所有网桥
    10. 我们查看一下网桥信息

      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字段存在,说明该网桥受控制器控制。那我们再看一下其所连控制器的信息。

    11. 获得所有网桥
    12. 我们查看一下网桥信息

      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。
    13. 获得所有openflow信息
    14. 代码为

      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的命令。
      ovs关系图

最后说明一下,用REST访问ovsdb可以使用程序化的方法获得ovs的信息,为下一步工作打下基础

Leave a Reply

Your email address will not be published. Required fields are marked *