将 Open vSwitch 从一个版本升级到下一个版本,并将使用该 Open vSwitch 的系统的流量中断降到最低,需要考虑以下几点:
-
如果升级只涉及升级 Open vSwitch 的 userspace 使用程序和守护进程,请确保新的 userspace 版本与先前加载的内核模块兼容。(生产环境:一般都是这种情况)
-
升级用户空间守护进程意味着必须重新启动它们。重启守护进程意味着 ovs-vswitchd 守护进程中的 OpenFlow 流将丢失。恢复流的一种方法是让控制器重新填充流。另一种方法是使用 ovs-ofctl 等程序保存以前的流,然后在重新启动后读取它们。只有当新的 Open vSwitch 接口保留旧的‘ ofport ’值时,恢复旧的流才是准确的。
-
当新的用户空间守护进程重新启动时,它们会自动刷新内核中旧的流设置。如果有数百个新流正在进入内核,而用户空间守护进程正忙于从控制器或 ovs-ofctl 等实用程序设置新的用户空间流,那么这样做的代价可能会很高。Open vSwitch 数据库通过 Open_vSwitch 表的 other_config:flow-restore-wait 列提供了一个解决这个问题的选项。详细信息请参考 ovs-vswitch.conf.db(5) 手册。
-
如果升级还涉及到升级内核模块,则需要卸载旧的内核模块,并加载新的内核模块。这意味着属于 Open vSwitch 的内核网络设备被重新创建,内核流丢失。如果立即重新启动用户空间守护进程并尽快恢复用户空间流,则可以减少流量的停机时间。
ovs-ctl 实用程序的重启功能只重启用户空间守护进程,确保 ‘ofport’ 值在重启期间保持一致,使用 ovs-ofctl 程序恢复用户空间流,并使用 other_config:flow-restore-wait 列将流量停机时间保持在最低限度。
ovs-ctl 实用程序的 force-reload-kmod 函数执行上述所有操作,但也用新模块替换旧的内核模块。
Debian、XenServer 和 RHEL 的 OpenvSwitch 启动脚本使用 ovs-ctl 的函数,建议在其他软件平台上也使用这些函数。
other_config : flow-restore-wait: optional string, either true or false
当 ovs-vswitchd 启动时,它有一个空的流表,因此它根据其配置以默认方式处理所有到达的数据包,通过丢弃它们或将它们发送到 OpenFlow 控制器或作为独立交换机进行交换。这种行为通常是可取的。
但是,如果 ovs-vswitchd作为“热升级”的一部分重新启动,则会导致数据包处理不当的时间相对较长。
这个选项可以优化热升级。当 ovs-vswitchd 将此值设置为 true 时,它既不会刷新或过期先前设置的数据路径流,也不会发送和接收任何数据路径流进出数据路径的数据包。当稍后将此值设置为 false 时,ovs-vswitchd 将开始从数据路径接收数据包并重新设置流。
此外,当该值设置为 true 时,ovs-vswitchd 将被阻止连接到控制器。这可以防止控制器在流恢复过程中对流表进行更改,从而导致不希望出现的中间状态。
一旦这个值被设置为 false 并且所需的流状态已经恢复,ovs-vswitchd 将能够重新连接到控制器并处理任何新的流表修改。
因此,有了这个选项,ovs-vswitchd 的热升级过程大致如下:
-
- Stop old ovs-vswitchd.
-
- Set other_config:flow-restore-wait to true.
-
- Start new ovs-vswitchd.
-
- Use ovs-ofctl (or some other program, such as an OpenFlow controller) to restore the OpenFlow flow table to the desired state.
-
- Set other_config:flow-restore-wait to false (or remove it entirely from the database).
The ovs-ctl’s restart and force-reload-kmod functions use the above config option during hot upgrades.
以上的流程便是社区文档中描述的,但是在 kube-ovn 的场景,ovs 是 k8s Daemonset,新 pod 是可以先创建的,社区做了一定的版本兼容性:应该还有进一步优化的空间