5.2. OVN の論理フローのモニタリング

OVN は論理フローを使用します。これは、優先度、マッチング、アクションで構成されるフローのテーブルです。これらの論理フローは、各コンピュートノード上で実行される ovn-controller に分散されます。コントローラーノード上で ovn-sbctl lflow-list コマンドを使用すると、論理フローの完全なセットを表示することができます。

前提条件

  • ML2/OVN を使用する RHOSP デプロイメント

Procedure

  1. コントローラーノードで ovn-sbctl --db=tcp:172.17.1.10:6642 lflow-list コマンドを実行します。
  2. 出力を検査します。

    $ ovn-sbctl --db=tcp:172.17.1.10:6642 lflow-list
        Datapath: "sw0" (d7bf4a7b-e915-4502-8f9d-5995d33f5d10)  Pipeline: ingress
          table=0 (ls_in_port_sec_l2  ), priority=100  , match=(eth.src[40]), action=(drop;)
          table=0 (ls_in_port_sec_l2  ), priority=100  , match=(vlan.present), action=(drop;)
          table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "sw0-port1" && eth.src == {00:00:00:00:00:01}), action=(next;)
          table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "sw0-port2" && eth.src == {00:00:00:00:00:02}), action=(next;)
          table=1 (ls_in_port_sec_ip  ), priority=0    , match=(1), action=(next;)
          table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "sw0-port1" && eth.src == 00:00:00:00:00:01 && arp.sha == 00:00:00:00:00:01), action=(next;)
          table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "sw0-port1" && eth.src == 00:00:00:00:00:01 && ip6 && nd && ((nd.sll == 00:00:00:00:00:00 || nd.sll == 00:00:00:00:00:01) || ((nd.tll == 00:00:00:00:00:00 || nd.tll == 00:00:00:00:00:01)))), action=(next;)
          table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "sw0-port2" && eth.src == 00:00:00:00:00:02 && arp.sha == 00:00:00:00:00:02), action=(next;)
          table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "sw0-port2" && eth.src == 00:00:00:00:00:02 && ip6 && nd && ((nd.sll == 00:00:00:00:00:00 || nd.sll == 00:00:00:00:00:02) || ((nd.tll == 00:00:00:00:00:00 || nd.tll == 00:00:00:00:00:02)))), action=(next;)
          table=2 (ls_in_port_sec_nd  ), priority=80   , match=(inport == "sw0-port1" && (arp || nd)), action=(drop;)
          table=2 (ls_in_port_sec_nd  ), priority=80   , match=(inport == "sw0-port2" && (arp || nd)), action=(drop;)
          table=2 (ls_in_port_sec_nd  ), priority=0    , match=(1), action=(next;)
          table=3 (ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
          table=4 (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
          table=5 (ls_in_pre_stateful ), priority=100  , match=(reg0[0] == 1), action=(ct_next;)
          table=5 (ls_in_pre_stateful ), priority=0    , match=(1), action=(next;)
          table=6 (ls_in_acl          ), priority=0    , match=(1), action=(next;)
          table=7 (ls_in_qos_mark     ), priority=0    , match=(1), action=(next;)
          table=8 (ls_in_lb           ), priority=0    , match=(1), action=(next;)
          table=9 (ls_in_stateful     ), priority=100  , match=(reg0[1] == 1), action=(ct_commit(ct_label=0/1); next;)
          table=9 (ls_in_stateful     ), priority=100  , match=(reg0[2] == 1), action=(ct_lb;)
          table=9 (ls_in_stateful     ), priority=0    , match=(1), action=(next;)
          table=10(ls_in_arp_rsp      ), priority=0    , match=(1), action=(next;)
          table=11(ls_in_dhcp_options ), priority=0    , match=(1), action=(next;)
          table=12(ls_in_dhcp_response), priority=0    , match=(1), action=(next;)
          table=13(ls_in_l2_lkup      ), priority=100  , match=(eth.mcast), action=(outport = "_MC_flood"; output;)
          table=13(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:01), action=(outport = "sw0-port1"; output;)
          table=13(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:02), action=(outport = "sw0-port2"; output;)
        Datapath: "sw0" (d7bf4a7b-e915-4502-8f9d-5995d33f5d10)  Pipeline: egress
          table=0 (ls_out_pre_lb      ), priority=0    , match=(1), action=(next;)
          table=1 (ls_out_pre_acl     ), priority=0    , match=(1), action=(next;)
          table=2 (ls_out_pre_stateful), priority=100  , match=(reg0[0] == 1), action=(ct_next;)
          table=2 (ls_out_pre_stateful), priority=0    , match=(1), action=(next;)
          table=3 (ls_out_lb          ), priority=0    , match=(1), action=(next;)
          table=4 (ls_out_acl         ), priority=0    , match=(1), action=(next;)
          table=5 (ls_out_qos_mark    ), priority=0    , match=(1), action=(next;)
          table=6 (ls_out_stateful    ), priority=100  , match=(reg0[1] == 1), action=(ct_commit(ct_label=0/1); next;)
          table=6 (ls_out_stateful    ), priority=100  , match=(reg0[2] == 1), action=(ct_lb;)
          table=6 (ls_out_stateful    ), priority=0    , match=(1), action=(next;)
          table=7 (ls_out_port_sec_ip ), priority=0    , match=(1), action=(next;)
          table=8 (ls_out_port_sec_l2 ), priority=100  , match=(eth.mcast), action=(output;)
          table=8 (ls_out_port_sec_l2 ), priority=50   , match=(outport == "sw0-port1" && eth.dst == {00:00:00:00:00:01}), action=(output;)
          table=8 (ls_out_port_sec_l2 ), priority=50   , match=(outport == "sw0-port2" && eth.dst == {00:00:00:00:00:02}), action=(output;)

OVN と OpenFlow には、主に以下のような相違点があります。

  • OVN ポートは、ネットワーク内にある論理エンティティーで、単一のスイッチ上にある物理ポートではありません。
  • OVN により、パイプライン内の各テーブルには番号に加えて名前が付けられます。名前は、パイプライン内のそのステージの目的を示します。
  • OVN の match 構文は、複雑なブール表現をサポートしています。
  • OVN の論理フローでは、OpenFlow よりも幅広いアクションをサポートしています。OVN の論理フローの構文で DHCP などの高度な機能を実装することができます。

ovn-trace

ovn-trace コマンドを使用して、パケットが OVN の論理フローをどのように通過するかシミュレーションしたり、パケットがドロップする原因を特定するのに役立てたりすることができます。ovn-trace コマンドには、以下のパラメーターを指定して実行してください。

DATAPATH
シミュレーションされるパケットの送信が開始される場所の論理スイッチまたは論理ルーター。
MICROFLOW
シミュレーションされるパケット。ovn-sb データベースで使用される構文で指定します。

この例では、シミュレーションされるパケットに --minimal の出力オプションが示されており、そのパケットが宛先に到達したことを表しています。

$ ovn-trace --minimal sw0 'inport == "sw0-port1" && eth.src == 00:00:00:00:00:01 && eth.dst == 00:00:00:00:00:02'
    # reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,dl_type=0x0000
    output("sw0-port2");

さらに詳しい情報を表示するには、シミュレーションされる同じパケットの --summary 出力に完全な実行パイプラインが表示されます。

$ ovn-trace --summary sw0 'inport == "sw0-port1" && eth.src == 00:00:00:00:00:01 && eth.dst == 00:00:00:00:00:02'
# reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,dl_type=0x0000
ingress(dp="sw0", inport="sw0-port1") {
    outport = "sw0-port2";
    output;
    egress(dp="sw0", inport="sw0-port1", outport="sw0-port2") {
        output;
        /* output to "sw0-port2", type "" */;
    };
};

この出力例には、以下の内容が示されています。

  • パケットは sw0-port1 ポートから sw0 ネットワークに入り、受信のパイプラインを通過します。
  • outport 変数が sw0-port2 に設定されているのは、このパケットの宛先が sw0-port2 に指定されていることを意味します。
  • パケットは受信のパイプラインから出力されます。このパイプラインは、outport 変数が sw0-port2 に設定された sw0 の送信パイプラインにパケットを送ります。
  • 出力のアクションは、送信のパイプラインで実行されます。このパイプラインでは、パケットが outport 変数の現在の値である sw0-port2 に出力されます。

関連資料

  • 詳しい情報は、ovn-trace の man ページを参照してください。