4、OVS核心概念:网桥、端口、流表、OpenFlow协议简介

好,咱们今天聊聊OVS的几个核心概念。说实话,这些概念是理解OVS的基石。你如果搞懂了网桥、端口、流表和OpenFlow协议,那OVS在你眼里就不再是黑盒子了。

我刚开始接触OVS的时候,也觉得很抽象。后来在项目中一点点摸索,才慢慢理清了它们之间的关系。说白了,OVS就是一个软件实现的虚拟交换机,它跟物理交换机在逻辑上是对应的。

4.1 网桥(Bridge)—— 虚拟交换机的核心

网桥是什么?你可以把它想象成一个虚拟的二层交换机。它负责转发数据包,连接各种虚拟端口。

在OVS里,网桥就是最顶层的逻辑设备。你创建一个网桥,就等于在宿主机上造了一台虚拟交换机。我习惯把网桥比作一个“交换矩阵”,所有流量都要经过它来决策。

创建网桥的命令很简单:

ovs-vsctl add-br br0

这条命令会创建一个名为 br0 的网桥。之后你就可以往里面添加端口了。

我的经验: 网桥的名字最好有意义。比如 br-mgmt 代表管理网桥,br-data 代表数据网桥。别像我早期那样,随便起个 br0br1,项目一多自己都分不清。

4.2 端口(Port)—— 连接容器与网络的桥梁

端口是网桥的“接口”。每个端口都连接着一个网络设备,比如虚拟网卡(veth pair)、TAP设备,甚至是物理网卡。

在Docker容器网络里,端口的作用尤其重要。容器通过veth pair连接到OVS网桥,veth的一端在容器里,另一端在OVS上。这样容器就能跟外界通信了。

添加端口的命令:

ovs-vsctl add-port br0 eth0
ovs-vsctl add-port br0 veth1

这里 eth0 是物理网卡,veth1 是虚拟网卡。你想想看,一个网桥可以同时连接物理和虚拟设备,这就是OVS的灵活之处。

注意: 端口类型有很多种,比如 internalpatchtunnel 等。我曾经在项目中误把端口类型设错,导致容器间通信失败。排查了半天才发现是端口类型不匹配。

4.3 流表(Flow Table)—— 转发决策的大脑

流表是OVS最核心的部分。它决定了数据包该怎么处理。每个流表由多条流表项组成,每条流表项包含匹配条件和动作。

匹配条件可以是源MAC、目的MAC、源IP、目的IP、端口号等等。动作可以是转发到某个端口、丢弃、修改字段等。

举个例子:

ovs-ofctl add-flow br0 "in_port=1,dl_dst=00:00:00:00:00:02,actions=output:2"

这条流表的意思是:从端口1进来的数据包,如果目的MAC是 00:00:00:00:00:02,就转发到端口2。

流表的匹配是从上到下的,优先级高的先匹配。如果没有匹配到任何流表项,默认动作是丢弃。嗯,这里要注意,默认丢弃意味着你如果不配置流表,网桥就是个“黑洞”。

核心要点: 流表是OVS的灵魂。你配置的每一条流表,都在告诉OVS“这个包该怎么走”。我建议初学者先手动添加几条简单的流表,感受一下匹配和转发的逻辑。

4.4 OpenFlow协议简介—— 控制与转发的分离

OpenFlow协议是OVS和控制器之间的通信语言。它定义了控制器如何向OVS下发流表,以及OVS如何上报状态。

说白了,OpenFlow让控制平面和数据平面分离了。控制器负责决策,OVS负责执行。这种架构的好处是灵活,你可以用软件定义整个网络的行为。

OpenFlow协议有几个版本,从1.0到1.5。OVS主要支持1.0和1.3。我个人习惯用1.3版本,因为它支持多级流表和组表,功能更强大。

查看当前OVS支持的OpenFlow版本:

ovs-ofctl -O OpenFlow13 dump-features br0

这里 -O OpenFlow13 指定了使用OpenFlow 1.3版本。

避坑指南: 我曾经在项目中遇到一个问题:控制器下发的流表在OVS上不生效。后来发现是OpenFlow版本不匹配。控制器用的是1.3,而OVS默认用的是1.0。所以一定要确保版本一致。

4.5 它们之间的关系

网桥、端口、流表和OpenFlow协议,它们之间的关系是这样的:

  • 网桥是容器,装着端口和流表。
  • 端口是网桥的“门”,数据从门进,从门出。
  • 流表是网桥的“大脑”,决定数据怎么走。
  • OpenFlow协议是“遥控器”,让外部控制器能指挥网桥。

你想想看,没有流表,网桥就是个傻瓜设备,只会广播。没有OpenFlow,你就得手动配置每一条流表,效率很低。有了OpenFlow,控制器可以动态下发流表,实现智能转发。

我举个例子帮你理解:

假设你有一个OVS网桥 br0,上面有两个端口 veth1veth2,分别连接两个容器。你想让容器A和容器B能互相通信。

手动配置流表:

ovs-ofctl add-flow br0 "in_port=veth1,actions=output:veth2"
ovs-ofctl add-flow br0 "in_port=veth2,actions=output:veth1"

这样,从veth1进来的包就转发到veth2,反之亦然。两个容器就能通信了。

但如果用OpenFlow控制器,你只需要在控制器上写一段逻辑,控制器会自动下发这些流表。这就是自动化的魅力。

总结一下: 网桥是基础,端口是入口,流表是核心,OpenFlow是灵魂。这四个概念搞懂了,OVS你就入门了。后面我们会深入流表的匹配过程,以及如何用OpenFlow实现复杂的网络策略。

好了,这一章就到这里。下一章我们聊聊如何用OVS搭建一个简单的Docker容器网络,到时候我会手把手带你操作。