以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发、订阅专栏!欢迎扫码关注个人公众号,不定期推送热点文章!
本文已在 CSDN、知乎等平台陆续收到好评反馈,文中方法经多位小伙伴亲测有效,并且同样适用于欧拉系统。
笔者承诺本文永不设置 VIP 可读,供大家免费参考!欢迎大家转发起来,让更多需要的人看到!
如果本文确实可以帮到大家,请点赞、关注,感谢支持和鼓励!
目录
一、背景回顾
【Docker】Kylin V10 下 MySQL 容器内存占用异常的解决方法 一文中提到的问题虽然解决了,但是笔者因为一个疑问决定继续深入挖掘,最终找到了问题的根因,本文将作为前文的延续进行说明。
二、疑问是啥
细心的读者会发现,【Docker】Kylin V10 下 MySQL 容器内存占用异常的解决方法 中「解决取值问题」部分,实测同一操作系统下主机与容器的 open files 参数取值居然也不一致,笔者一直很困惑容器的 open files 取值为何与主机不一致,这个取值又是从哪里来的?
三、原因是它
笔者查阅资料后得知,Linux 系统通过 /etc/security/limits.conf 来限制打开文件的数量(nofile),并对应 ulimit -a 中 open files 的值。
而 Docker 对打开文件数量(nofile)的限制与 Linux 系统的限制则是完全隔离的!
Docker 守护进程通过 docker.service 文件的 LimitNOFILE 参数限制容器的 open files,笔者在安装 Docker 时使用了 LimitNOFILE=infinity 这个默认配置,导致 Kylin V10 下容器取值为 1073741816(即 2^30,笔者猜测由于系统特性或存在 BUG,Kylin V10 与 其他操作系统对应的 infinity 换算方式不同),因此问题的解决方法也可以如下:
编辑对应的 docker.service 文件,修改如下:
LimitNOFILE=1048576
保存退出后执行
systemctl daemon-reload && systemctl restart docker
四、持续深挖
此部分更新于 2024.8.29
对于之前的猜测(由于系统特性或存在 BUG,Kylin V10 与 其他操作系统对应的 infinity 换算方式不同),笔者在后续很长一段时间内还保持关注,并持续做过一些深入探究。
目前笔者在两方面找到一些蛛丝马迹,写在这里供大家参考和研究。
1、关于 LimitNOFILE
笔者查阅资料得知,Docker 关于 LimitNOFILE 变更历史如下:
- 2023 年 8 月:在 docker.service 中移除了 LimitNOFILE=infinity
- 2021 年 5 月:LimitNOFILE=infinity 和 LimitNPROC=infinity 重新添加回 docker.service,以与 Docker CE 版本的配置同步
- 2016 年 7 月:LimitNOFILE=infinity 更改为 LimitNOFILE=1048576
- 2016 年 7 月:LimitNOFILE 和 LimitNPROC 从 1048576 更改为 infinity
- 2014 年 3 月:原始 LimitNOFILE + LimitNPROC 设置为 1048576
2、关于 infinity
此外,笔者查阅 Github Issue 时看到一种说法,特定发行版或内核中 infinity 被限制为 1048576(即 2^20),后续的一些系统上(内核 或 systemd),这个 infinity 上限是 1073741816(即 2^30),Kylin V10 操作系统作为近几年推广的国产化系统,正好满足这个设定。
# GitHub Issue 原文
Yes, the limit always was intended to be infinity, but some versions of systemd didn't accept that special value; the "infinity" limit used to be 1048576 so it was set to that value, but newer kernels (or systemd) raised this to 1073741816, so the infinity value is either 1048576 or 1073741816 (depending on your distro)
五、写在最后
本文介绍的解决方法可以作为一种通用方案使用,以规避 MySQL 以外的其他容器出现相同问题。
当然在具体实践中,如果遇到无法修改 LimitNOFILE 的情况(如实施交付时无权接触和修改客户环境的 docker.service 文件),还是可以使用之前的解决方法作为备用方案。