业务物理机换网卡操作
背景
业务物理机(igo101~igo105)业务网使用 NetworkManager 管理的 bond0(active-backup),成员口为两张业务物理网卡对应的 slave 连接:
| 连接名 | 作用 |
|---|---|
bond0 |
业务网 bond,承载主机 IP |
bond-slave-ens1f0 |
bond 成员 1 |
bond-slave-ens2f0 |
bond 成员 2 |
更换物理网卡后,内核网卡名通常会变化(例如 ens1f0 → ens1f0np0,ens2f0 → ens2f0np0)。若 NM 配置里仍写旧名,bond 无法正确绑定成员口,业务网中断,SSH 也可能失败。此时需通过带外控制台(BMC/iLO 等)登录修复。
适用范围: 适合 CentOS 7 / Rocky 9 操作系统(NetworkManager + bond0 场景)。
范围说明:
- 目标主机:
igo102~igo105(igo101已完成) - 只更换进入
bond0的两张业务网卡;ens17f*等其它口不在本次范围 - SSH 端口:
5008 - 操作用户:
igo(改系统网络配置需sudo)
换卡前现状示例(igo102):
- 实际成员:
ens1f0、ens2f0 bond0的primary:各机可能不同(如 102/103/104 为ens2f0,105 为ens1f0),修改时按本机原值映射,不要照搬其它机器
换卡后目标示例(igo101):
- 实际成员:
ens1f0np0、ens2f0np0 - slave 连接的
interface-name与bond0的primary均已改为新名
配置文件目录:
/etc/NetworkManager/system-connections/
bond0.nmconnection
bond-slave-ens1f0.nmconnection
bond-slave-ens2f0.nmconnection
ens1f0.nmconnection # 独立网卡配置,勿与 bond-slave 混淆
ens2f0.nmconnection
1. 手动修改配置文件
适用于未预置脚本、或需要逐步核对配置落盘内容的场景。
1.1 换卡前准备(可选但建议)
在仍可通过 SSH 登录时,记录本机当前配置:
hostname
cat /sys/class/net/bond0/bonding/slaves
cat /sys/class/net/bond0/bonding/primary
nmcli -g connection.interface-name,connection.master connection show bond-slave-ens1f0
nmcli -g connection.interface-name,connection.master connection show bond-slave-ens2f0
nmcli -g bond.options,ipv4.addresses,ipv4.gateway connection show bond0
sudo sed -n '1,80p' /etc/NetworkManager/system-connections/bond-slave-ens1f0.nmconnection
sudo sed -n '1,80p' /etc/NetworkManager/system-connections/bond-slave-ens2f0.nmconnection
sudo sed -n '1,80p' /etc/NetworkManager/system-connections/bond0.nmconnection
重点记录:
- 两个 slave 当前的
interface-name bond0的primarybond0的 IPv4 地址(例如10.10.10.102/24)
1.2 换卡后确认新网卡名
带外登录目标机后执行:
ip -o link show | awk -F': ' '{print $2}' | grep -E '^ens'
ls -1 /sys/class/net | grep -E '^ens'
对照旧名,确认新名。常见对应关系:
| 旧名 | 新名(示例) |
|---|---|
ens1f0 |
ens1f0np0 |
ens2f0 |
ens2f0np0 |
若实际新名与上表不一致,以本机 ip link / sysfs 看到的为准。
1.3 备份配置文件
ts=$(date +%Y%m%d%H%M%S)
sudo cp -a /etc/NetworkManager/system-connections/bond-slave-ens1f0.nmconnection \
/etc/NetworkManager/system-connections/bond-slave-ens1f0.nmconnection.bak.${ts}
sudo cp -a /etc/NetworkManager/system-connections/bond-slave-ens2f0.nmconnection \
/etc/NetworkManager/system-connections/bond-slave-ens2f0.nmconnection.bak.${ts}
sudo cp -a /etc/NetworkManager/system-connections/bond0.nmconnection \
/etc/NetworkManager/system-connections/bond0.nmconnection.bak.${ts}
1.4 修改配置文件
只改下列字段,其它内容(UUID、IP、DNS 等)保持不动。
(1)编辑 bond-slave-ens1f0.nmconnection
将:
interface-name=ens1f0
改为实际新名,例如:
interface-name=ens1f0np0
(2)编辑 bond-slave-ens2f0.nmconnection
将:
interface-name=ens2f0
改为实际新名,例如:
interface-name=ens2f0np0
(3)编辑 bond0.nmconnection
将 [bond] 段中的 primary 从旧成员名改为对应新名。例如本机原 primary=ens2f0,则改为:
[bond]
mode=active-backup
primary=ens2f0np0
可用编辑器修改,例如:
sudo vi /etc/NetworkManager/system-connections/bond-slave-ens1f0.nmconnection
sudo vi /etc/NetworkManager/system-connections/bond-slave-ens2f0.nmconnection
sudo vi /etc/NetworkManager/system-connections/bond0.nmconnection
修改后快速核对:
sudo grep -nE '^(interface-name|primary)=' \
/etc/NetworkManager/system-connections/bond-slave-ens1f0.nmconnection \
/etc/NetworkManager/system-connections/bond-slave-ens2f0.nmconnection \
/etc/NetworkManager/system-connections/bond0.nmconnection
1.5 重新加载并激活
以下命令会变更网络状态,可能导致短暂闪断:
sudo nmcli connection reload
sudo nmcli connection up bond-slave-ens1f0
sudo nmcli connection up bond-slave-ens2f0
sudo nmcli connection up bond0
1.6 验证
cat /sys/class/net/bond0/bonding/slaves
cat /sys/class/net/bond0/bonding/primary
cat /sys/class/net/bond0/bonding/active_slave
ip -4 -o addr show dev bond0
nmcli -t -f NAME,DEVICE,STATE connection show --active | grep -E 'bond'
ping -c 3 -W 2 10.10.10.254
预期:
slaves为新网卡名(如ens1f0np0 ens2f0np0)primary为映射后的新名bond0上 IPv4 地址仍为本机原地址- 可 SSH(端口
5008)登录
1.7 注意
- 不要改错成同目录下的
ens1f0.nmconnection/ens2f0.nmconnection(非 bond slave) - 不要改
uuid、不要随意改bond0的 IP primary必须按本机原 primary 做旧名→新名映射,不要统一抄成某一台的值- 建议一次只换一台,验证业务网恢复后再换下一台
2. 通过脚本切换
在对应服务器上以 igo 用户操作。建议换卡前生成并验证脚本;换卡后若 SSH 不通,通过带外控制台执行。
脚本路径:/home/igo/shell/fix-bond-nic-rename.sh
逻辑概要:
- 从 NM 读取当前配置中的成员名(
bond-slave-ens1f0/bond-slave-ens2f0的interface-name)以及bond0的primary - 在系统中解析实际网卡名:若配置名已存在则沿用;若不存在,则查找以该配置名为前缀的唯一网卡(例如配置为
ens1f0、实际为ens1f0np0) - 默认 dry-run,只打印计划变更
- 加
--apply后:用nmcli修改连接并connection up生效
2.1 在对应服务器上生成脚本
在每一台待换机(如 igo102~igo105)上执行下面整段命令,生成脚本(仅写文件,不改网络):
bash -s << 'END'
mkdir -p "$HOME/shell"
cat > "$HOME/shell/fix-bond-nic-rename.sh" << 'EOF'
#!/usr/bin/env bash
# After NIC replace: read bond configured names, resolve to real ifaces, update NM and activate.
# Usage:
# bash ~/shell/fix-bond-nic-rename.sh
# bash ~/shell/fix-bond-nic-rename.sh --apply
set -euo pipefail
APPLY=0
if [[ "${1:-}" == "--apply" ]]; then
APPLY=1
fi
CONN1="bond-slave-ens1f0"
CONN2="bond-slave-ens2f0"
BOND_CONN="bond0"
resolve_iface() {
local configured="$1"
if [[ -z "${configured}" ]]; then
echo "ERROR: empty configured iface" >&2
return 1
fi
if [[ -d "/sys/class/net/${configured}" ]]; then
printf "%s\n" "${configured}"
return 0
fi
local matches
matches="$(ls -1 /sys/class/net | grep -E "^${configured}" || true)"
if [[ -z "${matches}" ]]; then
echo "ERROR: configured ${configured} missing, and no iface starts with ${configured}" >&2
ls -1 /sys/class/net | grep -E "^ens" >&2 || true
return 1
fi
local count
count="$(printf "%s\n" "${matches}" | awk "NF{c++} END{print c+0}")"
if [[ "${count}" -ne 1 ]]; then
echo "ERROR: configured ${configured} missing; ambiguous candidates:" >&2
printf "%s\n" "${matches}" >&2
return 1
fi
printf "%s\n" "${matches}"
}
echo "Host: $(hostname -s 2>/dev/null || hostname)"
if [[ "${APPLY}" -eq 1 ]]; then
echo "Mode: APPLY"
else
echo "Mode: DRY-RUN"
fi
echo "=== present ens interfaces ==="
ls -1 /sys/class/net | grep -E "^ens" || true
CUR_IF1="$(nmcli -g connection.interface-name connection show "${CONN1}")"
CUR_IF2="$(nmcli -g connection.interface-name connection show "${CONN2}")"
BOND_OPTS="$(nmcli -g bond.options connection show "${BOND_CONN}")"
CUR_PRIMARY="$(printf "%s\n" "${BOND_OPTS}" | tr "," "\n" | awk -F= "/^primary=/{print \$2; exit}")"
IPADDR="$(nmcli -g ipv4.addresses connection show "${BOND_CONN}")"
NEW_IF1="$(resolve_iface "${CUR_IF1}")"
NEW_IF2="$(resolve_iface "${CUR_IF2}")"
if [[ -n "${CUR_PRIMARY}" ]]; then
NEW_PRIMARY="$(resolve_iface "${CUR_PRIMARY}")"
else
NEW_PRIMARY=""
fi
echo "=== resolve ==="
echo "${CONN1}: ${CUR_IF1} -> ${NEW_IF1}"
echo "${CONN2}: ${CUR_IF2} -> ${NEW_IF2}"
if [[ -n "${CUR_PRIMARY}" ]]; then
echo "${BOND_CONN} primary: ${CUR_PRIMARY} -> ${NEW_PRIMARY}"
else
echo "${BOND_CONN} primary: (empty)"
fi
echo "${BOND_CONN} ipv4.addresses: ${IPADDR}"
echo "bond.options now: ${BOND_OPTS}"
NEED_CHANGE=0
if [[ "${CUR_IF1}" != "${NEW_IF1}" || "${CUR_IF2}" != "${NEW_IF2}" ]]; then
NEED_CHANGE=1
fi
if [[ -n "${CUR_PRIMARY}" && "${CUR_PRIMARY}" != "${NEW_PRIMARY}" ]]; then
NEED_CHANGE=1
fi
if [[ "${NEED_CHANGE}" -eq 0 ]]; then
echo "No rename needed; bond names already match present ifaces."
echo -n "slaves: "; cat /sys/class/net/bond0/bonding/slaves 2>/dev/null || true
exit 0
fi
if [[ "${APPLY}" -eq 0 ]]; then
echo "Dry-run only. Re-run with --apply to apply changes."
exit 0
fi
echo "=== applying ==="
sudo nmcli connection modify "${CONN1}" connection.interface-name "${NEW_IF1}"
sudo nmcli connection modify "${CONN2}" connection.interface-name "${NEW_IF2}"
if [[ -n "${NEW_PRIMARY}" ]]; then
sudo nmcli connection modify "${BOND_CONN}" bond.options "mode=active-backup,primary=${NEW_PRIMARY}"
fi
sudo nmcli connection up "${CONN1}"
sudo nmcli connection up "${CONN2}"
sudo nmcli connection up "${BOND_CONN}"
echo "=== verify ==="
echo -n "slaves: "; cat /sys/class/net/bond0/bonding/slaves
echo -n "primary: "; cat /sys/class/net/bond0/bonding/primary
echo -n "active: "; cat /sys/class/net/bond0/bonding/active_slave
ip -4 -o addr show dev bond0
nmcli -g connection.interface-name,connection.master connection show "${CONN1}"
nmcli -g connection.interface-name,connection.master connection show "${CONN2}"
nmcli -g bond.options,ipv4.addresses connection show "${BOND_CONN}"
echo "DONE"
EOF
chmod 755 "$HOME/shell/fix-bond-nic-rename.sh"
ls -la "$HOME/shell/fix-bond-nic-rename.sh"
END
生成成功后应看到类似:
-rwxr-xr-x 1 igo igo .... /home/igo/shell/fix-bond-nic-rename.sh
2.2 换卡前确认脚本可用
在每台待换机上执行:
ls -la ~/shell/fix-bond-nic-rename.sh
sha256sum ~/shell/fix-bond-nic-rename.sh
bash ~/shell/fix-bond-nic-rename.sh
换卡前预期输出类似:
bond-slave-ens1f0: ens1f0 -> ens1f0
bond-slave-ens2f0: ens2f0 -> ens2f0
...
No rename needed; bond names already match present ifaces.
2.3 换卡后修复步骤
带外或 SSH(若仍可达)登录已换卡的那一台,先 dry-run:
bash ~/shell/fix-bond-nic-rename.sh
确认解析结果正确,例如:
bond-slave-ens1f0: ens1f0 -> ens1f0np0
bond-slave-ens2f0: ens2f0 -> ens2f0np0
bond0 primary: ens2f0 -> ens2f0np0
再执行生效(会变更网络配置):
bash ~/shell/fix-bond-nic-rename.sh --apply
2.4 验证
脚本末尾会打印 slaves / primary / bond0 地址等。也可再执行:
cat /sys/class/net/bond0/bonding/slaves
cat /sys/class/net/bond0/bonding/primary
ip -4 -o addr show dev bond0
ping -c 3 -W 2 10.10.10.254
然后从其它机器测试 SSH:
ssh -p 5008 igo@igo10X
2.5 脚本无法自动解析时
若 dry-run 报错(例如旧名消失后找不到唯一前缀匹配、或匹配到多个候选),不要直接 --apply,改用本文第 1 章手动改配置文件,或先根据 ip link 明确新名后再处理。
回滚建议
若修改后异常,可用换卡前备份的 .nmconnection.bak.* 恢复,然后:
sudo nmcli connection reload
sudo nmcli connection up bond-slave-ens1f0
sudo nmcli connection up bond-slave-ens2f0
sudo nmcli connection up bond0
注意:物理网卡已换成新硬件、内核只暴露新网卡名时,恢复成旧名配置无法工作,只能继续按新名修正。
操作检查清单
- 确认本次只换 bond 使用的两张业务网卡
- 换卡前记录本机
interface-name、primary、IP - 换卡后确认新网卡名
- 脚本方式:各机先执行 2.1 生成脚本,再 dry-run →
--apply;或按第 1 章手动改文件 - 确认
bond0slaves/primary/IP 正常 - 确认网关可达、SSH(
5008)恢复 - 单台验证完成后再处理下一台