在哪里可以找到默认的 docker ulimit 设置?

在哪里可以找到默认的 docker ulimit 设置?

我一直在尝试了解roribio16/alpine-sqs在一台机器上运行 docker 镜像时遇到的问题。每当我尝试在不指定任何其他设置的情况下运行镜像时,docker run roribio16/alpine-sqs

[xxxx@yyyy ~]$ docker run roribio16/alpine-sqs
2021-05-29 15:48:41,216 INFO Included extra file "/etc/supervisor/conf.d/elasticmq.conf" during parsing
2021-05-29 15:48:41,216 INFO Included extra file "/etc/supervisor/conf.d/insight.conf" during parsing
2021-05-29 15:48:41,216 INFO Included extra file "/etc/supervisor/conf.d/sqs-init.conf" during parsing
2021-05-29 15:48:41,216 INFO Set uid to user 0 succeeded
2021-05-29 15:48:41,222 INFO RPC interface 'supervisor' initialized
2021-05-29 15:48:41,222 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2021-05-29 15:48:41,222 INFO supervisord started with pid 1
2021-05-29 15:48:42,225 INFO spawned: 'sqs-init' with pid 9
2021-05-29 15:48:42,229 INFO spawned: 'elasticmq' with pid 10
2021-05-29 15:48:42,230 INFO spawned: 'insight' with pid 11
cp: can't stat '/opt/custom/*.conf': No such file or directory

> [email protected] start /opt/sqs-insight
> node index.js

15:48:42.605 [main] INFO  org.elasticmq.server.Main$ - Starting ElasticMQ server (0.15.0) ...
Loading config file from "/opt/sqs-insight/lib/../config/config_local.json"
15:48:42.929 [elasticmq-akka.actor.default-dispatcher-2] INFO  akka.event.slf4j.Slf4jLogger - Slf4jLogger started
Unable to load queues for  undefined
Config contains 0 queues.
library initialization failed - unable to allocate file descriptor table - out of memorylistening on port 9325
2021-05-29 15:48:43,233 INFO success: sqs-init entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:43,233 INFO success: elasticmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:43,234 INFO success: insight entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:43,234 INFO exited: sqs-init (exit status 0; expected)
2021-05-29 15:48:44,318 INFO exited: elasticmq (terminated by SIGABRT (core dumped); not expected)
2021-05-29 15:48:45,322 INFO spawned: 'elasticmq' with pid 67
15:48:45.743 [main] INFO  org.elasticmq.server.Main$ - Starting ElasticMQ server (0.15.0) ...
15:48:46.044 [elasticmq-akka.actor.default-dispatcher-2] INFO  akka.event.slf4j.Slf4jLogger - Slf4jLogger started
library initialization failed - unable to allocate file descriptor table - out of memory2021-05-29 15:48:47,223 INFO success: elasticmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:47,389 INFO exited: elasticmq (terminated by SIGABRT (core dumped); not expected)
2021-05-29 15:48:48,393 INFO spawned: 'elasticmq' with pid 89
15:48:48.766 [main] INFO  org.elasticmq.server.Main$ - Starting ElasticMQ server (0.15.0) ...
15:48:49.066 [elasticmq-akka.actor.default-dispatcher-3] INFO  akka.event.slf4j.Slf4jLogger - Slf4jLogger started
library initialization failed - unable to allocate file descriptor table - out of memory^C2021-05-29 15:48:49,559 INFO success: elasticmq entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2021-05-29 15:48:49,559 WARN received SIGINT indicating exit request
2021-05-29 15:48:49,559 INFO waiting for insight, elasticmq to die
2021-05-29 15:48:49,566 INFO stopped: insight (terminated by SIGTERM)
2021-05-29 15:48:50,431 INFO stopped: elasticmq (terminated by SIGABRT (core dumped))

经过一番谷歌搜索,我发现这个帖子有人在运行其他随机图像时遇到了同样的问题,然后发帖称他们设法通过在运行图像时设置一些 ulimit 来使图像运行,这对我也有用(docker run --ulimit nofile=122880:122880 roribio16/alpine-sqs)。

当我没有使用此配置时,我检查了容器内部设置的 ulimits

docker exec -it ca bash
 $ ulimit -a

发现nofile设置太高了,认为如果同时打开太多文件,则会导致容器内存耗尽。但我不太了解这是如何工作的,因此如果有人能就该特定主题做出澄清,我将不胜感激。

无论如何,我之所以这么胡言乱语,是想尝试找到默认 docker 容器 ulimits 的设置位置,因为我不明白为什么在我使用的机器上它们这么高。我有另一台机器没有这个问题。

我可以找到很多方法来更改默认限制,但似乎没有太多关于这些限制在哪里设置的信息。我理解根据docker 文档如果未设置自定义值,则 ulimits 应该从我的系统继承,但据我所知,我的系统 nofile 设置比我在容器中看到的要低得多。

(两台机器都运行 manjaro linux,但没有这个问题的是 XFCE,而有这个问题的是 KDE)。

答案1

我找到了这个问题的解释这个帖子

在某些时候,Java 8 似乎会为定义的打开文件数量分配内存。如果此数字太大,java 进程将退出并报告错误消息:

库初始化失败 - 无法分配文件描述符表 - 内存不足 *** JBossAS 进程 (85) 收到 ABRT 信号 ***

在我的例子中,我尝试在 Docker 容器中使用 Java 8 启动 Wildfly 17 应用程序服务器。应启动服务器的用户设置了大量打开的文件:

bash-4.2$ ulimit -a 
core file size          (blocks, -c) unlimited 
data seg size           (kbytes, -d) unlimited 
scheduling priority             (-e) 0 
file size               (blocks, -f) unlimited 
pending signals                 (-i) 29783 
max locked memory       (kbytes, -l) 64 
max memory size         (kbytes, -m) unlimited 
open files                      (-n) 1073741816 
pipe size            (512 bytes, -p) 8 
POSIX message queues     (bytes, -q) 819200 
real-time priority              (-r) 0 
stack size              (kbytes, -s) 8192 
cpu time               (seconds, -t) unlimited 
max user processes              (-u) unlimited 
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

在当前 Docker 版本(对我来说:20.10.21)中,默认打开文件数为infinity。您必须注意,docker 守护进程(dockerd)的打开文件数量与启动容器时打开的文件数量不同。

打开文件的数量docker 守护进程在 systemd 服务配置文件中配置。您可以使用命令覆盖它systemctl edit docker.service。这将在中创建一个新文件/etc/systemd/system/docker.service/docker.service.d/。在本例中,我将文件命名为override.conf。我设置了以下属性:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --default-ulimit nofile=8096:8096 --containerd=/run/containerd/containerd.sock
Environment="HTTP_PROXY=http://xxx.xxx.xxx.xxxx:yyyy"
Environment="HTTPS_PROXY=http://xxx.xxx.xxx.xxxx:yyyy"
**# LimitNOFILE=infinity**

请注意,我没有覆盖infinitydocker 守护进程本身的默认值 ()。您可以使用命令# cat /proc/$pid/limits($pid = process id) 检查为进程设置的实际打开文件数量。这将打印出 docker 守护进程的大量打开文件:

# cat /proc/828/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        unlimited            unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             unlimited            unlimited            processes
Max open files            1073741816           1073741816           files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       29783                29783                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

正如你已经发现的那样链接帖子,您必须限制启动 docker 容器时打开的文件数量。容器内的进程从此值 (-> ) 继承。这是通过docker 守护进程的ulimit -a程序参数实现的,该参数也在我的服务配置文件中定义。8096 个打开文件的值对于我的 wildfly 应用服务器来说已经足够了,并为我解决了这个问题。--default-ulimit nofile=8096:8096/etc/systemd/system/docker.service.d/override.conf

我希望这个答案有助于澄清这个问题。

相关内容