如何让systemd-networkd强制为未连接的接口设置静态IPv4地址
我完全懂你的困扰——原来的SysVinit不管接口有没有插网线,都会老老实实把静态IP配置好,换到systemd-networkd之后反而“认死理”,没链路就不干活,连带依赖这个接口的服务都启动失败,确实头疼。下面给你两个靠谱的解决方向:
方法一:让systemd-networkd无视链路状态强制配置IP
这是最直接的解决方案,只需要修改你的静态网络配置文件,加一个参数就能让systemd-networkd不管接口连没连网线都给它配上IP。
打开你的10-lan.network配置文件,在[Network]段里加上ConfigureWithoutCarrier=yes,修改后的文件应该是这样:
[Match] Name=lan [Network] Address=192.168.1.1/24 ConfigureWithoutCarrier=yes
保存后重启systemd-networkd服务生效:
systemctl restart systemd-networkd
现在你拔掉网线试试,用ip addr show lan就能看到IP已经被正常配置了,依赖这个接口的服务比如isc-dhcp-server也能正常启动了。
这个参数的作用就是告诉systemd-networkd:“别等链路起来了,不管有没有网线,先把IP配上再说”,完美复刻SysVinit的老行为。
方法二:调整依赖服务的启动条件(不修改网络配置的备选方案)
如果你不想改变networkd的默认行为,也可以从服务依赖入手,让那些需要绑定到本地接口的服务(比如isc-dhcp-server)不用等接口在线就能启动。
大部分这类服务默认会依赖network-online.target——这个target要求所有网络接口都处于在线状态才会触发。我们可以把依赖改成network.target,这个target只要求系统的网络栈初始化完成,不要求具体接口在线。
以isc-dhcp-server为例,执行以下命令编辑它的systemd单元文件:
systemctl edit isc-dhcp-server
在打开的编辑器里添加以下内容:
[Unit] After=network.target Wants=network.target # 注释掉或删除原来的After=network-online.target相关配置(如果有的话)
保存退出后,重启服务生效:
systemctl restart isc-dhcp-server
这样服务会在网络栈就绪后就启动,即使目标接口没插网线也能正常绑定到配置的静态IP上。
补充说明
systemd-networkd默认不配置无链路接口的IP,是为了适配笔记本这类经常切换网络的场景——避免给没连接的网卡留着IP导致路由混乱。但对于服务器这种需要固定IP的场景,ConfigureWithoutCarrier=yes就是专门解决这个问题的参数,也是最推荐的方案。
备注:内容来源于stack exchange,提问作者user3104525




