Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

A.19.3. 客户机失败的 PXE 引导(或 DHCP)

症状
客户机虚拟机可以成功启动,但随后无法从 DHCP 获取 IP 地址或使用 PXE 协议引导。此错误有两个常见原因:为网桥设置了很长时间,当 iptables 软件包和内核不支持 checksum mangling 规则时。
网桥上的 forward 延迟时间
正在调查
这是此错误的最常见原因。如果客户机网络接口连接到启用了 STP(Spanning Tree 协议)的桥接设备,并且设置了长的延时,则网桥将不会将网络数据包从客户机虚拟机转发到网桥,直到在客户机连接到网桥以来至少经过转发延迟秒数。此延迟允许网桥时间监控来自接口的流量,并确定其后面的 MAC 地址,并阻止网络拓扑中的转发循环。
如果转发延迟比客户机的 PXE 或 DHCP 客户端的超时时间更长,客户端的操作将失败,并且客户机将无法引导(如果是 PXE),或者无法获取 IP 地址(如果是 DHCP)。
解决方案
如果是这种情况,请将网桥的转发延迟更改为 0,在网桥中禁用 STP,或者同时更改这两者。
注意
只有网桥不使用多个网络来连接多个网络,但只是将多个端点连接到一个网络(由 libvirt使用的网桥,最常见的用例)才适用。
如果客户机具有连接到 libvirt- 管理的虚拟网络的接口,请编辑网络的定义,然后重新启动它。例如,使用以下命令编辑默认网络:
# virsh net-edit default
<bridge> 元素中添加以下属性:
<name_of_bridge='virbr0' delay='0' stp='on'/>
注意
delay='0'stp='on' 是虚拟网络的默认设置,因此仅当从默认修改配置时才需要这个步骤。
如果客户机接口连接到在 libvirt 之外配置的主机网桥,请更改延迟设置。
/etc/sysconfig/network-scripts/ifcfg-name_of_bridge 文件中添加或编辑以下行,以使用 0 秒打开 STP:
STP=on DELAY=0
更改配置文件后,重启网桥设备:
/usr/sbin/ifdown name_of_bridge
/usr/sbin/ifup name_of_bridge
注意
如果 name_of_bridge 不是网络中的 root 网桥,则该网桥的延迟最终会重置为 root 网桥的延时。要防止这种情况的发生,请在 name_of_bridge 上禁用 STP。
iptables 软件包和内核不支持 checksum mangling 规则
正在调查
只有当所有四个条件都为 true 时,这个信息才会出现问题:
  • 客户机使用 virtio 网络设备。
    如果是这样,配置文件将包含 model type='virtio'
  • 主机已加载 vhost-net 模块。
    如果 ls /dev/vhost-net 没有返回空结果,则会出现这种情况。
  • 客户机尝试从主机上直接运行的 DHCP 服务器获取 IP 地址。
  • 主机上的 iptables 版本早于 1.4.10。
    iptables 1.4.10 是第一个版本,用来添加 libxt_CHECKSUM 扩展。如果 libvirtd 日志中出现以下信息,会出现这种情况:
    warning: Could not add rule to fixup DHCP response checksums on network default
    warning: May need to update iptables package and kernel to support CHECKSUM rule.
    重要
    除非此列表中的所有其他条件也是 true,否则上述警告消息可以忽略,并且不是任何其他问题的指示符。
当出现这些条件时,从主机发送到客户机的 UDP 数据包具有取消计算的校验和。这使得主机的 UDP 数据包在客户机的网络堆栈看起来无效。
解决方案
要解决这个问题,使上述任何四点无效。最佳解决方案是将主机 iptables 和内核更新至 iptables-1.4.10 或更新版本。否则,最具体的修复是禁用这个特定虚拟机的 vhost-net 驱动程序。要做到这一点,使用以下命令编辑客户机配置:
virsh edit name_of_guest
<driver> 部分更改或添加 <interface> 行:
<interface type='network'>
  <model type='virtio'/>
  <driver name='qemu'/>
  ...
</interface>
保存更改,关闭 guest,然后重新启动它。
如果问题仍未解决,则问题可能是 firewalld 和默认的 libvirt 网络之间的冲突。
要解决这个问题,使用 service firewalld stop 命令停止 firewalld,然后使用 服务 libvirtd restart 命令重启 libvirt
注意
另外,如果正确配置了 /etc/sysconfig/network-scripts/ifcfg-network_name 文件,您可以确保客户机使用 dhclient 命令作为 root 用户获取 IP 地址。