环境:
我使用 CentOS-7 作为虚拟机管理程序,在libvirt
. 每个容器都运行 CentOS-7 的最小安装以及精简的 FreePBX(Asterisk、Apache、MySQL + 位)。
症状:
有16个容器正在运行,没有任何问题。当我再次启动一个容器时,它确实会启动,但在第 17 个容器启动后,我无法systemctl start/restart/stop <anything>
在任何容器中执行以下操作:
[root@test-lxc ~]# systemctl restart dnsmasq
Error: Too many open files
Run Code Online (Sandbox Code Playgroud)
诊断:
以下诊断和计数是在第 17 个 LXC 运行且systemctl restart blabla
出现故障时完成的:
我可以 ssh 到任何 LXC 并运行最基本的命令,例如 ls 等。我怀疑该限制在某种程度上只影响systemd
.
我试图理解我在哪里/为什么达到了极限。
[root@lxc-hypervisor]# sysctl fs.file-nr
fs.file-nr = 29616 0 12988463
Run Code Online (Sandbox Code Playgroud)
这没有经过调整,这只是默认安装的情况。与上述相同,最大(最后)值 = 12988463 由虚拟机管理程序报告,并且也在每个 LXC 内部。每个 LXC 中也报告了非常相似的第一个值,略低于 30000。
当我尝试计算每个 LXC 内所有进程的文件描述符时,我在每个 LXC 中得到的顺序是 400 ~ 500。
for pid in $( ls /proc/ | grep -E -e "^[0-9][0-9]*\$" ); do
ls -l /proc/${pid}/fd/ 2> /dev/null | wc -l
done
Run Code Online (Sandbox Code Playgroud)
没有虚拟机管理程序本身,总数约为 9000 (9k)。当我在虚拟机管理程序上运行它时,我通常会得到可疑的接近值,略高于 10000,例如 10005。
问题:
Q1. 限制是从哪里设置或继承的?
Q2。为什么限制会影响systemctl start/stop/restart blah
命令,但我仍然可以 ssh 进入 LXC,运行诸如带有大量分叉循环的 bash 脚本之类的命令,尽管是以 root 身份。
Q3。如何调整限制以允许运行更多 LXC。据我所知,RAM 和其他资源并不是限制。
我确实阅读了许多有关文件描述符限制主题的文章和答案,但我没有看到我的系统在哪里达到了限制。
也欢迎任何其他相关信息。
A.B*_*A.B 11
我相信你没有达到全局限制,而是inotify限制。这会在运行systemd 的容器上看到,因为systemd使用inotify工具进行簿记,但主机也会受到影响。不使用systemd(也不使用inotify )的容器可能不会受到影响。
/proc/sys/fs/inotify/max_user_instances
:这指定了每个真实用户 ID 可以创建的 inotify 实例数量的上限。
如果只使用非rootless(即:容器中的root才是真正的root )容器,那么root用户就成为瓶颈。让多个容器使用相同的无根用户映射也会为此容器的根用户造成此类瓶颈(但不会影响主机)。默认值为 128,对于容器使用来说太少了。
CentOS7(或 Rocky9)不包含 LXC 的任何默认设置。基于 Debian 的发行版在主机上包含此文件:
/etc/sysctl.d/30-lxc-inotify.conf
:
# Defines the maximum number of inotify listeners.
# By default, this value is 128, which is quickly exhausted when using
# systemd-based LXC containers (15 containers are enough).
# When the limit is reached, systemd becomes mostly unusable, throwing
# "Too many open files" all around (both on the host and in containers).
# See https://kdecherf.com/blog/2015/09/12/systemd-and-the-fd-exhaustion/
# Increase the user inotify instance limit to allow for about
# 100 containers to run before the limit is hit again
fs.inotify.max_user_instances = 1024
Run Code Online (Sandbox Code Playgroud)
因此,您应该通过在主机上创建此文件来执行相同的操作。立即生效(在主机上):
sysctl -w fs.inotify.max_user_instances=1024
Run Code Online (Sandbox Code Playgroud)