开发者
资源
华为鲲鹏 openEuler 操作系统下 ulimit 修改配置不生效的实践排坑
华为鲲鹏 openEuler 操作系统下 ulimit 修改配置不生效的实践排坑
原创
发表于06/13
230

在华为鲲鹏服务器(openEuler 操作系统)上,我们经常需要调整系统的资源限制,比如增大 open files(最大打开文件数)或 max user processes(最大用户进程数),以满足数据库(如 MongoDB、MySQL)或中间件(如 Nginx、Tomcat)的高并发需求。

然而,很多开发者会发现:明明修改了 /etc/security/limits.conf,但 ulimit -a 显示的值却没有变化;或者修改了服务的 systemd 单元文件,重启后限制依然还是 1024。这类问题通常源于对 Linux 资源限制机制的不了解。

本文将结合 openEuler 系统的实际特点,从 PAM 认证机制、systemd 服务管理、常见踩坑点三个维度,完整复盘如何排查并解决 ulimit 配置不生效的问题。

2. 背景知识:Linux 资源限制的两套体系

在 Linux 中,资源限制(rlimit)最终通过 setrlimit() 系统调用实现,但谁来调用、何时调用,取决于进程的启动方式:

启动方式资源限制来源配置路径
用户登录会话(SSH、本地终端)PAM 模块 pam_limits.so → 读取 /etc/security/limits.conf 及 limits.d/*.conf/etc/security/limits.conf
systemd 管理的系统服务systemd 自身的 LimitXXX= 指令/etc/systemd/system.conf(全局)或服务覆盖文件

openEuler 系统(基于 CentOS/RHEL 体系)同时支持上述两套体系,但它们的配置互不干扰。如果你修改了 limits.conf 却发现某个 systemd 服务不生效,那是正常的——因为服务根本不走 PAM。

3. 典型问题场景及排查步骤

3.1 场景一:用户通过 SSH 登录后 ulimit -n 仍是 1024

现象

bash

[root@openeuler ~]# ulimit -n
1024

明明 /etc/security/limits.conf 中已经配置了:

text

* soft nofile 65536
* hard nofile 65536

排查步骤

① 确认 PAM 是否调用了 pam_limits.so

检查 /etc/pam.d/sshd 文件(SSH 登录):

bash

cat /etc/pam.d/sshd | grep -E "session.*pam_limits"

如果没有任何输出,再看该文件是否通过 include 引用了其他公共文件,例如:

text

session include password-auth
session include system-auth

然后检查被引用的文件(如 /etc/pam.d/password-auth)是否包含:

text

session required pam_limits.so
openEuler 默认配置password-auth 和 system-auth 中通常会包含 pam_limits.so,因此无需在 sshd 中单独添加。

② 确认 pam_limits.so 模块是否存在

bash

ls -l /lib64/security/pam_limits.so

若不存在,重新安装 PAM 包:

bash

yum reinstall pam -y

③ 检查 limits.conf 语法

每行必须符合 <domain> <type> <item> <value> 格式,常见错误:

  • 遗漏 domain(如写成 soft nofile 65536 缺少开头的 *
  • item 拼写错误(如 nofile 写成了 openfile
  • 值超过内核上限(nofile 不能超过 /proc/sys/fs/nr_open,默认 1048576)

④ 添加日志调试

在 /etc/pam.d/password-auth 的 pam_limits.so 行后添加 debug

text

session required pam_limits.so debug

重新登录并查看日志:

bash

tail -f /var/log/secure

看到类似 pam_limits(sshd:session): reading settings from /etc/security/limits.conf 即表示模块已执行。

⑤ 重新登录

关键点:PAM 配置只在会话建立时读取一次。修改后必须 退出当前 SSH 会话并重新登录,而不是执行 source ~/.bashrc

3.2 场景二:修改了 limits.conf,但某个 systemd 服务(如 mongodb)仍受 1024 限制

原因:systemd 服务完全绕过 PAM,不会读取 limits.conf

解决方法:通过 systemd 单元文件单独设置。

方法一:使用 systemctl edit 添加覆盖配置(推荐)

bash

systemctl edit mongod

写入:

ini

[Service]
LimitNOFILE=65536
LimitNPROC=65536

保存退出,重载并重启:

bash

systemctl daemon-reexec
systemctl restart mongod

方法二:修改全局 systemd 默认值(影响所有服务)

编辑 /etc/systemd/system.conf,取消注释并修改:

text

DefaultLimitNOFILE=65536
DefaultLimitNPROC=65536

执行 systemctl daemon-reexec 生效。

验证服务实际限制

bash

cat /proc/$(pidof mongod)/limits | grep -E "Max open files|Max processes"

3.3 场景三:普通用户无法调高 ulimit -n 到期望值

现象:普通用户执行 ulimit -n 65536 报错 Operation not permitted

原因:当前 Shell 的硬限制(hard limit) 低于期望值。只有 root 可以调高硬限制。

解决方法

在 /etc/security/limits.conf 中为对应用户设置 hard nofile,然后重新登录。例如:

text

myuser hard nofile 65536
myuser soft nofile 65536

3.4 场景四:* 通配符不覆盖 root 用户

注意:在 limits.conf 中,* 代表“所有普通用户”,不包括 root。如果需要为 root 设置限制,必须明确写出:

text

root soft nofile 65536
root hard nofile 65536

4. openEuler 特有的注意事项

  • PAM 配置文件路径:openEuler 沿用 RHEL 体系,PAM 文件位于 /etc/pam.d/,公共配置为 password-auth 和 system-auth
  • 默认硬限制:openEuler 22.03 及更高版本中,用户进程的默认硬限制可能由 systemd 用户实例管理,建议优先修改 limits.conf 搭配 PAM。
  • 鲲鹏架构兼容性pam_limits.so 在 aarch64 下路径为 /lib64/security/pam_limits.so,与 x86_64 一致,无需特殊处理。

5. 快速排坑检查清单

检查项命令/文件预期结果
当前 Shell 限制ulimit -a符合预期值
PAM 是否加载 limits 模块grep pam_limits /etc/pam.d/sshd /etc/pam.d/password-auth至少一处有 session required pam_limits.so
limits.conf 语法cat /etc/security/limits.conf每行完整,domain 正确
是否重新登录退出 SSH 重新连接限制更新
systemd 服务是否独立配置systemctl cat <service> | grep Limit若服务需要高限制,应有 LimitNOFILE=
内核全局上限sysctl fs.file-maxcat /proc/sys/fs/nr_opennofile 不能超过 nr_open

6. 实战案例:在 openEuler 上为 MongoDB 调高文件描述符

需求:MongoDB 需要最大打开文件数 65536。

步骤

  1. 修改系统 PAM 配置(已默认开启,跳过)。
  2. 编辑 MongoDB 服务覆盖文件:
  3. bash
systemctl edit mongod
  1. 添加:
  2. ini
[Service]
LimitNOFILE=65536
  1. 重载 systemd:
  2. bash
systemctl daemon-reexec
systemctl restart mongod
  1. 验证:
  2. bash
cat /proc/$(pidof mongod)/limits | grep "Max open files"
  1. 输出应为 65536 65536 files

7. 总结

ulimit 配置不生效的根本原因在于:没有对准正确的配置入口

  • 对于交互式用户会话 → 检查 PAM 和 /etc/security/limits.conf
  • 对于 systemd 服务 → 检查单元文件中的 LimitXXX= 指令
  • 对于容器化环境(Docker/K8s) → 还需考虑容器运行时自身的限制

在华为鲲鹏 openEuler 系统上,上述规则同样适用。掌握这套排查方法论,就能快速定位并解决 90% 的资源限制问题。

附:常用调试命令速查

bash

# 查看进程实际限制
cat /proc/<PID>/limits

# 查看当前会话硬限制
ulimit -Ha

# 动态修改当前会话(仅临时)
ulimit -n 65536

# 检查哪个 PAM 文件包含了 pam_limits
grep -r "pam_limits.so" /etc/pam.d/

# 查看 systemd 服务生效的限制
systemctl show <service> -p LimitNOFILE

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞