PVE通过电源按钮开启/关闭win11虚拟机

概述

本教程将介绍如何在Proxmox VE (PVE) 环境中配置物理电源按钮来控制虚拟机的开关机,而不是控制宿主机。通过ACPI事件处理,可以实现按下电源按钮直接启动或关闭指定的虚拟机。

适用场景

  • 需要为家庭用户提供简单的虚拟机操作方式
  • 希望通过物理按钮控制虚拟机而非宿主机
  • 减少虚拟机管理的复杂度

实现原理

电源按钮的工作原理涉及BIOS、ATX电源和操作系统三个层面:

  1. 硬件层面:电源按钮连接主板排针,按下时短接两根线发出信号
  2. BIOS层面:现代电源支持ACPI,可由操作系统直接控制
  3. 系统层面:Linux系统可以自定义电源按钮的响应行为

配置步骤

1. BIOS设置 - 启用ACPI

在主板BIOS中进行以下设置:

  • 进入电源管理或节能相关设置
  • 启用所有ACPI相关选项
  • 设置电源管理为”由OS控制”

注意:不同主板的设置界面可能有所差异,请根据实际情况调整。

2. 屏蔽默认电源按钮事件

备份配置文件

1
cp /etc/systemd/logind.conf /etc/systemd/logind.conf.bak

编辑配置文件

1
nano /etc/systemd/logind.conf

修改配置内容

在配置文件中找到并修改以下两行(去掉注释符号#):

1
2
3
[Login]
HandlePowerKey=ignore
PowerKeyIgnoreInhibited=no

完整的配置文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
#UserStopDelaySec=10
HandlePowerKey=ignore
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=ignore
#HandleLidSwitch=suspend
#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
#HandleRebootKey=reboot
PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#RebootKeyIgnoreInhibited=no
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RuntimeDirectoryInodes=400k
#RemoveIPC=yes
#InhibitorsMax=8192
#SessionsMax=8192

重启服务和系统

1
2
systemctl restart systemd-logind
reboot

3. 安装ACPI支持并获取事件ID

安装必要软件包

1
apt install acpid acpi-support

提示:如果遇到依赖冲突,可以安装aptitude来解决依赖问题。

监听电源按钮事件

执行以下命令并按下电源按钮:

1
acpi_listen

预期输出示例:

1
2
button/power PBTN 00000080 00000000
button/power LNXPWRBN:00 00000080 00000032

记录下事件ID(如示例中的 00000080),后续配置需要使用。

4. 配置自定义电源按钮事件

创建ACPI事件文件

1
nano /etc/acpi/events/powerbtn

添加以下内容(根据第3步获取的事件ID修改):

1
2
event=button/power PBTN 00000080 00000000
action=/etc/acpi/power_btn.sh

创建电源按钮脚本

1
nano /etc/acpi/power_btn.sh
仅开机功能脚本
1
2
3
4
5
6
7
#!/bin/bash
output=$(qm status 102)
if [[ $output == *"stopped"* ]]; then
qm start 102
else
qm status 102
fi
开关机功能脚本
1
2
3
4
5
6
7
#!/bin/bash
output=$(qm status 102)
if [[ $output == *"running"* ]]; then
qm shutdown 102
else
qm start 102
fi

说明

  • 将脚本中的 102替换为你的虚拟机ID
  • 如果 qm shutdown不生效,可以改为 qm stop

设置脚本执行权限

1
chmod +x /etc/acpi/power_btn.sh

重启ACPI服务

1
systemctl restart acpid

5. 安装虚拟机Agent(可选)

如果需要电源按钮关机功能,需要在虚拟机中安装QEMU Guest Agent。

Windows虚拟机

  1. 访问 virtio-win下载页面
  2. 下载对应的ISO文件
  3. 在ISO中找到并安装Guest Agent
  4. 在PVE虚拟机选项中启用Agent

Linux虚拟机

1
2
3
4
5
# Debian/Ubuntu
apt install qemu-guest-agent

# CentOS/RHEL
yum install qemu-guest-agent

使用效果

配置完成后,按下机箱电源按钮即可:

  • 虚拟机关闭状态:启动虚拟机
  • 虚拟机运行状态:关闭虚拟机(需安装Guest Agent)

注意事项

  1. 本教程基于PVE 8.2版本测试,其他版本可能略有差异
  2. 不同主板的BIOS设置界面可能不同,请根据实际情况调整
  3. 确保虚拟机ID正确配置在脚本中
  4. 如需关机功能,必须在虚拟机中安装Guest Agent

故障排除

  • 如果电源按钮仍然关闭宿主机,检查logind.conf配置是否正确
  • 如果ACPI事件无响应,确认acpid服务是否正常运行
  • 如果脚本不执行,检查文件权限和路径是否正确

扩展应用

类似的方法也可以用于:

  • 配置Reset按钮功能
  • 笔记本合盖事件处理
  • 其他ACPI事件自定义

通过这种方式,可以让不熟悉虚拟化技术的用户也能方便地使用虚拟机,真正做到”科技以人为本”。

思路来自于BiliBlili大佬@Worktech,特此感谢