CentOS7网卡名称的修改

生产环境中,托管于机房的服务器经常会进行割接操作,为了能让网卡更容易让运维人员和机房识别,避免因为弄错网线或找错网卡导致业务中断,在服务器上架前就应该对所有网卡按照 eth0eth1 的方式来命名,并按照网卡的物理位置贴上标签。从 CentOS7 开始,系统中的默认的网卡命名方式已经不再是 eth0eth1 的格式了。

要想让操作系统按照 eth0eth1 的方式来命名,一般有如下两种方式。

修改 udev 的 rules 文件

手动修改

一般情况下,板载网卡(目前多数服务器为板载双网卡)的 MAC 地址相差 1,其余网卡则为外接网卡。

使用 ip addr show 命令可以查看一台机器上所有的网卡信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@m2 ~]# ip addr show 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:39:b5:c6 brd ff:ff:ff:ff:ff:ff
inet6 fe80::e349:3059:2d58:c589/64 scope link
3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:39:b5:c7 brd ff:ff:ff:ff:ff:ff
inet 172.20.35.2/22 brd 172.20.35.255 scope global dynamic ens33
inet6 fe80::d9b6:fc5b:da94:a526/64 scope link
4: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3f:ef:47 brd ff:ff:ff:ff:ff:ff
inet6 fe80::5043:4dc:eec2:582d/64 scope link
5: ens35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:87:80:67 brd ff:ff:ff:ff:ff:ff
inet6 fe80::c308:1eca:83e4:11c/64 scope link

以上命令输出结果中 00:50:56:39:b5:c600:50:56:39:b5:c7 这两个 MAC 地址相差为 1,因此可以大致断定网卡 ens32ens33 为板载网卡,网卡名顺序应该改为 eth0eth1,剩下两块网卡为外接网卡,命名为 eth2eth3

要修改默认的网卡命名方式,我们可以创建一个自定义 udev 的 rules 文件,如:/etc/udev/rules.d/70-mynet.rules,然后按照顺序将 MAC 地址与网卡名称绑定。

1
2
3
4
SUBSYSTEM=="net", ACTION="add", DRIVERS=="?*", ATTR{address}=="00:50:56:39:b5:c6", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION="add", DRIVERS=="?*", ATTR{address}=="00:50:56:39:b5:c7", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
SUBSYSTEM=="net", ACTION="add", DRIVERS=="?*", ATTR{address}=="00:50:56:3f:ef:47", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"
SUBSYSTEM=="net", ACTION="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:87:80:67", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"

除此之外,还需要更改网卡配置文件,配置 DEVICENAME 以及 HWADDR 参数。在 ifcfg 文件中使用 HWADDR 参数设定 MAC 地址,这样就可由 udev 识别,然后从 DEVICE 参数提供的字符串中提取网卡名称。

/etc/sysconfig/network-scripts/ifcfg-eth0 的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
UUID=a805585c-c69a-4885-8f83-16d67754dccb
# ----------------------------------
NAME=eth0
DEVICE=eth0
ONBOOT=yes
HWADDR=00:50:56:39:b5:c6
# ----------------------------------

/etc/sysconfig/network-scripts/ifcfg-eth1 的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
UUID=6d524d10-ee00-460e-af9c-61e57c833e75
# ----------------------------------
NAME=eth1
DEVICE=eth1
ONBOOT=yes
HWADDR=00:50:56:39:b5:c7
# ----------------------------------
IPADDR=172.20.35.2
NETMASK=255.255.252.0
BROADCAST=172.20.35.255
NETWORK=172.20.32.0
GATEWAY=172.20.32.7

/etc/sysconfig/network-scripts/ifcfg-eth2 的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
UUID=cfefc668-986c-4c4f-b673-66d4463a56e5
# ----------------------------------
NAME=eth2
DEVICE=eth2
ONBOOT=yes
HWADDR=00:50:56:3f:ef:47
# ----------------------------------

/etc/sysconfig/network-scripts/ifcfg-eth3 的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
UUID=1aa05d79-80f3-4550-bc57-9dc64a4c8ebf
# ----------------------------------
NAME=eth3
DEVICE=eth3
ONBOOT=yes
HWADDR=00:0c:29:87:80:67
# ----------------------------------

重启完成后验证。

脚本自动修改

手动修改配置起来比较麻烦,更容易出现人工错误。为了更精准,我写了下面的脚本,脚本会在不改变原有 IP 相关配置的情况下更新名称,没有按照 MAC 地址排序(即:网卡物理位置排序)。为了以防万一,建议在执行完之后进行人工确认,然后再重启。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash

# Test the operator is root or not
if test "${UID}" -ne 0 -o "${USER}" != "root";then
echo "Only root can run this script ... "
exit 5
fi

# Source function library.
. /etc/rc.d/init.d/functions

# Set up a default search path.
PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin"
export PATH

# Make sure umask is sane
umask 022

# Log that something succeeded
echo_info(){
echo -en "[ ";
${SETCOLOR_SUCCESS};
echo -en " INFO ";
${SETCOLOR_NORMAL};
echo -en " ] ";
echo "$@"
}

# Log that something Error
echo_error(){
echo -en "[ ";
${SETCOLOR_FAILURE};
echo -en " ERROR ";
${SETCOLOR_NORMAL};
echo -en " ] ";
echo "$@"
}

# Log a warning
echo_warning(){
echo -en "[ ";
${SETCOLOR_WARNING};
echo -en "WARNING";
${SETCOLOR_NORMAL};
echo -en " ] ";
echo "$@"
}

echo_long_split(){
echo "-----------------------------------------------"
}

# Check system version , used to CentOS 7.X and CentOS 8.X
if . /etc/os-release &>/dev/null;then
echo "------------- System Information --------------"
echo
echo " OS : ${PRETTY_NAME}"
echo " Arch : $(uname -m) $(getconf LONG_BIT) Bit"
echo " Kernel : $(uname -r)"
echo
echo_long_split
else
echo_error 'Your system version is not suitable for running this script ... '
exit 5
fi

counter=0
RETVAL=0
ifcfg_dir='/etc/sysconfig/network-scripts/'
ifcfg_bak_dir='/root/ifcfg_bak/'
logfile=${ifcfg_bak_dir}/$(basename $0).log
rules_file='/etc/udev/rules.d/70-my-custom-net.rules'

echo_info "Creating bakup directory."
echo_info "mkdir -pv ${ifcfg_bak_dir}"
mkdir -pv ${ifcfg_bak_dir}
exec > >(tee -a ${logfile}) 2>&1

for dev in /sys/class/net/*/device;do
old_name=$(awk -F/ '{printf $5}' <<< "${dev}")
if [[ "${old_name}" =~ eth[0-9] ]];then
echo_warning "The network card name ${old_name} may be correct. Please check it manually."
RETVAL=5
fi
done

if [[ ${RETVAL} -eq 0 ]]; then
>${rules_file}
else
exit ${RETVAL}
fi

for dev in /sys/class/net/*/device;do

old_name=$(awk -F/ '{printf $5}' <<< "${dev}")
old_ifcfg=${ifcfg_dir}/ifcfg-${old_name}

new_name="eth${counter}"
new_ifcfg=${ifcfg_dir}/ifcfg-${new_name}

hwaddr=$(tr 'a-z' 'A-Z' < ${dev%/*}/address)

echo_info "${old_name} => ${new_name} ${hwaddr}"


\cp ${old_ifcfg} ${new_ifcfg} && {
RETVAL=0
echo_info "cp ${old_ifcfg} ${new_ifcfg}"
} || {
echo_error "cp ${old_ifcfg} ${new_ifcfg}"
RETVAL=5
}


\mv ${old_ifcfg} ${ifcfg_bak_dir} && {
RETVAL=0
echo_info "mv ${old_ifcfg} ${ifcfg_bak_dir}"
} || {
echo_error "mv ${old_ifcfg} ${ifcfg_bak_dir}"
RETVAL=5
continue
}

echo 'SUBSYSTEM=="net", ACTION="add", DRIVERS=="?*", ATTR{address}=="'"${hwaddr}"'", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="'"${new_name}"'"' >> ${rules_file}

echo_warning "sed -ri '/HWADDR/d;s#(DEVICE=|NAME=).*#\1""${new_name}""#;/DEVICE=/aHWADDR=""${hwaddr}""' ${new_ifcfg}"
sed -ri -e '/HWADDR/d;s#(DEVICE=|NAME=).*#\1'"${new_name}"'#;/DEVICE=/aHWADDR='"${hwaddr}"'' ${new_ifcfg}

echo_long_split
(( counter += 1 ))
done

echo_info "cat ${rules_file}"
echo_long_split
cat ${rules_file}
echo_long_split

echo
echo_info "Logfile is ${logfile}"

[[ ${RETVAL} -eq 0 ]] && echo_warning "Please check it and reboot manually."

sleep 1s && kill 0 > /dev/null 2>&1

修改Grub2配置

如果并不关心网卡的物理位置,只想将网卡命名方式改为 eth0eth1 的格式,除了按照上面的方法,还可以修改 GRUB 菜单的内核启动命令行的参数。这种方法对云主机一样有效。

修改 /etc/default/grub 文件,在 GRUB_CMDLINE_LINUX= 参数中补充 net.ifnames=0 biosdevname=0

1
2
3
4
5
6
7
8
9
[root@bogon ~]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet net.ifnames=0 biosdevname=0"
GRUB_DISABLE_RECOVERY="true"
[root@bogon ~]#

修改完配置后,还需要通过 grub2-mkconfig 命令重新生成配置。

1
2
3
4
5
6
7
8
9
[root@bogon ~]# cp /boot/grub2/grub.cfg{,.old};          
[root@bogon ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-957.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-957.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-17fcd15f39ac46b6906c263179a1a3b9
Found initrd image: /boot/initramfs-0-rescue-17fcd15f39ac46b6906c263179a1a3b9.img
done
[root@bogon ~]#

在 CentOS7 中提供了 grubby 命令,可以用来查看 /boot/grub2/grub.cfg 中的 grub 策略。

1
2
3
4
[root@bogon ~]# grubby --info=ALL | grep args
args="ro crashkernel=auto rhgb quiet net.ifnames=0 biosdevname=0 "
args="ro crashkernel=auto rhgb quiet net.ifnames=0 biosdevname=0 "
[root@bogon ~]# grubby --info=DEFAULT

重启完之后网卡名称会更新,如果之前配置了静态 IP 地址的话会自动加到网卡上,但是这种配置方式在重启机器后并不会自动更新网卡的配置,还需要手动重命名网卡配置文件,并且更新文件中的 DEVICENAME 等字段。

1
[root@bogon ~]# reboot

补充说明: 使用 grubby 命令也可以直接修改 /boot/grub2/grub.cfg 中的 grub 策略。

1
2
3
4
5
6
[root@bogon ~]# cp /boot/grub2/grub.cfg{,.bak};
[root@bogon ~]# grubby --update-kernel=ALL --args="net.ifnames=1 biosdevname=1"
[root@bogon ~]# grubby --info=ALL | grep args
args="ro crashkernel=auto rhgb quiet net.ifnames=1 biosdevname=1"
args="ro crashkernel=auto rhgb quiet net.ifnames=1 biosdevname=1"
[root@bogon ~]#

这种方法并不会更新 /etc/default/grub ,按照规范,最好手动修改 /etc/default/grub 然后以此文件重新生成配置。

有钱任性,请我吃包辣条
0%