sysctl.d 是什么
/etc/sysctl.d 是内核参数的持久化配置目录,目录下的 *.conf 文件由 systemd 的 systemd-sysctl 按文件名字典序逐个读取并写入 /proc/sys。它解决的是 sysctl -w 重启失效的问题:把调优写成声明式配置,开机自动生效,也能按业务拆成多个文件分层管理。RHEL 7 以上、Ubuntu 16.04 以上等 systemd 发行版都支持,老系统仍以 /etc/sysctl.conf 为主。
基本信息
| 配置目录 | /etc/sysctl.d/(另有 /run、/usr/lib、/usr/local/lib 下的同名目录) |
|---|---|
| 生效命令 | sysctl --system 重新读取全部配置;重启由 systemd-sysctl 自动执行 |
| 传统路径 | /etc/sysctl.conf 仍被读取,位置在目录扫描之后 |
| 文件命名 | 只处理以 .conf 结尾的文件,用 99- 前缀保证排在最后 |
| 语法 | 参数 = 值,一行一条;# 开头为注释 |
| 分发方式 | 容器与镜像构建常把配置放在 /usr/lib/sysctl.d/ 作为默认值 |
典型使用场景
- 把压测验证过的网络调优固化为一份 99-net-tuning.conf,避免每次重启后手工重做
- 按子系统拆分文件:网络、内存、文件句柄各自成文,变更时只改相关文件、便于评审
- 发行版默认值放 /usr/lib/sysctl.d,业务覆盖值放 /etc/sysctl.d,分层清晰且升级不冲突
- 镜像与自动化装机:把基线写进配置文件,节点初始化后无需再执行一串 sysctl -w
- 配置审计:用 grep -r 扫描全部定义点,找出哪份文件在改关键参数
配置文件示例
配置文件示例
# /etc/sysctl.d/99-app-tuning.conf
# 语义:本文件最后加载,覆盖前面所有同名声明
net.core.somaxconn = 8192 # 全连接队列上限,应用 backlog 需同步调大
net.ipv4.tcp_max_syn_backlog = 8192 # 半连接队列上限
vm.swappiness = 10 # 降低换出倾向
fs.file-max = 2097152 # 系统级文件句柄上限
net.ipv4.ip_local_port_range = 1024 65535 # 出站端口范围,两个数字用空格分隔应用与验证
应用与验证
sysctl --system # 按 库目录 -> run -> etc -> sysctl.conf 顺序加载
systemd-sysctl # 只跑一次加载动作,输出被忽略的错误
sysctl net.core.somaxconn vm.swappiness # 回读运行时值,确认最后生效的数字
ls -1 /etc/sysctl.d/ # 看加载顺序前的文件名排序加载顺序读法
| 顺序段 | 位置 | 使用建议 |
|---|---|---|
| 1 | /usr/lib/sysctl.d/*.conf | 发行版或镜像自带默认值,不要手工改这里 |
| 2 | /usr/local/lib/sysctl.d/*.conf | 本地安装软件的默认值 |
| 3 | /run/sysctl.d/*.conf | 运行时临时生成,重启后消失 |
| 4 | /etc/sysctl.d/*.conf | 业务自定义配置放这里,优先级高于前三段 |
| 5 | /etc/sysctl.conf | 历史遗留入口,最后加载、覆盖同名项 |
同一目录内按文件名字典序加载,同名文件出现在不同目录时优先级高的目录胜出。所以同一个参数被写了两遍永远不报错,只会后者覆盖前者——排查时要用 grep -r 找出所有定义点,而不是只看自己写的那份文件。
sysctl -p 默认只读 /etc/sysctl.conf,不会扫描 sysctl.d 目录,改完新文件却用 sysctl -p 验证是最常见的假成功。加载目录配置必须用 sysctl --system,然后回读参数确认。
查清定义点
查清定义点
grep -rn 'tcp_max_syn_backlog' /etc/sysctl.d /usr/lib/sysctl.d /etc/sysctl.conf # 找全部定义点
# 部分发行版(Debian 系)把 /etc/sysctl.conf 做成 /etc/sysctl.d/99-sysctl.conf 软链接
ls -l /etc/sysctl.d/99-sysctl.conf # 确认是否软链接,避免与 sysctl.conf 重复处理值里的引号不会被解析:写成 net.ipv4.ip_local_port_range = '1024 65535' 时,引号会被当成值的一部分,加载时校验失败。多值参数(端口范围、tcp_rmem 的最小默认最大三段值)直接用空格分隔,不加引号;井号开头的行才是注释。
老发行版(CentOS 6 一类)没有 sysctl.d 目录约定,开机只在启动脚本里执行 sysctl -p /etc/sysctl.conf。把配置迁移到这类系统时,要先确认目标环境是否存在 systemd-sysctl 服务,否则放进新目录的文件根本不会被读取。