您的位置:首页 > 运维架构 > Linux

VMware (CentOS 6.x)克隆导致的网卡问题

2014-07-09 12:58 393 查看
环境:
VMware workstation 10 + CentOS 6.5
经过测试, CentOS 7.x 不存在该问题,仅 CentOS 6.x 系列存在。

故障:

为了方便,直接偷懒通过VMware workstation10的克隆功能,能够快速创建一个虚拟机。启动新创建的虚拟机,发现网卡无法使用。使用ifconfig命令,只有回环网卡:

[root@localhost ~]# ifconfig -a



然后,我重启网络服务,报以下错误:
[root@localhost ~]# service network restart
Bringing up interface eth0: Device eth0 does not seem to be present, delaying initialization.   [FAILED]
Bringing up interface eth1: Device eth1 does not seem to be present, delaying initialization.   [FAILED]




在RHEL5里也发生类似事情,因为复制虚拟机MAC会重新生成(由VMware虚拟机重新生成MAC地址),但是操作系统的MAC却写在ifcfg-eth*里,造成了不一致,所以不能启动网络接口,在RHEL5里可以使用kudzu或者注释网卡配置文件的MAC字段来解决这个问题。但是在RHEL6里,kudzu已经被hal服务取代了。虽然lspci能够正常认到网卡,但是却无法使用/etc/init.d/network restart来启动服务。尝试注释ifcfg-eth0的MAC字段,还是报错。查看了下udev的规则,发现了问题的所在。
udev将MAC与网卡名称的对应关系保存在 /etc/udev/rules.d/70-persistent-net.rules中。

[root@localhost ~]# vim /etc/udev/rules.d/70-persistent-net.rules



再看一下我们网卡配置文件:

[root@localhost ~]# grep HWADDR /etc/sysconfig/network-scripts/ifcfg-eth*




问题推测:
从上面的文件可以看出,udev的配置文件,与网卡配置文件ifcfg-eth*记录的MAC地址不一致。导致了前面提到的网络故障。

因为基本系统的网络相关配置都是基于eth0的,如果基于此克隆虚拟机继续克隆或复制新的虚拟机,网卡的标识每一次都会自动加1变成eth1(第二次克隆会变成eth2),dmesg却显示内核只识别到网卡eth0。

原因分析
很多Linux distribution使用udev动态管理设备文件,并根据设备的信息对其进行持久化命名。例如在CentOS中,udev会在系统引导的过程中识别网卡,将mac地址和网卡名称对应起来记录在udev的规则脚本中。但是通过VMware进行克隆,VMware会再自动重新生成虚拟机的MAC地址。这样,由于基本系统的虚拟机已经记录了原始虚拟机的网卡mac地址对应于网卡eth0,而在克隆出的虚拟机中由于mac地址发生改变,udev会自动将该mac对应于网卡eth1(累加的原则)。以此类推,udev会记录所有已经识别的mac与网卡名的关系,所以每次克隆网卡名称会自动加1,而其实kernel仅仅只识别到一张网卡,跟网卡名相关的网络配置也未发生任何变化。
udev将mac与网卡名称的对应关系保存在 # vi /etc/udev/rules.d/70-persistent-net.rules中,使用VMware克隆功能,会为新克隆的虚拟机创建一个与原始虚拟机网卡不同的MAC地址。对于CentOS这样的Linux系统,会把运行的网卡MAC地址记录到 /etc/udev/rules.d/70-persistent-net.rules文件中,这样克隆好的新系统里会多保存一个这样的记录。

网卡名相关的网络配置也未发生任何变化 # vi /etc/sysconfig/network-scripts/ifcfg-eth0。当新系统启动时,由于VMware已经为其配置了不同的MAC地址,因此系统会在启动扫描硬件时,把这个新的MAC地址的网卡当作是eth1,并且增加记入上述文件中。而此时配置文件中的/etc/sysconfig/network-scripts/ifcfg-eth0里记录的还是原来的MAC地址,而这个MAC地址在新系统里是不存在的,所以无法启动。

在新系统里,把rules文件里记录的老MAC对应的那个eth0一行删除掉,然后把新MAC对应的eth1的名字改为eth0。然后在ifcfg-eth0文件里把HDADDR的值改为新的MAC地址。这样rules和ifcfg-eth0就彼此对应(rules里的eth0对应ifcfg-eth0文件名,rules里的mac对应ifcfg-eth0文件里的HDADDR)好了。

虚拟机的配置文件:安装目录下的 *.vmx 配置文件,其MAC地址由VMware自动维护,保留最新创建的MAC地址





解决办法:
1、首先编辑udev的配置文件,删除原始的两条记录eth0和eth1, 然后再把eth3及eth4改为eth0,eth1即可

[root@localhost ~]# vi /etc/udev/rules.d/70-persistent-net.rules




2、然后,编辑 /etc/sysconfig/network-scripts/ifcfg-eth*, 根据实际情况

[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
将HWADDR修改为70-persistent-net.rules中eth0对应的MAC地址,使二者保持一致。并注释UUID。

3、重启系统: reboot

4、或者不用重启系统: start_udev , 然后重新启动网络服务: service network restart

总结上述操作,处理步骤
步骤1:将克隆出的虚拟机中只要删除与 NAME="eth0" 相关的行,并把下行的 eth1 的改为 eth0 ;并记录一下 ATTR{address} 的值;

步骤2:记录此克隆机MAC地址,然后编辑 # vi /etc/sysconfig/network-scripts/ifcfg-eth0 修改 HWADDR 并注释 UUID

步骤3: 重启系统;

下面提供一个脚本,自动处理上述步骤:
### 注意,需要根据实际的网卡数目进行相应的调整

echo "Updating 70-persistent-net.rules with eth0..."
sed -i '7,9d' /etc/udev/rules.d/70-persistent-net.rules
sed -i s/eth1/eth0/g /etc/udev/rules.d/70-persistent-net.rules

echo "Updating ifcfg-eth0 with new MAC address..."
newmac=`ip a | tail -n 1 | awk '{print $2}'`
oldmac=`grep HWADDR /etc/sysconfig/networking/devices/ifcfg-eth0 | awk -F "=" '{print $2}'`
sed -i s/$oldmac/$newmac/g /etc/sysconfig/networking/devices/ifcfg-eth0
cp /etc/sysconfig/networking/devices/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0

echo "Rebooting the OS"
sleep 2
reboot
原文参考:http://heylinux.com/archives/2416.html

后记
后来,有网友提到一个更简单粗暴的方法:
1、直接删除/etc/udev/rules.d/70-persistent-net.rules配置文件中的mac地址和网卡绑定行,重启后系统也会自动识别加载新网卡的mac信息的。

或者

2、通过VMware虚拟机软件,将原有的网卡删除,然后重新添加网卡
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息