我的 Fedora Linux(目前有 30 个)系统托管着多个虚拟机 (VM),这些虚拟机配置为在主机系统启动时启动。这些是孤立的服务器,应该从互联网上可见,不包含重要或关键数据,因此它们是否被黑客入侵并不重要(然后它们将被清除并重新加载)。
为了使它们可见,我必须将虚拟网桥上的目标 IP 的防火墙设置为直通模式。这些命令分组在 bash 脚本中。
我注意到,要使命令成功且有效,虚拟机必须启动并运行,这意味着我必须等待虚拟机启动完成,即可能是它们到达的时间multi-user.target
。
我的问题是虚拟机状态可以在来宾系统中测试,而我的 bash 脚本必须在主机系统中运行。
我已经尝试将 bash 脚本延迟固定的秒数,但这似乎并不总是正确的。虚拟机需要可变的启动时间(例如,当它们在第 n 次启动时运行 fsck 时),并且我无法可靠地预测所有准备就绪并运行的时间。
我的目标是 24/7 运行我的服务器,在主机自动重启的情况下(断电或其他事件后)自动将它们连接到互联网。
目前,我手动启动此脚本(有时我忘记这样做)。
问题:有没有办法(systemd、cron、at、...?)在虚拟机进入多用户模式后启动我的脚本?
编辑
根据@Michael D.的评论,我的描述不清楚或不准确。
firewall-cmd
除非命令中存在语法错误,否则始终“成功”终止。即使不存在设备的配置也会被防火墙拒绝而接受。因此我不能依赖 bash$?
来检测该命令是否会产生一些效果。监视返回码在这里没有帮助。
答案1
经过反复试验,这是我实施的解决方案。
我将脚本附加到systemd
服务中:
[Unit]
Description=Make VMs reachable from the internet
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/home/…/virbr0-enable.sh
[Install]
Alias=makeVMvisible.service
WantedBy=multi-user.target
我让它等到网络运行(之后网络在线.target),我认为,这取决于防火墙服务,以及之后多用户目标已达到。后者可能是多余的(因为我不知道目标和服务之间的确切依赖关系),但它没有坏处。
如此一来,还是没能起到作用。 systemd 服务没有故障,因为手动systemctl start makeVMvisible.service
会将虚拟桥置于直通模式。延迟似乎是必要的:我sleep
在脚本的开头添加了一个命令。
根据实验,延迟的阈值在 1 到 2 秒之间。我决定sleep 5
这对经过的时间没有太大影响,而且相当保守。
但是,我觉得我的解决方案不太令人满意。有谁知道比网络在线.target?
答案2
在外部 IP 地址传递到虚拟机之前,您能否从主机访问虚拟机?如果是这样,那么您可以使用远程功能来systemctl
检查虚拟机启动的状态。
这要求可以使用主机的 ssh 密钥访问 VM。
在主机上您将运行:
systemctl -H <vm name or ip> --quiet is-active multi-user.target
如果指定的单元处于活动状态,则会成功退出。
所以在 bash 中你可以这样做:
until systemctl -H <vm name or ip> --quiet is-active multi-user.target; do
sleep 5
done
现在,直到给定主机上的指定单元启动后,此操作才会继续。