2、Open vSwitch基础:OVS核心概念(Bridge、Port、Interface)、OVS安装与命令行工具(ovs-vsctl、ovs-ofctl)

好,我们正式开始OVS的学习。这一章是基础中的基础,但也是你后续理解CNI集成的关键。说白了,OVS就是一个软件实现的交换机,但它比Linux自带的bridge要灵活得多。我刚开始接触Kubernetes网络时,也想过直接用Linux bridge算了,但后来发现,真要搞网络策略、VXLAN隧道、流量镜像这些高级功能,OVS才是那个“瑞士军刀”。

2.1 OVS核心概念:Bridge、Port、Interface

这三个概念,你一开始可能会觉得有点绕。我当年也迷糊过一阵子。咱们一个一个拆开看。

2.1.1 Bridge(网桥)

Bridge就是OVS里的虚拟交换机。它负责转发数据包。你可以把它想象成一个物理交换机,只不过是用软件实现的。在Kubernetes节点上,我们通常会创建一个OVS bridge,比如叫 br-int,然后所有Pod的流量都通过这个bridge转发。

我个人习惯,在生产环境中,每个计算节点只创建一个OVS bridge。这样管理起来清晰,也方便和OpenStack或Kubernetes集成。你想想看,如果每个节点上创建十几个bridge,排查问题的时候光看名字就头大了。

2.1.2 Port(端口)

Port是Bridge上的一个逻辑连接点。数据包从Port进入或离开Bridge。Port有很多类型,比如 InternalPatchTunnel 等。每种类型都有它的用途。

  • Normal Port:最普通的端口,通常连接一个虚拟网卡(VIF)。
  • Internal Port:这种端口在OVS内部创建,同时在Linux内核中也会生成一个同名的虚拟网卡。比如你创建一个叫 br-int 的Internal Port,系统里就会多一个叫 br-int 的网卡。这个网卡可以用来配置IP地址,或者作为网关。
  • Patch Port:用于连接两个OVS bridge。我在做多网卡方案时经常用到,比如用Patch Port把 br-intbr-ex 连起来。
  • Tunnel Port:用于创建VXLAN、Geneve等隧道。这是跨节点通信的关键。

2.1.3 Interface(接口)

Interface是Port的“后端”。一个Port必须绑定一个Interface才能工作。Interface可以是物理网卡(比如 eth0)、虚拟网卡(比如 veth 对的一端)、或者OVS自己创建的虚拟网卡。

嗯,这里要注意:Port和Interface的关系,有点像“插座”和“插头”。Port是Bridge上的插座,Interface是插进去的插头。数据从Interface流入,经过Port,进入Bridge。

核心关系总结

Bridge 包含多个 Port,每个 Port 绑定一个 Interface。

数据流:Interface → Port → Bridge(查流表)→ Port → Interface

2.2 OVS安装

安装OVS其实很简单。不同发行版略有差异,但核心步骤差不多。我建议你直接用包管理器安装,省事。如果你非要编译源码,那也行,但生产环境我推荐用稳定版。

2.2.1 Ubuntu/Debian 安装

# 更新包索引
sudo apt-get update

# 安装OVS
sudo apt-get install -y openvswitch-switch openvswitch-common

# 启动服务
sudo systemctl enable openvswitch-switch
sudo systemctl start openvswitch-switch

# 检查状态
sudo systemctl status openvswitch-switch

2.2.2 CentOS/RHEL 安装

# 安装OVS
sudo yum install -y openvswitch

# 启动服务
sudo systemctl enable openvswitch
sudo systemctl start openvswitch

# 检查状态
sudo systemctl status openvswitch

安装完成后,你可以用 ovs-vsctl show 命令看看OVS是否正常运行。如果看到类似 Bridge "br0" 的信息,说明安装成功了。我曾经遇到过一个问题,安装后服务起不来,后来发现是内核模块没加载。执行 modprobe openvswitch 手动加载一下就好了。

2.3 命令行工具:ovs-vsctl 和 ovs-ofctl

这两个工具,你以后会天天用。它们分工明确:ovs-vsctl 负责管理OVS的配置(比如创建bridge、添加port),ovs-ofctl 负责管理OpenFlow流表(比如配置转发规则)。

2.3.1 ovs-vsctl:配置管理工具

这个工具说白了就是OVS的“配置中心”。你用它来增删改查bridge、port、interface等对象。

常用命令示例

# 创建一个名为 br-int 的 bridge
ovs-vsctl add-br br-int

# 查看所有 bridge 的信息
ovs-vsctl show

# 添加一个 Internal Port,名字也叫 br-int
ovs-vsctl add-port br-int br-int -- set Interface br-int type=internal

# 添加一个物理网卡 eth0 到 br-int
ovs-vsctl add-port br-int eth0

# 删除一个 port
ovs-vsctl del-port br-int eth0

# 设置 bridge 的 OpenFlow 版本(比如设置为 OpenFlow13)
ovs-vsctl set bridge br-int protocols=OpenFlow13

我个人习惯,每次创建完bridge后,都会用 ovs-vsctl show 确认一下。这个命令的输出很直观,能一眼看出当前OVS的拓扑结构。

小技巧:如果你想让某个Internal Port拥有IP地址,可以直接用 ip addr add 给它配IP。比如:

ip addr add 192.168.100.1/24 dev br-int
ip link set br-int up

2.3.2 ovs-ofctl:流表管理工具

这个工具才是OVS的灵魂。它用来操作OpenFlow流表。流表决定了数据包怎么转发。你可以把它理解成交换机的“路由表”,但比路由表灵活得多。

常用命令示例

# 查看 br-int 上的所有流表
ovs-ofctl dump-flows br-int

# 查看 br-int 上的流表统计信息
ovs-ofctl dump-ports br-int

# 添加一条流表规则:匹配源MAC,转发到 port 1
ovs-ofctl add-flow br-int "dl_src=00:11:22:33:44:55, actions=output:1"

# 添加一条流表规则:匹配目标IP,丢弃
ovs-ofctl add-flow br-int "ip,nw_dst=10.0.0.2, actions=drop"

# 删除所有流表(清空规则)
ovs-ofctl del-flows br-int

嗯,这里要注意:默认情况下,OVS bridge创建后,流表是空的。这意味着所有数据包都会被送到控制器(如果没有控制器,则会被丢弃)。所以,如果你刚创建完bridge,发现ping不通,别慌,先看看流表是不是空的。

避坑指南:我曾经在生产环境犯过一个低级错误。当时我清空了某个bridge的所有流表,结果所有Pod的网络瞬间中断。因为默认的“normal”规则(即像普通交换机一样学习MAC地址转发)并没有自动添加。所以,如果你需要bridge像普通交换机一样工作,记得添加一条“normal”规则:

ovs-ofctl add-flow br-int actions=normal

这条规则会让OVS退化为一个普通的二层交换机。但注意,这会绕过OpenFlow的精细控制,一般只在调试时用。

2.4 实战:创建一个简单的OVS网络

我们来动手做一个实验。这个实验会帮你把刚才的概念串起来。

  1. 创建bridge
    ovs-vsctl add-br my-bridge
  2. 创建两个Internal Port
    ovs-vsctl add-port my-bridge veth0 -- set Interface veth0 type=internal
    ovs-vsctl add-port my-bridge veth1 -- set Interface veth1 type=internal
  3. 给两个Port配置IP并启用
    ip netns add ns1
    ip netns add ns2
    
    ip link set veth0 netns ns1
    ip link set veth1 netns ns2
    
    ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth0
    ip netns exec ns1 ip link set veth0 up
    
    ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth1
    ip netns exec ns2 ip link set veth1 up
  4. 添加流表规则(让两个namespace能通信)
    # 添加normal规则,让OVS像普通交换机一样工作
    ovs-ofctl add-flow my-bridge actions=normal
  5. 测试连通性
    ip netns exec ns1 ping 10.0.0.2

    如果能ping通,恭喜你,你的第一个OVS网络搭建成功了!

这个实验虽然简单,但它展示了OVS最核心的工作流程:创建bridge → 添加port → 配置流表 → 数据转发。在Kubernetes CNI中,我们也是基于这个流程,只不过port变成了Pod的veth对,流表变成了更复杂的规则。

好了,这一章的内容就到这里。下一章我们会深入OpenFlow流表,看看那些“match-action”规则到底是怎么工作的。你想想看,掌握了这些,你就能像搭积木一样,用OVS搭建出各种复杂的网络拓扑了。