在我的服务器(Ubuntu 18.04 LTS)上,我正在运行一个 KVM 虚拟机,该虚拟机已经运行了一年多,但最近 - 可能是因为某些更新 - 每次重新启动主机时,虚拟机都会失去与网络的连接。最近两次发生这种情况时,我设法恢复了连接,但这次我再也无法让它工作了。
我读了很多教程和其他网页,感觉好像什么都试过不止一次,但显然我一定错过了什么。同时涉及的变量太多了,其中许多变量可能相互影响。所以对于这个问题,我想找到最佳的故障排除策略,使我(和其他人)能够尽可能有效地缩小连接问题的根源。更具体地说,我正在谈论通过 Ubuntu 18.04 上的桥连接的 KVM 虚拟机上的连接问题。
我意识到这个问题已经变得非常长了,所以让我澄清一下你无需阅读此处内容即可回答该问题。
在下面的标题下,我提到了在解决网络问题时需要解决的最重要的不确定领域,但无需在答案中详细讨论这些领域。把它们作为可能的起点。
如果您希望以特定机器的配置作为出发点,请向下滚动到我提供此类详细信息的底部(在“我的示例”标题下)。
网络计划
在 18.04 上对此进行故障排除时遇到的一个问题是,ubuntu 改为使用netplan
,这使得许多当前可用的建议变得过时。
切换到netplan
本身也会引起混乱,因为,据我所知,使用netplan
意味着所有网络配置都在 中完成/etc/netplan/*.yaml
,而不再在 中完成/etc/network/interfaces
,但是当我注释掉 中的所有内容时/etc/network/interfaces
,它似乎以某种方式被写回(可能是我自己通过 Gnome 桌面上的虚拟机管理器完成的)。
看来我不是唯一一个对此感到沮丧的netplan
人有人建议改回ifupdown
但是为了限制这个问题的范围,让我们留在 netplan 内并尝试在不切换回来的情况下修复问题。
NetworkManager 与 systemd-networkd
另一个困难是,Ubuntu 18.04 Server 和 Ubuntu 18.04 Desktop 之间至少有一个相关差异:服务器用途systemd-networkd
和桌面用途NetworkManager
,这需要不同的故障排除路径。更糟糕的是:如果您最初安装了服务器版本,但后来添加了 gnome 桌面怎么办?(我不记得我做了什么,但很可能这就是我所做的,因为我/etc/netplan/01-netcfg.yaml
说renderer: networkd
NetworkManager 似乎也在默认运行。)
修复主机或者虚拟机?
我的第三个不确定的领域是我应该修复主机还是虚拟机上的东西(或者主机上的更改是否也需要客户端上的更改)。到目前为止,我还没有太关注虚拟机,因为它运行良好,我从未更新过它(除了自动 ubuntu 安全更新)。但上次我设法修复了连接问题,我通过复制它的硬盘并创建一个新的虚拟机(在我看来是相同的)来实现的。我想这证实了虚拟机上的配置没有问题(因为虚拟机硬件是在主机上配置的),但它仍然告诉我,我可能需要更多地关注虚拟机的硬件配置。
需要重新启动才能应用更改吗?
在尝试不同的修复方法时,我也常常不确定
用户界面 (UI) 冲突?
最后,我意识到通过哪个 UI 进行某些更改可能很重要,因为他们可能会将这些更改写入不同的地方。我目前有以下用于配置我的虚拟机的界面:
- 命令行(最常用)
- 虚拟机管理器 (GUI)
- 炒锅/泡菜(网络界面)
- 我也运行着带有 Cloudmin 的 Webmin,但我的虚拟机没有显示在那里,所以我目前没有使用它。
我的例子
因此,尽管我的想法是找到一种通用的故障排除策略,但我认为从一个具体的例子开始总是一个好主意。以下是有关我当前设置的一些详细信息(如果评论中有要求,我会添加更多详细信息):
这是我当前的/etc/netplan/01-netcfg.yaml
(并且该目录中没有其他 yaml 文件):
network:
version: 2
renderer: NetworkManager
ethernets:
enp0s31f6:
dhcp4: no
bridges:
br0:
interfaces: [ enp0s31f6]
dhcp4: yes
dhcp6: yes
我使用 NetworkManager 的唯一原因是因为我一直在努力尝试但systemd-networkd
没有成功,所以我想我应该给 NetworkManager 一个机会(但我的直觉是我应该坚持使用systemd-networkd
)。因此,我设置managed=true
了我的/etc/NetworkManager/NetworkManager.conf
,现在看起来像这样:
[main]
plugins=ifupdown,keyfile
[ifupdown]
managed=true
[device]
wifi.scan-rand-mac-address=no
virsh net-list --all
给了我这个:
Name State Autostart Persistent
----------------------------------------------------------
br0 active yes yes
bridged inactive yes yes
default active yes yes
我尝试与我的虚拟机一起使用的桥是 br0。
这是 br0 的配置:
第二座桥是尝试重新开始,简单地创建一个新的桥并将虚拟机连接到该桥,但添加桥没有效果,可能是因为虚拟机管理器似乎将其写入/etc/network/interfaces
而不是 yaml 文件/etc/netplan/
这是我的/etc/network/interfaces
:
##auto lo br0
##iface lo inet loopback
##auto br1
##iface br1 inet dhcp
## bridge_ports enp0s31f6
## bridge_stp on
## bridge_fd 0.0
##iface br0 inet dhcp
## bridge_ports enp0s31f6
auto br0
iface br0 inet dhcp
bridge_ports enp0s31f6
bridge_stp on
bridge_fd 0.0
auto br-kvm
iface br-kvm inet dhcp
bridge_ports enp0s31f6
bridge_stp on
bridge_fd 0.0
请注意我是如何注释掉所有内容的(以确保该文件不会以某种方式影响我的配置),只是将它添加回底部,如上所述。
ifconfig
给出了一长串网桥(大多数都以类似 命名br-a5ffb2301edc
),但我不知道它们来自哪里(我想我在无数个小时的测试中不知不觉地创建了它们)。我不会在这里粘贴它们,只粘贴br0
实际的以太网接口:
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.4 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::4e52:62ff:fe09:7e59 prefixlen 64 scopeid 0x20<link>
ether 4c:52:62:09:7e:59 txqueuelen 1000 (Ethernet)
RX packets 806319 bytes 84505505 (84.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 307846 bytes 845321927 (845.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 4c:52:62:09:7e:59 txqueuelen 1000 (Ethernet)
RX packets 817196 bytes 101316866 (101.3 MB)
RX errors 0 dropped 13 overruns 0 frame 0
TX packets 821152 bytes 876709681 (876.7 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 16 memory 0xef000000-ef020000
这是我在虚拟机上测试网络连接的方法:
$ping 8.8.8.8
connect: Network is unreachable
编辑:这是虚拟机的内容/etc/netplan/50-cloud-init.yaml
:
network:
version: 2
# renderer: networkd
ethernets:
ens3:
addresses: []
dhcp4: true
dhcp6: false
optional: true
我不记得为什么几个月前我注释掉了 redererer 行(我也不知道现在假定的默认渲染器是什么),但这个确切的配置已经起作用了。
我还可以提一下,我突然想到这cloud-init
可能会把我(在主机上)的事情搞乱,所以我检查了/var/log/cloud-init-output.log
一下它是否在做任何事情:
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 running 'modules:config' at Fri, 21 Feb 2020 02:24:08 +0000. Up 50.91 seconds.
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 running 'modules:final' at Fri, 21 Feb 2020 02:24:15 +0000. Up 56.59 seconds.
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 finished at Fri, 21 Feb 2020 02:24:15 +0000. Datasource DataSourceNoCloud [seed=/var/lib/cloud/seed/nocloud-net][dsmode=net]. Up 56.76 seconds
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 running 'init-local' at Fri, 21 Feb 2020 02:59:28 +0000. Up 10.48 seconds.
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 running 'init' at Fri, 21 Feb 2020 03:04:29 +0000. Up 311.21 seconds.
ci-info: +++++++++++++++++++++++++++++++++++++++++Net device info+++++++++++++++++++++++++++++++++++++++++
ci-info: +-----------+-------+------------------------------+---------------+--------+-------------------+
ci-info: | Device | Up | Address | Mask | Scope | Hw-Address |
ci-info: +-----------+-------+------------------------------+---------------+--------+-------------------+
ci-info: | br-kvm | False | . | . | . | f2:7a:46:82:f9:e0 |
ci-info: | br0 | True | 192.168.1.4 | 255.255.255.0 | global | 4c:52:62:09:7e:59 |
ci-info: | br0 | True | fe80::4e52:62ff:fe09:7e59/64 | . | link | 4c:52:62:09:7e:59 |
ci-info: | enp0s31f6 | True | . | . | . | 4c:52:62:09:7e:59 |
ci-info: | lo | True | 127.0.0.1 | 255.0.0.0 | host | . |
ci-info: | lo | True | ::1/128 | . | host | . |
ci-info: +-----------+-------+------------------------------+---------------+--------+-------------------+
ci-info: +++++++++++++++++++++++++++++Route IPv4 info+++++++++++++++++++++++++++++
ci-info: +-------+-------------+-------------+---------------+-----------+-------+
ci-info: | Route | Destination | Gateway | Genmask | Interface | Flags |
ci-info: +-------+-------------+-------------+---------------+-----------+-------+
ci-info: | 0 | 0.0.0.0 | 192.168.1.1 | 0.0.0.0 | br0 | UG |
ci-info: | 1 | 169.254.0.0 | 0.0.0.0 | 255.255.0.0 | br0 | U |
ci-info: | 2 | 192.168.1.0 | 0.0.0.0 | 255.255.255.0 | br0 | U |
ci-info: +-------+-------------+-------------+---------------+-----------+-------+
ci-info: +++++++++++++++++++Route IPv6 info+++++++++++++++++++
ci-info: +-------+-------------+---------+-----------+-------+
ci-info: | Route | Destination | Gateway | Interface | Flags |
ci-info: +-------+-------------+---------+-----------+-------+
ci-info: | 1 | fe80::/64 | :: | br0 | U |
ci-info: | 3 | local | :: | br0 | U |
ci-info: | 4 | ff00::/8 | :: | br0 | U |
ci-info: +-------+-------------+---------+-----------+-------+
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 running 'modules:config' at Fri, 21 Feb 2020 03:04:33 +0000. Up 315.26 seconds.
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 running 'modules:final' at Fri, 21 Feb 2020 03:04:39 +0000. Up 321.85 seconds.
Cloud-init v. 19.4-33-gbb4131a2-0ubuntu1~18.04.1 finished at Fri, 21 Feb 2020 03:04:40 +0000. Datasource DataSourceNoCloud [seed=/var/lib/cloud/seed/nocloud-net][dsmode=net]. Up 322.15 seconds
看到它处于活动状态,我用 禁用了它sudo touch /etc/cloud/cloud-init.disabled
。但我的连接问题仍然没有解决。
编辑2:这是我检查过的其他内容(基于这个帖子) 是我的虚拟机的网络接口是否仍与我的网桥关联。为了获取接口的名称,我这样做了virsh domiflist LMS
(LMS 是我的虚拟机的主机名),我得到了以下信息:
Interface Type Source Model MAC
-------------------------------------------------------
vnet0 bridge br0 virtio 52:54:00:f0:0e:f8
它已经br0
在源下说明了,但我不确定这到底意味着什么,所以我使用仔细检查brctl show br0
,确认vnet0
与以下内容相关br0
:
bridge name bridge id STP enabled interfaces
br0 8000.4c5262097e59 yes enp0s31f6
vnet0
我非常希望找到丢失的 vnet0,以便可以修复它,但不幸的是,这也不是问题。
答案1
正如您所说,这是一个漫长而艰难的问题,因此我要做的第一件事就是尝试简化您的配置。
您的帖子中没有提到 iptables,这可能是导致您遇到问题的原因。您可以使用 查看当前规则iptables -vnL; iptables -t nat -vnL
。或者,您可以使用以下命令将内核设置为绕过网桥的 iptables:sysctl net.bridge.bridge-nf-call-iptables=0 net.bridge.bridge-nf-call-ip6tables=0 net.bridge.bridge-nf-call-arptables=0
就我个人而言,我讨厌 netplan 的额外抽象层,而且由于可以直接使用 networkd 进行桥接,因此我会摆脱 netplan.io 和 NetworkManager,并使用 networkd 完成所有操作。您的网络显然有一个 DHCP 服务器,因此您不需要使用 networkd 或 dnsmasq 中的 DNSServer 配置。networkd 的最佳 wiki 是https://wiki.archlinux.org/index.php/Systemd-networkd- 完整阅读它,因为其中有一些技巧,但是一旦你理解了它们,你可以将这些知识转移到其他主要发行版。
一旦掌握了窍门,排除网络故障也就不那么糟糕了:
journalctl -xe | grep networkd
或者进行完整调试:
mkdir /etc/systemd/system/systemd-networkd.service.d
echo -e "[Service]\nEnvironment=SYSTEMD_LOG_LEVEL=debug" >> /etc/systemd/system/systemd-networkd.service.d/override.conf
从那里,您可以进行故障排除,tcpdump -nni br0
以确保您的虚拟机确实在发送和接收流量,如果 virtio 驱动程序运行不正常,则可能并非如此。e1000 驱动程序似乎在任何地方都运行良好。