在具有多个 LXC 的环境中启动服务时出现“错误:打开的文件太多”

在具有多个 LXC 的环境中启动服务时出现“错误:打开的文件太多”

环境:

我使用 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

诊断:

以下诊断和计数是在第 17 个 LXC 运行且systemctl restart blabla出现故障时完成的:

我可以 ssh 到任何 LXC 并运行最基本的命令,例如 ls 等。我怀疑该限制在某种程度上只影响systemd.

我试图理解我在哪里/为什么达到了极限。

[root@lxc-hypervisor]# sysctl fs.file-nr
fs.file-nr = 29616      0       12988463

这没有经过调整,这只是默认安装的情况。与上述相同,最大(最后)值 = 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

没有虚拟机管理程序本身,总数约为 9000 (9k)。当我在虚拟机管理程序上运行它时,我通常会得到可疑的接近值,略高于 10000,例如 10005。

问题:

Q1.限制是从哪里设置或继承的?

Q2。为什么限制会影响systemctl start/stop/restart blah命令,但我仍然可以 ssh 进入 LXC,运行诸如带有大量分叉循环的 bash 脚本之类的命令,尽管是以 root 身份。

Q3。如何调整限制以允许运行更多 LXC。据我所知,RAM 和其他资源并不是限制。

我确实阅读了许多有关文件描述符限制主题的文章和答案,但我没有看到我的系统在哪里达到了限制。

也欢迎任何其他相关信息。

答案1

我相信你并没有达到全球极限,而是inotify限制。这会在运行的容器上看到系统因为系统使用inotify其记账便利,但主机也会受到影响。容器未使用系统(也不inotify)可能不会受到影响。

/proc/sys/fs/inotify/max_user_instances:

这指定了每个真实用户 ID 可以创建的 inotify 实例数量的上限。

如果只是非无根(即:容器里才是真正的)容器正在使用中,那么用户成为瓶颈。让多个容器使用相同的无根用户映射也会给该容器带来这样的瓶颈用户(但不影响主机)。默认值为 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

因此,您应该通过在主机上创建此文件来执行相同的操作。立即生效(在主机上):

sysctl -w fs.inotify.max_user_instances=1024

相关内容