我在 Debian 上运行 Xen,有五台客户虚拟机。我使用以下命令为其中两台虚拟机设置端口镜像
ovs-vsctl \
-- --id=@m1 create mirror name=detector \
-- add bridge xenbr1 mirrors @m1 \
-- --id=@m2 create mirror name=recorder \
-- add bridge xenbr1 mirrors @m2 \
-- --id=@eth1 get port eth1 \
-- [email protected] get port vif2.0 \
-- [email protected] get port vif5.0 \
-- set mirror detector select_src_port=@eth1 select_dst_port=@eth1 \
-- set mirror detector [email protected] \
-- set mirror recorder select_src_port=@eth1 select_dst_port=@eth1 \
-- set mirror recorder [email protected]
这似乎工作正常。所有这些虚拟机的网络设置都与配置中的以下内容类似:
vif = [ "script=vif-openvswitch,bridge=xenbr1", ...]
问题是,当我重新启动主机时,所有虚拟端口(vifX.Y)都分配了新的 UUID,因此镜像上的“output_port”被清除。
如何配置镜像端口以使其在重启后正确保留?
答案1
我假设它正在运行 XenServer。
使用@reboot cron任务。
@reboot root /usr/bin/bash <path_to_script> > /dev/null 2>&1
不幸的是,脚本可能有点复杂,因为您必须预测 vifs 的 domID 是什么(也许检查 VIF MAC 地址?)。
XS 存在一些问题,并且在重启后仍然存在,因为 XS 在重启时会从头重建 OVSdb。我使用了类似的方法在启动时创建补丁端口。
注意 - 如果您希望虚拟机重新启动来执行端口镜像,则可能必须使用 udev 脚本。
答案2
我最近在尝试解决几乎相同的问题时遇到了这个问题,尽管我想创建一个 SPAN 端口来镜像全部流量到单个端口。我通过在domU 的vif-script
XEN 文件中创建自定义“ ”来解决这个问题。.cfg
例如,您只需修改 XEN .cfg
VIF 条目以包含以下内容:
'mac=xx:xx:xx:xx:xx:xx,script=vif-ovs-spanport,bridge=ovsbr0'
启动时,脚本将创建一个新的镜像,该镜像具有一个唯一名称,结合了桥接器和设备/vif,将该镜像添加到桥接器,将该交换机上的所有流量镜像到新的指定端口/VIF。相反,在关闭时,脚本将从桥接器中删除镜像,并且作为副作用,销毁镜像。
您应该能够根据您的特定需求修改脚本,尽管您必须知道所有相关 domU 的端口名称。您可以使用该vifname=string
指令来确保接口的名称一致,但您仍然可能遇到顺序问题,即首先启动哪个 domU,以确保在使用之前创建端口。
也许也可以使用vif-post.d/*
脚本来完成类似的事情;YMMV。
vif-ovs-spanport
脚本
#!/bin/bash
#============================================================================
# ${XEN_SCRIPT_DIR}/vif-ovs-spanport
#
# Script for configuring a Open VSwitch (OvS) VIF to be a spanport;
# i.e. on a (new) mirror, sending all traffic on the bridge to the port.
#
# Usage:
# vif-ovs-spanport (add|remove|online|offline)
#
# Requires the same environment as is required by vif-openvswitch.
# Assumes that vif-openvswitch has already added the port to the bridge.
#
# XEN .cfg file recipie: modify VIF entry
# 'mac=xx:xx:xx:xx:xx:xx,script=vif-ovs-spanport,bridge=ovsbr0'
# On startup, the script will create a new mirror with a unique name
# combinging the bridge and device/vif, add that mirror to the bridge,
# mirroring all traffic on that switch to the new specified port/VIF.
#
# On shutdown, the script will remove the mirror from the bridge and
# as a side-effect, destroy the mirror.
#============================================================================
dir=$(dirname "$0")
prg=$(basename "$0")
# We inherit base behavior, and this should add the port to the bridge for us.
. "$dir/vif-openvswitch"
add_ovsmirror () {
local dev=$1
local mirror=$2
local bridge=$3
do_or_die \
ovs-vsctl --timeout=30 \
-- --id=@m create mirror name=${mirror} \
-- add bridge ${bridge} mirrors @m \
-- --id=@p get port ${dev} \
-- set mirror ${mirror} select_all=true output-port=@p
}
remove_ovsmirror () {
local mirror=$1
local bridge=$2
do_without_error \
ovs-vsctl --timeout=30 \
-- --id=@m get mirror ${mirror} \
-- remove bridge ${bridge} mirrors @m
}
#dev= set in environment
bridge="$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")"
# code stolen from vif-openvswitch
if [[ $bridge =~ ^([^.:]+)(\.([[:digit:]]+))?(:([[:digit:]]+(:[[:digit:]]+)*))?$ ]]; then
bridge="${BASH_REMATCH[1]}"
#tag="${BASH_REMATCH[3]}"
#trunk="${BASH_REMATCH[5]//:/,}"
else
fatal "No valid bridge was specified"
fi
mirror="${bridge}-mirror-span-${dev}"
case "$command" in
add|online)
check_tools
log debug "$prg creating $mirror on $bridge, then adding $dev to mirror."
add_ovsmirror $dev $mirror $bridge
;;
remove|offline)
log debug "$prg removing mirror $mirror."
remove_ovsmirror $mirror $bridge
;;
esac
log debug "Successful vif-ovs-spanport $command for $dev on $bridge ($mirror)."
if [ "$type_if" = vif -a "$command" = "online" ]; then
success
fi