系統啟動后bond配置不生效問題定位


背景描述

為了適配新功能,裸金屬服務的磁盤鏡像中做了如下修改:

  1. dracut添加network, iscsi模塊
  2. grub添加rd.iscsi.firmware=1參數
  3. 刪除網卡配置文件/etc/sysconfig/network-scripts/ifcfg-*
  4. 禁止network服務開機啟動,防止網絡中斷

修改鏡像后,需對裸金屬服務既有功能進行測試,包括初始化密碼、重置密碼、從卷創建、從備份創建、重新部署、網卡bond配置等等。

環境准備

基礎網段:10.33.46.0/24

裸金屬節點:72a651ba-f6e7-42a0-892d-62089769ceb1,bm-11

裸金屬網卡組:

  • 模式:active-backup
  • 關聯網卡:eth0、eth3
  • 所屬節點:72a651ba-f6e7-42a0-892d-62089769ceb1
  • 關聯vif:84a48aa9-bf77-40a5-a410-a94a052cd5a7,10.33.46.186

裸金屬鏡像:hikos-x86_64-baremetal-cloudinit

問題描述

裸金屬節點啟動后發現bond配置未生效,eth0不是bond0的從屬網卡,而是通過dhcp獲取了ip,如下圖所示:

問題排查

檢查網卡配置文件,eth0、eth3、bond0的配置正常:

手動重啟NetworkManager服務,eth0依然通過dhcp獲取ip。

嘗試ifup eth0,不生效且無任何輸出;嘗試ifdown eth0后再ifup,發現eth0成功變為bond0的從屬網卡。

由於NetworkManager服務通過ifcfg-rh腳本來兼容/etc/sysconfig/network-scripts/目錄下的網卡配置文件,本質上還是用ifup命令拉起各個網卡,因此推測在initrd階段,eth3網卡就已經拿到ip,NetworkManager服務的啟動不會對已拉起的eth3網卡做修改,才導致bond配置不生效。

測試重新制作initrd,將之前添加的network、iscsi模塊忽略,重啟系統后發現bond生效,因此原因應該是initrd階段eth3網卡已拉起。

cat /etc/dracut.conf
# omit_dracutmodules+="network iscsi"
dracut -v -f -N /boot/initramfs-3.10.0-1160.49.1.el7.x86_64.img 3.10.0-1160.49.1.el7.x86_64
# 重啟系統

重啟后恢復initrd至原樣。

解決方案

常規解決方案為在NetworkManager服務啟動前刷新網卡ip,是NetworkManager能夠根據網卡配置重新拉起網卡。

當裸金屬從卷啟動時,要求系統啟動的過程中網絡一直能聯通,因此可以屏蔽從卷啟動方式裸金屬的網卡bond功能。在NetworkManager服務啟動前判斷是否是從卷啟動,如果不為從卷啟動,則刷新網卡,所使用到的命令如下:

# 搜索網卡中的iscsi配置,若搜索不到則報錯
iscsiadm -m fw
# 刷新所有網卡的配置
ip addr flush scope global

最終決定在cloud-init的local階段執行此命令,修改cloud-init的cmd/main.py文件,如下所示:

diff --git a/main.py b/main.py
index b562646..4f0d7a9 100644
--- a/test1
+++ b/test2
@@ -359,6 +359,7 @@ def main_init(name, args):
         # dhcp clients to advertize this hostname to any DDNS services
         # LP: #1746455.
         _maybe_set_hostname(init, stage='local', retry_stage='network')
+        _may_flush_ip_link()
     init.apply_network_config(bring_up=bool(mode != sources.DSMODE_LOCAL))

     if mode == sources.DSMODE_LOCAL:
@@ -712,6 +713,19 @@ def _maybe_set_hostname(init, stage, retry_stage):
                 'Failed setting hostname in %s stage. Will'
                 ' retry in %s stage. Error: %s.', stage, retry_stage, str(e))

+def _may_flush_ip_link():
+    LOG.debug("Cleaning up ip link address.")
+
+    ipsan_check_cmd = ['iscsiadm', '-m', 'fw']
+    ip_addr_cmd = ['ip', 'addr', 'flush', 'scope', 'global']
+
+    try:
+        util.subp(ipsan_check_cmd)
+
+    except Exception as e:
+        LOG.debug("iscsiadm failed to display nic iscsi info, will"
+        " flush ip link address. Error: %s", str(e))
+        util.subp(ip_addr_cmd)

 def main_features(name, args):
     sys.stdout.write('\n'.join(sorted(version.FEATURES)) + '\n')

附錄

參考文檔

dracut 054 (kernel.org)

# generated by dracut initrd

如果再次啟動后發現仍未生效,查看網卡配置文件發現有# generated by dracut initrd的字樣,這是由於dracut的ifcfg模塊會寫入根文件系統的網絡配置,需忽略initrd的ifcfg模塊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM