/etc/networking/interfaces
使用“可预测的网络接口名称”时如何重置?
早于 15.10 的 Ubuntu 版本使用的网络适配器名称如下:
eth0
eth1
eth2
更换网卡或将虚拟机移至新的虚拟机管理程序会导致 Linux 增加接口编号。删除/etc/udev/rules.d/70-peristent-net.rules
将使Linux重新使用eth0
。
Ubuntu 15.10 及更高版本使用 '可预测的网络接口名称'。网络适配器名称源自 MAC 地址。
ens3
ens32
ens192
迁移虚拟机时,网络将无法启动,因为/etc/network/interfaces
仍然引用旧的不存在的网络适配器。
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto ens32
iface ens32 inet dhcp
pre-up sleep 2
重置 /etc/network/interfaces 文件的最佳方法是什么?
我需要执行此操作前关闭虚拟机并迁移到新的虚拟机管理程序,因为我正在使用包装工制作自动化的黄金图像,基于厨师/便当金色的图像。
我发现删除 /etc/network/interfaces 不起作用,因为迁移后下次启动时不会自动重新生成该文件。
我尝试编辑 grub 文件以恢复为“eth0”命名约定。虽然 /etc/network/interfaces 确实引用了旧名称 (eth0),但虚拟机将不会获得 IP,并且任何重新启动都会导致虚拟机使用新的命名约定。我还发现 systemd 将始终优先,除非我可以保证biosdevname=0
永久保留在 grub 配置中。不知道如何永久应用这个
GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 bios.devname=0"
如果可能的话,我宁愿不使用云初始化或使用任何启动后脚本,因为我宁愿保持黄金图像尽可能干净。
当然,云提供商(Azure、AWS、RackSpace、Openstack)在导入虚拟机时已经解决了这个问题。我不可能是第一个尝试使用可预测的网络接口名称迁移虚拟机的人。
我在关闭和迁移虚拟机之前尝试运行这些命令
apt-get remove biosdevname -y;
ln -s /dev/null /etc/systemd/network/99-default.link;
我发现当我迁移虚拟机时,/etc/network/interfaces
仍然ip address
参考ens32
答案1
当然,云提供商(Azure、AWS、RackSpace、Openstack)在导入虚拟机时已经解决了这个问题。
我认为OpenStack使用cloud-init、ConfigDrive格式,并提供与VM硬件匹配的网络配置。资料来源:
- https://bugs.launchpad.net/cloud-init/+bug/1577747
- https://cloudinit.readthedocs.io/en/latest/topics/datasources/configdrive.html?highlight=configdrive
- https://ask.openstack.org/en/question/63105/ways-to-inject-networking-configuration-on-instance-boot/
- https://access.redhat.com/documentation/en/red-hat-enterprise-linux-atomic-host/version-7/installation-and-configuration-guide/#setting_up_cloud_init
如果您排除首次启动脚本,那么有一个明显的答案。
以前,实际上可以保证配备单个以太网卡的主机只有一个“eth0”接口。有了这个新方案,管理员现在必须首先检查本地接口名称是什么,然后才能在其上调用命令,而以前他很有可能认为“eth0”是正确的名称。
我不喜欢这个,如何禁用它?
您基本上有三个选择:
- 您禁用固定名称的分配,以便再次使用不可预测的内核名称。为此,只需为默认策略屏蔽 udev 的 .link 文件: ln -s /dev/null /etc/systemd/network/99-default.link
https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
切换回旧的持久接口名称不是记录的选项之一。
另一种选择是默认启用网络接口的设置,无论其确切名称如何。我认为 NetworkManager 默认支持这一点。 systemd-networkd 也可以被告知这样做。
一旦您为虚拟机拥有多个网络设备,它们可能就需要特定的配置......
除了 VM 之外,NetworkManager 式方法还有一个明显的优点:一台 PC 可能有多个网络接口,可能是不同类型的,但只有其中一个连接。例如,这可以在某些高级主板上看到,或者在第一个网络接口未按预期工作并且在某个时刻安装了第二个接口的系统上看到。
答案2
我放弃了尝试干净地做到这一点,并想出了以下技巧。通过在关闭虚拟机并迁移之前运行以下脚本,虚拟机在开机时将使用 eth0 作为网络适配器。
ln -s /dev/null /etc/systemd/network/99-default.link;
echo '# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet dhcp
pre-up sleep 2' > /etc/network/interfaces
sed -i.bak 's/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 bios.devname=0 quiet"/' /etc/default/grub
update-grub
apt-get remove biosdevname -y || true;
严格来说,apt-get remove biosdevname
这不是必需的,因为 ubuntu 16.04 上默认不安装该软件包。另外,由于未安装biosdevname,因此不需要bios.devname=0
添加。GRUB_CMDLINE_LINUX_DEFAULT
如果将来安装了biosdevname,它确实可以防止网络中断。
答案3
您需要可预测的网络接口名称吗?
我的解决方案是卸载biosdevname
,这可靠地导致网络接口始终命名为 eth0、eth1 等。我还没有找到一个充分的理由来安装可预测的网络接口名称或biosdevname。
在/etc/udev/rules.d/70-persistent-net.rules
中,您可以修改命名为 eth0、eth1 等的硬件 MAC 地址。我通常删除该文件的内容,将其另存为空白文件,重新启动,然后我就得到了一个干净的石板,并显示了正确的网络适配器...
# This file was automatically generated by the /lib/udev/write_net_rules
# program,run by the persistent-net-generator.rules rules file.
#
# This file was automatically generated by the /lib/udev/write_net_rules
# program,run by the persistent-net-generator.rules rules file.
#
# You can modify it,as long as you keep each rule on a single
# line,and change only the value of the NAME= key.
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="xx:xx:xx:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="xx:xx:xx:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
^^ 其中 xx:xx:xx:xx:xx:xx 是网络适配器的唯一 MAC 地址。
我知道你提到删除这个文件不是解决方案,但我发布了上面的例子,因为至少在 Suse 中它是/lib/udev/write_net_rules
创建这个文件的。因此,看看回溯到该文件是否有帮助,如果它适用于您的发行版,您也许可以修改它来解决您的问题。
请注意,这是我从 Suse 版本 11 中了解到的,这是 systemd 之前的旧 Init 方式。不确定 systemd 下最新版本的 linux 是否已更改。
答案4
将 Ubuntu 14.04 主机升级到 16.04 时遇到了这个问题。biosdevname
软件包未安装,因此按照OP所述"biosdevname=0 net.ifnames=0"
使用。/etc/default.grub
我运行此脚本,如果输出看起来不错,则将输出重定向到/etc/udev/rules.d/70-persistent-net.rules
构建新的 udev 规则,以防内核决定以不同的顺序枚举以太网端口。
#!/bin/bash
count=0
# build array of network devices starting with eth? from /proc
for dev in `cat /proc/net/dev | egrep 'eth.*:' | awk '{print $1};' | cut -d':' -f1 | sort`; do
edev[$count]="$dev"
let count="$count+1"
done
# use array to find mac address
for d in ${edev[@]}; do
mac=`ip addr show "$d" | grep ether | awk '{print $2};'`
if [ -n "$mac" ]; then
echo "# mac for $d is $mac"
fi
printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="%s"\n' $mac $d
done