返回

连接 VNC 端口时自动启动 KVM-QEMU VM:使用 Systemd 套接字

Linux

在连接到 VNC 端口后通过 systemd 套接字自动启动 KVM-QEMU VM

摘要

在本文中,我们将探索如何利用 systemd 套接字在连接到 VNC 端口时自动启动 KVM-QEMU 虚拟机 (VM)。我们将深入了解两种不同的方法,并提供故障排除技巧以解决常见问题。

介绍

虚拟化是现代计算中的一个关键概念,它允许在单个物理服务器上运行多个独立的 VM。通过将 VM 的启动与 VNC 连接事件联系起来,我们可以实现更自动化和动态的虚拟化环境。

方法

方法 1:Socket-Start

在第一种方法中,我们将使用 systemd 的 socket-start 机制。为此,我们需要创建两个 systemd 单元文件:一个套接字单元(监听 VNC 连接)和一个服务单元(启动 VM)。

  • 套接字单元 (kvm1.socket)
[Unit]
Description=KVM1 VM socket

[Socket]
ListenStream=5900
NoDelay=true
DeferAcceptSec=15
[Install]
WantedBy=sockets.target
  • 服务单元 (kvm1.service)
[Unit]
Description = kvm1
After=network.target
[Service]
Type=notify
ExecStart=virsh start ubuntu23.10-kvm1
#ExecStartPost=/usr/local/bin/waitport 127.0.0.1 5900 #This is somewhat a script to do "sleep every 0.1 until port is open"
#ExecStop=virsh shutdown ubuntu23.10-kvm1

[Install]
WantedBy=multi-user.target

方法 2:Socket 代理

在第二种方法中,我们将使用 systemd 套接字代理来将 VNC 连接转发到另一个端口。这可以避免 VNC 端口被第一个连接占用。

  • 代理套接字单元 (kvm1-proxy.socket)
[Unit]
Description=KVM1 VM socket

[Socket]
ListenStream=5888
NoDelay=true
DeferAcceptSec=15
[Install]
WantedBy=sockets.target
  • 代理服务单元 (kvm1-proxy.service)
[Unit]
Requires=kvm1.service
After=kvm1.service

[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd 127.0.0.1:5900
  • 服务单元 (kvm1.service)
[Unit]
Description=kvm1

[Service]
ExecStart=virsh start ubuntu23.10-kvm1
ExecStartPost=/bin/sleep 1
ExecStop=virsh shutdown ubuntu23.10-kvm1

[Install]
WantedBy=multi-user.target

故障排除

方法 1 问题:VM 无法启动

原因: VNC 端口被第一个连接占用。

解决方案: 使用第二种方法(套接字代理)将 VNC 端口转发到另一个端口。

方法 2 问题:kvm1-proxy.service 无法停止

原因: 在 VM 关闭后,kvm1-proxy.service 仍处于活动状态。

解决方案: 在 VM 关闭时添加 ExecStopPost=/bin/systemctl stop kvm1-proxy.service 行到 kvm1.service 单元文件中。

结论

通过利用 systemd 套接字和 socket-start 机制,我们可以创建在连接到 VNC 端口时自动启动的 KVM-QEMU VM。这为我们提供了更动态和响应式的虚拟化环境。

常见问题解答

  1. 为什么我们需要使用 systemd 套接字?

    systemd 套接字允许我们在特定网络事件(如连接到 VNC 端口)发生时触发服务。

  2. 哪种方法更好,socket-start 还是 socket 代理?

    这取决于你的特定情况。如果 VNC 端口不太可能被其他连接占用,那么 socket-start 方法可能会更简单。对于更复杂的设置,socket 代理方法提供了更多的控制和灵活性。

  3. 为什么我的 VM 无法启动,提示“连接 refused”?

    这可能是因为套接字代理服务尚未连接到 VM。确保 VM 正在运行,并且套接字代理已配置为使用正确的端口。

  4. 如何停止我的 VM?

    你可以使用 virsh shutdown <VM 名称> 命令手动停止 VM。或者,你可以在 kvm1.service 单元文件中添加 ExecStop=virsh shutdown ubuntu23.10-kvm1 行,以便在 VM 关闭时自动停止它。

  5. 如何更改 VNC 端口?

    在 kvm1.socket 单元文件中编辑 ListenStream 行并使用所需的端口号替换 5900。在 kvm1-proxy.service 单元文件中编辑 ExecStart 行并用所需的端口号替换 127.0.0.1:5900。