最近项目里需要一个kvm虚拟机状态监控的功能,比如虚拟机由running状态变化到stop状态时记录事件并且回调函数。
使用virsh指令使得虚拟机由running状态变化到stop状态时由两种方式:destroy和shutdown。destroy是比较暴力的做法,相当于物理机的直接关闭电源;shutdown则是比较优雅地做法,按部就班的关闭虚拟机。
测试时,使用virsh destroy关闭虚拟机没有问题,可以直接关掉。但是使用shutdown来关闭时就出现了关不掉的情况,如图:
究其原因,如果我们使用vnc来连接虚机的话可以发现,在我们执行virsh shutdown命令的时候,虚机弹出了一个确认框来询问我们是否真的要关掉虚拟机。一方面为了更安全,另一方面就显得更优雅了呢。
至此,问题应该描述清楚了,接下来是解决方法。以下四种方法的结果并不是完全相同,需要大家根据自己的需求来酌情选择合适的方式。
查询linux关机快捷键,可以看到Ctl-Alt-F1 或Ctl-Alt-Del等结果(错误)。基于这个方式,我们可以使用到virsh sendkey这个指令来进行操作。
在vb中有一个模拟键盘操作的语句叫做sendkey,通过发送{Ctrl + z}等不同指令来模拟键盘操作。virsh sendkey也是类似的作用,只不过是对虚拟机发起的键盘模拟操作。
使用方式,宿主机上键入:virsh send-key --domain --key就可以了。
这里我测试了Ctl-Alt-Del,它并没有实现关机,而是实现了注销。
在虚机登录的情况下,我们键入
virsh send-key basis_ubuntu16 KEY_LEFTCTRL KEY_LEFTALT KEY_DELETE
可以使得虚拟机从登录状态转化为注销状态。
该方法虽然有些作用,但是跟我需求不一致,所以对我来说很鸡肋。
展示如何在每次执行关机、重启、注销时禁用确定框。Ubuntu 总是配置好了一个对话框,每当你要关机、重启或者注销时提示你。这是一个保护措施,防止你本不打算这样做却错误关机或重启。不是所有人都想每次关机的时候被询问。忙碌的小伙伴们可能就让自己的电脑那么醒着,因为他执行了关闭命令,却忘了确认那个该死的对话框。
这个教程将会指导你每一次关机的时候如何避免那个对话框。
当这个特性被激活,你将会收到下面的提示。
Are you sure you want to close all programs and shutdown your computer?
运行下面命令关掉它。
按下键盘上的Ctrl – Alt – T打开终端。然后敲击下面的命令
gsettings set com.canonical.indicator.session suppress-logout-restart-shutdown true
就这么简单,你再也不会被该死的确认对话框骚扰了。
如果想恢复这个对话框,敲下面的命令就可以了
gsettings set com.canonical.indicator.session suppress-logout-restart-shutdown false
原文链接:https://linux.cn/article-2598-1.html
按照上述方法描述,我进行了测试。在虚拟机用户登录状态进行可以将虚拟机直接关掉。
virsh shutdown --doamin
但是在虚拟机注销状态下,进行shutdown时也会出现同样的询问界面。
这一情况的具体原因,我没有深追到实现。我猜测该方法只是针对用户来做了一个省事的操作,用户没有登录那肯定不行了。另外该方式还可以进行关机、重启菜单等选项的隐藏,具体指令如下,大家可以自己进行尝试了。
suppress-logout-menuitem 隐藏登出菜单
suppress-restart-menuitem 隐藏重启菜单
suppress-shutdown-menuitem 隐藏关机菜单
该方法虽然已经起到很大的作用了,但是跟我的需求仍然有出入,不仅要在登录状态下,在注销状态下也要实现实现一步到位的shutdown才是我的初衷。
shutdown使用发送acpi指令来控制虚拟机的电源,而KVM虚拟机安装linux系统时默认没有安装acpi服务,反以导致不能关闭虚拟机,需要安装acpi。据说windows会自动安装acpi服务,暂时没有测试。
首先进行acpi的安装。
centOS
[root@kvm_client_00 ~]# yum install acpid -y
[root@kvm_client_00 ~]# /etc/init.d/acpid restart //重新启动acpic服务,安装后默认会加入到开机启动的
Ubuntu
[root@softinst-KVM:~$ apt-get install acpid -y
[root@softinst-KVM:~$ systemctl restart acpid.service
acpi工作原理:
ACPId服务是AdvancedConfigurationandPowerInterface缩写,acpid中的d则代表daemon。
Acpid是一个用户空间的服务进程,它充当Linux内核与应用程序之间通信的接口,负责将kernel中的电源管理事件转发给应用程序。
ACPId服务与内核的通信方式:acpid用poll函数挂在/proc/acpi/event文件上。内核在drivers/acpi /event.c中实现了该文件的接口,
一旦总线事件列表(acpi_bus_event_list)上有电源管理事件发生,内核就会唤醒挂在/proc /acpi/event上的acpid,acpid再从/proc/acpi/event中读取相应的事件。
acpid与应用程序的通信方式有两种,
其一是通过本地socket,其文件名为/var/run/acpid.socket,应用程序只要连接到这个socket上,不用发送任何命令就可以接收到acpid转发的电源管理事件。
其二是通过配置文件。在acpid收到来自内核的电源管理事件时,根据配置文件中的规则执行指定的命令。
ACPId服务事件的格式为:
device_classbus_idtypedata。device_class和bus_id是字符串,type和data是十六制整数。在配置文件中可以使用通配符,来匹配指定的事件。
安装启动acpi之后我直接进行了virsh shutdown测试,但是发现根本不起作用。所谓按照acpi原理我查找了配置文件。
ACPId服务配置文件为/etc/acpi/events/power.conf,我的虚机是/etc/acpi/events/powerbtn
打开配置文件,看到了电源事件:
可以看到,响应动作是执行脚本文件,所以我又去查看了一下脚本文件。
内容较多,大致意思就是满足一定情况时,我才会执行shutdown -h now操作。所以看到这里,我直接做了个粗劣的操作,直接将配置文件里的事件响应动作改成
/sbin/shutdown -h now那不应该就可以了嘛。这里配置文件默认是只读文件,所以要赋予权限:
sudo chmod 777 /etc/acpi/events/powerbtn
最后配置文件改成了这样:
执行virsh shutdown ,果不其然,虚拟机一步到位被shutdown掉了。
qga是一种宿主机和虚拟机的交互方式,这里通过它对虚拟机进行关机,确认宿主机有安装qemu-guest-agent工具,然后在虚拟机的xml配置文件中增加下面代码。
<channel type="unix">
<source mode="bind"/>
<target type="virtio" name="org.qemu.guest_agent.0"/>
channel>
我的虚拟机可以用virsh shutdown关机,问题解决!
qga的参考链接:
原理:
http://www.cnblogs.com/biangbiang/p/3222458.html
示例:
http://serverfault.com/questions/672253/how-to-configure-and-use-qemu-guest-agent-in-ubuntu-12-04-my-main-aim-is-to-get
原文链接:https://blog.csdn.net/h807892124/article/details/50600198
该方法是看到有的博主介绍的方法,涉及到qemu通信,时间紧张就没细看,毕竟问题解决了嘛!