redhat 万兆和千兆的网卡命名问题

新弄了一批机器,为了准备切换到万兆环境,给机器配了双千兆和双万兆混合的4接口网卡,然后就出了一点问题

centos 7 引入了网络一致化命名规则,具体可以看红帽的联网指南

主要部分摘抄如下

------------引用专用分割线----------------------------

8.1. 命名方案层级结构

默认情况下,systemd 会使用以下策略,采用支持的命名方案为接口命名:

方案 1:如果固件或 BIOS 信息适用且可用,则使用整合了为板载设备提供索引号的固件或 BIOS 的名称(例如:eno1),否则请使用方案 2。

方案 2:如果固件或 BIOS 信息适用且可用,则使用整合了为 PCI 快速热插拔插槽提供索引号的固件或 BIOS 名称(例如 ens1),否则请使用方案 3。

方案 3:如果硬件连接器物理位置信息可用,则使用整合了该信息的名称(例如:enp2s0),否则请使用方案 5。

方案 4: 默认不使用整合接口 MAC 地址的名称(例如:enx78e7d1ea46da),但用户可选择使用此方案。

方案 5:传统的不可预测的内核命名方案,在其他方法均失败后使用(例如: eth0)。

这个策略(如上所述)是默认策略。如果该系统已启用 biosdevname,则会使用该方案。注:启用 biosdevname 需要添加 biosdevname=1 作为命令行参数(Dell 系统除外),此时只要安装 biosdevname,就会默认使用该方案。如果用户已添加 udev 规则,该规则会更高内核设备名称,则会优先使用这些规则。

设备命名过程如下:

/usr/lib/udev/rules.d/60-net.rules 文件中的规则会让 udev 帮助工具 /lib/udev/rename_device 查看所有 /etc/sysconfig/network-scripts/ifcfg-suffix 文件。如果发现包含 HWADDR 条目的 ifcfg 文件与某个接口的 MAC 地址匹配,它会将该接口重命名为 ifcfg 文件中由 DEVICE 指令给出的名称。

/usr/lib/udev/rules.d/71-biosdevname.rules 中的规则让 biosdevname 根据其命名策略重命名该接口,即在上一步中没有重命名该接口、已安装 biosdevname、且在 boot 命令行中将 biosdevname=0 作为内核命令给出。

/lib/udev/rules.d/75-net-description.rules 中的规则让 udev 通过检查网络接口设备,填写内部 udev 设备属性值 ID_NET_NAME_ONBOARD、ID_NET_NAME_SLOT、ID_NET_NAME_PATH。注:有些设备属性可能处于未定义状态。

/usr/lib/udev/rules.d/80-net-name-slot.rules 中的规则让 udev 重命名该接口,优先顺序如下:ID_NET_NAME_ONBOARD、ID_NET_NAME_SLOT、ID_NET_NAME_PATH。并提供如下信息:没有在步骤 1 或 2 中重命名该接口,同时未给出内核参数 net.ifnames=0。如果一个参数未设定,则会按列表的顺序设定下一个。如果没有设定任何参数,则不会重命名该接口。

-----------以上是红帽的联网指南-------

其实简述上面的信息就是首先看内核参数是否启用了biosdevname=1 (默认是启用),如果bios提供了设备的名称就使用bios提供的名称

如果没有,就根据网卡配置中 device=eth,em,xyz 的名字来命名这个网卡,但是如果这样命名的话,必须在配置里写死网卡的mac地址

作为网卡的识别标志,对单网卡当然没什么问题,但是如果在集群环境里,HA,以及bonding环境里,为了快速切换网络流量,往往要屏蔽mac,

使用虚拟mac,或者多块网卡使用一个mac地址,这个时候需要在配置文件里屏蔽mac地址,因此就需要区改udev的配置文件来解决

我所遇到的问题是,使用了biosdevname=0和 net.ifnames=0 参数后,(因为以前有大量的centos6的机器,为了移植方便,不使用一致性命名规则,网卡名依然是eth0,eth1.。。。)安装服务器时一切正常,但启动系统后,发现系统将插在第一个端口的网卡认为是eth2,和预期不符,本能的认为udev可以解决问题,于是添加了udev的规则

```

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="24:6e:96:ac:a1:xa", ATTR{type}=="1", KERNEL=="*", NAME="eth0"

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="24:6e:96:ac:a1:xb", ATTR{type}=="1", KERNEL=="*", NAME="eth1"

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="24:6e:96:ac:a1:xc", ATTR{type}=="1", KERNEL=="*", NAME="eth2"

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="24:6e:96:ac:a1:xd", ATTR{type}=="1", KERNEL=="*", NAME="eth3"

```

发现不起作用,,难道写错了?换个规则,用pci设备号去绑定

SUBSYSTEM=="net", ACTION=="add", KERNEL=="eth*", SUBSYSTEM=="pci", KERNELS===="0000:01:00.0", NAME="eth0"

依然没用

用下面的命令debug一下

udevadm test /sys/class/net/eth0

结果缩略如下

rules contain 49152 bytes tokens (4096 * 12 bytes), 13451 bytes strings

2076 strings (25677 bytes), 1399 de-duplicated (12904 bytes), 678 trie nodes used

NAME 'eth2' /etc/udev/rules.d/60-net.rules:6

IMPORT builtin 'net_id' /usr/lib/udev/rules.d/75-net-description.rules:6

IMPORT builtin 'hwdb' /usr/lib/udev/rules.d/75-net-description.rules:12

IMPORT builtin 'path_id' /usr/lib/udev/rules.d/80-net-setup-link.rules:5

IMPORT builtin 'net_setup_link' /usr/lib/udev/rules.d/80-net-setup-link.rules:9

No matching link configuration found.

RUN '/usr/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/$name --prefix=/net/ipv4/neigh/$name --prefix=/net/ipv6/conf/$name --prefix=/net/ipv6/neigh/$name' /usr/lib/udev/rules.d/99-systemd.rules:55

Error changing net interface name 'eth0' to 'eth2': File exists

could not rename interface '2' from 'eth0' to 'eth2': File exists

created db file '/run/udev/data/n2' for '/devices/pci0000:00/0000:00:1c.4/0000:06:00.0/net/eth0'

ACTION=add

DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:06:00.0/net/eth0

ID_BUS=pci

ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Gigabit 4P X540/I350 rNDC)

粗体看到原来是设备已经存在,无法重命名,于是想到的重新加载驱动

modprobe -rv igb

modprobe -rv ixgbe

然后按顺序加载驱动

modprobe ixgbe

modprobe  igb

终于可以看到效果了,不过重启就完蛋了

于是想是否可以调整驱动加载顺序?

找了半天文档,发现可以通过重新打包内核启动文件和编译内核两条路实现,不过这显然又增加了很多麻烦,总不能升级一次内核,就重新打一次包吧

看看其他方法。最好发现简单的方法就是修改启动内核的参数 将 biosdevname=0和net.ifnames=0 改为 biosdevname=0和net.ifnames=1 ,这样系统启动时,会按照上述一致性命名规则,重新命名网卡,可以预期的是,已dell板载网卡为例,网卡会依次命名为eno1,eno4,等等,然后再加载udev规则,按照udev规则,再次重新命名为我们期望的eth0,eth1,等等

当然配置文件可以用ansible搞定,我这里的模版内容就是

ifcfg-eth0.j2

------

NAME="eth0"

DEVICE="eth0"

ONBOOT=yes

HWADDR="{{ hostvars[inventory_hostname].ansible_eth1.macaddress }}"

NETBOOT=yes

IPV6INIT=no

BOOTPROTO=static

TYPE=Ethernet

----------

这样udev 规则就生效了,其实就是启动过程中,当上述两个参数全为0时,网络设备只能叫ethx,先加载的驱动抢占了eth0和eth1时,(我这里是千兆的设备驱动 igb先启动)后起的设备想按udev规则rname时,发现eth0,和eth1 已经被占据了,因此命名失败,所以深入理解启动顺序和动作其实还是蛮重要的


参考链接  https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/networking_guide/sec-understanding_the_device_renaming_procedure


红帽知识库文章引用如下


Why RHEL7 system is failing in renaming the interfaces with error "systemd-udevd: error changing net interface name ethX to ethY: File exists" ? 

SOLUTION 已验证 - 已更新 2015年四月23日19:40 - English 

环境Red Hat Enterprise Linux 7.1udevd

问题

In RHEL 7 system NIC naming has been changed to ethX style by adding net.ifnames=0 and biosdevname=0 to grub file. After doing that and rebooting the system when system boots up, MAC address mapping to NIC names are as eth0 - 8c:dc:d4:b7:xx:xx and eth1 - 8c:dc:d4:33:yy:yyNow the requiremet is NIC port whose MAC is 8c:dc:d4:b7:xx:xx should be named as eth1 and the NIC port whose MAC is 8c:dc:d4:33:yy:yy should be named as eth0.So to achieve that have tried adding HWADDR accordingly in the respective ifcfg-ethN files and then after reboot interfaces are coming up in the same way as that as that of original mapping.In logs can see below error at the time when udev tried renaming the interfaces:RawApr 20 05:32:38 HOSTNAME systemd-udevd: error changing net interface name eth0 to eth1: File existsApr 20 05:32:38 HOSTNAME systemd-udevd: error changing net interface name eth1 to eth0: File exists

决议There is no fixed supported way to achieve this particular type of interface renaming.There were couple of bugs raised- #1184167 , #1048399 to achieve that type of interface renaming, but all got closed with status as "CLOSED CANTFIX"Workaround is to change the net.ifnames=1 , then after rebuilding the grub and rebooting the system , renaming as per requirement may be achieved. This may happen because udev running from the initramfs will rename the interfaces to their Consistent Device Names. Then when the root file system will be mounted udev will run again and this time it finds the DEVICE/HWADDR pairs in the ifcfg-ethX files and renaming might happen accordingly.If the NIC drivers didn't load until after the root file system was mounted, this would break. Its hard to expect this workaround to always work 100% in all cases, If the timing changes the behaviour could be different.

根源

There is no fixed supported way to achieve this particular type of interface renaming. When the system boots and the NIC modules are loaded, before any renaming or naming scheme takes place, the interfaces will be named eth0, eth1, eth2, etc as the NIC modules and interfaces are created.Further the requirement of renaming eth0 to eth1 and eth1 to eth0 could not be achieved because system cannot rename a device to some other name that is already in use.

诊断步骤

Check NIC configuration , booting logs how interface came up etc.Can refer to Red Hat Documentation on renaming the interfaces in RHEL7.

不会插入代码框啊,发现发布完了都错行了,找时间学习学习编辑器

你可能感兴趣的:(redhat 万兆和千兆的网卡命名问题)