ProxmoxVE(PVE)踩坑记录

  • 2019-07-30
  • 3,653
  • 5
  • 4

  之前入了一个四网口H310的工控板,装上了i3 8100T cpu弄了一个ITX主机来做一个高端软路由,刚开始用的是esxi上面跑了一个Openwrt,一直用得挺稳定,没啥问题。当然,esxi是基于red hat深度定制的,使用的是vmware自家的虚拟化技术,因此对于硬件要求比较苛刻,装在民用主板上,会有很多功能模块没有驱动用不了,就比如最开始连最常见的Intel I211网卡的驱动都不支持,而且竟然不支持温度监控,所以,这么不自由的系统,还是决定弃坑了,转战PVE,而PVE是基于debian开发的,虚拟化技术支持openVZ和KVM,前端用的是qemu,都是开源软件,比较自由。当然,自由带来的代价就是,一如既往,坑非常多,所以,本文总结一下我所遇到的一些烦死人的坑吧。

一、如何让管理端通过虚拟机上网

由于我用这台机器来做软路由,所以我期望的网络拓扑如下图:

其中enp1s0~enp4s0是四个物理网口,其中enp1s0~enp3s0三个网口分别连接到vmbr0~vmbr2这三个虚拟桥接网络中,这三个vmbr作为oepnwrt虚拟机的三个LAN口,其中物理网口enp4s0直通openwrt虚拟机,作为WAN口使用。

pve管理界面的网络设置如下图:

虚拟机网卡直通教程网上有很多,我这里就不再赘述了,直接上图:

即添加一个PCI设备就行,其中只要前面的设备位置04:00.0这个要对应你想要直通的网卡在系统中的位置编号才行。

然后,按照这样设置,虚拟机里WAN口应该就能正常PPPOE拨号获得IP地址了,而插在LAN口上的网线也能自动获取IP地址。

那么关键问题来了,如何让主机自动获得一个IP地址呢?我尝试过修改/etc/network/interfaces中的内容,因为在这个文件中,vmbr0~vmbr2均被配置成manual,也就是说手动设置:

auto lo
iface lo inet loopback

iface enp1s0 inet manual

iface enp2s0 inet manual

iface enp3s0 inet manual

iface enp4s0 inet manual

auto vmbr0
iface vmbr0 inet manual
        bridge-ports enp1s0 
        bridge-stp off
        bridge-fd 0

auto vmbr1
iface vmbr1 inet manual
        bridge-ports enp2s0
        bridge-stp off
        bridge-fd 0

auto vmbr2
iface vmbr2 inet manual
        bridge-ports enp3s0
        bridge-stp off
        bridge-fd 0

我本来尝试把iface vmbr0 inet manal改成iface vmbr0 inet dhcp,结果发现并不能在开机时获取一个IP,后来经过查看日志发现,系统启动的过程,是会先去请求DHCP,当所有网络接口初始化完毕后才会启动虚拟机,因此由于主机vmbr0在请求DHCP的时候,虚拟机还没启动,所以自然无法获得IP。那怎么办呢?

  后来我想了个办法,就是弄个计划任务,每隔1分钟检查vmbr0是否有IP,如果没有就去请求一个,这样就能解决问题了,脚本如下:

#!/bin/sh

vmbr0_ip=$(/usr/sbin/ifconfig vmbr0 | grep "inet " | awk '{print $2}')

if [ -z "$vmbr0_ip" ]
then
        echo "vmbr0 has no IP,get a IP"
        /usr/sbin/dhclient -4 vmbr0
else
        echo "vmbr0 already has an IP,skip.."
fi

文件命名为getip.sh,然后再crontab里面加下面一行就行:

* * * * * /root/getip.sh

注意,脚本要赋予执行权限,即chmod +x getip.sh,并且你们应该也注意到了,脚本里面的程序要写绝对路径,即/usr/bin/ifconfig,如果只写ifconfig就会因为环境变量有问题而找不到这个程序,这个是个大坑。

  保存后,每次启动系统,crontab都会去执行这个脚本,这样vmbr0就能自动获得一个IP了:

二、关于无法使用pve关闭虚拟机

  这是个大坑,因为每次重启主机,系统都会先等待所有虚拟机关闭才会执行,而我一开始不知道怎么回事,关机的qmshutdown命令一直卡死,虚拟机一点反应都没有,感觉虚拟机没有正确响应关机命令。

  后来查了一些资料才发现,这是因为QEMU设置里面开启了QEMU代理引起的:

如果一开始不知道这个设置是什么玩意开了的话,那就容易碰到这个坑。

  QEMU代理即qemu-guest-agent,是一个运行在虚拟机里面的程序,主机可以直接通过qemu-guest-agent获取虚拟机的运行状态,比如IP地址,进程列表之类的,还可以直接在虚拟机里执行命令,如果开启了这个功能,虚拟机中必须安装相对应的qemu-ga才行。然而,我实际测试,编译内核的时候把qemu-ga一起编译进去,qemu-ga可以正常运行,主机也可以正确获得虚拟机的信息。然而还是无法关机。经过分析发现,TMD竟然关机只是在虚拟机里执行/sbin/shutdown,而openwrt里面没这个命令,取而代之的叫做/sbin/poweroff。由于我的openwrt编译的是squashfs版本,所以没法修改/sbin目录,重启就会恢复原始状态,所以决定放弃QEMU代理这个设定了。

  如果关闭了qemu代理的话,主机控制虚拟机的方式就会使用最底层的ACPI信号来发送关机命令,这样就没有问题了。

P.S. 竟然QEMU agent关机的时候竟然只是执行/sbin/shutdown,一点都不智能啊,这也太sb了吧。。

评论

  • Dazzy回复

    kvm guest关机是个问题。不过网络方面,建议还是看看官方的pve admin guide比较好。
    不需要把网卡直通给vm的,除非是host没驱动,识别不了的特殊型号。但看你用e1000,也不是什么罕见型号。网卡由host负责,每个端口指派一个vmbr[n],全部manual, pppoe那些不指定任何ip,然后你爱openwrt几个网卡就虚拟几个virtio网卡,一个或者多个(如果你打算多拨汇聚)接管pppoe的物理端口所在vmbr[n],另一堆接lan,host管理口给指定一个静态ip,接lan所在vmbr[n]即可。要分多少个vlan管虚拟机,要么就多几张虚拟网卡接剩下的vmbr[n],要么就vlan tag解决,virtio-net性能杠杠的。
    我家openwrt就是这么跑的。autostart简单直接。host局域网管理,和通过openwrt上网apt-get upgrade轻松自如。proxmox ve比较多坑,集中在多节点ha上,这种单机跑linux vm,没什么问题。

  • riverqh回复

    vmbr0直接指定一个和OpenWRT同LAN段的静态IP,网关指向OpenWRT的LAN IP

    • Jarvis回复

      这样也可以的,不过就是如果以后LAN IP要改的话就得接显示器了。

  • jc回复

    请教下 主路由就是OpenWrt么,不知道ikuai是否可以正常关机?

    • Jarvis回复

      我用的是openwrt,ikuai支持qemu-guest-agent么?我没用过?

发表评论

*

浙ICP备16016405号-2
浙公网安备 33010602007544号