KVM访问虚拟机这件事,绝大多数人的卡点不在命令,而在网络模型的选择上,想稳定访问虚拟机,先确认当前用的是用户模式、NAT还是桥接,再根据不同场景来操作。
kvm虚拟机无法访问,先检查这四个环节
新装好一台KVM虚拟机,却发现在外部设备上怎么也访问不到它,这种现象相当常见,而且多半不是虚拟化本身出了问题,而是虚拟机在网络层面没有完全接入你所在的物理网络。
网卡模型选错是最大的坑
默认用virt-manager创建虚拟机时,虚拟网卡通常挂在virbr0这个默认NAT网桥上,虚拟机会拿到类似168.122.x的IP地址,这个子网被限制在宿主机内部,宿主机可以访问虚拟机,虚拟机也能通过宿主机的转发访问外网,但局域网内其他设备根本不知道168.122.x这个网段的存在,自然无法直接访问虚拟机的IP。
打破这个限制的唯一办法是让虚拟机的网卡直接挂到物理网络上,也就是说,把虚拟机的网卡从默认NAT模式改成桥接模式,让虚拟机的IP地址和宿主机处于同一个网段,这样,外部设备访问虚拟机就跟访问一台普通物理机没什么区别。
防火墙在宿主机和虚拟机两层同时拦截
就算网卡模式正确,还有一道隐藏的墙需要拆掉,业内专家指出,KVM宿主机上运行的防火墙服务(常见的是firewalld或iptables)默认只放行极少数流量,其余全部拒绝,如果虚拟机提供服务,但宿主机防火墙没有放行对应端口,外部访问同样会超时。
建议先关掉防火墙测试一次连接,确认是防火墙阻拦后,再打开防火墙并精确放行所需端口,也有不少情况是虚拟机内部系统自带的防火墙没有放行,这里需要进虚拟机系统里单独确认。
网关和路由没有指对方向
宿主机通过物理网卡接入局域网,网关指向路由器,而虚拟机使用NAT模式时,默认网关指向宿主机的virbr0,这种结构下,虚拟机能正常上网,但局域网的设备回程路由时找不到虚拟机在哪里,因为虚拟机的IP段没有在路由器上注册。
即便外部设备的请求能进到虚拟机,虚拟机的回包也会因为网关不对而丢失,排查时可以先在虚拟机里执行ip route看默认路由指到了哪里,再确认宿主机网桥是否工作正常。
kvm访问虚拟机命令,真正能落地的操作清单
很多教程把KVM的命令堆了一整屏,真正日常高频使用的就几条,下面这些命令按排查顺序排列,实用度极高。
先确认虚拟机当前状态
virsh list --all
这条命令列出宿主机上所有虚拟机以及它们的运行状态,已定义但未运行的虚拟机会显示为shut off,如果虚拟机没启动,后续所有操作都无法推进。
给虚拟机开机的几种方式
virsh start <虚拟机名称>
开机会自动进行,等十几秒左右再查看虚拟机是否正常起来,如果虚拟机配置了自启动,可以执行:
virsh autostart <虚拟机名称>
之后宿主机重启,虚拟机会自动跟随启动。
查询虚拟机IP地址的规范做法
virsh domifaddr <虚拟机名称>
这个命令直接显示虚拟机的IP地址、MAC地址以及对应的网卡接口名,比进入虚拟机里慢慢查效率高很多,对于安装了qemu-guest-agent的虚拟机,这条命令特别准确。
通过控制台直接进入虚拟机系统
virsh console <虚拟机名称>
执行命令后屏幕可能一片黑,属于正常现象,按一下回车键唤醒控制台登录界面,如果始终没有输出,多半是没有在虚拟机系统的grub引导里添加console=tty0 console=ttyS0参数,这个配置在创建虚拟机时就要做,后补需要修改引导文件。
查看虚拟机的网卡信息
virsh domiflist <虚拟机名称>
输出结果里能看到虚拟机的网卡类型、源设备、MAC地址,这也是排查“虚拟机为什么无法访问”的重要命令,如果这里显示network default,说明虚拟机挂在NAT网络下,外部设备无法直接访问是正常的,如果显示桥接设备名,例如bridge br0,说明已经切换到桥接模式。
NAT模式下临时对外开放一个端口
虚拟机已经跑在NAT模式下了,又不想迁移到桥接模式,可以通过端口映射的方式让外部设备访问到虚拟机,常用工具是firewalld的富规则或iptables的DNAT规则。
端口映射的一个典型场景是:宿主机IP是168.1.10,虚拟机IP是168.122.5,希望外部设备通过访问宿主机的2222端口来连接虚拟机的22端口,可以使用下面的方式:
firewall-cmd --add-forward-port=port=2222:proto=tcp:toport=22:toaddr=192.168.122.5 --permanent firewall-cmd --reload
同时还需要打开宿主机的IP转发功能:
sysctl -w net.ipv4.ip_forward=1
在配置文件/etc/sysctl.conf里写入net.ipv4.ip_forward=1则可以永久生效。
外部设备访问KVM虚拟机的三种落地方式
不同使用场景决定了不同访问策略,下面按配置复杂度从低到高排列,你可以根据实际情况对号入座。
桥接模式:最省心的局域网直接访问方案
适合场景:虚拟机需要完整暴露在局域网里,其他设备像访问普通电脑一样访问虚拟机。
操作路径:
- 在宿主机上创建一个Linux网桥,把物理网卡作为网桥端口加进去。
- 在virt-manager的虚拟机设置里,将虚拟网卡的网络设备指定为刚创建的网桥。
- 启动虚拟机,配置虚拟机的静态IP,使其与宿主机处于同一网段。
这个方案配置完成之后,虚拟机的行为跟一台独立主机完全一致,外界访问不需要做任何额外设置,生产环境里的虚拟机大多采用这种做法。
风险提示:在物理网卡加到网桥的瞬间,宿主机网络会有短暂中断,生产宿主机操作前务必确认有带外管理或远程控制卡可用,防止网络断连后无法恢复。
端口映射:不改变网络架构的折中方案
适合场景:宿主机由国内云厂商提供(控制台里无法轻易修改网络拓扑),或者你不想动现有网络结构,此时通过端口映射对外开放虚拟机服务的指定端口。
配置完成后需要注意两点,防火墙的端口放行区段要覆盖映射的宿主机端口;云厂商控制台里的安全组策略也需要放行对应的入方向端口,否则映射做了也白做。
费用方面不需要额外投入,因为端口映射依托宿主机现有的公网能力实现。
外部访问KVM虚拟机的图形桌面方案
如果虚拟机里跑的是桌面环境,SSH连接远不如直接开图形界面直观,KVM原生支持VNC或者SPICE协议,在虚拟机配置的图形显卡框架中选择VNC,并指定监听地址和端口,默认只监听回环地址,外部无法直接连接,需要将监听地址改成0.0.0,并在宿主机防火墙中放行对应端口,再用VNC客户端访问。
桥接网络配置过程中容易出现的事故点
桥接模式虽好用,配置时总要出点小插曲,有几个细节值得提前掌握。
物理网卡做了绑定,桥也要跟着绑
服务器一般有多块网卡,不少管理员做了bond(网卡绑定),直接拿物理网卡做网桥会出问题,网桥端口要放在bond接口上,而不是底层的物理网卡上。
网桥下的虚拟机总是拿不到IP
检查网桥是否处于up状态,同时查看宿主机/etc/sysconfig/network-scripts/下的网桥配置文件是否设置了BOOTPROTO和IP地址,有些系统在创建网桥后需要重启NetworkManager服务才会生效。
桥接模式下宿主机自身失联
这种情况多出在配置完网桥但忘了给网桥分配原物理网卡的IP地址,网桥配置里要显式写上原有的IP信息,同时物理网卡上的IP配置要移除。
kvm访问虚拟机常见问题和自查思路
虚拟机里能上外网,但宿主机无法访问虚拟机的SSH端口,是什么原因?
先确认虚拟机的SSH服务监听的地址是0.0.0还是0.0.1,监听在回环地址上,外部连接必然失败,同时检查宿主机防火墙是否有拦截,用telnet <虚拟机IP> 22测试端口连通性,能快速定位问题发生在哪一层。
KVM虚拟机从NAT切换到桥接模式之后IP变了,原来的服务起不来怎么办?
NAT模式下分配给虚拟机的IP通常来自168.122.x内网段,切换桥接后,虚拟机需要重新通过DHCP获取局域网IP或者手动配置静态IP,服务启动脚本里如果写死了旧IP,需要同步更新,宿主机防火墙中NAT专用的转发规则可以删除,因为它们已经不适用于桥接模式了。
KVM虚拟机和宿主机之间的文件传输没有头绪,怎么访问虚拟机的文件系统?
不需要通过网络,可以使用guestmount或virt-copy-in/out工具直接读取虚拟机的磁盘镜像文件,前提是虚拟机已关机,或者你确认能安全卸载文件系统,具体操作为:guestmount -a /var/lib/libvirt/images/虚拟机.qcow2 -i /mnt,之后/mnt目录就是虚拟机的根文件系统,直接复制文件即可,对于Windows虚拟机,libguestfs工具集也提供了对应支持。
回到最初的问题:kvm访问虚拟机不必过度迷信某一条命令或某个工具,也没必要一上来就重做网络,先确认网络模型,再排查防火墙,最后用对应的命令做精准操作,多数情况下几分钟就能解决,记不住所有参数没关系,核心原则是:虚拟机的网络要么跟宿主机同一张网,要么通过宿主机端口中转,这两条路打通了,外部访问自然顺理成章。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/647462.html




