You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

双NIC设备自动连接已插网线接口的技术配置问询

解决双NIC设备启动时systemd因DHCP超时挂起的问题

我来帮你搞定这个问题——我之前在处理批量克隆服务器部署时遇到过几乎一模一样的场景:双NIC配置全DHCP,结果没插网线的接口会让systemd卡在启动流程里等5分钟,太耽误事了。核心原因就是systemd默认会等待所有配置了自动联网的接口完成DHCP协商,哪怕那个接口根本没载波(网线没插)。下面给你几个针对性的解决方案,按省心程度排序:

方案1:用NetworkManager自动识别可用接口(推荐,适合绝大多数发行版)

如果你的系统用的是NetworkManager(不管是桌面还是服务器,现在大部分发行版默认都是它),可以配置让它只给插了网线的接口启动DHCP,没插的直接忽略:

  1. 先编辑NetworkManager的全局配置,启用keyfile插件:
    sudo nano /etc/NetworkManager/NetworkManager.conf
    
    [main]段里加一行:
    plugins=keyfile
    
  2. 创建一个配置文件,设置设备的自动连接规则:
    sudo mkdir -p /etc/NetworkManager/conf.d/
    sudo nano /etc/NetworkManager/conf.d/90-nic-auto-connect.conf
    
    写入这些内容,意思是让网卡只有在检测到网线插好(有载波)时才尝试自动连接,而且不重试:
    [device]
    match-device=interface-name:en*;interface-name:eth*
    autoconnect-retries=0
    autoconnect=false
    carrier-wait-timeout=0
    
    这里的en*eth*是匹配你的网卡接口名,要是你的网卡叫别的(比如ens33),直接写对应的前缀就行,不确定的话用ip link show看一下。
  3. 给每个网卡单独创建DHCP连接配置,让它们在有载波时自动启动:
    先弄第一个网卡,比如enp0s3
    sudo nano /etc/NetworkManager/system-connections/enp0s3.nmconnection
    
    内容抄这个,记得把接口名改成你自己的:
    [connection]
    id=enp0s3
    type=ethernet
    interface-name=enp0s3
    autoconnect=true
    
    [ipv4]
    method=auto
    
    [ipv6]
    method=auto
    
    然后复制一份改个名,给另一个网卡(比如enp0s4)也弄一份。
  4. 最后重启NetworkManager生效:
    sudo systemctl restart NetworkManager
    
    这样以后不管网线插哪个口,只有插了的那个会自动连DHCP,另一个没插的不会触发任何超时等待,启动速度直接恢复正常。

方案2:给systemd-networkd缩短超时(适合纯systemd的轻量服务器)

如果你的系统没装NetworkManager,用的是纯systemd-networkd,那直接改网卡的配置文件,把超时时间改短,或者设置只在有载波时启动DHCP:

  1. 找到你的网卡配置文件,一般在/etc/systemd/network/下面,比如叫20-wired.network
    sudo nano /etc/systemd/network/20-wired.network
    
  2. [Network]段里加这两行,把载波等待和DHCP超时都改短:
    [Network]
    DHCP=yes
    CarrierTimeout=3s  # 3秒足够判断有没有插网线
    DHCPTimeout=5s     # DHCP协商超时设成5秒,不用等默认的久时间
    
  3. 要是想更彻底,直接让配置只在有载波时生效,就加个[Match]段:
    [Match]
    Name=en* eth*
    Carrier=yes  # 只有检测到载波时才应用这个DHCP配置
    
  4. 重启systemd-networkd:
    sudo systemctl restart systemd-networkd
    
    这样未插网线的接口会快速放弃DHCP协商,不会让systemd卡5分钟。

方案3:用udev规则动态开关接口

还有一种思路,用udev规则实时检测网卡状态,插了网线就启用接口,没插就禁用:

  1. 创建udev规则文件:
    sudo nano /etc/udev/rules.d/90-nic-auto-control.rules
    
  2. 写入这两条规则:
    # 网卡检测到载波(插网线)时启用接口
    SUBSYSTEM=="net", ACTION=="change", ATTR{carrier}=="1", RUN+="/usr/sbin/ip link set $name up"
    # 网卡丢失载波(拔网线)时禁用接口
    SUBSYSTEM=="net", ACTION=="change", ATTR{carrier}=="0", RUN+="/usr/sbin/ip link set $name down"
    
  3. 重新加载udev规则并触发:
    sudo udevadm control --reload-rules
    sudo udevadm trigger
    
    这种方法会动态管理接口状态,没插网线的接口会被自动禁用,根本不会参与DHCP协商,从根源上解决超时问题。

偷懒方案:直接禁用一个网卡的自动连接

要是你的场景可以接受优先用某一个接口(比如固定用enp0s3),那最简单的就是直接把另一个网卡设为手动模式,不让它自动连:

  • 用NetworkManager的话,直接在nmcli里把另一个接口的autoconnect设为no:
    sudo nmcli connection modify enp0s4 autoconnect no
    
  • 用systemd-networkd的话,直接禁用对应的服务:
    sudo systemctl disable --now systemd-networkd@enp0s4.service
    
    这种方法最省事,但缺点是如果哪天网线插去禁用的那个口了,就得手动改回来,适合固定接口的场景。

内容的提问来源于stack exchange,提问作者DuineAnaithnid

火山引擎 最新活动