PVE下虚拟机和LXC容器会有概率性的宕机(原因不详,可能是硬件问题(温度,资源,驱动),也可能系统问题),下面脚本是用于每隔15分钟检测一次虚拟机是否有心跳,如果没有心跳,就强制重启虚拟机(含LXC容器)。
- 脚本主体
#!/usr/bin/env bash
# 定义一个函数,用于检查并重启虚拟机或LXC容器
function check_and_restart() {
type="${1}" # 虚拟机或LXC容器的类型
vm_id="${2}" # 虚拟机或LXC容器的ID
vm_ip="${3}" # 虚拟机或LXC容器的IP地址
# 使用ping命令检测虚拟机或LXC容器是否可达
ping -c 1 "${vm_ip}" > /dev/null
if [[ $? != 0 ]]; then
# 记录当前时间和信息
now=$(timedatectl status | grep 'Local time' | awk -F"Local time: " '{ print $2 }')
echo "[${now}] [NO] id = ${vm_id}, ip = ${vm_ip} ($type)"
if [[ "${type}" == "vm" ]]; then
# 如果是虚拟机,尝试停止和启动虚拟机
/usr/sbin/qm stop "${vm_id}"
/usr/sbin/qm start "${vm_id}"
elif [[ "${type}" == "lxc" ]]; then
# 如果是LXC容器,尝试停止和启动LXC容器
/usr/sbin/pct stop "${vm_id}"
/usr/sbin/pct start "${vm_id}"
else
echo "Unknown VM type for id=${vm_id}"
fi
fi
}
# 主函数,用于循环检查虚拟机列表
function main() {
vm_list="${1}" # 虚拟机列表,格式为 type:id:ip
for each in ${vm_list}; do
type=$(echo "${each}" | awk -F: '{ print $1 }') # 提取虚拟机或LXC容器的类型
vm_id=$(echo "${each}" | awk -F: '{ print $2 }') # 提取虚拟机或LXC容器的ID
vm_ip=$(echo "${each}" | awk -F: '{ print $3 }') # 提取虚拟机或LXC容器的IP
check_and_restart "${type}" "${vm_id}" "${vm_ip}" # 调用检查并重启函数
done
}
# 需要检查的虚拟机和LXC容器列表,格式为 type:id:ip,其中type=vm表示虚拟机,type=lxc表示LXC容器
vm_list="
vm:100:192.168.50.61
vm:101:192.168.50.62
lxc:102:192.168.50.63
"
# 调用主函数并传入虚拟机和LXC容器列表
main "${vm_list}"
- 脚本调度
crontab -e
*/15 * * * * bash /root/check_and_restart.sh >> /root/log.txt
systemctl restart cron
- 注意事项
因为一些虚拟机开机特别慢(以Windows代表),因此时间太短也不行,间隔尽量长一些。否则虚拟机开一半就还得stop再start,陷于永久循环。