sysctl参数重启失效是因为未持久化落盘且未正确加载:必须将参数写入/etc/sysctl.d/99-custom.conf并执行sudo sysctl --system加载,而非仅改/etc/sysctl.conf后用sysctl -p;验证需用sysctl命令或cat /proc/sys/检查运行时值。

sysctl 参数改完重启就失效?不是内核不认,是没落盘 + 没触发加载。持久化必须两步:写对位置、用对命令。
参数写进 /etc/sysctl.d/99-custom.conf 才可靠
直接改 /etc/sysctl.conf 看似简单,但系统更新或重装可能覆盖它;现代发行版(Ubuntu 20.04+、RHEL 8+、Debian 11+)默认由 systemd-sysctl 服务管理,优先读取 /etc/sysctl.d/*.conf。
- 文件名必须以数字开头 +
.conf结尾,例如/etc/sysctl.d/99-network.conf,数字控制加载顺序(越小越早) - 每行只能是
key = value格式,等号两侧允许空格,但不能有 Tab 或行尾注释(net.core.somaxconn = 65535 # bad会报错) - 注释必须独占一行,以
#开头 - 文件权限设为
644即可,属主建议root:root;若设成600且非 root 可读,sysctl --system会跳过并静默忽略
用 sysctl --system 加载,别只用 sysctl -p
sysctl -p 默认只读 /etc/sysctl.conf,完全不看 /etc/sysctl.d/ 下的文件——这是 90% “写了不生效” 的根源。
-
sudo sysctl --system才是正确命令,它按序加载:/usr/lib/sysctl.d/*.conf→/run/sysctl.d/*.conf→/etc/sysctl.d/*.conf→/etc/sysctl.conf - 同一参数在多个文件中出现时,后加载的会覆盖前面的,所以数字前缀很重要
- 执行后若报
error: "net.ipv4.ip_forwad" is an unknown key,说明拼写错误或内核未启用对应模块(比如ip_forward需要CONFIG_IP_FORWARD编译选项) - 报错会中断当前文件处理,但不影响已成功加载的其他文件
验证是否真生效,别信命令输出
sysctl --system 不报错 ≠ 参数已写入内核。必须查运行时值。
- 用
sysctl net.core.somaxconn查单个值,输出应为net.core.somaxconn = 65535,而不是报错或返回旧值 - 或直接读
/proc/sys/对应路径:cat /proc/sys/net/core/somaxconn,结果必须和预期一致 - 某些参数(如
net.ipv4.tcp_tw_recycle)在 Linux 4.12+ 已移除,写进去会静默失败,sysctl -a | grep tw_recycle查不到就说明不支持 - 容器内改不了?不是权限问题,而是 namespace 限制——宿主机上设好,容器启动时加
--sysctl参数才有效
动态场景用 systemd drop-in 注入 /run/sysctl.d/
当参数依赖运行时信息(如容器 IP、网卡名、CPU 数量),硬编码到磁盘配置里不现实。
- 创建覆盖目录:
sudo mkdir -p /etc/systemd/system/systemd-sysctl.service.d - 新建
override.conf,用ExecStartPre在服务启动前生成临时配置:[Service] ExecStartPre=/bin/sh -c 'echo "net.core.somaxconn = $(nproc)" > /run/sysctl.d/10-dynamic.conf'
-
/run/sysctl.d/默认在sysctl --system扫描路径中,且重启后自动清空,避免残留 - 注意:该方式仅适用于
systemd系统,且需确保systemd-sysctl服务启用(sudo systemctl is-enabled systemd-sysctl)
实际调参时最易被忽略的是参数间的隐式依赖,比如调大 net.ipv4.tcp_rmem 的最大值,却忘了同步提升 net.core.rmem_max,结果内核自动降级为后者值——这种“写了等于没写”的情况,必须靠 cat /proc/sys/... 逐层验证。


















