openvswitch
ovs是一个开源的虚拟交换机,具有强大的功能
ovs通过flow能实现很多策略和功能
安装
apt
sudo apt install openvswitch-switch
yum
官方未提供yum源需要编译安装
# 安装编译依赖
yum -y install
epel-release \
rpm-build \
rpmlint \
yum-utils \
rpmdevtools \
gcc \
gcc-c++ \
autoconf \
automake \
libtool \
systemd-units \
openssl \
openssl-devel \
python3-devel \
desktop-file-utils \
groff \
graphviz \
checkpolicy \
selinux-policy-devel \
python3-sphinx \ # 需要epel源
procps-ng \
libcap-ng \
libcap-ng-devel \
libpcap-devel \
numactl-devel \
dpdk-devel \
libbpf-devel \
numactl-devel \
unbound \
unbound-devel
# 创建并切换到ovs用户
useradd ovs && su - ovs
# 创建编译的文件夹
rpmdev-setuptree
wget https://www.openvswitch.org/releases/openvswitch-2.16.0.tar.gz
tar -C ~/rpmbuild/SOURCES/ -xzf openvswitch-2.16.0.tar.gz
# 编译为rpm
rpmbuild -bb --nocheck ~/rpmbuild/SOURCES/openvswitch-2.16.0/rhel/openvswitch-fedora.spec
# 安装
yum -y install ~/rpmbuild/SOURCES/openvswitch-2.16.0-1.el7.x86_64.rpm
# 启动服务
systemctl start openvswitch
systemctl enable openvswitch
bridge
查看
ovs-vsctl list-br
增加
# 增加一个网桥叫vbr0
ovs-vsctl add-br vbr0
删除
ovs-vsctl del-br ovs-switch
port
查看所有ports
ovs-vsctl list-ports BRIDGE
查看端口id
ovs-vsctl list interface veth | grep "ofport"
增加
ovs-vsctl add-port BRIDGE PORT
删除
ovs-vsctl del-port BRIDGE PORT
flow
flow翻译为流表,其表示一些规则,能够控制数据包的转发
显示 vbr0的 flow
ovs-ofctl dump-flows vbr0
cookie=0x0, duration=17.496s, table=0, n_packets=0, n_bytes=0, priority=0 actions=NORMAL
清除vbr0所有flows
ovs-ofctl del-flows vbr0
显示vbr0的groups表
ovs-ofctl dump-groups vbr0
增加流表
ovs-ofctl add-flow vbr0 "table=0, priority=0 actions=NORMAL"
flow语法
一般语法为: 基本 匹配规则 actions
组成
如:"table=0, priority=0 actions=NORMAL"
基本:
- duration_sec – 生效时间
- table_id – 所属表项,id越小匹配靠前
- priority – 优先级,数越大优先级越高
- n_packets – 处理数据包数量
- idle_timeout – 空闲超时时间(秒),超时则自动删除该表规则,0 表示该流规则永不过期。
idle_timeout 不包含在 ovs-ofctl dump-flows br_name 的输出。
匹配字段:
in_port – vSwitch 的 INPUT Port 号
dl_src (Data Link layer) – 源 MAC 地址
dl_dst – 目的 MAC 地址
nw_src (Network layer) – 源 IP 地址
nw_dst – 目的 IP 地址
tp_src – TCP/UDP 源端口号
tp_dst – TCP/UDP 目的端口号
dl_type – 以太网协议类型,又称数据包(Packet)类型
ARP Packet – dl_type=0x0806
IP Packet – dl_type=0x0800
RARP Packet – dl_type=0x8035
nw_proto – 网络层协议类型,与 dl_type 一起使用
ICMP Packet – dl_type=0x0800,nw_proto=1
TCP Packet – dl_type=0x0800,nw_proto=6
UDP Packet – dl_type=0x0800,nw_proto=17
actions:
- NORMAL 和普通交换机一样正常转发
- OUTPUT 转发到某个端口
- GROUP 指定某个grup在处理
- DROP 丢弃
例子:
# 增加一条flows匹配端口id是1的端口,将他的数据转发到端口是2的接口上
ovs-ofctl add-flow vbr0 "table=1,priority=1,in_port=1,actions=output:2"
group
查看
ovs-ofctl dump-groups vbr0
全部删除
ovs-ofctl del-groups vbr0
增加group表
ovs-ofctl add-group vbr0 <group>
group语法
组表需要在流表上跳转,一个group有很多bucket,很具类型选择执行
group有很多类型(type)
select 随机执行一个Bucket,一般用于负载均衡
all 所有的Bucket 都执行
group表有很多可以参考后面的地址
# 将目标地址是192.168.1.66的流量跳转到group:1去
ovs-ofctl add-flow vbr0 "table=0,priority=888,in_port=5,dl_type=0x0800,nw_dst:192.168.1.66/32,actions=group:1"
# 修改ip地址为172.16.1.1或172.16.1.1者然后从vbr0发出
ovs-ofctl add-group vbr0 group_id=1,type=select,bucket=actions=mod_nw_dst:172.16.1.1,output:vbr0,bucket=actions=mod_nw_dst:172.16.1..2,output:vbr0
ovs-docker
docker默认未集成ovs驱动,我们可以通过创建个无网络的容器通过
ovs-docker
这个工具配置网络
# 启动一个无网络的容器
docker run --net=none --privileged=true -it ubuntu:14.04 bash
# 在容器id为04c864c8ec59 中创建一个叫eth0的网卡并连接在vbr0,
ovs-docker add-port vbr0 eth0 04c864c8ec59 --ipaddress="192.168.1.2/24" --gateway=192.168.1.1
参考资料
https://zhuanlan.zhihu.com/p/37408341
https://www.cnblogs.com/jmilkfan-fanguiju/p/11825081.html
https://docs.openvswitch.org/en/latest