Open vSwitch 入門實踐(3)使用OVS配置流量映象

語言: CN / TW / HK

前言

當我們想要在不影響虛擬網路裝置資料報文收發的情況下獲取對應虛擬網路裝置的流量時,流量映象是一個很好的選擇。流量映象是指將經過指定埠(映象埠)的報文複製一份到另一個指定埠(觀察埠),通過觀察埠接收到的資料報文,就可以有效識別虛擬網路的執行情況。

OVS提供了相關命令來配置或刪除埠映象,下面我們來實驗一下。

如何使用

流量映象類

流量映象分為映象源和映象目的兩部分。

映象源

  • select_all:布林型別(true,false)。設定為 true 時,表示此網橋上的所有流量。
  • select_dst_port:字串(埠名稱)。表示此埠接收的所有流量。
  • select_src_port:字串(埠名稱)。表示此埠傳送的所有流量。
  • select_vlan:整形(1-4096)。表示攜帶此VLAN標籤的流量。

映象目的

  • output_port:字串(埠名稱)。接收流量報文的觀察埠。
  • output_vlan:整形(1-4096)。表示只修改VLAN標籤,原VLAN標籤會被剝離。

基礎操作命令

新增流量映象

ovs-vsctl -- set Bridge <bridge_name> mirrors=@m \
 -- --id=@<port0> get Port <port0> \
 -- --id=@<port1> get Port <port1> \
 -- --id=@m create Mirror name=<mirror_name> select-dst-port=@<port0> select-src-port=@<port0> output-port=@<port1>

這行命令會輸出一個映象ID

刪除流量映象

ovs-vsctl remove Bridge <bridge-name> mirrors <mirror-id>

在原流量映象的基礎上增加一個映象源

# 獲取埠的ID
ovs-vsctl get port <port_name> _uuid

# 在原流量映象的基礎上增加映象源
ovs-vsctl add Mirror <mirror-name> select_src_port <port-id>
ovs-vsctl add Mirror <mirror-name> select_dst_port <port-id>

在原流量映象的基礎上刪除一個映象源

# 獲取埠的ID
ovs-vsctl get port <port_name> _uuid

ovs-vsctl remove Mirror <mirror-name> select_src_port <port-id>
ovs-vsctl remove Mirror <mirror-name> select_dst_port <port-id>

清空流量映象

ovs-vsctl clear Mirror

檢視流量映象

ovs-vsctl list Mirror

關閉埠的MAC地址學習

ovs-ofctl mod-port <bridge-name> <port-name> NO-FLOOD

實驗

實驗拓撲

實驗拓撲分為一個網橋,三個虛擬網路裝置,

# 新增網橋
ovs-vsctl add-br br-int
# 新增三個內部埠
ovs-vsctl add-port br-int vnet0 -- set Interface vnet0 type=internal
ovs-vsctl add-port br-int vnet1 -- set Interface vnet1 type=internal
ovs-vsctl add-port br-int vnet2 -- set Interface vnet2 type=internal
# 新增三個netns
ip netns add ns0
ip netns add ns1
ip netns add ns2
# 將內部埠分別移動到netns中
ip link set vnet0 netns ns0
ip link set vnet1 netns ns1
ip link set vnet2 netns ns2

# 啟動埠並配置IP
ip netns exec ns0 ip link set lo up
ip netns exec ns0 ip link set vnet0 up
ip netns exec ns0 ip addr add 10.0.0.1/24 dev vnet0

ip netns exec ns1 ip link set lo up
ip netns exec ns1 ip link set vnet1 up
ip netns exec ns1 ip addr add 10.0.0.2/24 dev vnet1
# 注意這裡只啟動了網絡卡,但沒有配置IP
ip netns exec ns2 ip link set lo up
ip netns exec ns2 ip link set vnet2 up

ovs-vsctl -- set Bridge br-int mirrors=@m \
 -- --id=@vnet1 get Port vnet1 \
 -- --id=@vnet2 get Port vnet2 \
 -- --id=@m create Mirror name=mirror_test select-dst-port=@vnet1 select-src-port=@vnet1 output-port=@vnet2

測試

在第一個控制檯上執行以下命令產生流量

ip netns exec ns0 ping 10.0.0.2

在第二個控制檯上執行以下命令抓包

ip netns exec ns2 tcpdump -i vnet2

輸出

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vnet2, link-type EN10MB (Ethernet), capture size 262144 bytes
22:26:31.140974 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 4599, seq 23, length 64
22:26:31.140996 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 4599, seq 23, length 64
22:26:32.141066 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 4599, seq 24, length 64
22:26:32.141085 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 4599, seq 24, length 64
22:26:33.141066 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 4599, seq 25, length 64
22:26:33.141108 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 4599, seq 25, length 64
22:26:34.141044 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 4599, seq 26, length 64
22:26:34.141062 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 4599, seq 26, length 64
^C
8 packets captured
8 packets received by filter
0 packets dropped by kernel

清空環境

ip netns del ns0
ip netns del ns1
ip netns del ns2

ovs-vsctl del-br br-int