openvswitch基础

举报
Tony Zhang 发表于 2019/12/25 19:30:00 2019/12/25
【摘要】 openvswitch基础基础命令# 1 创建网桥[root@vm180 ~]# ovs-vsctl add-br br0# 2.1 创建内部接口port1[root@vm180 ~]# ovs-vsctl add-port br0 port1 -- set interface port1 type=internal# 2.2 创建成功后会在系统产生一个对应的网络接口port1[root@v...

openvswitch基础

基础命令

# 1 创建网桥
[root@vm180 ~]# ovs-vsctl add-br br0

# 2.1 创建内部接口port1
[root@vm180 ~]# ovs-vsctl add-port br0 port1 -- set interface port1 type=internal

# 2.2 创建成功后会在系统产生一个对应的网络接口port1
[root@vm180 ~]# ip link
...
16: port1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether ca:d0:b7:fc:64:d7 brd ff:ff:ff:ff:ff:ff   
    
# 3 将系统网络接口(eth1)加入到网桥中
[root@vm180 ~]# ovs-vsctl add-port br0 eth1

# 4.1 创建patch port(类似于veth pair),用于连接两个ovs网桥,在网桥br0上创建patch port
[root@vm180 ~]# ovs-vsctl add-port br0 patch-eb4c163-a -- set interface patch-eb4c163-a type=patch options:peer=patch-eb4c163-b

# 4.2 在网桥br1上创建patch port
[root@vm180 ~]# ovs-vsctl add-port br1 patch-eb4c163-b -- set interface patch-eb4c163-b type=patch options:peer=patch-eb4c163-a

# 4.3 查看patch port
[root@vm180 ~]# ovs-vsctl show
f22b449d-96ff-4a7c-ab99-bc488bfecb05
    Bridge "br0"
        Port "tap0"
            interface "tap0"
                type: internal
        Port "br0"
            interface "br0"
                type: internal
        Port "patch-eb4c163-a"
            interface "patch-eb4c163-a"
                type: patch
                options: {peer="patch-eb4c163-b"}
    Bridge "br1"
        Port "tap1"
            interface "tap1"
                type: internal
        Port "patch-eb4c163-b"
            interface "patch-eb4c163-b"
                type: patch
                options: {peer="patch-eb4c163-a"}
        Port "br1"
            interface "br1"
                type: internal
    ovs_version: "2.5.6"
    
# 5.1 在vm180上创建vxlan0接口,指定VNI为100
[root@vm180 ~]# ovs-vsctl add-port br0 vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.144.60.181 options:key=100

# 5.2 在vm181上创建vxlan0接口,指定VNI为100
[root@vm181 ~]# ovs-vsctl add-port br0 vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.144.60.180 options:key=100

# 6.1 设置端口的tag(vlan id)
[root@vm180 ~]# ovs-vsctl set port <port> tag=<tag-id>

# 6.2 清除端口的tag(vlan id)
[root@vm180 ~]# ovs-vsctl clear port <port> tag

流表命令

# 查看网桥br0上的流表
[root@vm181 ~]# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=49275.418s, table=0, n_packets=22400, n_bytes=5299127, idle_age=12, priority=0 actions=NORMAL
 
 # 查看port的ofport,常用于匹配项in_port,和动作output的参数
 [root@vm181 ~]# ovs-vsctl list interface tap0
 _uuid               : 5ab1ac08-fba5-4c6c-a48e-0dec5e0bc808
admin_state         : up
bfd                 : {}
bfd_status          : {}
cfm_fault           : []
cfm_fault_status    : []
cfm_flap_count      : []
cfm_health          : []
cfm_mpid            : []
cfm_remote_mpids    : []
cfm_remote_opstate  : []
duplex              : []
error               : []
external_ids        : {}
ifindex             : 6
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current        : []
link_resets         : 1
link_speed          : []
link_state          : up
lldp                : {}
mac                 : []
mac_in_use          : "8e:10:e3:4b:ff:4f"
mtu                 : 1500
name                : "tap0"
ofport              : 2
ofport_request      : []
options             : {}
other_config        : {}
statistics          : {collisions=0, rx_bytes=206024, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=2580, tx_bytes=5086470, tx_dropped=0, tx_errors=0, tx_packets=19925}
status              : {driver_name=openvswitch}
type                : internal

或者
[root@vm181 ~]# ovs-ofctl show br0
 OFPT_FEATURES_REPLY (xid=0x2): dpid:0000f6c9e8e36e4a
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 2(tap0): addr:8e:10:e3:4b:ff:4f
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 8(vxlan1): addr:fe:cd:6c:ac:d6:d5
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 9(vxlan0): addr:c6:d0:85:7e:ca:63
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br0): addr:f6:c9:e8:e3:6e:4a
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0

# 查看网桥的fdb表
[root@vm181 ~]# ovs-appctl fdb/show br0
 port  VLAN  MAC                Age
    2     0  8e:10:e3:4b:ff:4f    0

OVS实战

vlan

# 创建三台主机
[root@vm181 ~]# ip netns add vm0
[root@vm181 ~]# ip netns add vm1
[root@vm181 ~]# ip netns add vm2

# 在br0上创建tap0并接入到vm0中
[root@vm181 ~]# ovs-vsctl add-port br0 tap0 -- set interface tap0 type=internal
[root@vm181 ~]# ip link set tap0 netns vm0
# 进入vm0设置ip
[root@vm181 ~]# netns=vm0; ip netns exec ${netns} bash --rcfile <(echo "PS1=\"${netns}$ \"")
vm0$ ip addr add 172.16.0.100/24 dev tap0
vm0$ ip link set tap0 up
vm0$ ip link set lo up
vm0$ ip addr
...
14: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether 42:cb:85:b8:bf:2a brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.100/24 scope global tap0
       valid_lft forever preferred_lft forever
    inet6 fe80::40cb:85ff:feb8:bf2a/64 scope link 
       valid_lft forever preferred_lft forever
vm0$ exit

# 在br0上创建tap1并接入到vm1中
[root@vm181 ~]# ovs-vsctl add-port br0 tap1 -- set interface tap1 type=internal
[root@vm181 ~]# ip link set tap1 netns vm1
# 进入vm1设置ip
[root@vm181 ~]# netns=vm1; ip netns exec ${netns} bash --rcfile <(echo "PS1=\"${netns}$ \"")
vm1$ ip addr add 172.16.0.101/24 dev tap1
vm1$ ip link set tap1 up
vm1$ ip link set lo up
vm1$ ip addr
...
15: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether 82:86:1f:c6:d3:8a brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.101/24 scope global tap1
       valid_lft forever preferred_lft forever
    inet6 fe80::8086:1fff:fec6:d38a/64 scope link 
       valid_lft forever preferred_lft forever
vm1$ exit

# 在br0上创建tap2并接入到vm2中
[root@vm181 ~]# ovs-vsctl add-port br0 tap2 -- set interface tap2 type=internal
[root@vm181 ~]# ip link set tap2 netns vm2
# 进入vm2设置ip
[root@vm181 ~]# netns=vm2; ip netns exec ${netns} bash --rcfile <(echo "PS1=\"${netns}$ \"")
vm2$ ip addr add 172.16.0.102/24 dev tap2
vm2$ ip link set tap2 up
vm2$ ip link set lo up
vm2$ ip addr
...
16: tap2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether 56:0b:aa:c1:91:8d brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.102/24 scope global tap2
       valid_lft forever preferred_lft forever
    inet6 fe80::540b:aaff:fec1:918d/64 scope link 
       valid_lft forever preferred_lft forever
vm2$ exit

# 将tap0、tap1和tap2加入到vlan100中
[root@vm181 ~]# ovs-vsctl set port tap0 vlan tag=100
[root@vm181 ~]# ovs-vsctl set port tap1 vlan tag=100
[root@vm181 ~]# ovs-vsctl set port tap2 vlan tag=100
[root@vm181 ~]# ovs-vsctl show
a2341c69-656c-477f-bf5e-d922ceffc6b8
    Bridge "br0"
        Port "tap0"
            tag: 100
            Interface "tap0"
                type: internal
        Port "br0"
            Interface "br0"
                type: internal
        Port "tap2"
            tag: 100
            Interface "tap2"
                type: internal
        Port "tap1"
            tag: 100
            Interface "tap1"
                type: internal
    ovs_version: "2.5.6"
# 连通性检查vm0 -> vm1和vm2
vm0$ ping 172.16.0.101
PING 172.16.0.101 (172.16.0.101) 56(84) bytes of data.
64 bytes from 172.16.0.101: icmp_seq=1 ttl=64 time=0.188 ms

vm0$ ping 172.16.0.102
PING 172.16.0.102 (172.16.0.102) 56(84) bytes of data.
64 bytes from 172.16.0.102: icmp_seq=1 ttl=64 time=0.041 ms

# 将tap3加入到vlan101中
[root@vm181 ~]# ovs-vsctl set port tap2 tag=101
[root@vm181 ~]# ovs-vsctl show
a2341c69-656c-477f-bf5e-d922ceffc6b8
    Bridge "br0"
        Port "tap0"
            tag: 100
            Interface "tap0"
                type: internal
        Port "br0"
            Interface "br0"
                type: internal
        Port "tap2"
            tag: 101
            Interface "tap2"
                type: internal
        Port "tap1"
            tag: 100
            Interface "tap1"
                type: internal
    ovs_version: "2.5.6"

# 连通性检查,vm0 -> vm1:通,vm0 -> vm2:不通
vm0$ ping 172.16.0.101
PING 172.16.0.101 (172.16.0.101) 56(84) bytes of data.
64 bytes from 172.16.0.101: icmp_seq=1 ttl=64 time=0.200 ms

vm0$ ping 172.16.0.102
PING 172.16.0.102 (172.16.0.102) 56(84) bytes of data.
From 172.16.0.100 icmp_seq=10 Destination Host Unreachable

防火墙

实验环境:vm0和vm1,在br0上配置防护策略。

防护策略:

  1. 默认丢弃所有包

  2. 开通vm0的tcp 22端口

# 在vm0上开启tcp服务,监听22端口
vm0$ nc -k -lp 22

# 清空br0上的流表
[root@vm181 ~]# ovs-ofctl del-flows br0

# 在vm1上连接vm0的22端口
vm1$ nc -v 172.16.0.100 22
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection timed out.

# 开启br0的arp功能
[root@vm181 ~]# ovs-ofctl add-flow br0 arp,actions=normal

# 在br0上添加流表,开通vm0的tcp 22端口
[root@vm181 ~]# ovs-ofctl add-flow br0 nw_dst=172.16.0.100/24,tcp,tp_dst=22,actions=NORMAL
[root@vm181 ~]# ovs-ofctl add-flow br0 nw_src=172.16.0.100/24,tcp,tp_src=22,actions=NORMAL

# 查看流表
[root@vm181 ~]# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=70.116s, table=0, n_packets=2, n_bytes=84, idle_age=12, arp actions=NORMAL
 cookie=0x0, duration=38.510s, table=0, n_packets=4, n_bytes=288, idle_age=14, tcp,nw_dst=172.16.0.0/24,tp_dst=22 actions=NORMAL
 cookie=0x0, duration=15.212s, table=0, n_packets=1, n_bytes=74, idle_age=14, tcp,nw_src=172.16.0.0/24,tp_src=22 actions=NORMAL

# 连通性测试
vm1$ nc -v 172.16.0.100 22
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 172.16.0.100:22.

NAT

# 重置br0上的流表
[root@vm181 ~]# ovs-ofctl del-flows br0
[root@vm181 ~]# ovs-ofctl add-flow br0 actions=NORMAL

# 创建vm3
[root@vm181 ~]# ip netns add vm3

# 创建br-nat网桥
[root@vm181 ~]# ovs-vsctl add-br br-nat

# 在br-nat上创建接口并连接到vm3上
[root@vm181 ~]# ovs-vsctl add-port br-nat tap3 -- set interface tap3 type=internal
[root@vm181 ~]# ip link set tap3 netns vm3

# 进入vm3配置接口ip
[root@vm181 ~]# netns=vm3; ip netns exec ${netns} bash --rcfile <(echo "PS1=\"${netns}$ \"")
vm3$ 
vm3$ ip addr add 203.0.1.101/24 dev tap3
vm3$ ip link set tap3 up
vm3$ ip link set lo up
vm3$ ip addr
...
19: tap3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether 4a:74:91:ef:00:a6 brd ff:ff:ff:ff:ff:ff
    inet 203.0.1.101/24 scope global tap3
       valid_lft forever preferred_lft forever
    inet6 fe80::4874:91ff:feef:a6/64 scope link 
       valid_lft forever preferred_lft forever

# 连接br0和br-nat
[root@vm181 ~]# ovs-vsctl add-port br0 patch-nat-a -- set interface patch-nat-a type=patch options:peer=patch-nat-b
[root@vm181 ~]# ovs-vsctl add-port br-nat patch-nat-b -- set interface patch-nat-b type=patch options:peer=patch-nat-a
[root@vm181 ~]# 
[root@vm181 ~]# ovs-vsctl show
a2341c69-656c-477f-bf5e-d922ceffc6b8
    Bridge br-nat
        Port br-nat
            Interface br-nat
                type: internal
        Port patch-nat-b
            Interface patch-nat-b
                type: patch
                options: {peer=patch-nat-a}
        ...
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
        Port patch-nat-a
            Interface patch-nat-a
                type: patch
                options: {peer=patch-nat-b}
        ...
    ovs_version: "2.5.6"

vxlan

  1. 静态隧道

[root@vm180 ~]# ovs-vsctl add-port br-tun vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.144.60.181 options:key=1000

[root@vm180 ~]# ovs-vsctl show
f22b449d-96ff-4a7c-ab99-bc488bfecb05
    Bridge br-tun
        Port "p2"
            tag: 101
            Interface "p2"
                type: internal
        Port "vxlan0"
            Interface "vxlan0"
                type: vxlan
                options: {key="1000", remote_ip="192.144.60.181"}
        Port "p1"
            tag: 100
            Interface "p1"
                type: internal
        Port br-tun
            Interface br-tun
                type: internal
    ovs_version: "2.5.6"

[root@vm181 ~]# ovs-vsctl add-port br-tun vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.144.60.180 options:key=1000

[root@vm181 ~]# ovs-vsctl show
a2341c69-656c-477f-bf5e-d922ceffc6b8
    Bridge br-tun
        Port "p2"
            tag: 101
            Interface "p2"
                type: internal
        Port br-tun
            Interface br-tun
                type: internal
        Port "vxlan0"
            Interface "vxlan0"
                type: vxlan
                options: {key="1000", remote_ip="192.144.60.180"}
        Port "p1"
            tag: 100
            Interface "p1"
                type: internal
    ovs_version: "2.5.6"
    
[root@vm181 ~]# ping 10.0.0.101 
PING 10.0.0.101 (10.0.0.101) 56(84) bytes of data.
64 bytes from 10.0.0.101: icmp_seq=1 ttl=64 time=0.504 ms
64 bytes from 10.0.0.101: icmp_seq=2 ttl=64 time=0.206 ms
  1. 动态隧道

# 设置vxlan端口
[root@vm180 ~]# ovs-vsctl add-port br-tun vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=flow options:key=flow

[root@vm181 ~]# ovs-vsctl add-port br-tun vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=flow options:key=flow

# 设置流表
[root@vm180 ~]# ovs-ofctl add-flow br-tun "dl_vlan=100,actions=set_tunnel:1000,set_field:192.144.60.181->tun_dst,NORMAL"

[root@vm181 ~]# ovs-ofctl add-flow br-tun "in_port=2,actions=load:1000->NXM_NX_TUN_ID[],set_field:192.144.60.180->tun_dst,NORMAL"

[root@vm181 ~]# ping 10.0.0.101 
PING 10.0.0.101 (10.0.0.101) 56(84) bytes of data.
64 bytes from 10.0.0.101: icmp_seq=1 ttl=64 time=0.454 ms
64 bytes from 10.0.0.101: icmp_seq=2 ttl=64 time=0.113 ms
  1. 动态隧道的建立需要设置相应的流表,从数据包匹配的流表中提取目标vtep的地址。

Openvswitch Tunnel TLV

tunnel tlv(type、length和value)是一个网桥的元数据(key、value形式),可以用于标记/分类一个网桥,并用在流表匹配、action等中。流表中通过tun_metadatan对元数据进行读取,如下:

ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0"
ovs-ofctl add-flow br0 tun_metadata0=1234,actions=controller

http://www.openvswitch.org/support/dist-docs-2.5/ovs-ofctl.8.html

分片模式

  1. normal(默认):和为分片的报文段一样通过流表,TCP、UDP端口和ICMP类型、code字段总是被置0,即使是分片中的第一个报文段(offset等于0)。

  2. nx-match:和为分片的报文段一样通过流表,对于分片中的第一个报文段(offset等于0)TCP、UDP端口和ICMP类型、code字段 可用的,但是其他分片(offset不等于0)的这些字段总是被置0。

流语法/匹配字段

dl_vlan_pcp : 3bit,Priority Code Point (PCP),指定帧的优先级0~7,数值越大优先级越高

dl_type:数据链路层协议(如Ethernet)中封装的协议类型,即以太类型

arp_spa:source ip address

arp_tpa:target ip address

dl_*:data link layer

nw_*:network layer

ip:dl_type=0x0800

arp:dl_type=0806

nw_proto/ip_proto:网络层协议中封装的协议类型,即IP协议

tun_id:vni

tun_src/tun_dst:隧道端点的IPv4地址

action

set_tunnel: id

move:src[start..end]−>dst[start..end] 拷贝,src和dst字段必须是NXM字段(nicira-ext.h)

set_field:00:11:22:33:44:55->eth_src 等效于 load:0x001122334455->OXM_OF_ETH_DST[]

ecmp

ovs-ofctl add-group br0 group_id=1,type=select,bucket=output:2,bucket=output:3 ovs-ofctl add-flow br0 dl_type=0x0800,nw_src=192.168.1.0/24,actions=group:1

用户态vxlan

ovs-vsctl set bridge br0 datapath_type=netdev datapath_type:

  • system表示内核数据通路。

  • netdev表示用户态数据通路

https://github.com/openvswitch/ovs/blob/master/Documentation/intro/install/userspace.rst

http://docs.openvswitch.org/en/latest/howto/userspace-tunneling/


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。